Reference for API authentication, RBAC, and step sandboxing in DuraDX.
DuraDX provides security features for production deployments:
- API Authentication — Bearer token authentication for admin API endpoints.
- Workflow RBAC — Role-based access control for workflow operations.
- Step Sandboxing — Configuration flag for restricting shell step execution.
Set the api_auth field in your Config:
use duradx::security::ApiAuth;
let mut config = Config::new("my-app", "postgres://localhost/mydb");
config.api_auth = ApiAuth::BearerToken("my-secret-token".to_string());| Variant | Description |
|---|---|
ApiAuth::None |
No authentication (default). All endpoints are open. |
ApiAuth::BearerToken(String) |
Require Authorization: Bearer <token> header on all admin API requests. |
When ApiAuth::BearerToken is configured, every admin API request must include:
Authorization: Bearer my-secret-token
Requests without a valid token receive 401 Unauthorized.
The health check endpoint (GET /) is exempt from authentication.
The auth middleware is implemented as an Axum layer in src/security/auth.rs. It extracts the Authorization header, validates the bearer token, and passes through on match.
use duradx::security::auth::auth_middleware;
use axum::middleware;
// Applied automatically when api_auth is configured
let app = Router::new()
.route("/workflows", post(list_workflows))
.layer(middleware::from_fn(auth_middleware));Role-based access control restricts who can execute, read, cancel, or administer workflows.
Permissions are stored in the workflow_permissions table:
| Column | Type | Description |
|---|---|---|
workflow_name |
TEXT | Workflow name this permission applies to. |
principal |
TEXT | User ID, team name, or role. |
permission |
TEXT | Permission type: execute, read, cancel, admin. |
created_at |
BIGINT | When the permission was created. |
Primary key: (workflow_name, principal, permission).
use duradx::security::rbac::{SetPermissionInput, DeletePermissionInput};
// Grant permission
ctx.system_db().set_permission(&SetPermissionInput {
workflow_name: "process_order".to_string(),
principal: "team-backend".to_string(),
permission: "execute".to_string(),
}).await?;
// Check permission
let allowed = ctx.system_db().check_permission(
"process_order",
"team-backend",
"execute",
).await?;
// List permissions
let perms = ctx.system_db().list_permissions("process_order").await?;
// Revoke permission
ctx.system_db().delete_permission(&DeletePermissionInput {
workflow_name: "process_order".to_string(),
principal: "team-backend".to_string(),
permission: "execute".to_string(),
}).await?;| Permission | Description |
|---|---|
execute |
Can start/enqueue the workflow. |
read |
Can view workflow status and steps. |
cancel |
Can cancel the workflow. |
admin |
Full control (execute + read + cancel + manage permissions). |
- Always set
ApiAuth::BearerTokenin production. Use a strong, randomly generated token. - Bind admin port to localhost or internal network. Use a reverse proxy for external access.
- Use RBAC to restrict workflow operations to authorized teams/users.
- Rotate tokens periodically. Update the config and restart the application.
- Use HTTPS via a reverse proxy (nginx, Caddy) — the admin API is HTTP-only.
- Admin API — HTTP endpoints protected by auth
- Configuration — api_auth config field
- Architecture — system design and admin server