Authentication & RBAC
OSAPI uses JWT bearer tokens for authentication and fine-grained resource:verb
permissions for authorization. Every API endpoint (except health probes)
requires a valid token.
How It Works
JWT Signing
OSAPI uses HMAC-SHA256 (HS256) symmetric signing. The same signing_key is
used to both create and verify tokens:
osapi token generate ──[signs with signing_key]──> JWT
Client ──[sends JWT]──> API Server ──[verifies with signing_key]──> Allow/Deny
Only someone who knows the signing key can create valid tokens. If the signing key is compromised, rotate it immediately -- all previously issued tokens become invalid.
Token Structure
A token carries three pieces of authorization data:
- Roles (
rolesclaim, required) -- one or more ofadmin,write,read - Permissions (
permissionsclaim, optional) -- directresource:verbgrants that override role expansion - Subject (
subclaim) -- user identity for audit logging
Generate tokens with the CLI. See CLI Reference for usage and examples, or the API Reference for the REST endpoints.
Permission Resolution
When a request arrives, the middleware resolves the caller's effective permissions:
Roles and Permissions
Built-in roles expand to these default permissions:
| Role | Permissions |
|---|---|
admin | agent:read, agent:write, node:read, node:write, network:read, network:write, job:read, job:write, health:read, audit:read, command:execute, file:read, file:write, docker:read, docker:write, docker:execute, cron:read, cron:write, sysctl:read, sysctl:write, ntp:read, ntp:write, timezone:read, timezone:write, power:execute, process:read, process:execute, user:read, user:write, package:read, package:write, log:read, certificate:read, certificate:write, service:read, service:write |
write | agent:read, node:read, node:write, network:read, network:write, job:read, job:write, health:read, file:read, file:write, docker:read, docker:write, cron:read, cron:write, sysctl:read, sysctl:write, ntp:read, ntp:write, timezone:read, timezone:write, process:read, user:read, user:write, package:read, package:write, log:read, certificate:read, certificate:write, service:read, service:write |
read | agent:read, node:read, network:read, job:read, health:read, file:read, docker:read, cron:read, sysctl:read, ntp:read, timezone:read, process:read, user:read, package:read, log:read, certificate:read, service:read |
Custom Roles
Define custom roles in the configuration to create new role names or override default permission mappings:
controller:
api:
security:
roles:
ops:
permissions:
- node:read
- health:read
netadmin:
permissions:
- network:read
- network:write
- health:read
Configuration
controller:
api:
security:
# HS256 signing key (REQUIRED)
# Generate with: openssl rand -hex 32
signing_key: '<64-char hex string>'
client:
security:
# JWT for client requests (REQUIRED)
# Generate with: osapi token generate
bearer_token: '<jwt>'
See Configuration for the full reference including custom roles and CORS settings.
Agent-Level Authentication (PKI)
JWT-based auth secures the REST API between clients and the controller. For agent-level trust -- ensuring that only approved agents process jobs and that jobs originate from a trusted controller -- OSAPI provides an optional PKI enrollment system.
When PKI is enabled, each agent generates an Ed25519 key pair and submits an enrollment request. An administrator accepts or rejects the request, establishing cryptographic trust. The controller signs jobs with its private key, and agents verify the signature before processing.
PKI is complementary to JWT auth: JWTs authenticate API callers, while PKI authenticates the agent-controller relationship over NATS. See Agent Identity & PKI for full details.
Related
- Agent Identity & PKI -- machine-ID identity, PKI enrollment, job signing
- CLI Reference -- token generation and validation commands
- API Reference -- REST API documentation
- Configuration -- full configuration reference
- Architecture -- system design overview