Skip to content

Get Started

How Alter works

The mental model behind every Alter call, in one page.

Alter is a credential vault, an authorization layer, and an audit pipeline behind a single SDK method. This page walks the flow end-to-end so the rest of the docs can stop re-explaining it.

Every integration with a third-party API has four problems:

  1. Storage — somewhere to keep OAuth tokens or API keys.
  2. Retrieval — refreshing tokens before expiry, picking the right one per user.
  3. Authorization — deciding whether a given caller is allowed to use a given credential right now.
  4. Audit — recording every access with enough context to answer “who used what, when, and why.”

Alter owns all four. Application code makes one call.

Application Alter SDK Alter backend Third-party API
│ │ │ │
│── request(grant_id) ────▶│ │ │
│ │── signed call ────────▶│ │
│ │ policy check │
│ │ token retrieval │
│ │ token refresh (if expired) │
│ │ audit row │
│ │── inject + forward ───────────────────────────▶
│ │ │
│ │◀── response ───────────────────────────────────│
│◀── response ─────────────│ │ │

Application code never holds, logs, or stores the token. Whether the injection happens on the backend or inside the SDK depends on the runtime mode the call uses.

Alter exposes four primitives. The full definitions live in Concepts; this is the one-paragraph version.

  • App — the unit that owns API keys, provider configuration, and grants. One per integrated product.
  • Provider — a third-party service Alter knows how to talk to. Two kinds: OAuth providers (Google, Slack, GitHub) and managed-secret providers (Stripe API key, Datadog API key, AWS).
  • Grant — a stored authorization to call a provider on behalf of someone. Identified by a grant_id. Created when a user completes OAuth or when an operator provisions a managed secret.
  • Agent (optional) — a workload identity with its own API key and access set. Use when an AI agent or background workload needs to be revocable and auditable independently of the app key.

Alter handles two distinct credential models. Both reach the same app.request() method:

OAuth grantsManaged secrets
Provided byAn end user completing OAuthAn operator pasting the credential in the portal
RefreshAutomatic, per-providerOperator rotates when the underlying credential rotates
Bound toThe user who authorizedA user, group, system, or agent (operator’s choice)
Read in code asgrant_idgrant_id

The SDK call site is identical. The difference is where the credential came from, not how it’s used.

For OAuth grants, the SDK needs to know which grant to use. Three modes, explained on one page:

  1. JWT identity — the recommended path for any app with logged-in users. Configure the IDP once, the SDK resolves the grant from each user’s JWT.
  2. Explicit grant_id — for scripts, batch jobs, and managed-secret grants.
  3. Headlessapp.connect() for CLIs, notebooks, and one-time setup flows.

Managed-secret grants bound to a user or group resolve under JWT identity the same way OAuth grants do; the credential type doesn’t change the call site.

  • Token storage (encrypted at rest in a dedicated vault, never in the application database).
  • Token refresh (handled per-provider, automatically).
  • Per-user scoping (grants are bound to principals; the SDK resolves them).
  • Audit logging (every call writes a row with caller, principal, provider, status).
  • End-user revocation UX (end users get the Wallet dashboard for free).
  • Policy enforcement (rules engine on every retrieval).