Skip to content

API tokens#

An API token is a non-interactive identity. CI pipelines, scripts, and agents that cannot open a browser authenticate with one.

A token is not a copy of the person who created it. It is its own principal, with its own permissions and its own rows in the audit trail.


Create a token#

curl -fsS -X POST \
  -H "Authorization: Bearer $LENS_AGENTS_TOKEN" \
  -H "Content-Type: application/json" \
  https://agents.example.com/v1/orgs/$ORG_ID/api-tokens \
  -d '{
    "name": "ci-deploy",
    "description": "Deploy pipeline",
    "expiresInDays": 90
  }'
Create an API token called ci-deploy in the acme org for the deploy
pipeline, expiring in 90 days.

The secret is returned in the agent's output, so capture it and clear the conversation if it is long-lived.

nexusctl api-token create --org acme \
  --name ci-deploy \
  --description "Deploy pipeline" \
  --expires-in-days 90

The secret is shown once

The platform stores a hash. Capture the secret at creation and put it straight into your secret manager — it cannot be retrieved later, only replaced.

Omitting --expires-in-days creates a non-expiring token. Set an expiry unless you have a specific reason not to; a token that expires is one you are forced to review.


Use it#

curl -fsS -H "Authorization: Bearer $LENS_AGENTS_TOKEN" \
  https://agents.example.com/v1/orgs

The same bearer token authenticates the MCP endpoint, so an external agent gets governed tools with no browser flow:

curl -fsS -X POST https://agents.example.com/mcp \
  -H "Authorization: Bearer $LENS_AGENTS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Granting access#

A fresh token can authenticate and little else. Two things give it reach:

Team membership decides which projects it can see.

Add the ci-deploy token to the platform-team team, and give that team
MEMBER access to the production project.
nexusctl team add-member platform-team --org acme --api-token <token-uuid>
nexusctl team set-access platform-team --org acme --project production --role MEMBER

Policy bindings decide what it may do in those projects.

Bind the ci-deploy policy to the ci-deploy token in production. Call
the binding ci-deploy-access.
nexusctl policy-binding create --project production \
  --name ci-deploy-access \
  --policy $POLICY_ID \
  --subject api-token=<token-uuid>

Grant the narrowest set that makes the job work. A CI token that only needs to list sandboxes should not carry a policy that also allows cluster writes.


MCP tool visibility#

Tokens see fewer platform tools than a signed-in user. Operational tools — sandboxes, policies, credentials, clusters, audit queries — are available. Organization lifecycle, connector management, and spending-limit changes are not.

Restricted tools are not listed for a token at all, so an agent holding one cannot discover its way to them.


List and revoke#

curl -fsS -H "Authorization: Bearer $LENS_AGENTS_TOKEN" \
  https://agents.example.com/v1/orgs/$ORG_ID/api-tokens

curl -fsS -X DELETE -H "Authorization: Bearer $LENS_AGENTS_TOKEN" \
  https://agents.example.com/v1/api-tokens/$API_TOKEN_ID
List the API tokens in the acme org. Which have no expiry, and
which have not been used recently?
nexusctl api-token list --org acme
nexusctl api-token revoke ci-deploy --org acme

Revocation takes effect immediately. The token's audit history stays — revoking an identity does not erase what it did.


Operating them well#

  • Name tokens after the job, not the person. ci-deploy survives a team change; alexs-token does not.
  • One token per job. Rotating a shared token means coordinating every consumer at once.
  • Set expiries and rotate on a schedule you actually keep.
  • Review periodically. api-token list against your list of live automations finds the ones nobody owns.
  • Revoke on offboarding. Tokens are org-scoped and survive the departure of whoever created them.