alden

Security model

What Alden protects, against whom, and how. For reporting a problem, see SECURITY.md.

What's worth protecting

Who might try

How Alden handles it

Tokens. Your GitHub token, and the Anthropic or OpenAI API key if you stored one with alden auth model or in Settings, live in the OS keychain, or, where there's no keychain, a file only your user can read. Alden never logs them, never sends them anywhere but GitHub and the key's own provider (Anthropic, or OpenAI), and never puts them in a prompt. alden auth model reads the key without echoing it; the web UI's key field is write-only (the server stores the key and answers only where the key comes from, never the key), and alden auth status, alden doctor and the session API name the source, never the key. Other model credentials come from the provider's own configuration and stay with its SDK.

alden ui. The server listens on 127.0.0.1 only. Every API call must carry a random session key, which reaches the browser in the link's #fragment (never sent to a server or in a Referer) and is compared in constant time. The server also rejects any Host or Origin that isn't its own, which stops other websites, including through DNS rebinding. It sends no CORS headers, so other pages can't read its responses. Pages get a strict Content Security Policy (only Alden's own scripts, styles and images, plus GitHub avatars), can't be framed, and send no referrer. Every route the server answers is listed in Architecture.

The desktop app. It runs the bundled alden as alden ui --json and shows that server in its window. The window only loads Alden's own server on 127.0.0.1 (and a bundled loading page), with the same session key and checks as a browser. While your Mac has been idle for 3 minutes, the app calls the local POST /api/prepare once a minute to brief the top PRs waiting on you. Those briefings ask the model only if background.model is true in your user config; a repo's .alden.toml can't set it, so a repo can't make you spend. They're kept in the running server's memory only.

alden mcp. Briefings, PR text and code, and your memory notes go into your AI coding tool's context, and from there to that tool's model provider, under your agreement with it. Everything that came from a PR is labelled as written by its author, and the tool is told to treat it as data, never instructions. A PR can still try prompt injection on an assistant that has tools of its own, so keep your tool asking before it runs commands. The MCP tools write only to Alden's own database and post nothing to GitHub: alden_draft_comment drafts a comment or a reply, and there is no tool that sends one or resolves a thread. See Alden in your AI coding tool.

Posting to GitHub. Alden posts only what you send: one review, from the UI's Send button or alden send after you confirm what it shows, made of exactly the comments, replies and body you see (Alden adds nothing), and the threads you ticked to resolve. Nothing sends in the background, from a model, or from an AI coding tool, and a prompt injected through a PR can at most draft a comment you then read before sending. No request is retried automatically, so a timeout can't post a review twice. A review with replies takes a few requests (a pending review, the replies, the submit, then the resolves); if one fails before the submit, Alden deletes the pending review, so nothing half-posts. It needs no scope Alden didn't already ask for (repo). Drafts stay in the local database until you send or delete them. See Comments and sending a review.

PR content.

Secrets in diffs. Before a prompt is sent, anything that looks like a credential is replaced with a placeholder that keeps only its kind and length (see Privacy and data). Detection is heuristic, so use --no-llm for changes you know contain secrets, and rotate any secret that was committed.

Your data. Nothing goes to Alden's developers except anonymous usage stats, and only if you opt in (Usage stats). Feedback, memory, notes, spend and comment drafts stay in the SQLite database ~/.alden/alden.db, settings in ~/.alden/config.toml, and PR checkouts in ~/.alden/worktrees. alden feedback --export replaces repo names with a hash salted with a value that never leaves your machine, and each flag's title with a code salted fresh for each export, and drops paths, lines and notes; PR numbers, check ids, verdicts, times and the model stay. --full keeps everything.

Update check. alden --version and alden doctor ask the npm registry (registry.npmjs.org) for Alden's newest version, at most once a day. Nothing about you or your repos is sent. alden config set updates.check false or ALDEN_NO_UPDATE_CHECK turns it off.

Supply chain. Dependencies are audited before each release (pnpm audit), lockfiles are committed, and releases are built in CI from a tag, with macOS binaries signed and notarized.

Known limits