Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.alterauth.com/llms.txt

Use this file to discover all available pages before exploring further.

A grant is a stored consent record that lets a principal call a third-party API through Alter. Five terms appear everywhere in Alter docs and SDK. Learn them once here; every other page links back.

Grant

A row that says this principal can call this provider with these scopes until this policy expires. Every call from the SDK passes through a grant.
  • Identified by a UUID (grant_id).
  • Created when a user completes OAuth, or when an operator provisions a managed secret.
  • Refers to (but does not contain) the encrypted credential in the vault.
  • Revocable independently of the underlying credential.

Principal

The owner of a grant — who is calling. Four kinds, never interchangeable:
KindWho it isTypical creator
UserAn end user authenticated via the IDP (Auth0, Clerk, Okta, …)OAuth flow
GroupA set of users defined in the IDPOperator binds a managed secret to an IDP group
SystemThe app itself, no human or agentOperator provisions a managed secret with no principal
AgentA named, operator-provisioned workload identityOperator creates an agent and binds a managed secret to it
Principal kind decides what the SDK permits. A user-principal call resolves the grant from a JWT; an agent-principal call resolves from the agent’s binding; a system-principal call requires grant_id to be passed explicitly.

Caller

Free-form audit attribution — what code path made the call. Set once at SDK construction, immutable for the instance:
vault = App(api_key=KEY, caller="email-research-bot")
Caller is not an access boundary. It does not narrow what the principal can do. It exists so audit queries can answer “which feature ran this call?” without threading metadata through every layer. When caller is the UUID of a managed agent, audit rows record the managed-agent attribution. When it’s any other string, it’s a free-form label. Either is fine.

Context

Free-form per-call metadata. A dict of strings attached to a single vault.request():
await vault.request(method, url, grant_id=g, context={"tool": "list_emails", "run_id": "abc"})
Stored in the audit row as JSONB. Use it for tool name, run ID, thread ID — anything worth surfacing when grepping the audit trail later.

Delegation

A pointer that says this agent may use this user’s grant. Created when a user consents at the Connect UI with an agent named on the consent screen. Distinct from the underlying OAuth grant: revoking a delegation removes the agent’s access path without touching the user’s grant. See Agents → Approvals for the runtime API and the revocation surface.

Picking a principal in code

The principal is implied by which class is constructed and how the call is authenticated:
ConstructionWith…Principal at runtime
App(api_key=APP_KEY)nothing elseSystem — pass grant_id explicitly
App(api_key=APP_KEY, user_token_getter=…)a JWT per callUser — SDK auto-resolves the user’s grant
Agent(api_key=AGENT_KEY)nothing elseAgent — pass grant_id mapped to this agent
The full decision tree lives in Identity resolution. The deep operational detail (cardinality rules, when caller becomes attribution, JWT-overrides-agent precedence) lives in Agents → Overview and OAuth → Managing grants.

See also