Skip to main content
Every token you issue is a potential attack surface. If a token is leaked — through a log file, a misconfigured environment variable, or a compromised CI runner — an attacker holds access until you discover and revoke it. Expiration limits that window automatically. Rotation lets you replace the secret without disrupting the integration. Together, they form the foundation of a durable token security posture.

Setting an expiration date

Pass an expires_at field in ISO 8601 format when creating a token. Tooken enforces this deadline precisely: requests authenticated with the token after this timestamp are rejected immediately.
curl --request POST \
  --url https://api.tooken.io/v1/tokens \
  --header 'Authorization: Bearer tok_live_xxxxxxxxxxxxxxxxxxxx' \
  --header 'Content-Type: application/json' \
  --data '{
    "name": "ci-deploy-bot",
    "scopes": ["tokens:rotate"],
    "expires_at": "2025-06-01T00:00:00Z"
  }'
If you omit expires_at, the token never expires automatically. In most cases you should set an expiration — see the best practices section below.

What happens when a token expires

When expires_at passes, Tooken transitions the token’s status to expired. Any request that presents this token receives a 401 Unauthorized response:
401 response
{
  "error": "unauthorized",
  "message": "Token has expired"
}
The token ID remains in your account history and in audit logs. You cannot reactivate an expired token — create a new one if you need to re-establish access.

Rotating a token

Rotation generates a new secret for an existing token while preserving its ID, name, and scopes. Use rotation on a regular schedule so you replace credentials before they grow stale, without changing anything in your infrastructure that references the token ID. Call POST /tokens/:id/rotate with your API key:
curl --request POST \
  --url https://api.tooken.io/v1/tokens/tok_a1b2c3d4e5f6g7h8i9j0k1l2/rotate \
  --header 'Authorization: Bearer tok_live_xxxxxxxxxxxxxxxxxxxx'
Tooken returns the full token object with the new secret:
rotation response
{
  "id": "tok_a1b2c3d4e5f6g7h8i9j0k1l2",
  "name": "ci-deploy-bot",
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.new-secret...",
  "scopes": ["tokens:rotate"],
  "status": "active",
  "created_at": "2024-03-15T10:00:00Z",
  "expires_at": "2025-06-01T00:00:00Z",
  "last_used_at": "2024-06-01T14:32:11Z",
  "created_by": "user_abc123"
}
The old secret is invalidated the moment rotation completes. Any service still using the previous secret will receive 401 Unauthorized immediately. Update your secrets manager or environment variables with the new token value before the rotation request returns, or coordinate a brief deployment window to avoid dropped requests.

Rotate vs. revoke: choosing the right action

SituationAction
Scheduled credential refreshRotate
Suspected or confirmed compromiseRevoke
Service is being decommissionedRevoke
Scope change requiredRevoke and re-create
Secret has aged past your policy limitRotate
Rotation is a planned, non-destructive operation. Revocation is permanent and immediate — use it when you cannot trust the existing secret under any circumstances.

Rotation best practices

1

Define a rotation schedule before deploying

Decide how long each token type should live before its first rotation. Match the schedule to the token’s risk profile and access level.
2

Automate rotation for CI/CD pipelines

Short-lived tokens in CI environments — 24 to 72 hours — reduce the window of exposure from build log leaks. Trigger rotation at the start of each deployment pipeline using a provisioner token that holds the tokens:rotate scope.
3

Update secrets atomically

Fetch the new token value from the rotation response and write it to your secrets manager in the same step. Avoid any gap where the old secret is invalidated but the new one has not been deployed.
4

Verify after rotation

Make a test request with the new token immediately after rotation to confirm the credential is active and the service is running correctly before closing the deployment.

Expiration policy recommendations

CI/CD and automation

Set expires_at to 24–72 hours. Rotate at the start of every pipeline run. These tokens are most exposed to log and environment leaks.

Stable service integrations

Set expires_at to 90 days and rotate on a scheduled basis (monthly or quarterly). Monitor last_used_at to detect stale tokens.

Human-issued tokens

Set expires_at to 30 days maximum. Require explicit renewal so unused tokens expire naturally rather than accumulating.

Internal tooling

Treat like stable integrations. 90-day expiration with quarterly rotation, audited against the Tooken dashboard.

Frequently asked questions

Tooken rejects the request immediately and returns 401 Unauthorized with the message "Token has expired". The request does not reach any downstream system. Your service will need to catch this error and surface it — either by alerting an operator or by triggering an automated re-provisioning flow if your architecture supports it.
No. Tooken does not support updating expires_at on an existing token. To extend the credential’s lifetime, revoke the current token and create a new one with the desired expiration date and the same scopes. This intentional constraint keeps your audit log accurate — every token’s history is immutable once created.
Configure a webhook on the token.expiring event from the Tooken dashboard. Tooken fires this event 7 days and 1 day before a token’s expires_at timestamp. Your webhook receiver can trigger an alert, open a ticket, or kick off an automated rotation workflow. See the webhooks documentation for event payload details.