API Tokens for Automation

An API token is a long-lived, named, revocable credential for anything that talks to Athena without a person at the keyboard: PowerShell scripts, scheduled tasks, CI pipelines and other REST clients. A token acts as you, never with more than you hold at the moment it is used, and, unlike an interactive sign-in, it keeps working across server restarts until it expires or is revoked.

API tokens are for people and automation that call Athena. They are not the registration tokens used to enrol new agents, and managed machines never use them. Agents authenticate with their own certificates (see Certificates & PKI).

Why use an API token instead of a password#

A normal sign-in (password, LDAP or SSO) gives you a short-lived session token. That is right for a person, but awkward for automation: the session expires on the Token Expiration clock, and with the default signing-key rotation every server restart signs it out (see Sessions & Server Restarts). An unattended script would have to store a password and sign in again and again.

An API token avoids both problems:

How a token is authorised#

Who can use API tokens#

PermissionAllowsDefault roles
apitokens.useCreate, list and revoke your own API tokens.Operator, Admin
apitokens.manageSee every user’s tokens and revoke any of them.Admin

If you don’t have apitokens.use, the API Tokens panel does not appear on your profile. See Permission Model & Role Bundles for how permissions map to roles.

Creating a token in the console#

  1. Click your initials badge in the top bar and choose Profile.
  2. In the API Tokens panel, click New token.
  3. In the New API token dialog, fill in:
    • Name: a label you will recognise later, for example CI deploy. Up to 100 characters. It must be unique among your tokens that have not been revoked (case-insensitive).
    • Expires in (days): from 1 up to the maximum set by your administrator. The default is 30.
    • Limit to selected permissions (optional): tick it and choose permissions from the list of those you currently hold. Leave it unticked to give the token everything you hold.
  4. Click New token. The dialog closes and the panel shows the secret, which starts with ath_, along with a copy button and this warning: “Copy this token now. Only its hash is stored, so it cannot be shown again.”

The full secret is shown once. It disappears when you refresh the page, create another token or revoke one. Athena stores only a hash and the last four characters, so nobody can retrieve the secret later, not even an administrator. If you lose it, revoke the token and create a new one. Store the secret like a password: in a secrets manager or your CI system’s secret store, never in a script or source control.

The panel lists all your tokens as name …last4, each with a status (Active, Expired or Revoked), its expiry, when it was last used (or never), and its scope (everything you hold or the list of permissions). If any active token expires within 7 days, the panel shows a “Expiring within 7 days: …” notice naming them. Create the replacement before the old token expires.

Using a token with PowerShell#

PowerShell module 2.14.0 and later can connect with a token in place of a password. Nothing is entered interactively: every request carries the token. On connect, the module checks the token once, so a bad token fails straight away instead of on your first real command:

# Store the secret somewhere safe; this reads it from an environment variable
Connect-Athena -Server athena.example.local -ApiToken $env:ATHENA_API_TOKEN

# Then use any cmdlet as normal
Get-AthenaAgent

-Port still defaults to 8443. A session connected this way has no session-expiry clock of its own: it lasts until the token expires or is revoked. A token session cannot create new tokens.

The module also manages tokens:

CmdletWhat it does
New-AthenaApiToken -Name <name> [-ExpiresInDays <1–3650>] [-Permission <id[]>] Creates a token for the signed-in user. The returned object’s Token property is the secret, shown once. The cmdlet warns you to store it. Without -ExpiresInDays the token lives 30 days. Values above the server’s maximum are refused. Supports -WhatIf.
Get-AthenaApiToken [-All] Lists your tokens, or with -All every user’s tokens (requires apitokens.manage). Never returns secrets.
Revoke-AthenaApiToken -Id <guid> [-Force] Revokes a token. It asks for confirmation unless you pass -Force, and it accepts tokens from the pipeline.
# A 90-day token with everything you hold
$t = New-AthenaApiToken -Name "CI deploy" -ExpiresInDays 90
$t.Token   # the ath_ secret - copy it now

