Skip to content

Roles

Configure and manage roles for fine-grained access control in Mantis.

FieldTypeDescription
idUUIDUnique identifier
nameStringRole name (unique, lowercase)
descriptionStringHuman-readable description
is_systemBooleanSystem role flag (cannot be deleted)
created_atDateTimeCreation timestamp
updated_atDateTimeLast modification

System roles are created during installation and cannot be deleted.

Full system administrator access:

Permissions: ALL (111 permissions)
is_system: true

Capabilities:

  • All CRUD operations on all resources
  • System configuration and settings
  • User and role management
  • Tenant administration
  • Encryption key management

Day-to-day deployment operations:

Permissions: 30+ deployment/operational permissions
is_system: true

Capabilities:

  • Create, read, update actions/sequences/solutions
  • Create and manage deployments
  • Register and manage targets
  • View and update environments
  • Read system statistics
  • Create promotions and rollbacks

Cannot:

  • Manage users or roles
  • Modify system settings
  • Delete resources (most types)
  • Create/manage tenants

Read-only access to operational resources:

Permissions: 20 read permissions
is_system: true

Capabilities:

  • View all deployment-related resources
  • View targets and environments
  • View deployment history and status
  • View system statistics

Cannot:

  • Create, modify, or delete any resources
  • Execute deployments
  • View admin settings

Full access within tenant scope:

Permissions: All except system-level
is_system: false (created via migration, but acts as system role)

Capabilities:

  • All operations within assigned tenant
  • Manage tenant-scoped users
  • Configure tenant settings
  • Full deployment lifecycle management

Cannot:

  • Create or delete tenants (tenants:create, tenants:delete)
  • Access system administration (system:admin)
  • Modify global settings (settings:manage)
  • Read audit logs (audit:read)

The following permissions are withheld from the seeded tenant_admin role. Five system-tier permissions are excluded at seed time: tenants:create, tenants:delete, system:admin, settings:manage, and audit:read. Several permissions added by later migrations were also granted to admin only and never extended to tenant_admin: deployments:update, deployments:trigger, deployments:override_freeze, and wireguard:manage. In addition, the notifications resource permissions (notifications:read, notifications:create, notifications:update, notifications:delete) were not granted to tenant_admin when that resource was introduced.

Separately, when a tenant_admin delegates roles/permissions to others, a secure-by-default ceiling applies: it may confer only permissions it itself holds or ones carried by the baseline viewer/operator roles — anything else, including any future system-tier permission, is refused (mandible/src/routes/admin/users.rs, roles.rs). See Permissions → Tenant Admin Role.

Terminal window
curl -X GET \
-H "Authorization: Bearer $TOKEN" \
"https://api.mantis.local/api/v1/admin/roles?page=1&limit=20"

Response:

{
"data": [
{
"id": "019b937d-4862-802a-9dd6-b840c22b87ac",
"name": "admin",
"description": "Full system administrator with all permissions",
"is_system": true,
"user_count": 2,
"permission_count": 111,
"created_at": "2024-01-01T00:00:00Z"
},
{
"id": "019b937d-4862-8e07-ac3a-1b8589d1b807",
"name": "operator",
"description": "Can manage deployments and targets",
"is_system": true,
"user_count": 10,
"permission_count": 54,
"created_at": "2024-01-01T00:00:00Z"
}
],
"meta": {
"total": 5,
"page": 1,
"limit": 20
}
}
Terminal window
curl -X GET \
-H "Authorization: Bearer $TOKEN" \
"https://api.mantis.local/api/v1/admin/roles/$ROLE_ID"

Response:

{
"id": "019b937d-4862-8e07-ac3a-1b8589d1b807",
"name": "operator",
"description": "Can manage deployments and targets",
"is_system": true,
"permission_groups": [
{
"resource": "actions",
"permissions": [
{
"id": "019b937d-4862-8ba3-98ce-0f03fba1c12d",
"name": "actions:create",
"resource": "actions",
"action": "create",
"description": "Create new actions"
},
{
"id": "019b937d-4862-892f-8964-135631fe2351",
"name": "actions:read",
"resource": "actions",
"action": "read",
"description": "View actions"
}
]
},
{
"resource": "deployments",
"permissions": [
{
"id": "019b937d-4862-8e2a-88e4-d34627a858db",
"name": "deployments:create",
"resource": "deployments",
"action": "create",
"description": "Start new deployments"
}
]
}
],
"users": [
{
"id": "019b937d-4862-8e07-ac3a-1b8589d1b807",
"username": "bob",
"email": "bob@example.com",
"display_name": "Bob Jones"
}
],
"created_at": "2024-01-01T00:00:00Z",
"updated_at": null
}
Terminal window
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "deployer",
"description": "Can only create and monitor deployments",
"permission_ids": [
"019b937d-4862-8ba3-98ce-0f03fba1c12d",
"019b937d-4862-892f-8964-135631fe2351",
"019b937d-4862-8e2a-88e4-d34627a858db"
]
}' \
"https://api.mantis.local/api/v1/admin/roles"
Terminal window
curl -X PUT \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "deployer-updated",
"description": "Updated description"
}' \
"https://api.mantis.local/api/v1/admin/roles/$ROLE_ID"
Terminal window
curl -X DELETE \
-H "Authorization: Bearer $TOKEN" \
"https://api.mantis.local/api/v1/admin/roles/$ROLE_ID"
Terminal window
curl -X GET \
-H "Authorization: Bearer $TOKEN" \
"https://api.mantis.local/api/v1/admin/roles/$ROLE_ID/permissions"
Terminal window
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"permission_ids": [
"019b937d-4862-8ba3-98ce-0f03fba1c12d",
"019b937d-4862-892f-8964-135631fe2351",
"019b937d-4862-8e2a-88e4-d34627a858db"
]
}' \
"https://api.mantis.local/api/v1/admin/roles/$ROLE_ID/permissions"
Terminal window
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"permission_ids": ["019b937d-4862-8ba3-98ce-0f03fba1c12d"]
}' \
"https://api.mantis.local/api/v1/admin/roles/$ROLE_ID/permissions/remove"
Terminal window
curl -X GET \
-H "Authorization: Bearer $TOKEN" \
"https://api.mantis.local/api/v1/admin/roles/$ROLE_ID/users"

