Anvil. Back to home
v1.2 · Effective 2026-11-04

This is Anvil’s current public statement. Where a signed Master Services Agreement or Data Processing Addendum differs from this page, the signed agreement governs. If you need a signed DPA, email henry@anvilcontrol.ai — the DPA page says exactly where we stand on producing one.

Privacy

Anvil sits in front of actions that move money, delete records, or send messages. To do that we necessarily see something about those actions. This page says exactly what — surface by surface — and nothing more than we can point to in the running code.

Everything below describes Anvil Cloud, the hosted service at anvilcontrol.ai. If you run Anvil self-hosted, the data stays in your own infrastructure and this page describes only the marketing site and the ghost intake, if you use them.

The short version

Who we are and how to reach us

Anvil is operated by Henry Miller, an individual trading as Anvil, based in San Francisco, California. Privacy questions, access requests, deletion requests, and DPA requests all go to henry@anvilcontrol.ai, and a human reads that inbox every business day. There is no support queue between you and the person who wrote the service.

We have not incorporated an operating entity yet. When we do, we will name it here and on the Terms, and we will notify customers under a signed agreement. A registered mailing address will follow the entity — we would rather leave that blank than print an address that is really a home.

Our roles: when we are the controller, and when you are

We wear two hats, and which one applies depends on the data.

For your account, our request and security logs, the marketing site, and support correspondence, Anvil is the controller — we decide why that data exists and what happens to it, and the rights described below are exercised against us directly.

For customer data flowing through a guarded action — the amounts, action names, counterparties, approvals, and payloads inside your decision records — you are the controller and Anvil is your processor, acting on your instructions under the DPA. If one of your end users asks us about their data, we will not answer for you: we refer them to you and tell you it happened.

If you are unsure which hat applies to something, ask, and we will tell you.

What we collect, by surface

1. The ghost intake

The ghost intake at go.anvilcontrol.ai/ghost is deliberately anonymous — you can use it without an account. It is also the surface where you hand us the most sensitive material, so it gets the most specific disclosure. The wording below says the same thing as the disclosure rendered on the intake screen itself, and a test holds the retention numbers in the two places to the same value, so they cannot drift apart quietly.

If you ask us to email you a copy of your ghost report, that email — including your address and the report PDF — is sent through our email provider (see the sub-processor list).

2. Account and sign-in

Sign-in is Google OAuth with the scope openid email profile. From what Google returns we store your verified email address — which becomes your workspace identity — Google's account identifier for you, the email-verified flag, your display name, and the URL of your profile photo, with created and updated timestamps. Your session record holds a session id, your user id, email, name, photo URL, and first-seen and last-seen timestamps.

Both records live in Redis and expire 30 days after they were last written, so an account you stop using ages out on its own. We do not receive your Google password, and we do not read your mail, your files, or your contacts.

For each workspace we store the workspace name, the verified email, and a creation timestamp. A workspace email supplied during provisioning is a separate field from the address you signed in with, and only a Google-verified sign-in proves ownership of an address — we do not treat a self-declared email as an ownership claim.

3. API keys

An Anvil API key is stored as a hash plus a short non-secret prefix, a label you choose, and created / last-used / revoked timestamps. The key itself is not recoverable from our database; if you lose it, you rotate it.

4. Runtime decision records

When your code calls Anvil to guard an action, we record what we decided and why. Per call that means: an identifier and idempotency key, the action name, the policy and mode in effect, the outcome and status, the amount in cents where the action has one, the number of attempts, the reason and the specific rule that blocked it, timestamps, duration, a trace id, and a hash of the payload. Approval and override records additionally carry the operator's email, so a maker-checker decision is attributable to a person.

Sensitive-data (egress) checks record the classes of sensitive data found and the field names redacted — not the values.

Blocked calls. There is one place where we store the call body itself: when an enforce-mode rule blocks a call, Anvil captures the input body — up to 128 KB — so that an operator who reviews and overrides the block can retry the original request. That body is whatever your code was about to send, so it can contain personal data, payment references, or confidential business detail; it exists only to make an operator-reviewed retry possible. Records carry an explicit flag for whether the body was captured, so the interface never implies a retry it cannot perform. On every other path — ghost mode, allowed calls, dry runs — we hold the fingerprint, not the body.