# A read-only token for a reporting script
New-AthenaApiToken -Name "inventory report" -Permission agents.view

# Every live token that expires within a week (admins)
Get-AthenaApiToken -All | Where-Object { $_.IsActive -and $_.ExpiresAt -lt (Get-Date).AddDays(7) }

# Revoke a token by name without prompting
Get-AthenaApiToken | Where-Object Name -eq "old laptop" | Revoke-AthenaApiToken -Force

Using a token with the REST API#

Send the token on each request to /api/… in either of these headers:

Authorization: Bearer ath_…
# or
X-Athena-Api-Token: ath_…
curl -H "Authorization: Bearer $ATHENA_API_TOKEN" https://athena.example.local:8443/api/auth/me

If a token is refused, the 401 response has a WWW-Authenticate header with the reason, naming the token by its label and last four characters. For example: Bearer error="invalid_token", error_description="API token 'CI deploy' (...a1f3) is revoked". Other reasons are an expired token (with its expiry time) or an owner who is disabled or removed. A value that is malformed or unknown is reported only as Invalid API token.

Token management endpoints:

Method & pathPermissionPurpose
GET /api/api-tokensapitokens.useYour own tokens, newest first (never the secrets).
POST /api/api-tokensapitokens.useCreate a token. The response is the only place the secret appears. 400 for a bad name, a lifetime above the maximum, or a permission you don’t hold. 403 if the caller is itself using an API token.
DELETE /api/api-tokens/{id}apitokens.useRevoke your own token, or anyone’s with apitokens.manage. 404 if the token isn’t visible to you or is already revoked.
GET /api/api-tokens/allapitokens.manageEvery user’s tokens.
POST /api/api-tokens/users/{userId}/revoke-allapitokens.manage Revoke every live token a user owns. data is the number revoked.
POST /api/api-tokens
{
  "name": "CI deploy",
  "expiresInDays": 90,
  "permissions": ["agents.view"]
}

Leave out expiresInDays to get the 30-day default. Leave out permissions to give the token everything you hold. If you send permissions, it must contain at least one permission.

Maximum lifetime policy#

Administrators set the longest lifetime a new token may have in Settings → Security → API Tokens, under API token policy → Maximum lifetime. The allowed range is 1 to 3650 days and the default is 365. Users can choose any lifetime up to this value. Changing it does not affect existing tokens, which keep the expiry they were created with.

SettingConfig keyDefaultRange
Maximum lifetimeSecurity:ApiTokenMaxExpiryDays365 1–3650 days

A request for a lifetime above the maximum is refused, not shortened. The error is “A token lifetime must be between 1 and N days (Settings > Security > API Tokens).”

Reviewing and revoking everyone’s tokens#

Holders of apitokens.manage also see an All API tokens table on Settings → Security → API Tokens. It has columns for Owner, Token (name and last four characters), Scope, Created, Expires (with an expires within 7 days hint), Last used (time and client IP address), and Status. For revoked tokens, Status shows who revoked them. Each live token has two actions:

Revocation takes effect on the token’s next request. The table never shows secrets. The Last used time and address are updated at most once a minute per token.

Audit trail and monitoring#

Token activity is written to the audit log. Every entry names the token by label and last four characters, for example 'CI deploy' (…a1f3):

Event typeWhen
ApiTokenCreatedA token is created. The entry includes its expiry and scope.
ApiTokenRevokedA token is revoked. The entry includes the owner and the user who revoked it.
ApiTokenExpiredA token passes its expiry. Recorded once per token by a background check that runs every 15 minutes.
ApiTokenUsedA token is used successfully. Sampled to at most one entry per token per hour.
ApiTokenAuthFailed (Warning)A revoked, expired or unknown token is presented, or one whose owner is disabled. Recorded at most once a minute per token and reason.

If you scrape Athena’s Prometheus metrics, the counter athena_api_token_auth_total counts token checks, labelled by result: success, malformed, unknown, revoked, expired, owner_disabled or error. A rise in unknown or revoked usually means a script is still using an old token.

Recommended practices#