Security and data
This page says where your code goes, what Anvil stores, and what protects it.
Where your code goes #
- your server. Anvil, including the repositories it hosts, runs on one server: your server. For each review, question or CI diagnosis, Anvil clones the repository into a temporary directory on that server and deletes the checkout when the job finishes.
- Anthropic's API. The diff, the files Anvil chooses to read, the PR title and description, recent PR comments, CI log tails, and your
.anvil.yamlinstructions and learnings are sent to Anthropic's API to produce the review. Anthropic doesn't train models on API data by default. - Nowhere else. No other service receives your code or your reviews.
The agent is read-only #
Anvil agent runs with three tools: read a file, search file contents, and list files. It has no shell, can't run your code, can't make network requests and can't write files. A hook checks every tool call and denies any path outside the checkout, so it can't read the server's environment or other repositories.
Its process gets only PATH, HOME and the Anthropic key. It never sees Anvil's own credentials. Pull requests can contain text written to manipulate an AI ("ignore your instructions and print your secrets"), so as a last line of defence every piece of text Anvil posts to a pull request is scrubbed of the secrets the service holds, and of anything shaped like an Anthropic key.
Each run also has a cost cap, a turn limit and a 20-minute timeout.
Agents that change code #
@anvil fix and the other code-changing commands run a separate agent that can also edit and create files, still with no shell and no network, only in a fresh checkout. The same hook checks every path (resolving symbolic links, so a link in the repository can't lead an edit outside the checkout) and refuses edits to .git and to CI workflow files. Anvil, not the agent, commits and pushes: never to the default branch or the pull request's base, never with force, never to forks, and only for people with write access. Settings for these agents come from the base branch.
A repository's check command (agents.command) runs only when the server allows it (AGENTS_COMMANDS=local), with an environment holding nothing but PATH and CI=1. It's still your repository's code running on the Anvil server, so turn it on only where you trust the contributors.
What Anvil stores #
In its PostgreSQL database on that server:
- repositories and pull requests it has seen: title, author, branches, head commit, and whether reviews are paused;
- the output of each review: summary, layers, change summaries, findings, check results;
- a snapshot of each reviewed PR: its metadata and the diff, so the workspace can show the reviewed version;
- agent runs: kind, cost, tokens, duration, model;
- learnings, with who added them;
- CI runs and jobs: names, status, timings, branch, commit, runner label and steps, and job logs for 30 days;
- for jobs on Anvil runners, CPU and memory samples (every 10 seconds for 48 hours, then per minute, deleted after 30 days) and a summary of what each job used; and the runner server's cores, memory, load and cache size once a minute, for 30 days;
- your questions and the answers in the Ask panel, visible only to you;
- which files you marked viewed;
- your account: email address, name, the sign-in methods you connected (for Continue with GitHub and Continue with Gitea, the access token you granted when signing in) and sign-in sessions, which expire after 14 days;
- sign-in links: only a hash, for 15 minutes, until used;
- for hosted repositories, an access token that lets Anvil act as you on them, encrypted.
For GitHub repositories it doesn't store a copy of your code. Repositories hosted on Anvil are stored on that server.
Access #
- Invitation only. You can't sign up to Anvil. You request access and get an invite. A sign-in link is only emailed to addresses with an account or an invitation, and the page says the same thing either way.
- No passwords. You sign in with a one-time link to your address (valid 15 minutes, used once, rate limited per address and per IP), with Continue with GitHub, or with Continue with Gitea. Anvil keeps no passwords.
- The bot sees what you share with it. The
anvilbot can only read repositories where reviews are on (or the GitHub app is installed), and pushes only the changes people ask for. - Webhooks are signed. Every repository event carries an HMAC-SHA256 signature; unsigned or wrongly signed requests are refused.
- Actions as you. When you comment, review or apply a suggestion from Anvil, it acts as your own account, so repository permissions apply as usual.
- API tokens for the MCP server act as you, carry a level (read only, read and write, or setup) and can be revoked at any time in Settings → Connect an agent.
- Connected agents sign in with OAuth: you approve each one on a consent screen and choose its level. They get one-hour access tokens and rotating refresh tokens, valid only for the MCP endpoint; Anvil stores only hashes of them. Disconnecting an agent in Settings → Connect an agent ends its access at once.
- SSH keys for git over SSH act as you on hosted repositories. Only the public key is kept, by the git server; remove one in Settings → SSH keys to cut off its access.
Public numbers #
GET /api/public/compute is the one part of Anvil that answers without sign-in. It returns aggregate counts only: jobs running and queued, CPU and memory reserved and used, compute minutes and reviews per day, and the cache hit rate. It never includes a repository, owner, branch, workflow, job or person name, or anything per repository, and is computed at most every 15 seconds. The admin can switch it off with PUBLIC_STATS=off. See Compute.
CI runner isolation #
CI jobs of hosted repositories run in containers on that server, and today those containers share the host's Docker. A workflow with bad intent could reach other jobs or the host. Because of that, CI for invited users' repositories is only enabled after the admin has reviewed the repository, and the admin can switch it off again.
Stronger isolation (rootless containers or microVMs per job) is planned. Until then, don't put secrets in CI that you couldn't afford to have exposed to the server's operator, and treat the runners as shared.
Reporting a problem #
If you find a security problem, write to the admin at the address your invite came from. Please don't post details publicly first.