Reference
alter audit
Read the audit log: runtime calls, portal actions, grant events, and traces.
Every credential-touching call and every admin action produces an audit row. These read-only commands query the log from several angles.
alter audit list [--since ...] [--start ...] [--end ...] [--action ...] [--policy-decision ...] [--root-grantee ...]alter audit providers [--app ...]alter audit show <trace-id>alter audit explain <trace-id>alter audit portal-actions [--start ...] [--end ...] [--principal-kind ...] [--resource-type ...]alter audit grant-events [--start ...] [--end ...] [--grant-type ...] [--provider ...]alter audit traces [--start ...] [--end ...] [--actor ...]alter audit threads [--start ...] [--end ...] [--app ...] [--actor ...]alter audit thread <thread-id>alter audit agents [--start ...] [--end ...] [--app ...]alter audit agent <actor-id> [--principal-kind actor|agent|key] [--additional-key-ids ...]alter audit integrity-check --start ... --end ... [--table ...]All commands need dashboard_audit:read and accept --output. For line-oriented pipelines, use --output jsonl with jq / grep. That is also the CLI’s export path — alter audit list --since 30d --output jsonl > audit.ndjson is the programmatic equivalent of the dashboard’s CSV/NDJSON export. Enum, ID, and date filters are validated client-side, so a typo fails fast; free-form filters (--action, --provider, --resource-type) pass through and simply match nothing when misspelled.
alter audit explain <trace-id> is the diagnostic companion to show: instead of raw events, it translates the trace’s terminal state into a concrete fix — a policy denial names the policy posture to review (alter policy show-app); a scope mismatch names the rotate command; a suspended agent points at alter agents resume (suspension is reversible — re-consent and rotation do not help); a revoked agent points at recreating it (alter agents create — revocation is terminal); a revoked/expired grant points at re-consent or secret rotation; an unexplained provider 4xx points at the request-shape lint in alter verify (a provider 401/403 points at re-consent or credential rotation instead, and a 429 at backoff — do not run verify for those); a provider 5xx says retry with backoff. The mapping is deterministic over fields the audit rows already carry — when nothing matches, it says so and defers to show.
explain accepts json, jsonl, or table. Its report is a single object,
so jsonl falls back to pretty-printed JSON.
Time filters: --start <iso> / --end <iso> give absolute bounds on every list-style command. The --since <duration> shorthand (e.g. 1h, 7d) — a relative start — is only available on audit list; the other list-style commands accept --start / --end only. On audit list, --start and --since are mutually exclusive.
Audit rows across the trail — token retrievals, outbound API calls, approvals, grant and delegation lifecycle, portal and Wallet policy changes, and provisioning.
| Flag | Default | Description |
|---|---|---|
--since <duration> | — | Relative start, e.g. 24h, 7d. Mutually exclusive with --start. |
--start <iso> / --end <iso> | — | Absolute bounds. |
--app <app-id-or-name> | all | Filter by app. |
--action <action> | all | e.g. token.retrieved. |
--actor <actor-id> | all | Filter by actor. |
--provider <provider> | all | Filter by provider ID (e.g. google), not display name. |
--policy-decision <decision> | all | ALLOW, DENY, or ERROR (case-sensitive). |
--root-grantee <id> | all | Filter by root grantee: the ID of the end user, group or agent the access was originally granted to, which is the id field of alter end-users list, alter managed-secrets groups list or alter agents list. A malformed ID exits 2 before any request. A backend that did not apply the filter exits 1 with no rows. See Search by root grantee. |
--limit <n> | 100 | Page size (1–500). |
--offset <n> | 0 | Pagination offset. |
alter audit list --since 24h --policy-decision DENYSearch by root grantee
Section titled “Search by root grantee”--root-grantee <id> narrows the list to access originally granted to one end user, group or agent. Take the ID from the id field of alter end-users list --output json for an end user, alter managed-secrets groups list --output json for a group, or alter agents list --output json for an agent. The filter composes with every other list filter and with --limit / --offset.
alter audit list --since 7d --root-grantee 3f6c2a1e-8b9d-4c7e-a5f0-1d2e3f4a5b6c --output jsonWhen the backend applies the filter, its response carries a root_grantee_coverage field. The CLI prints that value and what it means to stderr, so a script can tell the result is partial. stdout carries the rows only, in every --output format. Today the value is direct_access_only, and the CLI prints:
No audit record carries a root grantee yet, so this result has only token and managed-secret records of the user’s, group’s or agent’s direct use of its own grant: retrievals, refreshes made during a request, failures, and refusals of a request to use the grant once it was identified. Access through a delegation, background (refresh-ahead) refreshes, provider calls, grant lifecycle events, approvals and attempts refused before the grant was identified are not included.
A delegated row names the delegate, not the original grantee, which is why access through a delegation is not found. Existing rows are never filled in later, so an empty result does not mean the access was never used. Rows that never carry a grantee (portal and Wallet configuration changes, and IDP provisioning) are left out while the filter is set. A root_grantee_coverage value this CLI version does not recognize still marks the result as partial. The CLI prints the raw value with a generic notice.
A response without a root_grantee_coverage value comes from a backend that predates the filter. That backend ignores --root-grantee and returns the unfiltered trail. The CLI then prints no rows, says on stderr that --root-grantee was not applied, and exits 1.
The table’s RULE column names the policy rule a row is about: the rule that
decided a policy decision (a deny, an IP-allowlist rejection, a step-up or
approval requirement, or the rule whose obligations shaped a permit), or the
policy rule a portal or Wallet change created, updated, or deleted. In JSON
output the same ids are policy.policy_rule_id (the policy_rule_id field of
the policy object) and resource_id. End-user
policy changes made in the Wallet appear with log_type end_user_config,
actor: null and the end user who made the change in end_user — for
example:
alter audit list --since 7d --action policy_rule.created --output json \ | jq '.[] | {log_type, resource_id, actor: (.end_user.identifier // .actor.identifier // .developer_id)}'In --output json, each row’s action_type is read, write, denied
or error: denied marks a request Alter refused before the provider was
called (a policy, scope, approval, key or rate-limit refusal of a credential
request, or an outbound API call it cannot send as written), and error is
everything else that did not succeed, server faults included.
Every list-style audit command emits the rows themselves in every output
format — --output json is the rows array, matching every other list
command. When more rows remain, the command prints the next --offset to run
on stderr, so a | jq pipeline keeps clean data on stdout.
providers
Section titled “providers”The provider IDs present in an app’s audit events — the values --provider
accepts. One vocabulary across categories: OAuth provider IDs (google),
managed-secret template IDs (openai) — a custom managed secret is
identified by its name-derived slug — and identity-provider types (okta).
Derived from the audit data itself (the same source as the dashboard’s
Provider filter dropdown), so a provider whose configuration was since deleted
still appears as long as its audit rows do.
| Flag | Default | Description |
|---|---|---|
--app <app-id-or-name> | ALTER_APP_ID / workspace pin | App whose audit trail to facet. |
alter audit providers --app my-appalter audit providers --output json | jq -r '.[].provider_id'Show every event for one trace, by trace ID.
alter audit show <trace-id>portal-actions
Section titled “portal-actions”Admin actions taken in the dashboard or via the CLI — app CRUD, key mints, policy edits.
The default table includes TYPE (read, write, or error) and RESULT (success, failure, denied, or error). When a record omits the classification, TYPE displays —; additive future string values are shown verbatim instead of aborting the listing. Successful list/export/integrity operations remain visible as reads; their summary payload is not reported as a created resource. Failed or denied dashboard actions have type error, regardless of the intended operation (denied applies to credential requests and API calls Alter refused; see list).
| Flag | Description |
|---|---|
--principal-kind <kind> | portal, sdk, system, or pat. Use pat to see CLI-driven actions. |
--resource-type <type> | Filter by resource type. |
--action <action> | e.g. app.created. |
--app, --start, --end, --limit, --offset | As above (--limit range 1–500, default 100). |
# BSD/macOS date:alter audit portal-actions --principal-kind pat \ --start $(date -u -v-7d +%Y-%m-%dT%H:%M:%SZ)# GNU date (Linux): --start $(date -u -d "7 days ago" +%Y-%m-%dT%H:%M:%SZ)grant-events
Section titled “grant-events”Grant-lifecycle events for both OAuth and managed-secret grants.
| Flag | Description |
|---|---|
--grant-type <type> | oauth or managed_secret. |
--provider <provider> | Filter by provider ID (e.g. google), not display name. |
--app, --start, --end, --limit, --offset | As above (--limit range 1–500, default 100). |
# BSD/macOS date:alter audit grant-events --grant-type oauth \ --start $(date -u -v-30d +%Y-%m-%dT%H:%M:%SZ)# GNU date (Linux): --start $(date -u -d "30 days ago" +%Y-%m-%dT%H:%M:%SZ)traces
Section titled “traces”Trace summaries — one row per request trace, with event count and status.
| Flag | Description |
|---|---|
--actor <actor-id> | Filter by actor. |
--app, --start, --end, --limit, --offset | As above (--limit range 1–200, default 50). |
# BSD/macOS date:alter audit traces --app <app-id-or-name> \ --start $(date -u -v-24H +%Y-%m-%dT%H:%M:%SZ)# GNU date (Linux): --start $(date -u -d "24 hours ago" +%Y-%m-%dT%H:%M:%SZ)threads
Section titled “threads”Conversation threads — groups of related traces. One row per thread, with trace and event counts.
| Flag | Description |
|---|---|
--actor <actor-id> | Filter by actor. |
--app, --start, --end, --limit, --offset | As above (--limit default 50, max 200). |
alter audit threads --app <app-id-or-name>thread
Section titled “thread”Show every trace and event for one thread, by thread ID.
alter audit thread <thread-id>agents
Section titled “agents”Audit activity grouped by principal — one row per agent-identity key group, actor, or effective agent, with thread / trace / event counts. Key groups (principal_kind: "key") are the primary kind: keys sharing one agent identity merge into a single row whose keys facets carry the per-key IDs and counts (key_count is the group’s true distinct-key total).
| Flag | Description |
|---|---|
--app, --start, --end, --limit, --offset | As above (--limit default 50, max 200). |
alter audit agents --app <app-id-or-name>Show one principal’s audit detail (its threads and traces), by ID.
| Flag | Description |
|---|---|
--principal-kind <kind> | actor (default), agent, or key — whether <actor-id> is an actor ID, an effective-agent ID, or an API-key ID (the primary agent identity in the grouped view). |
--additional-key-ids <ids...> | Sibling API-key IDs of a multi-key agent group (repeat the option or space-separate IDs; at most 50). Requires --principal-kind key; merges every key’s events into one timeline. |
--app <app-id-or-name> | Filter by app. |
alter audit agent <actor-id> --principal-kind agent# Merge a multi-key agent group's timeline (ids from `alter audit agents` → keys facets):alter audit agent <key-id> --principal-kind key --additional-key-ids <key-id-2> <key-id-3>integrity-check
Section titled “integrity-check”Verify audit-log integrity over a date window. Read-only: the server recomputes each row’s content hash and, on credential rows that carry one, its lineage hash, and reports any row where either no longer matches (tampering), mutating nothing. Each entry of invalid_rows names the row’s table and id and, in failed_hash, which hash failed: content, lineage or both. Between them the two hashes cover how a credential row’s access was authorized: the grantee, the access path and delegation chain, the verified end-user subject where one was recorded, and the root grantee, except references to records that can be deleted (an end user, an agent, an API key), which are cleared when that record is. The end user’s display identifier and name are recorded but not hash-covered. Rows written before the lineage hash was introduced carry none and are checked by content hash alone. The window must be 90 days or less.
| Flag | Required | Description |
|---|---|---|
--start <iso> | yes | Start of the window (inclusive). |
--end <iso> | yes | End of the window (exclusive). Window must be ≤ 90 days. |
--table <name> | no | Limit to one audit table (default: all): api-calls, oauth-tokens, or managed-secrets. |
# BSD/macOS date:alter audit integrity-check \ --start $(date -u -v-7d +%Y-%m-%dT%H:%M:%SZ) \ --end $(date -u +%Y-%m-%dT%H:%M:%SZ)# GNU date (Linux): --start $(date -u -d "7 days ago" +%Y-%m-%dT%H:%M:%SZ)Recipes
Section titled “Recipes”Investigate denied calls
# Recent denialsalter audit list --since 24h --policy-decision DENY# Find a trace to expand (trace IDs come from `audit traces`), then drill in# (BSD/macOS date; GNU: --start $(date -u -d "24 hours ago" +%Y-%m-%dT%H:%M:%SZ))alter audit traces --start $(date -u -v-24H +%Y-%m-%dT%H:%M:%SZ) \ --output json | jq -r '.[].trace_id'alter audit show <trace-id>Stream a day of activity into a pipeline
alter audit list --since 24h --output jsonl | jq -c 'select(.action == "token.retrieved")'Find CLI / PAT-driven admin actions
# BSD/macOS date:alter audit portal-actions --principal-kind pat \ --start $(date -u -v-7d +%Y-%m-%dT%H:%M:%SZ)# GNU date (Linux): --start $(date -u -d "7 days ago" +%Y-%m-%dT%H:%M:%SZ)Related
Section titled “Related”- Audit logs — what gets recorded and why
alter policy— the policy whose decisions show up here