Skip to content

API Tokens

API tokens provide authentication for automated systems like CI/CD pipelines, scripts, and integrations. Unlike sessions, tokens are long-lived and don’t require interactive login.

AspectAPI TokensSessions
Use CaseAutomation, CI/CDHuman users
CreationDeployers (for themselves) or adminsOAuth flow
LifetimeUntil deleted or the optional expires_atWeb: idle timeout; CLI: 90 days from last use
MFANot applicableSupported
CSRFNot requiredRequired
RevocationManual deleteLogout (web or rack-gateway logout), or revoking it from the user’s sessions

Each API token consists of:

Format: rgw_<random>
Example: rgw_kX7mN2pQ9rT4wY8zA1bC3dE5fG...=
^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^
prefix random component
ComponentDescription
rgw_Rack Gateway token prefix
Random32 bytes, base64url encoded (with padding)

Like session tokens, API tokens are hashed before storage:

Client has: rgw_kX7mN2pQ9rT4wY8...
Database: SHA-256 hash of full token

API tokens store explicit permissions. Roles are a shortcut at creation time:

RoleUse CasePermissions
viewerMonitoringRead-only access
opsEmergency scriptsRestart, exec, view env
deployerDeploy automationFull deploy capabilities
cicdCI/CD pipelinesMinimal deploy + approval
adminRack automationAll Convox operations, capped by the owner’s role

See Roles for detailed permission lists.

A token is always limited by the person who owns it:

  • Capped by the owner’s current role. Every request needs the permission in the token’s own list and in the owner’s current role. Demote the owner and their tokens lose the extra access on the next request.
  • Stops working with its owner. Tokens of a locked or deleted user are rejected.
  • Created within the owner’s role. When a token is created or edited, each permission must be one the owner’s role grants. Deployers can create tokens for themselves; only admins can create tokens for other users.
  • Rack access only, plus a few gateway endpoints. Tokens can use the rack proxy (/api/v1/rack-proxy/*) and only these gateway endpoints: GET /api/v1/info, GET /api/v1/rack, POST /api/v1/deploy-approval-requests and GET /api/v1/deploy-approval-requests/:id. User, token, settings, audit-log and approval endpoints refuse tokens, even admin-owned ones.
  • No privileged runs. Tokens can never start a process with a custom image, host volumes, privileged mode or node placement options.
  1. Navigate to API Tokens in the sidebar
  2. Click Create Token
  3. Enter a descriptive name (e.g., ci-production-deploy)
  4. Select the appropriate role
  5. Click Create
  6. Copy the token immediately - it won’t be shown again
Terminal window
# Create a CI/CD token
rack-gateway api-token create --name "GitHub Actions" --role cicd
# Create a viewer token for monitoring
rack-gateway api-token create --name "Datadog Monitor" --role viewer
Terminal window
# Set token as environment variable
export RACK_GATEWAY_API_TOKEN=rgw_kX7mN2pQ9rT4...
# Or use --api-token flag
rack-gateway apps --api-token rgw_kX7mN2pQ9rT4...

Include the token in the Authorization header:

Terminal window
curl -H "Authorization: Bearer rgw_kX7mN2pQ9rT4..." \
https://gateway.example.com/api/v1/rack-proxy/apps

These examples deploy straight away, which needs a token with the deploy permissions themselves. A cicd token deploys only with an approved deploy approval: request one first (rack-gateway deploy-approval request --wait).

name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy
env:
RACK_GATEWAY_API_TOKEN: ${{ secrets.RACK_GATEWAY_API_TOKEN }}
run: |
rack-gateway deploy -a myapp

Store the token in GitHub Secrets (Settings → Secrets and variables → Actions).

Users with gateway:api_token:read (every role) see their own tokens; admins see everyone’s:

Terminal window
rack-gateway api-token list
Terminal window
# Revoke by ID
rack-gateway api-token delete <token-id>

Or through the web UI: API Tokens → Select Token → Delete

Each token tracks:

FieldDescription
nameDescriptive identifier
permissionsExplicit permissions on the token
userThe owner, whose role caps the token
created_byUser who created the token (an admin can create one for another user)
created_atCreation timestamp
expires_atOptional expiry
last_used_atLast successful use

Use descriptive names that indicate:

  • Purpose: ci-production-deploy
  • Environment: staging-monitoring
  • System: github-actions-main

Bad examples: token1, test, my-token

Always use the minimum required role:

SystemRecommended RoleReason
CI/CD deploycicdMinimal scope + approvals
MonitoringviewerRead-only sufficient
Emergency restartopsOnly restart, no deploy
Rack automationadminOnly if it really needs every Convox operation

Rotate tokens periodically:

  1. Create new token with same role
  2. Update all systems using old token
  3. Verify systems work with new token
  4. Delete old token

Recommended rotation frequency:

  • Production tokens: Quarterly
  • CI/CD tokens: Every 6 months
  • Development tokens: Annually

Review token usage regularly:

  • Tokens not used in 90+ days should be reviewed
  • Unexpected usage patterns may indicate compromise
  • Failed authentication attempts are logged
  • Never commit tokens to git
  • Use secrets management (AWS Secrets Manager, Vault, etc.)
  • Environment variables are preferred over config files
  • CI/CD systems have secure secret storage

If a token is exposed:

  1. Delete immediately

    Web UI → API Tokens → Delete token

  2. Review audit logs

    Check what actions were taken with the token

  3. Create replacement

    Generate new token with same role

  4. Update systems

    Deploy new token to affected systems

  5. Investigate

    Determine how exposure occurred

  • Tokens should only be used over HTTPS
  • Tokens have no IP allowlist, so keep the gateway on a private network (CI runners reach it through Tailscale or a VPN)

All token usage is logged:

{
"timestamp": "2024-01-15T10:30:00Z",
"user_email": "deployer@example.com",
"api_token_id": 42,
"api_token_name": "ci-production-deploy",
"action_type": "convox",
"action": "build.create",
"resource": "myapp",
"status": "success",
"rbac_decision": "allow",
"http_status": 200
}

Token requests carry api_token_id and api_token_name, and user_email is the token’s owner.

API tokens don’t support MFA because:

  • Automation can’t complete interactive MFA
  • The token’s permissions, capped by its owner’s role, determine access
  • Audit logging provides accountability

For sensitive operations requiring human approval, use Deploy Approvals.

Tokens don’t expire unless you set expires_at when creating them (for example rack-gateway api-token create --expires-at 2027-01-01T00:00:00Z):

  • Without an expiry, tokens suit long-running automation
  • Manual rotation/deletion is still required
  • Regular review process recommended

Tokens are passed in headers, not cookies:

  • Not vulnerable to CSRF attacks
  • No CSRF token required
  • Bearer token auth is inherently CSRF-safe