API Token
A bearer credential that lets code outside the portal reach a circle's API. The plaintext is shown once at creation, the server keeps only its hash, and scopes, expiry, and rotation give a script exactly the reach it needs and no more.
Working with it
Selecting a API Token reveals its settings in the properties panel; it has no dedicated full-screen workbench.
How it appears
The same element type rendered as a definition, a circle instance, and a live workspace card.
When to use / not
When to use
- Authenticating a CI/CD pipeline, deploy script, or scheduled job that calls the API without a human at the keyboard.
- Giving an external integration scoped, machine-to-machine access (read / write / deploy / admin) instead of full circle credentials.
- Rotating credentials on a schedule — `rotate` issues a fresh token with an optional grace period so the old one keeps working during the cutover.
- Auditing or revoking programmatic access: inspect usage with `activity`, kill a leaked token instantly with `revoke`.
When not to use
- Defining what authentication an element requires — that is auth-policy's job; api-token only mints and manages the credentials themselves.
- Letting end-users of a hosted portal in — api-tokens are collaborator-only machine credentials, not an audience sign-in; reach for oauth for human login.
- Throttling request volume as a feature — per-token rate limits exist as a safety rail, but rate-limit is the element for shaping traffic.
Topology
Attaches to another element as a modifier, shaping that element's behaviour rather than running on its own.
Properties
token_typestring- Token type: bearer or api-key
descriptionstring- Human-readable description of the token's purpose
scopesarray- Permission scopes for this token
expires_atstring- Expiration time (null = never expires)
rate_limitobject- Rate limiting configuration
allowed_ipsarray- IP whitelist (CIDR notation)
allowed_originsarray- Allowed CORS origins
statusstring- Current status of the token
Capabilities
Defined for this element
- Auth
- Crypto
- Evaluate
- Observe
Operations
- activityGET
- attachPOST
- deleteDELETE
- detachPOST
- disablePOST
- enablePOST
- evaluatePOST
- generatePOST
- getGET
- get_attached_modifiersGET
- intentionGET
- list_attachmentsGET
- readme_updatePOST
- revokePOST
- rotatePOST
- schemaGET
- scopesGET
- updatePATCH
Ports
Inputs
- scopesconfig
- expires_atconfig
- rate_limitconfig
- ip_whitelistconfig
Composition
Validation rules
- Token has no expiration - consider setting expires_in_days for security
- Token has wildcard scope - consider limiting permissions
API Token (api-token)
Category: modifiers | Form: | Symbol: Tk
Secure token for programmatic API access
Creates secure bearer tokens for programmatic API access. Unlike middleware modifiers, api-token is a settings modifier (CascadeTarget::Settings) — it does not cascade or intercept requests. Tokens are prefixed “trif_” followed by a UUID, stored as SHA-256 hash in spec.token_hash. The plaintext token is shown only once on creation/rotation. Has its own executor (ApiTokenOpsExecutor) with four operations:
revoke(sets status=“revoked”),rotate(generates new token with optional grace_period_hours for old token),activity(queries usage logs with pagination),scopes(lists granted scopes, default [“read”]). Spec fields: scopes (array), expires_at (RFC3339), status, token_hash. Use api-token for CI/CD and external integrations; use auth-policy for defining what authentication is required.
Guide
Overview
An API Token provides programmatic access to the Triform API. Use tokens for CI/CD pipelines, scripts, and external integrations.
Creating Tokens
Tokens are created within a circle and inherit that circle’s access:
POST /api/{circle}/
{
"element_type": "api-token",
"slug": "ci-deploy",
"meta": {
"name": "CI/CD Deploy Token"
},
"spec": {
"scopes": ["read", "deploy"],
"expires_at": "2027-01-01T00:00:00Z"
}
}
The token value is returned once at creation. Store it securely.
Scopes
Tokens have limited permissions via scopes:
| Scope | Permissions |
|---|---|
read | Read-only access to resources |
write | Create and modify resources |
deploy | Deploy projects |
admin | Full circle admin access |
Using Tokens
Include the token in the Authorization header:
curl -H "Authorization: Bearer tf_xxxxxxxxxxxx" \
https://api.triform.dev/api/{circle}/
Token Lifecycle
Created → Active → Revoked/Expired
↓
Rotated → New Token Active
Rotation
Rotate tokens periodically for security:
POST /api/{circle}/{token}/ops/rotate
{
"grace_period_hours": 24
}
A grace period keeps both old and new tokens valid during transition.
Revocation
Immediately invalidate a token:
POST /api/{circle}/{token}/ops/revoke
Security Features
- IP Whitelist - Restrict to specific IPs
- Rate Limiting - Per-minute and per-day limits
- Expiration - Automatic expiry
- Audit Logging - All usage tracked
API
POST /api/{circle}/{token}/ops/revoke # Revoke immediately
POST /api/{circle}/{token}/ops/rotate # Rotate token
GET /api/{circle}/{token}/ops/activity # View usage
GET /api/{circle}/{token}/ops/scopes # View scopes
Directory Structure
.triform/
├── definition.yaml # Element type definition
├── properties.yaml # Configurable properties
├── contract.yaml # Bonds & capabilities
├── ops.yaml # Operations
└── schema.json # JSON Schema
Runtime Behavior
| Property | Value |
|---|---|
| Cascade | none — settings modifier, not evaluated in middleware cascade |
| Eval Order | n/a |
| Phase | n/a (token validation is handled by auth-policy; this element manages token lifecycle) |
| Fail Action | n/a |
| Applies To | circles (token grants access to a circle) |
API Token has its own executor with dedicated operations: revoke, rotate, activity, and scopes. These run outside the standard middleware pipeline.
Capabilities
- bearer: Bearer token authentication
- scopes: Scoped permissions
- expiration: Token expiration
- rotation: Token rotation
Properties
| Property | Type | Default | Description |
|---|---|---|---|
token_type | string | "bearer" | Token type: bearer or api-key |
description | string | — | Human-readable description of the token’s purpose |
scopes | array | ["read"] | Permission scopes for this token |
expires_at | string | — | Expiration time (null = never expires) |
rate_limit | object | — | Rate limiting configuration |
allowed_ips | array | — | IP whitelist (CIDR notation) |
allowed_origins | array | — | Allowed CORS origins |
status | string | "active" | Current status of the token |
Operations
activity
Get /ops/activity | Auth: Read
View usage activity
Queries usage logs for this token with pagination (limit max 100, offset). Returns the generic activity list shape (items, total, page, per_page, has_more) shared by every element’s activity op. Per-call detail (endpoint, method, HTTP status, IP address) is carried in each item’s
datafield as{type:"api-token-call", endpoint, method, status, ip_address}. Use to audit token usage or detect unauthorized access patterns.
attach
Post /ops/attach | Auth: Read
Attach this modifier to a target element
Attaches this modifier to a target element. The target_id must be a UUID of an existing element that supports this modifier type (check applies_to in definition.yaml). Priority controls evaluation order when multiple modifiers of the same type are attached — lower priority runs first. The attachment is stored in element_modifiers table. Cascade resolution runs at bond-time to merge this modifier into the target’s resolved config. Common mistake: attaching to an incompatible element type — check topology rules first.
delete
Delete /ops/delete | Auth: Admin
Delete element (soft delete)
Soft delete — sets state to ‘deleted’ but retains the record. Cannot delete elements that have children (has_no_bond precondition) or active runs. Requires admin auth and confirmation.
detach
Post /ops/detach | Auth: Read
Detach this modifier from a target element
Removes this modifier from a target element. Requires the target_id. Pervasive modifiers (audit, policy) can only be detached at the level they were originally attached — inherited pervasive modifiers cannot be detached by child elements. After detach, cascade resolution re-runs to remove this modifier’s effect from the resolved config.
disable
Post /ops/disable | Auth: Admin
Disable element (hides and prevents use)
Idempotent — safe to call on already-disabled elements. Optionally pass a reason string. Disabled elements cannot be invoked or executed. Inverse of enable.
enable
Post /ops/enable | Auth: Admin
Enable element (makes usable and visible)
Idempotent — safe to call on already-enabled elements. Transitions element to ready/enabled state. Cannot enable deleted elements. Inverse of disable.
evaluate
Post /ops/evaluate | Auth: Read
Evaluate modifier against current context
Evaluates this modifier against a context and optional target_id. Returns applies (bool), result (modifier-specific), and message. For modifiers without custom evaluation logic, returns a default pass result. Auth-policy returns allowed/denied. This is the explicit evaluation endpoint — during normal request flow, modifiers are evaluated automatically by the cascade resolver as middleware.
generate
Post /ops/generate | Auth: Admin
Generate a new API token
Creates a new “trif_” prefixed API token. The plaintext token is returned ONCE in the response — store it securely immediately. The server stores only a SHA-256 hash. Set scopes (default [“read”]), expires_at (optional RFC3339 timestamp), and token_type (personal, service, ci). The token_prefix (first 12 chars) is stored for identification. Returns the full token, prefix, and creation metadata.
get
Get /ops/get | Auth: Read
Get element details
Element is already resolved by the routing layer — this returns the cached element, not a fresh DB query. Use the path /api/{circle}/{slug} to address elements.
get_attached_modifiers
Get /ops/attached/{target_id} | Auth: Read
Get all modifiers attached to a target element
Lists all modifiers attached to a specific target element, including modifier_id, type, subcategory, and priority. Useful for debugging cascade resolution or understanding which policies apply to an element before invoking it.
intention
Get /ops/intention | Auth: Read
Get element intention with full inheritance chain
Returns three levels: direct (this element’s intention), inherited (from category and root), and resolved (final merged intention). Useful for understanding an element’s purpose in context of its hierarchy.
list_attachments
Get /ops/targets | Auth: Read
List all elements this modifier is attached to
Returns all target elements where this modifier is currently applied. Shows target_id, target_type, priority, and cascade_policy.
readme_update
Post /ops/readme_update | Auth: Write
Update element README.md content
Creates or overwrites README.md in the element’s git repo. Commits to the draft branch. Content must be provided as a markdown string.
revoke
Post /ops/revoke | Auth: Admin
Revoke this token immediately
Immediately invalidates this token by setting spec.status=“revoked” and recording revoked_at. Irreversible — a revoked token cannot be un-revoked. Use rotate instead if you need to replace a token with a grace period for the old one.
rotate
Post /ops/rotate | Auth: Admin
Rotate token (new token, old revoked)
Generates a new “trif_” prefixed token and stores its SHA-256 hash. The new plaintext token is returned ONCE in the response — store it immediately. Optional grace_period_hours (default 0) keeps the old token valid for that duration. Token prefix (first 12 chars) is returned for identification. Use for scheduled credential rotation in CI/CD pipelines.
schema
Get /ops/schema | Auth: Read
Get element input/output schema (MCP tools/list compatible)
Returns type-level port schemas from the TypeRegistry — not instance-specific overrides. Includes direction (input/output), required flag, and JSON schema per port. Useful for understanding what data an element accepts and produces.
scopes
Get /ops/scopes | Auth: Read
View token scopes
Returns the token’s granted scopes (default [“read”] if not configured) and expires_at (RFC3339 timestamp, null if no expiration). Check scopes before attempting operations that require specific permissions.
update
Patch /ops/update | Auth: Write
Update element
Partial update — send only the fields you want to change.
spec,name, andintentionare all independently optional.specMUST be a JSON object when present; deep-merged into the existing spec by default. Empty{"spec":{}}preserves existing spec content but still records a new version (no-op for content, not for version state). To clear/replace the entire spec wholesale send{"spec":{...},"deep":false}. List-typed spec fields use replace semantics (the patch list replaces the existing list, no array merging). Coordinates Git + DB writes. Slug cannot be changed after creation.
Error Codes
| Code | Class | Retryable | Description |
|---|---|---|---|
TOKEN_EXPIRED | auth | no | Token has expired |
TOKEN_REVOKED | auth | no | Token was revoked |
TOKEN_SCOPE_DENIED | auth | no | Scope not permitted |
Lifecycle / runtime
Defined for this element
Execution model: sync
Observability
Defined for this element
Metrics
- evaluation_count
- rejection_count
Events
- api-token.evaluated
- api-token.rejected
Pricing / cost
Platform default
Operation costs
- create: free
- update: free
- delete: free
- get: free
- list: free
- invoke: 10000 micro-AU
- tool_use: free
Set it up
- Token Typestring
- personal (user), service (machine-to-machine), ci (CI/CD pipeline)
- Descriptionstring
- What this token is for
- Scopesstring
- Permissions for this token