Role-Based Access Control (RBAC)
Manage access to your Arc deployment with organizations, teams, and granular permissions down to the measurement level.
Overview
Arc Enterprise RBAC builds on top of Arc's token-based authentication to add organizational structure and fine-grained permissions:
Organization (e.g., "Acme Corp")
└── Team (e.g., "Data Engineering")
└── Role (e.g., "production-readwrite")
├── Database: "production" → [read, write, delete]
└── Database: "analytics" → [read]
└── Measurements: ["metrics_*", "events_*"]
Key capabilities:
- Organizations — Top-level grouping for your company or division
- Teams — Group users by function (engineering, analytics, operations)
- Roles — Define permissions per database with optional measurement restrictions
- Measurement-level permissions — Restrict access to specific measurements using wildcard patterns
- Backward compatible — Existing OSS token permissions continue to work
Prerequisites
- Authentication must be enabled (
ARC_AUTH_ENABLED=true) - Arc Enterprise license with RBAC feature
Permission Model
Permissions are defined at the role level and apply to specific databases:
| Permission | Description |
|---|---|
read | Query data from the database |
write | Write data to the database |
delete | Delete data from the database |
admin | Full administrative access |
Roles can optionally restrict access to specific measurements within a database using wildcard patterns (e.g., metrics_* matches metrics_cpu, metrics_memory, etc.).
API Reference
All RBAC endpoints require admin authentication.
Organizations
Create Organization
curl -X POST http://localhost:8000/api/v1/rbac/organizations \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme Corp",
"description": "Main organization"
}'
Response:
{
"success": true,
"data": {
"id": 1,
"name": "Acme Corp",
"description": "Main organization",
"created_at": "2026-02-13T10:00:00Z",
"updated_at": "2026-02-13T10:00:00Z"
}
}
List Organizations
curl -H "Authorization: Bearer $ADMIN_TOKEN" \
http://localhost:8000/api/v1/rbac/organizations
Get Organization
curl -H "Authorization: Bearer $ADMIN_TOKEN" \
http://localhost:8000/api/v1/rbac/organizations/1
Update Organization
curl -X PATCH http://localhost:8000/api/v1/rbac/organizations/1 \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"description": "Updated description"}'
Delete Organization
curl -X DELETE http://localhost:8000/api/v1/rbac/organizations/1 \
-H "Authorization: Bearer $ADMIN_TOKEN"
Teams
Create Team
curl -X POST http://localhost:8000/api/v1/rbac/organizations/1/teams \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Data Engineering",
"description": "Data engineering team"
}'
Response:
{
"success": true,
"data": {
"id": 1,
"organization_id": 1,
"name": "Data Engineering",
"description": "Data engineering team",
"created_at": "2026-02-13T10:00:00Z",
"updated_at": "2026-02-13T10:00:00Z"
}
}
List Teams
curl -H "Authorization: Bearer $ADMIN_TOKEN" \
http://localhost:8000/api/v1/rbac/organizations/1/teams
Get Team
curl -H "Authorization: Bearer $ADMIN_TOKEN" \
http://localhost:8000/api/v1/rbac/teams/1
Update Team
curl -X PATCH http://localhost:8000/api/v1/rbac/teams/1 \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"description": "Updated team description"}'
Delete Team
curl -X DELETE http://localhost:8000/api/v1/rbac/teams/1 \
-H "Authorization: Bearer $ADMIN_TOKEN"
Roles
Create Role
curl -X POST http://localhost:8000/api/v1/rbac/teams/1/roles \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "production-readwrite",
"database_pattern": "production",
"permissions": ["read", "write"]
}'
Response:
{
"success": true,
"data": {
"id": 1,
"team_id": 1,
"name": "production-readwrite",
"database_pattern": "production",
"permissions": ["read", "write"],
"created_at": "2026-02-13T10:00:00Z",
"updated_at": "2026-02-13T10:00:00Z"
}
}
Use * as the database pattern to grant permissions across all databases. For example, "database_pattern": "*" with "permissions": ["read"] grants read access to every database.
List Roles
curl -H "Authorization: Bearer $ADMIN_TOKEN" \
http://localhost:8000/api/v1/rbac/teams/1/roles
Get Role
curl -H "Authorization: Bearer $ADMIN_TOKEN" \
http://localhost:8000/api/v1/rbac/roles/1
Update Role
curl -X PATCH http://localhost:8000/api/v1/rbac/roles/1 \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"permissions": ["read", "write", "delete"]}'
Delete Role
curl -X DELETE http://localhost:8000/api/v1/rbac/roles/1 \
-H "Authorization: Bearer $ADMIN_TOKEN"
Measurement Permissions
Restrict a role to specific measurements within its database pattern.
Add Measurement Permission
curl -X POST http://localhost:8000/api/v1/rbac/roles/1/measurements \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"measurement_pattern": "metrics_*"
}'
List Measurement Permissions
curl -H "Authorization: Bearer $ADMIN_TOKEN" \
http://localhost:8000/api/v1/rbac/roles/1/measurements
Remove Measurement Permission
curl -X DELETE http://localhost:8000/api/v1/rbac/roles/1/measurements/1 \
-H "Authorization: Bearer $ADMIN_TOKEN"
Walkthrough: Setting Up RBAC
This example sets up a typical organization with two teams and different access levels.
Step 1: Create the Organization
curl -X POST http://localhost:8000/api/v1/rbac/organizations \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "Acme Corp"}'
Step 2: Create Teams
# Data Engineering team — full access
curl -X POST http://localhost:8000/api/v1/rbac/organizations/1/teams \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "Data Engineering"}'
# Analytics team — read-only access
curl -X POST http://localhost:8000/api/v1/rbac/organizations/1/teams \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "Analytics"}'
Step 3: Create Roles
# Data Engineering: read/write/delete on production database
curl -X POST http://localhost:8000/api/v1/rbac/teams/1/roles \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "production-full",
"database_pattern": "production",
"permissions": ["read", "write", "delete"]
}'
# Analytics: read-only on production, restricted to specific measurements
curl -X POST http://localhost:8000/api/v1/rbac/teams/2/roles \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "production-readonly",
"database_pattern": "production",
"permissions": ["read"]
}'
Step 4: Restrict Measurements (Optional)
# Analytics team can only see metrics_* and events_* measurements
curl -X POST http://localhost:8000/api/v1/rbac/roles/2/measurements \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"measurement_pattern": "metrics_*"}'
curl -X POST http://localhost:8000/api/v1/rbac/roles/2/measurements \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"measurement_pattern": "events_*"}'
Best Practices
-
Principle of least privilege — Start with minimal permissions and expand as needed. Use read-only roles as the default for analytics users.
-
Use measurement restrictions — When teams only need access to specific data, restrict by measurement pattern rather than granting full database access.
-
Use wildcard patterns carefully — Database pattern
*grants access to all databases. Use specific patterns when possible. -
Pair with audit logging — Enable audit logging to track RBAC changes and access patterns.
-
Plan your hierarchy — Design your organization and team structure before implementation. A typical pattern is one organization per company, teams per department or function.
Next Steps
- Audit Logging — Track all access and changes for compliance
- Query Governance — Add rate limits and quotas per token