Skip to content

Commands

alter managed-secrets

Manage backend credentials, their grants, and effective access.

Managed secrets are backend-only credentials (API keys, signing secrets) that Alter stores and injects into outbound requests — no OAuth user involved. These commands cover the full lifecycle: the secrets themselves, the grants that hand them to principals, and the helpers that answer “who can reach this secret.”

alter managed-secrets templates
alter managed-secrets list
alter managed-secrets show <secret-id>
alter managed-secrets create --name <name> --credential-value <value> [...]
alter managed-secrets rotate <secret-id> --credential-value <value>
alter managed-secrets delete <secret-id> [--confirm <slug>]
alter managed-secrets access <secret-id>
alter managed-secrets set-delegation-policy <secret-id> [--allow-group-delegation] [--max-delegation-ttl-days <days>]
alter managed-secrets set-allowed-hosts <secret-id> --host <host> [--host ...] | --clear
alter managed-secrets users
alter managed-secrets groups list | show <group-id>
alter managed-secrets grants list | list-for-agent | create | update | revoke

All commands are app-scoped — pass --app <id>, or link a workspace / set ALTER_APP_ID. Reads need dashboard_secrets:read; create / rotate / set-delegation-policy / set-allowed-hosts / grant operations need dashboard_secrets:write; delete needs dashboard_secrets:delete.

List the managed-secret template catalog for the app (openai, aws, …). Templates pre-fill the credential type and injection rules.

Terminal window
alter managed-secrets templates
Terminal window
alter managed-secrets list
alter managed-secrets show <secret-id> # never exposes the credential value

Create a managed secret and its base grant. --name is required unless you supply a full --input body.

The slug is server-generated from --name — the name is slugified (e.g. Stripe Productionstripe-production), with a -<N> suffix appended only if that slug is already taken in the app. Name the secret after the provider so the slug is meaningful; the slug is the stable machine handle the SDK, CLI, dashboard, and audit logs reference. A stale request body that still ships a slug field is silently ignored.

FlagDescription
--name <name>Human display name. Required.
--description <text>Free-form description.
--template <id>Template ID (e.g. openai); omit for a custom secret.
--credential-type <type>bearer_token (default), header_key, basic_auth, or aws_sig_v4.
--credential-value <value>Primary credential. See credential intake.
--credentials <@file.json>Multi-field credentials as a JSON object — preferred for multi-field types.
--credential-field <k=v>Repeatable; sets one additional credential field per flag.
--injection-header <name>Header to inject into (default Authorization).
--injection-format <template>Header value template (default Bearer {token}).
--injection-rule <@file.json>JSON array of additional injection rules.
--label <label>Base-grant display label.
--account-identifier <id>Optional account identifier metadata stored on the secret.
--account-display-name <name>Optional account display name metadata.
--allow-group-delegationAllow members of a group-typed grant to delegate this secret to an agent (default: off).
--max-delegation-ttl-days <days>Cap on a single delegation’s lifetime, 1–1825 days (default 90).
--input <path>JSON body from a file (@path) or stdin (-); replaces the per-field flags.
Terminal window
# Single-field bearer token, value piped from stdin
printf '%s' "$OPENAI_KEY" | alter managed-secrets create \
--name "OpenAI" --template openai --credential-value -

The primary credential value (--credential-value) accepts three forms, in decreasing order of safety:

FormReads from
--credential-value -One line from stdin (preferred for CI).
--credential-value @/path/to/fileA file.
--credential-value <value>Inline — prints a shell-history warning.

Multi-field credential types (such as aws_sig_v4, which needs an access key, secret key, and region) take either --credentials @file.json (a JSON object of string fields — it may also include a top-level credential_value to satisfy the primary value in one file) or repeated --credential-field key=value flags. If both are supplied, the file wins and the flags are ignored with a warning.

Swap the stored credential while active grants continue to use the same managed secret. Same credential-intake forms as create.

Terminal window
printf '%s' "$NEW_KEY" | alter managed-secrets rotate <secret-id> --credential-value -

