Develop
Manage API Tokens
Every application that calls your gateway sends a Verdictan API token. Give each application its own token, so you can limit what it can reach and revoke it without affecting anything else.
Your first gateway's credentials come from the quickstart. This page covers every token after that.
Create an application token
Sign in to the EU Console or US Console with permission to manage API tokens.
- Open API Tokens and select Create token.
- Name it after the application, for example
support-app-test. - Choose durable for a token you'll keep using, and set an expiry.
- Pick a role with the permissions the application needs.
- Add gateway, provider, model, team, and spend limits.
- Create the token and copy its value right away. The Console shows it only once.
Store the value in the application's secret manager or environment. For a throwaway token, set an expiry and at least one spend or request-count limit.
Create an application token with the CLI
After verdictan auth login, this creates a token that lasts one day and allows at most three requests:
verdictan token create \
--name support-app-test \
--purpose general \
--key-class disposable \
--max-requests 3 \
--expires-in 24hSave the value and the ID. Add --gateway-id, --provider, --model-filter, or --team-id as your application needs. See the token command reference.
Verify the application token
With your agent's central URL (without /v1) and the new token:
export VERDICTAN_BASE_URL="https://<your-published-hostname>"
export VERDICTAN_CLIENT_TOKEN="replace-with-your-application-token"
curl --fail-with-body --silent --show-error \
--header "Authorization: Bearer $VERDICTAN_CLIENT_TOKEN" \
"$VERDICTAN_BASE_URL/v1/models"The response lists the models this token can use. Listing models doesn't call a provider, so also send one small model request and check its response and recorded usage.
Don't confuse this with the gateway runtime token, which starts the gateway and never goes in an application.
Replace a token without an interruption
- Create a replacement with the same role and bindings.
- Put it in the application's secret configuration and send a test request.
- Check that the recorded usage belongs to the replacement.
- Revoke the old token once every consumer has switched.
This gives you an overlap. verdictan token rotate <token-id> instead replaces the value in place, immediately; use it only when you can update every consumer at once.
Narrow or revoke access
Clone narrower creates a new token with the same or fewer permissions and limits, for example keeping only one model of a two-model filter. It can never widen access. From the CLI:
verdictan token clone "$TOKEN_ID" --reason "support app: gpt-4o-mini only" --model-filter gpt-4o-miniTo revoke a token, open it in API Tokens, select More → Revoke, check the name, and confirm.
From the CLI, take the ID from verdictan token list:
TOKEN_ID="replace-with-the-token-id-to-revoke"
verdictan token delete "$TOKEN_ID" --yes--yes skips the confirmation. New requests with the old value are rejected; a request already in progress can finish.
If you think a token was exposed, use Emergency revoke in the Console, or verdictan token emergency-revoke "$TOKEN_ID" --reason "<why>". It records your reason with the revocation. Investigate before you issue a replacement.
Examine tokens
verdictan token list
verdictan token get "$TOKEN_ID"get shows the token's role, bindings, expiry, and usage. A missing last_used_at means the token is new or unused; find its owner before you revoke it.
Set the scope with bindings
Add bindings before a token's first use. They limit the damage if it leaks.
| Binding | Effect |
|---|---|
gateway_id | Only that hosted gateway runtime can use the token |
team_id | The team owns or limits the token |
user_id | The user owns the token, and is the default spend owner when no gateway attribution exists |
provider | Only that upstream provider |
model_filter | Only the listed models |
budget_id, max_budget | Spending stops at the budget |
max_requests | The token stops after this many requests |
A request the token's bindings or permissions don't allow is denied, however valid the token itself is. The Usage explorer can filter to one token; when the gateway forwards only key_id, it attributes spend to the token's owner fields.
Select a key class
| Key class | For | Required limits |
|---|---|---|
durable | Long-lived gateway or client workloads | Expiry optional |
virtual | Workloads narrowed to a provider, model, or gateway | Expiry optional |
disposable | Short jobs and limited-use automation | An expiry, plus max_budget or max_requests |
All classes appear in the /v1/tokens inventory. Create and clone responses include token_value once; after that you only see metadata: key_class, resource_id, resource_vrn, attached policies, limits, and depletion state.
Token profiles
Different workloads need different kinds of token:
| Workload | Profile | Where the credential goes |
|---|---|---|
Application, SDK, IDE, or curl calling the gateway | purpose=general, principal_type=api_token | Authorization: Bearer on each gateway request |
| Gateway runtime | purpose=gateway_runtime, bindings.gateway_id, bindings.team_id | VERDICTAN_API_TOKEN on the gateway host |
| Long-term machine integration | purpose=integration, bindings.team_id | Authorization: Bearer on each control-plane request |
| Upstream model provider | Not a Verdictan token | The provider credential on the gateway host or in Secrets |
The Console form creates purpose=general tokens. Gateway credentials come from the gateway setup flow. For integration or runtime tokens, use the CLI or the API.
API fields and a creation example
| Field | Values | Meaning |
|---|---|---|
purpose | general, gateway_runtime, integration | The workload class |
principal_type | api_token, gateway_runtime | The principal shape the policy engine sees |
bindings | gateway_id, team_id, user_id, provider, model_filter, budget_id, max_budget, max_requests | Scope limits and default owner attribution |
key_class | durable, virtual, disposable | The governed key class |
token_value | vdt_... | The one-time secret the client sends as Authorization: Bearer |
verdictan token create has no principal_type flag and always creates api_token principals. A gateway_runtime principal, created through the API, also needs a team binding. The CLI spells purposes in kebab case (--purpose gateway-runtime); the API and token metadata use gateway_runtime.
With the regional API URL and an administrative token, this creates a short-lived application token:
curl --fail-with-body --silent --show-error \
--request POST "$VERDICTAN_API_URL/v1/tokens" \
--header "Authorization: Bearer $VERDICTAN_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"name": "support-app-test",
"purpose": "general",
"principal_type": "api_token",
"key_class": "disposable",
"bindings": {"max_requests": 3},
"expires_in_seconds": 86400
}'The response includes token_value once, so keep it out of shared logs. Add the bindings and role IDs your workload needs. You cannot grant permissions you aren't allowed to grant yourself.
Troubleshooting
| Problem | What to check |
|---|---|
| Create token is disabled | Pick at least one role and fill in the required fields. |
401 | The application has the right value, and the token hasn't expired or been revoked. |
403 | The error code, then the role's permissions, gateway and model limits, and request quota. |
| The token stops before it expires | Its remaining budget and request count. Expiry is not the only limit. |
| Clone fails | The clone's limits and bindings must be equal or narrower. |
Next steps
- Usage Costs and Budgets: pick a spend control and test it.
- Debugging Requests: trace an application failure.
- Token command reference: automate token management.