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.

By the end of this guide, a backend service calls a third-party API using an operator-provisioned credential — a Datadog API key, a Stripe secret key, an AWS access key — without that credential ever appearing in the application’s environment, config files, or logs. The flow:
  1. The operator stores the credential once in the developer portal.
  2. The operator issues a grant binding the credential to a principal (system, user, group, or agent).
  3. The backend calls app.request() with the resulting grant_id. Alter injects the credential into the outgoing call.

Prerequisites

  • An app with a alter_key_app_… API key.
  • A managed-secret provider configured — this guide uses Datadog as the example.
  • The credential itself, generated at the provider (Datadog → API Keys → New Key).

Walkthrough

1. Store the credential

In the developer portal:
  1. Open the app and go to Managed Secrets.
  2. Pick Datadog from the catalog (or Custom for anything not listed).
  3. Paste the API key into the Credential field.
  4. Click Store.
The plaintext is encrypted and sent to the vault. The portal will not display it again.

2. Issue a grant

A stored credential is not usable until a grant binds it to a principal. From Managed Secrets → Datadog → Grants → New Grant:
  • System — the credential is callable by anyone holding the app key, with no user identity required. Use this for backend services and cron jobs.
  • User — bind to one named user (resolved from their JWT). Useful when each user gets a per-user Datadog key.
  • Group — bind to an IDP group. All current and future members of the group can use it.
  • Agent — bind to a managed agent. Only that agent can reach the credential.
For a system-bound grant, the portal returns a grant_id. Copy it into application config. Equivalent SDK call (operator path):
from alter_sdk import App
from alter_sdk.models import SystemPrincipal

alter = App(api_key=os.environ["ALTER_API_KEY"])

result = await alter.create_managed_secret_grant(
    managed_secret_id="ms_datadog_abc",
    principal=SystemPrincipal(label="prod-monitoring"),
)
print(result.grant_id)

3. Call the provider

The application calls request() against the provider, passing the grant_id:
from alter_sdk import App, HttpMethod

alter = App(api_key=os.environ["ALTER_API_KEY"])

response = await alter.request(
    HttpMethod.POST,
    "https://api.datadoghq.com/api/v1/events",
    grant_id=os.environ["DATADOG_GRANT_ID"],
    json={"title": "Deployment", "text": "Service deployed to prod"},
)
The Datadog API key is injected as DD-API-KEY: … (per the Datadog template). Application code never holds it.

Patterns

Per-user managed secrets

For a product where each user holds their own API key at a provider, bind a managed secret per user. The user uploads the credential through a UI flow; the backend stores it bound to the user’s identity. At call time, the SDK resolves the grant from the user’s JWT exactly as it would for an OAuth grant — see Call APIs on behalf of users.

Rotation

When the credential at the provider rotates:
  1. Generate the new credential at the provider.
  2. Open Managed Secrets → [Provider] → Update credential.
  3. Paste the new value and save.
Every existing grant_id keeps working — the credential is replaced in place, the grant identity is unchanged. No application restart, no env-var update.

AWS managed secrets

AWS managed secrets carry extra structure because Alter computes SigV4 signatures per request. See AWS managed secret reference.

Group-bound managed secrets

For a “support team” Datadog key, bind the grant to an IDP group:
from alter_sdk.models import GroupPrincipal

await alter.create_managed_secret_grant(
    managed_secret_id="ms_datadog_abc",
    principal=GroupPrincipal(
        external_group_id="support",
        idp_id="ipd_clerk_xyz",
        label="support-team",
    ),
)
Any user whose JWT carries the support group claim can now resolve this grant under JWT identity.

Troubleshooting

ErrorLikely causeFix
GrantNotFoundErrorgrant_id is wrong or the grant was revoked.Re-issue the grant from the portal.
ProviderAPIError (401)The credential at the provider was revoked or expired.Generate a new credential at the provider, update the stored value.
ProviderAPIError (403)The credential lacks permission for the route.Check the credential’s permission scope at the provider.
Application can read the credentialMisconfiguration.Managed secrets are write-only; if anything in the application has plaintext access, the storage path is wrong.

What’s next

Managed secret providers

The full catalog of pre-configured providers.

AWS reference

SigV4 specifics and boto3 integration.

Give an agent scoped access

Bind a managed secret to an AI agent.