For users who can only run deployments:

{
"name": "deployment-executor",
"description": "Can create and monitor deployments only",
"permissions": [
"deployments:create",
"deployments:read",
"deployments:cancel",
"targets:read",
"solutions:read",
"environments:read"
]
}

For managing a specific environment:

{
"name": "prod-admin",
"description": "Production environment administrator",
"permissions": [
"deployments:create",
"deployments:read",
"deployments:cancel",
"targets:read",
"targets:update",
"environments:read",
"environments:update",
"freezes:create",
"freezes:read",
"freezes:update",
"promotions:create",
"rollbacks:create"
]
}

For compliance and audit access:

{
"name": "auditor",
"description": "Read-only access for audit purposes",
"permissions": [
"actions:read",
"sequences:read",
"solutions:read",
"targets:read",
"deployments:read",
"environments:read",
"users:read",
"roles:read",
"freezes:read",
"promotions:read",
"rollbacks:read",
"statistics:read"
]
}

For infrastructure team managing targets:

{
"name": "target-manager",
"description": "Manage targets and registrations",
"permissions": [
"targets:create",
"targets:read",
"targets:update",
"targets:delete",
"registrations:read",
"registrations:approve",
"registrations:reject",
"registrations:revoke",
"registration_tokens:create",
"registration_tokens:read",
"registration_tokens:revoke",
"certificates:read",
"environments:read",
"environments:manage_targets",
"tags:read"
]
}

Create roles that build on each other:

Implementation:

  1. Create base viewer with read permissions
  2. Create operator with viewer permissions + write permissions
  3. admin has all permissions (system role)

Create distinct roles for different functions:

Assign multiple roles to users:

All role operations are logged:

EventCategorySeverity
authz.role_createdAuthorizationInfo
authz.role_updatedAuthorizationInfo
authz.role_deletedAuthorizationInfo
authz.role_permissions_assignedAuthorizationSecurity
authz.role_permissions_removedAuthorizationSecurity
  • Use lowercase with hyphens: prod-admin, target-manager
  • Be descriptive: deployment-executor not de
  • Include scope if applicable: env-staging-deployer
  1. Start minimal - Add permissions as needed
  2. Group logically - Keep related permissions together
  3. Document purpose - Clear descriptions help maintenance
  4. Regular review - Audit permissions quarterly
MistakeImpactSolution
Too many adminsSecurity riskLimit to 2-3 admins
Overly broad rolesExcess accessCreate specific roles
Orphaned rolesMaintenance burdenRegular cleanup
No role descriptionsConfusionDocument purpose
-- roles table
CREATE TABLE roles (
id UUID PRIMARY KEY,
name TEXT NOT NULL UNIQUE,
description TEXT,
is_system BOOLEAN NOT NULL DEFAULT FALSE,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP
);
-- roles_permissions junction
CREATE TABLE roles_permissions (
role_id UUID NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
permission_id UUID NOT NULL REFERENCES permissions(id) ON DELETE CASCADE,
PRIMARY KEY (role_id, permission_id)
);
-- users_roles junction
CREATE TABLE users_roles (
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
role_id UUID NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
granted_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
granted_by UUID REFERENCES users(id),
PRIMARY KEY (user_id, role_id)
);
  1. Verify role exists:

    Terminal window
    curl -s -H "Authorization: Bearer $TOKEN" \
    https://api.mantis.local/api/v1/admin/roles | jq '.data[].name'
  2. Check ID format - Role IDs are UUIDs

System roles are protected:

  • admin, operator, viewer are is_system: true
  • Cannot update name, description, or permissions
  • Cannot delete

Solution: Create a custom role with desired permissions.

  1. Check for multiple role assignments:

    Terminal window
    curl -s -H "Authorization: Bearer $TOKEN" \
    https://api.mantis.local/api/v1/admin/users/$USER_ID/roles
  2. Check token expiration - User may have cached JWT