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). On paid plans the KEK lives in a hardware-backed (HSM) key vault and never leaves the HSM; on the Free plan it is a per-organisation key derived from a secret held in the same vault. Only the wrapped values are persisted.
- 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 network in Australia; 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 integrity
The audit_log table has no everyday edit path, but it is not immutable.
- Postgres Row-Level Security (RLS). The proxy writes through a role
with
INSERTonaudit_logand nothing else. Dashboard reads are gated by RLS so an authenticated owner sees only their organisation’s rows (or, for a member, their own). A few backend functions also insert rows (registrations, anomaly checks, actions recorded from the dashboard). No application role hasUPDATE,DELETE, orTRUNCATEon the table. - No edit path from the application. There is no API or dashboard surface that mutates audit rows. Two named database jobs do change the table: a daily retention purge deletes rows older than your plan’s window (never younger than 90 days), and claiming an anonymous trial into an existing account re-attributes that trial’s rows to the account. Rows are not hash-chained; per-decision tamper evidence comes from the signed governance receipts.
- 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
When an agent’s calls keep failing at the platform end, AgentValet pauses it rather than let it hammer a platform that is rejecting it.
- Thresholds. 3 auth failures (the credential was rejected and a
refresh didn’t fix it) or 5 upstream failures (network error, timeout)
open a per-agent breaker. The count restarts if 10 minutes pass
between failures. Signature and permission failures, and upstream error
responses such as a
404, don’t count. - Open, then half-open. While open, calls are refused with
circuit_breaker_openfor a 5-minute cooldown. The next call after that is a probe: success closes the breaker, failure re-opens it. - Not a suspension. The breaker doesn’t change the agent’s status. An owner can close it early with Reset circuit breaker on the agent page.
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(Secrets detected in request params) and the denial is audited with 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 our sign-in provider. Every dashboard write that touches sensitive state requires a verified 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 (Australia) | Compute for the proxy and the OAuth token broker | Request bodies in transit; encrypted credentials at rest |
| Cloudflare (global network) | Tunnel ingress to the proxy, Pages (dashboard, landing, docs hosting), DNS, edge caching | Request metadata, cached static assets |
| Supabase (Australia) | PostgreSQL (audit log, credential metadata, RLS), Storage (MCPB bundle distribution), Edge Functions | All persisted application data |
| Clerk (United States) | Owner identity, session JWTs, MFA | Owner email, login events |
| Microsoft Azure Key Vault (Australia) | Key Vault Premium: HSM-backed key-encryption keys for paid orgs, and per-organisation derived keys on the Free tier | Wrapped keys only; never a credential |
| Stripe (global, including the United States) | Subscription billing, payment processing | Billing email, payment metadata; no platform credentials |
| Resend (Tokyo, Japan) | 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 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. Credentials, grants and audit records are hosted in Australia; owner sign-in (Clerk, United States), email (Resend, Japan) and billing (Stripe) are processed overseas. Another region can be stood up on request.
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 + the audit trail 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].