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
ASIAcredentials.