Security Architecture
Technical reference for Clevername’s layered defense-in-depth architecture: how credentials are stored, how agents are governed, and what the platform can and cannot protect against.
Clevername is an agent governance platform designed with security as a primary constraint, not an afterthought. The core security thesis: every AI agent should be locked to its governed mandate — continuously, from governance through every action it takes. Enterprises should be able to connect all their AI tooling through a single policy-enforced gateway without ever trusting that gateway with their most sensitive data unless they explicitly choose to. Users who want zero server-side visibility of their stored logs can enroll in passphrase-derived zero-knowledge I/O-log encryption — the key never leaves their device, so Clevername cannot read those stored logs. (Provider API keys are held server-side in Secret Manager + CMEK, since the gateway must use them to route calls.) Teams that need automated agents make an informed, explicit grant. Everything in between is configurable per organization.
1. Key Custody & Zero-Knowledge I/O Encryption
Two kinds of sensitive data flow through an agent governance platform: the API keys that authorize calls to Anthropic, OpenAI, Google, and other providers, and the request/response (I/O) content that passes through the gateway. Clevername handles them differently and is precise about which is zero-knowledge and which is not.
Provider API keys — server-side custody (not zero-knowledge)
Provider keys are stored server-side in GCP Secret Manager, wrapped with Cloud KMS (CMEK). Because Clevername is a gateway that routes and governs calls on the agent’s behalf, the backend must be able to decrypt and use the key — so this is not zero-knowledge, by design. Keys are never written to the application database in plaintext; they live only in Secret Manager and are fetched into memory at call time. This is the standard model used by API gateways (Stripe, Twilio, AWS) and is disclosed at key-entry time. A passkey-derived, client-side zero-knowledge vault for provider keys — where even Clevername could not read them — is on the roadmap and not yet enabled.
I/O logs — zero-knowledge at rest (opt-in)
Users can enroll in zero-knowledge encryption of their stored request/response logs from the privacy settings. The scheme:
Your passphrase (never leaves the browser)
│
▼
PBKDF2-SHA256 (600,000 iterations, per-user salt) → KEK
│
▼
RSA-OAEP-2048 keypair generated in-browser
• public key → uploaded to hub-core (encrypts on the write path)
• private key → wrapped with the KEK (AES-256-GCM), stored as ciphertext
│
▼
Per record: hub-core encrypts content with a random DEK and wraps
that DEK to your public key. Only your browser — after deriving the
KEK from your passphrase — can unwrap the DEK and read the content.Hub-core holds only your public key and the wrapped private-key blob; it has no way to unwrap stored logs. One honest caveat: the gateway necessarily sees request/response plaintext transiently in memory while it scans and routes the call, then encrypts it and drops the plaintext. So the guarantee is precise — zero-knowledge at rest (Clevername cannot read your storedlogs), not “we never see plaintext at all.”
| Action | Can the server do it? |
|---|---|
| Read your stored I/O logs (ZK enabled) | No — stored as ciphertext; private key never leaves your browser |
| See request/response plaintext during a live call | Yes — transiently, to scan and route, then encrypted + dropped |
| Decrypt your stored logs without your passphrase | No — KEK is derived client-side only |
| Be compelled to produce your stored logs in plaintext | No — server cannot produce what it cannot decrypt |
| Read or use your provider API keys | Yes — provider keys are server-side (Secret Manager + CMEK), by design |
2. CMEK — Cloud KMS Key Wrapping
By default, GCP Secret Manager encrypts stored data with Google-managed keys. Clevername adds a CMEK layer: a Cloud KMS key wraps the data encryption key for every stored secret. On the default multi-tenant deployment this is a single shared, Clevername-managed KMS key — not a per-tenant key, and not one the customer owns or controls. Practical consequences:
- Secrets are wrapped by a Cloud KMS (CMEK) key, adding an encryption layer above Google’s default at-rest encryption
- Disabling the KMS key immediately denies access to all CMEK-wrapped secrets (break-glass)
- The KMS key has its own audit trail separate from Secret Manager
- Key rotation policy is configurable and verifiable
Implementation
Cloud KMS (us-east1)
└── Keyring: clevername-user-secrets
└── Key: user-secret-key (AES-256, software-protected)
│
▼ wraps/unwraps DEK per secret version
Secret Manager
├── clevername-key-{user_id}-{provider}
├── clevername-mcp-{user_id}-{server_id}
├── clevername-org-key-{org_id}-{provider}
└── clevername-team-key-{team_id}-{provider}Every secret uses user_managed replication pinned to us-east1with the KMS key as the CMEK reference. Google’s Secret Manager service agent uses the KMS key to wrap the data encryption key (DEK); the DEK encrypts the actual payload. The KMS key itself never leaves the HSM.
Revocation (Break-Glass)
# Immediately deny all access to CMEK-wrapped secrets gcloud kms keys versions disable 1 \ --location us-east1 \ --keyring clevername-user-secrets \ --key user-secret-key \ --project clevername-488215 # Restore gcloud kms keys versions enable 1 \ --location us-east1 \ --keyring clevername-user-secrets \ --key user-secret-key \ --project clevername-488215
3. Least-Privilege IAM
A naive Secret Manager deployment grants roles/secretmanager.secretAccessor at the project level — the service account can read any secret. A compromised hub-core-runtime instance could simultaneously read database credentials, OAuth client secrets, internal service tokens, and every user key.
Two-Binding Model
Unconditional resource-level bindings — Platform secrets receive individual per-secret secretAccessor bindings for each service’s own runtime identity (hub-core-runtime and siblings). These are explicit per-secret grants, not project-wide.
Conditional project-level binding — A CEL condition restricts the project-level binding to user-key prefixes only:
resource.name.startsWith("projects/clevername-488215/secrets/clevername-key-") ||
resource.name.startsWith("projects/clevername-488215/secrets/clevername-mcp-") ||
resource.name.startsWith("projects/clevername-488215/secrets/clevername-org-key-") ||
resource.name.startsWith("projects/clevername-488215/secrets/clevername-team-key-") ||
resource.name.startsWith("projects/clevername-488215/secrets/clevername-site-")Workload Identity Federation
The GitHub Actions CI/CD pipeline uses Workload Identity Federation — no service account key files are ever created or stored. OIDC tokens from GitHub Actions are exchanged for short-lived GCP credentials via a WIF pool. The hub-core Cloud Run service accesses GCP APIs using its attached service account identity. No key files, no long-lived credentials in the container.
4. Agent Vault Grants — The Delegation Model
True zero-knowledge key management and fully autonomous scheduled agents are architecturally incompatible. A scheduled agent running at 3 AM cannot ask you to unlock your passkey. Clevername makes this trade-off explicit and user-controlled.
Grant Architecture
User browser (vault unlocked)
│
├── Decrypt API key locally (KEK from passkey)
├── POST /hub/vault/agent-grants (HTTPS)
│ { provider, agent_id, plaintext_key }
▼
Hub-core (requires AAL2 — MFA verified)
├── Verify agent ownership
├── AES-256-GCM(plaintext_key, VAULT_DELEGATION_KEY)
│ VAULT_DELEGATION_KEY from GCP Secret Manager (CMEK)
└── Store: agent_vault_grants { encrypted_key, key_iv, expires_at }
At dispatch:
hub-core → load grant → decrypt with VAULT_DELEGATION_KEY
→ use for inference call → discard plaintextGrants are per-agent, per-provider, time-limited (default 1-year), revocable, and MFA-gated at creation.
| Item | Where it lives | Who controls revocation |
|---|---|---|
| Provider key ciphertext | GCP Secret Manager (CMEK) | User (delete key) + platform |
| Agent grant ciphertext | Database | User (delete grant) |
| VAULT_DELEGATION_KEY | GCP Secret Manager (CMEK) | Platform + user |
| I/O-log KEK (passphrase-derived) | Browser memory only | User (passphrase) |
| Plaintext key at dispatch | Hub-core memory, ~50ms | Neither — transient |
5. Audit Logging Architecture
Every call through hub-core is audit-logged with timestamp, user ID, org ID, session ID, provider, model, token counts, tool calls, content hash, and policy decisions. Records use a hash chain: each record’s SHA-256 incorporates the previous record’s hash. Any deletion or modification breaks the chain detectably.
GCP Secret Manager DATA_READ and DATA_WRITE events are logged separately to Cloud Logging — a log that the application layer cannot modify or delete. These can be exported to BigQuery or a SIEM for compliance reporting.
# All secret access events in the last 7 days gcloud logging read \ 'resource.type="secretmanager.googleapis.com/Secret" AND protoPayload.methodName="google.cloud.secretmanager.v1.SecretManagerService.AccessSecretVersion"' \ --project=clevername-488215 \ --freshness=7d \ --format=json
6. Content Scanning and Prompt Security
All content flowing through the MCP gateway is scanned bidirectionally. Input scanning covers prompt injection (Unicode normalization, XML tag smuggling, Base64 obfuscation, Zalgo text, Unicode tag codepoints, temporal/conditional injection), credential leakage, and PII. Output scanning covers URL blocking and sensitive data redaction.
Every agent deployed through an org with Agent Review enabled must complete a 27-question security intake. The intake compiles to a guardrail profile cryptographically bound to the agent version. Model or system prompt changes require re-governance. At runtime the profile enforces MCP server allowlists, tool-level allowlists, URL blocking, and high-risk action detection patterns.
When a high-risk pattern fires, hub-core intercepts the tool call before execution, creates a SignedApproval push notification to the approver’s iOS device, and blocks execution until a cryptographically signed Ed25519 decision arrives. The LLM cannot bypass this — it operates at the protocol layer.
7. Network Architecture
Internet │ ▼ HTTPS / TLS 1.3 Vercel Edge (clevername.net) │ ▼ GCP Identity Token (short-lived OIDC) GCP Cloud Run — hub-core (--no-allow-unauthenticated, org-policy enforced) │ ▼ Service Account + private VPC GCP Secret Manager, Cloud KMS, Cloud Storage, Cloud Run (litellm) │ ▼ TLS External AI providers (Anthropic, OpenAI, Google)
No Cloud Run service is directly exposed to the public internet. GCP org policy blocks allUsers invoker bindings at the organizational level — even a misconfiguration would be rejected by the policy. CI/CD uses pinned GitHub Actions versions. Docker images are built from python:3.13-slim. Artifact Registry scans for CVEs before deployment.
8. Threat Model and Honest Limitations
Protections in scope
| Threat | Defense |
|---|---|
| Casual read of secrets without the KMS key | CMEK — Cloud KMS key wrapping; disabling the key makes wrapped secrets unreadable |
| Stolen SA key files | WIF — no SA key files exist |
| Overprivileged SA reads wrong secrets | IAM condition scoping |
| Prompt injection | Unicode normalization + injection pattern scanner |
| Agent exfiltrates data via URLs | N3 URL blocking in output |
| Agent calls unauthorized tools | Per-session MCP allowlist enforcement |
| High-risk actions without human sign-off | SignedApproval gate (Ed25519) |
| Audit log tampering | Hash chain integrity check |
| Secret access without audit trail | GCP Secret Manager DATA_READ logs |
| Credential stuffing | Rate limiting, MFA enforcement, AAL2 |
| Cross-user data access (IDOR) | Server-side ownership checks on every query (app-layer tenant scoping); database-level RLS rolling out |
| Agent grant creation without MFA | AAL2 required for vault grant endpoints |
Out of scope
Compromised user device. If an attacker controls the device where you unlock your vault, they can observe the plaintext key during decryption. Device security is out of scope.
Compromised GCP account with Owner role. An attacker with GCP Owner on clevername-488215 can access Cloud KMS, view audit logs, and potentially compromise the VAULT_DELEGATION_KEY. Platform-level GCP security (MFA on GCP accounts, Access Transparency) is the relevant defense.
AI model behavior.Hub-core enforces policy at the infrastructure layer. It cannot guarantee an allowed model will never produce harmful output — that is the scanner’s job, and the scanner has known false-negative rates.
Legal compulsion.A valid legal process served on Floyd Media LLC could compel disclosure of server-side provider keys and metadata. Zero-knowledge I/O logs, however, cannot be produced in plaintext — the server cannot decrypt them without the user’s passphrase.
9. Compliance Posture
| SOC 2 Criterion | Implementation |
|---|---|
| CC6.1 — Logical access controls | IAM condition scoping, WIF, server-side ownership checks (DB-level RLS rolling out) |
| CC6.2 — Authentication | Supabase JWT, MFA enforcement, AAL2 |
| CC6.3 — Authorization | Per-session guardrail profiles, MCP allowlists |
| CC7.1 — Change management | CI/CD with test gates, canary deployments |
| CC7.2 — System monitoring | GCP audit logs, Cloud Logging, application audit log |
| CC9.2 — Vendor management | Pinned dependencies, Artifact Registry CVE scanning |
| A1.2 — Availability monitoring | Cloud Run health checks, canary smoke test |
| C1.1 — Confidentiality | CMEK, zero-knowledge I/O-log encryption, server-side key custody |
| P5.1 — Data retention | Configurable 365-day audit log retention |
GDPR: right to erasure via DELETE /hub/account, cascade deletes across all user tables. HIPAA: not BAA-covered by default; enterprise customers should discuss dedicated deployment. PCI DSS: Clevername does not process payment card data; Stripe handles payments.
10. Incident Response
Key compromise response
- Rotate key at the provider (Anthropic, OpenAI, etc.)
- Delete vault entry or re-encrypt with new key in dashboard
- Revoke all agent grants:
DELETE /hub/vault/agent-grants - Review Secret Manager DATA_READ audit logs for unexpected accesses
Platform delegation key compromise
# 1. Generate new delegation key python3 -c "import secrets; print(secrets.token_hex(32))" # 2. Add new version to GCP Secret Manager echo -n $NEW_KEY | gcloud secrets versions add \ clevername-vault-delegation-key --data-file=- # 3. Redeploy hub-core (picks up new version at startup) # All existing agent grants become unreadable — users must re-grant
CMEK revocation (break-glass)
gcloud kms keys versions disable 1 \ --location us-east1 \ --keyring clevername-user-secrets \ --key user-secret-key \ --project clevername-488215
Appendix A: Cryptographic Parameters
| Use Case | Algorithm | Key Size | Mode | IV/Nonce |
|---|---|---|---|---|
| I/O-log encryption (client-side) | AES | 256-bit | GCM | 96-bit random |
| Server-side key encryption | AES | 256-bit | GCM | 96-bit random |
| Agent vault grant encryption | AES | 256-bit | GCM | 96-bit random |
| PBKDF2 (KEK derivation) | SHA-256 | — | — | 128-bit random salt |
| PBKDF2 iterations | — | — | — | 600,000 |
| SignedApproval decisions | Ed25519 | 256-bit | — | — |
| KMS DEK wrapping | AES | 256-bit | GCM | GCP-managed |
| Audit hash chain | SHA-256 | 256-bit | — | — |