Like apps delete, it’s gated behind the separate dashboard_secrets:delete scope and a type-to-confirm check against the secret’s slug:

  • Interactive: the CLI prompts for the slug. This path also needs dashboard_secrets:read — it fetches the secret to show the slug in the prompt.
  • Non-interactive (CI): pass --confirm <slug>. A dashboard_secrets:delete-only PAT (no :read) must use this form.
Terminal window
alter managed-secrets delete <secret-id> --confirm openai-api

Compute the effective access for a secret — every principal that can reach it, whether directly, through a group, as a system principal, or via an agent. Use --output json to keep the full nested envelope with per-path counts.

Terminal window
alter managed-secrets access <secret-id> --output json

Set the user → agent delegation policy on a managed secret — controls whether members of a group-typed grant may delegate the secret to an agent, and caps a delegation’s lifetime. Needs dashboard_secrets:write.

FlagDescription
--allow-group-delegationAllow members of a group-typed grant to delegate this secret to an agent (default: off).
--max-delegation-ttl-days <days>Cap on a single delegation’s lifetime, 1–1825 days (default 90).
Terminal window
# Enable group delegation with a 30-day cap
alter managed-secrets set-delegation-policy <secret-id> --allow-group-delegation --max-delegation-ttl-days 30
# Turn group delegation back off (omit the flag)
alter managed-secrets set-delegation-policy <secret-id>

Restrict which destination hosts a secret may be injected into when proxied — an egress allowlist that bounds where the credential can be sent. Needs dashboard_secrets:write.

FlagDescription
--host <host>Allowed host: exact (api.stripe.com) or leading-wildcard subdomain (*.stripe.com). Repeatable, or comma-separated; both forms accumulate.
--clearRemove all configured allowed hosts. With default enforcement, proxy calls for the secret are blocked until hosts are configured again. Mutually exclusive with --host.
Terminal window
# Restrict to Stripe only
alter managed-secrets set-allowed-hosts <secret-id> --host api.stripe.com --host '*.stripe.com'
# Clear all allowed hosts (proxy calls are blocked until hosts are configured)
alter managed-secrets set-allowed-hosts <secret-id> --clear

Picker helpers for building grants — list the app’s users and groups, with substring search.

Terminal window
alter managed-secrets users --search alice
alter managed-secrets groups list --idp <idp-id>
alter managed-secrets groups show <group-id>

users and groups list accept --idp <uuid>, --search, --limit, and --offset. groups show paginates members and grants independently with --member-limit / --member-offset / --grant-limit / --grant-offset.

Grants hand a secret to a principal. Revoking a grant is a soft-delete (recoverable by re-granting), so it needs only dashboard_secrets:write.

alter managed-secrets grants list <secret-id>
alter managed-secrets grants list-for-agent <agent-id>
alter managed-secrets grants create <secret-id> --principal-type <type> [...]
alter managed-secrets grants update <grant-id> [--label ...] [--expires-at ...]
alter managed-secrets grants revoke <grant-id> [--yes]

The principal type drives which flags are required:

--principal-typeRequired flags
user--app-user-id <uuid>, --label <string>
group--idp-id <uuid>, --external-group-id <id>, --label <string>
agent--agent-id <uuid>
system

Optional on every type: --description, --expires-at <iso>, and --grant-policy <@file.json> for the full policy shape. Or supply the whole body with --input.

Terminal window
alter managed-secrets grants create <secret-id> \
--principal-type agent --agent-id <agent-id> --expires-at 2026-12-31T00:00:00Z

Edit --label, --description, --expires-at, or --grant-policy (at least one required), or supply --input.

Terminal window
alter managed-secrets grants update <grant-id> --label "renamed"
Terminal window
alter managed-secrets grants revoke <grant-id> # prompts y/N
alter managed-secrets grants revoke <grant-id> --yes # CI

Provision a backend credential in CI

Terminal window
printf '%s' "$OPENAI_KEY" | alter managed-secrets create \
--name "OpenAI" --template openai --credential-value -

Grant an agent access, then verify it resolved

Terminal window
alter managed-secrets grants create <secret-id> --principal-type agent --agent-id <agent-id>
alter managed-secrets access <secret-id> --output json | jq '.entries'