Assumed sessions

An assumed session is one set of short-lived STS credentials that was minted by POST /v1/authz/assume-role. The row tracks the role assumed, the principal who assumed it, the issued accessKeyId, and the expiry. Use this surface to audit who's currently acting under which role and to revoke a session early if needed.

For role creation and trust policies, see Roles. For the assume-role call itself, see Authz.

All endpoints require a bearer admin JWT — see Authentication.

Endpoints

Method Path Purpose
GET /v1/iam/assumed-sessions List active and recently expired sessions
POST /v1/iam/assumed-sessions/:id/revoke Kill an active session immediately

List sessions

GET /v1/iam/assumed-sessions

Returns the 200 most recent assumed sessions for roles in the active workspace, newest issued first. The list mixes active, expired, and revoked rows — filter client-side via status if you want one bucket.

Response

{
  "data": [
    {
      "id": "ars_01KPG…",
      "role": {
        "id": "rol_01KPG…",
        "name": "BillingReader"
      },
      "sessionName": "daily-etl-2026-05-12",
      "sessionAccessKeyId": "ASIA0123456789ABCDEF",
      "assumedByType": "service_account",
      "assumedBy": "svc_01KPG30TZK…",
      "issuedAt": "2026-05-12T18:00:00.000Z",
      "expiresAt": "2026-05-12T19:00:00.000Z",
      "revokedAt": null,
      "status": "active"
    },
    {
      "id": "ars_01KPG…",
      "role": { "id": "rol_01KPG…", "name": "BillingReader" },
      "sessionName": null,
      "sessionAccessKeyId": "ASIA1234…",
      "assumedByType": "user",
      "assumedBy": "usr_01KPG…",
      "issuedAt": "2026-05-12T15:00:00.000Z",
      "expiresAt": "2026-05-12T16:00:00.000Z",
      "revokedAt": null,
      "status": "expired"
    }
  ]
}

status is computed server-side: revoked (revokedAt is set), expired (past expiresAt), or active.

Revoke a session

POST /v1/iam/assumed-sessions/:id/revoke

Stamps revokedAt on the row. The credentials stop working immediately — subsequent signed requests fail with INVALID_CREDENTIALS.

204 No Content.

Errors

Status error.code When
404 NOT_FOUND No such session, or session belongs to a role in a different workspace.
409 ALREADY_REVOKED Session was already revoked.

Note that you cannot revoke an already-expired session — it's already not usable, and the row is preserved for audit. The 409 makes the API idempotent for the dashboard's "revoke" button (clicking twice doesn't error confusingly).

The assumed-session object

Field Type Description
id string (ars_…) Stable row ID. Used to revoke.
role object The assumed role — id and name.
sessionName string | null Optional caller-supplied label (passed to assume-role).
sessionAccessKeyId string (ASIA…) The credential's accessKeyId. Useful for tracing audit events back to this session — every signed request carries this in the JWT.
assumedByType user | service_account | role Kind of principal that assumed the role.
assumedBy string The originating usr_… / svc_… / rol_….
issuedAt ISO 8601 When the credentials were issued.
expiresAt ISO 8601 When they stop working naturally.
revokedAt ISO 8601 | null When (and if) they were revoked early.
status active | expired | revoked Computed.

The actual secret credentials (secretAccessKey, sessionToken) are never returned here — only the public sessionAccessKeyId. The secrets exist only in the assume-role response.

Why a session might appear

Each row corresponds to one successful POST /v1/authz/assume-role. Failed attempts (trust-policy denied) don't create a row; they show up in the audit log as iam.assume_role with outcome: "failure".

Tracing an audit entry back to a session

Audit-log entries created by an assumed-role session carry the sessionAccessKeyId in metadata. To find "who's behind this session?" pivot through the assumed-sessions list:

huudis iam assumed-sessions list --filter access-key=ASIA0123…
# returns one row with `assumedBy: svc_01KPG30TZK…`

This lets you collapse "service account → role → individual operation" into one audit story.

Revoke vs. expire

When to use
Wait for expiry Default. Sessions are short-lived; just let them age out.
Explicit revoke A credential has leaked, or a workload is misbehaving and you can't stop it at the source quickly.

Revoke is loud in the audit log (assumed_role_session_revoked) — pair with a notification to your on-call so they know a credential just got cut.

Limits

  • The session-list endpoint returns at most 200 rows. For longer history, the audit log is the durable source.
  • A single role can have unbounded concurrent active sessions — Huudis doesn't cap. If your workflow needs a "one assumed session at a time" guarantee, enforce it caller-side.

Events

No webhook events. Audit-log entries (iam.assume_role and assumed_role_session_revoked) carry the lifecycle.

Next

  • Roles — the role definitions backing each session.
  • Authz — the AssumeRole endpoint that issues sessions.
  • API authentication — how to sign requests with ASIA credentials.