Roles and Permissions
Aegis uses Role-Based Access Control (RBAC) with six roles organized in a hierarchy. Every authenticated request carries the user's role, which is checked against the required role for each endpoint.
Role Hierarchy
admin
└─ red_lead / blue_lead
└─ red_tech / blue_tech
└─ viewer
Higher roles generally include the capabilities of lower roles, with some
team-specific restrictions (e.g. a red_lead cannot perform blue_lead actions).
Admin bypass:
adminALWAYS passes any role check, regardless of which role is required. There is no endpoint an admin cannot call.
Role Descriptions
admin
Primary use case: Platform administrator. Full system access.
Can do:
- Everything any other role can do
- Create, update, deactivate, and delete users
- View audit logs (
GET /api/v1/audit-logs) - Delete snapshots (
DELETE /api/v1/snapshots/{id}) - Delete alert rules
- Trigger MITRE ATT&CK sync (
POST /api/v1/system/sync-mitre) - Manage webhooks (
GET/POST/PATCH/DELETE /api/v1/webhooks) — admin only - Set data classification on tests (
PATCH /api/v1/tests/{id}/classification) - View scheduler status (
GET /api/v1/system/scheduler-status) - Configure SSO (
PUT /api/v1/sso/config) - Manage data sources (
POST/PATCH/DELETE /api/v1/data-sources) - Complete campaigns (along with red_lead)
Cannot do:
- Be locked out — bypasses all role checks by design
red_lead
Primary use case: Red Team Lead. Manages the offensive side of operations.
Can do:
- Create, update, and delete tests (in
draftorrejectedstate) - Create campaigns and complete them (
POST /campaigns/{id}/complete) - Create test templates
- Create and manage playbooks and lessons
- Validate the red side of a test (
POST /tests/{id}/validate-red) - Manage attack paths (including delete)
- Create alert rules
- Generate professional reports (PDF, DOCX, HTML)
- Start test execution
- Upload red evidence
- Submit red assessment
- All viewer capabilities
Cannot do:
- Access audit logs
- Perform blue-side actions (validate-blue, submit-blue, update blue fields)
- Delete snapshots
- Sync MITRE data
- Access or manage webhooks
- Set data classification
blue_lead
Primary use case: Blue Team Lead. Manages the defensive side of operations.
Can do:
- Evaluate and validate the blue side of a test (
POST /tests/{id}/validate-blue) - Validate blue side (
POST /tests/{id}/validate-blue) - Manage detection assets and detection rules
- Create playbooks and lessons
- Generate a revalidation queue
- Manage ownership of assets
- Create alert rules
- Generate professional reports (PDF, DOCX, HTML)
- Upload blue evidence (in
blue_evaluatingstate) - Submit blue assessment
- All viewer capabilities
Cannot do:
- Complete campaigns (red_lead + admin only)
- Start test execution (
POST /tests/{id}/start-execution) - Validate the red side
- Access audit logs
- Delete snapshots
- Sync MITRE data
- Access or manage webhooks
red_tech
Primary use case: Red Team Technician. Executes attacks.
Can do:
- Start test execution (
POST /tests/{id}/start-execution) — movesdraft→red_executing - Update red-side fields (
PATCH /tests/{id}/red):tool_used,command_executed,output_observed,red_notes, etc. - Upload red evidence files
- Submit red assessment (
POST /tests/{id}/submit-red) — movesred_executing→blue_evaluating - Pause and resume test timers
- Create worklogs for tests
- View all read-only data (same as viewer)
Cannot do:
- Create new tests
- Create campaigns
- Manage playbooks or lessons
- Access webhooks, audit logs, or admin endpoints
- Perform blue-side actions
- Validate either side
- Generate professional reports
blue_tech
Primary use case: Blue Team Technician. Evaluates detection.
Can do:
- Update blue-side fields (
PATCH /tests/{id}/blue):detection_result(detected/not_detected/partial),detection_notes,alert_fired,response_action, etc. - Upload blue evidence files (only while test is in
blue_evaluatingstate) - Submit blue assessment (
POST /tests/{id}/submit-blue) — movesblue_evaluating→in_review - Evaluate detection rules (
POST /api/v1/detection-rules/evaluate) - Create detection validations
- Pause and resume test timers
- Create worklogs for tests
- View all read-only data (same as viewer)
Cannot do:
- Start test execution
- Submit red assessment
- Validate either side
- Create tests, campaigns, playbooks, or lessons
- Access webhooks, audit logs, or admin endpoints
- Generate professional reports
viewer
Primary use case: Stakeholder, auditor, or report consumer. Read-only access plus report generation.
Can do:
- Read all entities: tests, techniques, campaigns, playbooks, lessons, coverage, snapshots, alerts, dashboards, detection lifecycle, scores, heatmap, threat actors, compliance, analytics
- Generate professional reports: PDF, DOCX, HTML (all report types)
- Mark own notifications as read
Cannot do:
- Create or modify any entity (no POST/PATCH/DELETE on data entities)
- Upload evidence
- Change test state
- Manage users, webhooks, alert rules, playbooks, campaigns, or any configuration
Access Matrix
The table below shows key endpoints and which roles can call them. ✅ = allowed, ❌ = forbidden, * = with restrictions (see notes)
| Endpoint | admin | red_lead | blue_lead | red_tech | blue_tech | viewer |
|---|---|---|---|---|---|---|
| POST /tests | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
| PATCH /tests/{id} (general) | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
| POST /tests/{id}/start-execution | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ |
| PATCH /tests/{id}/red | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ |
| POST /tests/{id}/submit-red | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ |
| PATCH /tests/{id}/blue | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ |
| POST /tests/{id}/submit-blue | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ |
| POST /tests/{id}/validate-red | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
| POST /tests/{id}/validate-blue | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |
| POST /tests/{id}/reopen | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
| POST /tests/{id}/pause-timer | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| PATCH /tests/{id}/classification | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| POST /campaigns | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
| POST /campaigns/{id}/complete | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
| POST /campaigns/from-threat-actor/{id} | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
| POST /knowledge/playbooks | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
| GET /reports/generate/* | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ |
| GET /audit-logs | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| ALL /webhooks | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| DELETE /snapshots/{id} | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| POST /system/sync-mitre | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| PUT /sso/config | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| PATCH /data-sources | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| GET /users (list) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| POST /users | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| PATCH /alerts/rules | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
| POST /alerts/evaluate | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
| GET /scores/organization | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| PATCH /scores/config | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
Notes on Role Enforcement
- JWT carries the role: The user's role is embedded in the JWT payload and re-verified against the database on every request.
- Admin bypass is unconditional: The
require_role()dependency immediately returns ifcurrent_user.role == "admin". - Resource ownership: Some endpoints additionally check that the requesting user owns the resource (e.g. API keys, worklogs, notifications). Admins bypass ownership checks too.
- must_change_password: If this flag is set on the user record, all endpoints
return
403 PASSWORD_CHANGE_REQUIREDuntil the password is changed viaPOST /api/v1/auth/change-password.