Strait supports multiple authentication mechanisms and a layered authorization model: API key scopes for machine access and role-based access control (RBAC) for user access.Documentation Index
Fetch the complete documentation index at: https://docs.strait.dev/llms.txt
Use this file to discover all available pages before exploring further.
Authentication Schemes
1. Internal Secret
A global shared secret for administrative tasks and internal service-to-service communication.Configure via the
INTERNAL_SECRET environment variable.2. API Keys
Per-project API keys with scoped permissions. Recommended for external integrations.- Start with
strait_prefix - Are SHA-256 hashed before storage
- Track
last_used_attimestamps - Support
expires_atfor time-limited access - Can be revoked at any time
- Support rotation with grace periods (
replaced_by_key_id,grace_expires_at) - Are scoped to a project and a set of permissions
3. JWT Run Tokens (SDK)
Short-lived JWTs scoped to a specific run, used by the SDK for/sdk/v1 endpoints.
- Algorithm: HS256
- Subject: The
runID - Signing Key:
JWT_SIGNING_KEYenvironment variable
4. OIDC Bearer Tokens (Optional)
For user-facing API calls, non-strait_ bearer tokens can be validated via OIDC when configured.
- Configure issuer/audience/public-key verifier settings in server config
- Valid tokens are mapped to actor identity and project context
- OIDC and internal-secret header-based identity can coexist during rollout
API Key Scopes
Every API key has a list of scopes that control what it can do. Scopes are enforced on every request.Available Scopes
| Scope | Description |
|---|---|
* | Full access (wildcard) |
jobs:read | List and get jobs, job groups, environments, dependencies, versions, health |
jobs:write | Create, update, delete jobs, groups, environments, dependencies |
jobs:trigger | Trigger job runs (single and bulk) |
runs:read | List and get runs, events, checkpoints, outputs, debug bundles |
runs:write | Cancel runs, replay, update metadata, set debug mode |
workflows:read | List and get workflows, steps, runs, labels, dry-run, graph |
workflows:write | Create, update, delete workflows, pause/resume, approve/skip steps |
workflows:trigger | Trigger workflow runs, retry workflow runs |
secrets:read | List job secrets |
secrets:write | Create and delete job secrets |
api-keys:manage | Create, list, and revoke API keys |
rbac:manage | Create/update/delete roles, assign/remove members |
stats:read | View queue statistics |
Backwards Compatibility
API keys with empty scopes ([]) retain full access. This ensures pre-existing keys continue to work after the scope enforcement upgrade.
Scope Validation
Unknown scopes are rejected at API key creation time:Actor Identity
Every request is attributed to an actor for audit purposes.How Actor Identity Works
API key requests: The actor is alwaysapikey:<key-id> with type api_key. Actor headers (X-Actor-Id) are ignored on API key requests to prevent impersonation.
Internal secret requests: The app can pass user identity via headers:
- Sets
actor_type = "user"andactor_id = "user_abc123"in the request context - Applies
X-Project-Idto request context when project-scoped authorization is required - Asynchronously syncs the actor profile to the
known_actorstable - Records the actor as
created_byorupdated_byon mutations
Audit Columns
The following tables have audit columns:jobs—created_by,updated_byworkflows—created_by,updated_byjob_runs—created_byworkflow_runs—created_by
Role-Based Access Control (RBAC)
RBAC provides fine-grained access control for users (as opposed to API keys, which use scopes).How It Works
- Roles define a set of permissions (same scope strings as API keys)
- Members link a user (from your external auth provider) to a role within a project
- When a user makes a request (via internal secret +
X-Actor-Id), the middleware loads their role and checks permissions
System Roles
Four built-in system roles are available:| Role | Permissions |
|---|---|
| admin | * (full access) |
| operator | jobs:read, jobs:write, jobs:trigger, runs:read, runs:write, workflows:read, workflows:write, workflows:trigger, secrets:read, stats:read, rbac:manage |
| viewer | jobs:read, runs:read, workflows:read, stats:read |
| triggerer | jobs:read, jobs:trigger, runs:read, workflows:read, workflows:trigger |
Custom Roles
Create project-specific roles with any combination of permissions:Managing Members
Assign a user to a role:Permission Resolution
TherequirePermission middleware resolves authorization in this order:
- Internal secret (no scopes in context) → allow immediately
- API key → check if key’s scopes include the required permission
- User → load role permissions from DB (cached for 30s), check if role includes the required permission
Permission Cache
User permissions are cached for 30 seconds to avoid hitting the database on every request. The cache is automatically invalidated when:- A member’s role is changed (
POST /v1/members) - A member is removed (
DELETE /v1/members/{userID})
Middleware Chain
Authentication flows through these middleware inapps/strait/internal/api/middleware.go:
apiKeyOrSecretAuth— Routes to API key auth (strait_bearer), OIDC bearer auth (optional), or internal secret authapiKeyAuth— Validates key hash, checks revocation/expiration/rotation grace, sets scopes +actorType=api_keyin contextinternalSecretAuth— Constant-time secret comparison, optionally extracts actor fromX-Actor-*and project fromX-Project-IdoidcAuth— Validates configured OIDC bearer tokens and maps claims into actor/project contextrequirePermission(scope)— Checks authorization based on actor type (see Permission Resolution above)runTokenAuth— JWT validation for SDK endpoints only
Managing API Keys
Create
List
Revoke
Rotate (with Grace Period)
grace_expires_at to support zero-downtime credential rollouts.