Audit integrity. Audit records can be linked into a tamper-evident hash chain, which anvil verify checks. HMAC signing of that chain is off unless you set a signing key (ANVIL_AUDIT_SIGNING_KEY); with no key set, the chain is tamper-evident but not cryptographically attested, and we label it that way in the product rather than implying otherwise.

5. Product usage

Per guard call we record the workspace, the action name, the idempotency key, the outcome, and the duration, so we can show you your own usage and so we can tell whether the service is healthy. This is operational metadata, not content.

6. Ordinary web and email

The marketing pages, docs, pricing, and this page are static and carry no analytics scripts, no advertising pixels, and no third-party cookies. Our servers write standard request logs (IP address, user agent, path, status, timing) for security and debugging. Cookies we set are functional: a session cookie after sign-in, and short-lived cookies that carry a sign-in across our own origins.

If you subscribe to status-page notifications, we store your email address or webhook URL, a double-opt-in confirmation token, and the timestamps of confirmation and unsubscribe.

What we do not do

Sub-processors

These are the third parties that can process customer data on our behalf. The first five rows are in active use today. The two AI rows are conditional: they process nothing unless a deployment has AI analysis enabled *and* a provider key configured, and on anvilcontrol.ai today it is off. We do not list aspirational vendors, and we do not pad the list to look bigger.

Sub-processorWhat it does for usWhat it can seeWhere
RailwayHosts the application services, the Postgres database, and RedisEverything stored by the serviceUnited States
CloudflareCDN and static hosting for the anvilcontrol.ai apexRequest metadata for the marketing siteGlobal edge, US origin
GitHub (Microsoft)Source hosting and the build pipeline, and storage of the daily database backup as a private build artifactA full copy of the database, inside that backup artifactUnited States
ResendTransactional and alert email (ghost reports, status-page confirmations, alerts)Recipient address and message contentUnited States
GoogleOAuth sign-in only, scope openid email profileYour Google account identity, at sign-inUnited States
AnthropicAI-assisted analysis — only when the deployment has AI analysis enabled with an Anthropic keyA redacted excerpt of content submitted for analysisUnited States
Google (Gemini)AI-assisted analysis — only when the deployment has AI analysis enabled with a Gemini keyA redacted excerpt of content submitted for analysisUnited States

The two AI rows are conditional on purpose. On a deployment where AI analysis is not enabled, no content reaches either provider, and we will not claim otherwise to look more capable.

The GitHub row is there for a specific reason: our host does not provide native Postgres backups on our current plan, so the daily backup is taken by our own build pipeline and kept there. That means a full copy of the database exists in a second place, readable by repository collaborators. It is a deliberate trade for having a restorable backup at all, and it belongs on this list rather than in a footnote.

Customer-directed integrations are different. When you connect a system you own — Stripe, Datadog, CloudWatch, Splunk, Temporal, Airflow, Twilio, n8n, LangSmith, Langfuse, Helicone — Anvil pulls *from* that provider using credentials you supply. That is your integration under your agreement with that provider, not our sub-processing of your data, and Anvil holds the credential in memory for the pull window and never returns it to the browser.

Changes. We maintain this list as the current one. Customers under a signed agreement are notified before a new sub-processor starts processing their data, with the objection procedure set out in the DPA.

International transfers

Anvil Cloud is hosted in the United States, and our sub-processors above process in the United States. If you are outside the US, using the hosted service means your data is transferred to and processed in the US. We do not operate an EU or UK data residency option today, and during beta the service is aimed primarily at US customers.

Where a transfer mechanism such as the EU standard contractual clauses or the UK addendum is required, a signed DPA is the instrument that carries it. A public page cannot execute those clauses — see the note at the top of the DPA for exactly where we stand on producing one.

