Reference
Security Architecture
How Alter stores, retrieves, and authorizes credential access.
This page is the whitepaper-style reference for how Alter handles credentials end to end. It covers the security boundaries that matter for compliance reviews, threat models, and architecture decisions. For day-to-day SDK usage, see the Guides.
Trust boundaries
Section titled “Trust boundaries”Three boundaries matter:
- Application ↔ Alter SDK — the application holds an API key (
alter_rk_…,alter_ak_…, or a legacyalter_key_…key — per-agent keys currently mint with the legacy prefix). The SDK signs every request with the key. - Alter SDK ↔ Alter backend — every request is cryptographically signed; the backend verifies the signature before performing any action.
- Alter backend ↔ third-party provider — Alter stores the OAuth tokens and credentials. The SDK or backend injects them into outgoing provider requests as headers, depending on the runtime mode the call uses. The public SDK response never returns the plaintext credential to application code.
The Alter API key authenticates the right to use credentials within its scope, not to read them through a public plaintext-credential method. In retrieve mode, however, the SDK must hold a credential briefly in the application process to make the provider call, so a fully compromised process can inspect it. Proxy mode keeps credential material on the Alter backend. Completing rotation by revoking an old Alter API key invalidates that leaked key.
Vault storage
Section titled “Vault storage”OAuth tokens, refresh tokens, and managed-secret credentials are encrypted at rest by the configured secret-storage backend. Encryption keys are managed outside the application data store. The separation is deliberate:
- The application data store holds non-secret identity, lifecycle, and authorization metadata.
- The dedicated secret store holds the encrypted credential material.
Compromise of the metadata store alone does not expose provider credentials. Access to credential material remains controlled by the separate secret-storage boundary.
Token retrieval
Section titled “Token retrieval”Every credential-touching SDK request goes through the same core pipeline:
- Authentication. The API key signature is verified. The backend resolves the calling principal as the app or the key-bound agent; application-key calls can also carry explicit agent attribution without changing which key authenticated the request.
- Authorization. The grant is looked up. The caller must have an explicit authorization path, such as an app operating on its own grant, an agent holding a delegation, or a verified user identity matching a user-bound grant.
- Policy evaluation. Every applicable policy in the effective chain is evaluated. A denial returns the rule’s typed SDK error, such as
PolicyViolationErrororQuotaExceededError; the provider is not called. - Token retrieval. The token is decrypted from the vault. If expired (or within a refresh buffer), the backend refreshes it using the stored refresh token while coordinating concurrent refresh attempts.
- Injection. The token is injected as a header on the outgoing provider request (
Authorization: Bearer …by default; the managed-secret configuration controls the exact format). In proxy mode the backend injects and makes the outgoing call; in retrieve mode the SDK injects and makes the call from the application process. See runtime modes. - Audit. The terminal result — success, denial, or error — emits one or more audit events carrying the relevant caller, principal, provider, and policy context.
If authentication, authorization, policy evaluation, or vault retrieval fails, no provider call is made.
Fail-closed authorization
Section titled “Fail-closed authorization”Alter is fail-closed at every authorization gate:
- A policy that cannot be evaluated denies the request.
- A JWT that cannot be verified denies the request.
- A vault unreachable for token retrieval denies the request.
There is no “skip on error” path at an authorization gate. Operators can configure permissive policies, but an unevaluable gate never silently allows access.
Audit coverage is enforced separately: a missing terminal emit is treated as a code defect, so tests fail while production emits a critical gap signal and attempts a fallback audit event. A storage failure in the audit writer is cascade-isolated so it cannot turn an otherwise completed provider operation into a second failure.
Identity resolution
Section titled “Identity resolution”For user-principal grants resolved via JWT identity, the trust chain is:
- The end user authenticates at the configured IDP.
- The IDP issues a JWT signed with the IDP’s private key.
- The application includes the JWT on every Alter call (via
user_token_getter). - Alter verifies the JWT signature against the IDP’s JWKS (fetched and cached).
- The
subclaim resolves to an Alter user record. - The grant lookup is scoped to that user.
JWKS keys are refreshed automatically. Once a signing key is absent from the refreshed key set, a JWT signed by that key is rejected on verification.
Per-key isolation
Section titled “Per-key isolation”Each API key carries:
- A scope set on the Alter API — what management operations the key authorizes.
- A binding to an app — keys cannot read cross-app data.
- A type — app key, agent key, or derived key.
A derived key inherits a subset of the parent’s scopes (intersection only — never broader). Per-request attenuation via with_constraints() further narrows in-process without minting a new key — it can narrow scopes, attach an optional request rule (evaluated server-side, carried by every request the returned instance makes and able only to further restrict each one), or both.
Audit trail
Section titled “Audit trail”Credential-touching SDK requests emit at least one terminal audit event, and can emit separate events for credential retrieval, provider execution, approval, and lifecycle changes. Grant lifecycle and administrative actions emit their corresponding audit events. See Audit logs.
The canonical API-call audit stores request metadata and body-size information, not injected credentials or raw request and response bodies. Operators can separately enable diagnostic payload capture for proxied calls. That capture stores the caller-supplied request body before credential injection and the provider response body, never injected credential headers; each body is capped at 64 KiB by default and carries an explicit truncation flag when larger.
End-user revocation
Section titled “End-user revocation”End users sign into the Wallet at any time to see and revoke every grant their identity owns across every Alter app integrated with their IDP. Grant revocation is immediate, and the next call against that grant raises GrantRevokedError. If sibling grants still share the same connection, their authorization remains intact; disconnecting the underlying connection revokes all of them and removes the stored credential.
There is no “developer can suppress revocation” flag — the Wallet exists by virtue of an IDP being configured.
Delegation as a first-class boundary
Section titled “Delegation as a first-class boundary”Delegation is the path that allows an AI agent to act on behalf of a user without seeing the user’s credentials. Each delegation is a separately revocable authorization edge, distinct from the underlying connection. The user can revoke the delegation (the agent loses access; the connection stays active) or revoke the connection (both are torn down).
Operational properties
Section titled “Operational properties”- Signed requests. Every SDK → backend call is cryptographically signed; replays are rejected.
- Encryption in transit. Production SDK and browser interactions use HTTPS.
- Key plaintext shown once. Every API key (app, agent, derived) is shown to the operator exactly once at mint time. Subsequent fetches return only non-secret metadata and a display prefix for identification; the stored verifier is never returned.
Compliance posture
Section titled “Compliance posture”For compliance evidence, the following surfaces are typically requested:
- Audit log export for the period under review — see Audit log export.
- Identity provider configuration — confirming JWT verification is enforced.
- Policy configuration for sensitive grants — confirming gating is in place.
- Key rotation evidence — the audit log contains every mint, deprecate, and revoke event.