Security
How AgentValet protects your credentials, audit data, and the agents that act on your behalf.
This page is the engineering detail. The one-page statement of what is held where, who processes it, how long it is kept and which compliance claims are true today is the trust centre ; when the two disagree, the trust centre is the one we update first. If your security team needs a DPA, DPIA, or SOC 2 status confirmation, email [email protected] — see SOC 2 & compliance below.
Encryption at rest
Envelope encryption. Every stored credential is wrapped under a unique data encryption key (DEK) generated per credential. The DEK is itself wrapped under your tenant’s key encryption key (KEK), which lives in Azure Key Vault Premium and is HSM-backed. Only the wrapped values are persisted; the master key never leaves the HSM.
- Algorithm: AES-256-GCM for credential payloads. Each ciphertext carries its own random IV and an authentication tag, so tampering is detected on decrypt.
- Per-tenant isolation: each organisation has its own KEK. A compromise of one tenant’s wrapped DEK cannot decrypt any other tenant’s data.
- No plaintext anywhere we control: backups, replicas, snapshots all contain only the wrapped form.
- Operator access is metadata only. AgentValet engineers can read the existence of a credential row (who owns it, which platform, when rotated) but cannot read the cleartext.
Encryption in transit
- TLS 1.2+ on every public endpoint:
api.agentvalet.ai,app.agentvalet.ai,docs.agentvalet.ai,agentvalet.ai. - Ingress to the proxy is a Cloudflare Tunnel: the host has no public inbound port, and TLS terminates at Cloudflare. Dashboard, landing and docs are served from Cloudflare Pages.
- The proxy and the OAuth token broker run on one private Docker network on a single host in Sydney; the broker is not reachable from the internet.
- Cleartext credentials exist briefly in memory inside the proxy when a call decrypts → forwards → re-encrypts a response. The decrypted form is never logged.
Audit immutability
The audit_log table is append-only by construction.
- Postgres Row-Level Security (RLS). Two Postgres roles touch the
table. The proxy uses a write-only role with
INSERTonaudit_logand nothing else. The dashboard uses a read-only role gated by RLS so an authenticated owner sees only their own rows. Neither role hasUPDATE,DELETE, orTRUNCATEon the table. - No edit path from the application. There is no API or dashboard surface that mutates audit rows. The only way to alter history is to drop the table — which requires DB-owner credentials no application role holds.
- Forensic fields are Enterprise-opt-in.
ip_address,user_agent,geo_country,geo_city, andgeo_asnexist on every audit row but are leftNULLunless your org has forensic capture explicitly enabled in Settings → Privacy. Privacy-by-default; you choose when to start recording.request_idis not gated: it is thecorrelation_idthe proxy returns on every response, written on every plan so the row can always be found.session_idis caller-asserted and written whenever the agent supplies one.
See Audit & revocation for the user-facing behaviour.
Circuit breaker auto-suspension
When an agent misbehaves, AgentValet stops it before damage compounds.
- Threshold: 3 consecutive failures. Signature mismatch, scope denial,
proxy error, or upstream error all increment a per-agent counter. The
fourth consecutive failure is rejected with
circuit_breaker_openand the agent is moved tosuspendedstatus server-side. - Reset on success. Any successful call resets the counter to zero. There is no time-based decay — we want the breaker to stay open until either a human resumes the agent or the agent recovers genuinely.
- Human-in-the-loop reactivation. Suspended agents do not auto-resume. You investigate (the audit log shows the three failures), fix the underlying issue, and click Reactivate in the dashboard.
See Circuit breaker and the troubleshooting guide circuit_breaker_open.
No-plaintext logging
Three layers of defence against credentials ending up in logs or error traces:
- Secrets scan at the request boundary. A regex pattern set checks
inbound
datapayloads for AWS access keys, Stripe live keys, Slack tokens, GitHub PATs, Azure PATs, and generic bearer tokens. A match returns400 secret_detectedwith the matched pattern’s type, never the value. - Decrypt-in-memory-only. Credentials are unwrapped just-in-time inside the proxy call path and discarded after the outbound HTTP request resolves. The structured logger explicitly excludes the plaintext field.
- Pino redact list. Production logs run through a Pino redactor that
masks any field named
token,password,private_key,secret,authorization, orcookieregardless of where in the object tree it appears.
Identity & access
- Owners authenticate via Clerk. Every dashboard write that touches sensitive state requires a verified Clerk session.
- Agents authenticate via RS256 JWTs signed with a per-agent private
key. Public keys are stored in the
agentstable; the proxy verifies every call against the on-file public key. Compromise of one agent’s key affects only that agent. - Service-to-service calls to the key vault authenticate with a dedicated service principal whose access is limited to wrap/unwrap on the key hierarchy, and the vault’s firewall admits the proxy host only.
Subprocessors
| Subprocessor | Role | Data type |
|---|---|---|
| Vultr | Compute for the proxy and the OAuth token broker (Sydney) | Request bodies in transit; wrapped credentials at rest on the broker’s database volume |
| Cloudflare | Tunnel ingress to the proxy, Pages (dashboard, landing, docs hosting), DNS, edge caching | Request metadata, cached static assets |
| Supabase (Sydney) | PostgreSQL (audit log, credential metadata, RLS), Storage (MCPB bundle distribution), Edge Functions | All persisted application data |
| Clerk | Owner identity, session JWTs, MFA | Owner email, login events |
| Microsoft Azure Key Vault | Key Vault Premium: HSM-backed key-encryption keys for paid orgs and the master secret the Free-tier derived keys come from | Wrapped keys only; never a credential |
| Stripe | Subscription billing, payment processing | Billing email, payment metadata; no platform credentials |
| Resend | Transactional email (approval notifications, sign-in links) | Owner email addresses, notification subjects |
| The OAuth providers you connect | Each platform you authorise an agent for receives the calls the agent makes | Whatever the agent sends to that platform |
The OAuth token broker (Nango) is self-hosted on our own host and is not a third party. Each sub-processor’s standard data-processing terms apply. We do not share customer data with any other party.
Vulnerability disclosure
Email [email protected] with:
- A clear description of the issue
- Steps to reproduce (or a proof-of-concept)
- Any test credentials we should rotate after the report
We respond within two business days to acknowledge receipt and within ten business days with a triage decision. Critical issues (remote credential exposure, audit-log tampering, auth bypass) are treated as page-out events.
Safe harbour. Good-faith research that respects user privacy, avoids data exfiltration, and reports privately to the address above is welcome and will not be pursued legally or reported to law enforcement.
A machine-readable copy of this policy (RFC 9116) is served at
/.well-known/security.txt on agentvalet.ai, app.agentvalet.ai,
api.agentvalet.ai and docs.agentvalet.ai.
SOC 2 & compliance
Current status: we are not SOC 2 or ISO 27001 certified and no audit is under way. We can walk an Enterprise prospect through our current control mapping under NDA — email [email protected].
SLA. Uptime terms with service credits are agreed per Enterprise contract. Standard plans run on a best-effort basis. There is no public status page yet; the dashboard shows a banner when our own canary detects an outage.
DPA. A signable Data Processing Agreement is available on request via [email protected]. All Enterprise contracts include a DPA by default.
GDPR. AgentValet is built privacy-by-default: forensic capture is opt-in, plaintext credentials are never persisted, every persisted byte is encrypted at rest with per-tenant key isolation, and the audit log gives data subjects a complete record of how an agent handled their data. All data is hosted in Sydney, Australia today; per-customer region selection is not yet offered.
HIPAA / PCI-DSS. Not in scope today. If you need HIPAA or PCI-DSS attestation, talk to us about the Enterprise + custom deployment path — the architecture is compatible (envelope encryption + HSM + RLS + audit immutability all map onto the relevant controls), but the certifications themselves require a contract-specific scoping exercise.
Questions this page didn’t answer? Email [email protected] or, for contractual / privacy-officer questions, [email protected].