Sign-up abuse controls use counters keyed by hashed network identifiers, rather than email addresses or raw IP addresses. Redis attempt counters expire after two minutes. Expired workspace-creation counters are removed during later successful sign-up activity; inactive counters can remain until that cleanup runs.

Retention

We would rather publish what the code does than a schedule it does not implement.

WhatHow longNotes
Ghost intake log or config textNot retainedParsed in memory; never written to a file or a database row
Ghost intake report and its PDFUp to 30 min (job store) / up to 12 h (memory)Held so the report can be rendered, downloaded, and emailed. Dropped on restart
Ghost intake session countersUp to 12 hoursIn memory only
Connector credentialsThe pull window, up to 12 hoursIn memory only, never returned to the browser
AI inference cacheWhile AI analysis is enabledExists only on deployments with AI analysis on
Sign-in and session records30 days after last useIn Redis; expires on its own
Idempotency records24 hours by defaultThis is the duplicate-suppression window, tunable per call
Decision records, receipts, policies, usage eventsRetained until deletion is requestedNo automatic expiry is implemented today
Database backups14 daysA daily dump kept as a private build artifact at GitHub; 14 days is that artifact's retention
Request and security logsShort operational window at our hostNot a customer-facing retention commitment

Production retention and deletion periods for decision records are an open decision, not a settled one, and we are not going to invent one on a web page. Nothing in the code expires a decision record today; it is there until you ask us to remove it. If you need a contractual retention period, say so and we will agree it in a signed DPA. Backups, security logs, records under legal hold, and records we are required to keep may persist for a limited period after a deletion request — a deletion request reaches live systems first and ages out of the 14-day backup window after that.

Why we are allowed to process it

Where the GDPR or the UK GDPR applies to data for which we are the controller, these are our lawful bases:

What we processBasis
Your account, workspace, and the service itselfPerformance of our contract with you
Request and security logs, abuse prevention, debuggingOur legitimate interest in keeping the service working and safe, balanced against your interests
Alert and status-page email you asked forYour consent, withdrawable at any time
Records we are required to keep, and responses to lawful requestsCompliance with a legal obligation

Where we are your processor rather than the controller, your instructions are the basis, and the DPA is the operative document.

Your choices and requests

Email henry@anvilcontrol.ai to access, correct, export, or delete your data, to object to or restrict a processing activity, or to withdraw consent. We confirm receipt within one business day and complete the request within 30 days. If something is genuinely going to take longer, we will tell you before the 30 days are up and say why, rather than going quiet.

If you are in the EU, the UK, or Switzerland, you may also complain to your data protection supervisory authority, and if you are in California you may complain to the California Privacy Protection Agency or the Attorney General. We would rather you came to us first so we can fix it, but that is your right and not conditional on trying us.

Where a privacy law gives you rights beyond the above, those rights apply.

Security

Security has its own page. The security policy opens with what actually protects your data — encryption, tenant isolation, access control, credential storage, backups and the daily restore test — and then covers the vulnerability reporting channel, our response-time commitments, and what is in and out of scope. The contractual version of the same controls is section 5 of the DPA.

In short: transport encryption everywhere, encryption at rest at our host and at GitHub for the backup artifact, tenant isolation enforced at the query layer and regression-tested, API keys stored only as hashes, and one person with production access.

We hold no SOC 2, no ISO 27001, and no completed third-party penetration test. If one of those is a requirement for you, tell us and we will tell you honestly where we are rather than where we would like to be.

No system is completely secure, and for a customer under a signed agreement the security schedule in that agreement — not this page — defines what we have committed to.

Children

Anvil is a developer tool sold to businesses. It is not directed to children, and we do not knowingly collect personal information from anyone under 16.

Changes to this statement

This page is generated from a reviewed source document, so what you read here is what was reviewed. Every version carries a version number and an effective date at the top, and the "What changed" note at the foot of the page says what moved and when. Superseded versions stay in our public source history, so "we updated the privacy statement" is something you can check rather than take on trust.

For a material change affecting customers under a signed agreement, we notify them rather than relying on you re-reading a web page.

What changed in v1.2

Superseded versions remain in our public source history, so a change to this page is something you can check rather than take on trust.