16 KiB
Aegis API Documentation
This document provides an overview of the Aegis REST API. For interactive documentation with request/response examples, visit:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
Base URL
All API endpoints are prefixed with /api/v1.
Authentication
The API uses JWT (JSON Web Token) for authentication. Include the token in the Authorization header:
Authorization: Bearer <your-token>
Obtaining a Token
curl -X POST http://localhost:8000/api/v1/auth/login \
-d "username=admin&password=admin123"
Response:
{
"access_token": "eyJ...",
"token_type": "bearer"
}
Endpoints
Authentication
POST /auth/login
Authenticate and receive a JWT token.
Request (form data):
username: stringpassword: string
Response (200):
{
"access_token": "string",
"token_type": "bearer"
}
GET /auth/me
Get current authenticated user.
Headers: Authorization: Bearer <token>
Response (200):
{
"id": "uuid",
"username": "string",
"email": "string|null",
"role": "string",
"is_active": true
}
Techniques
GET /techniques
List all techniques with optional filters.
Query Parameters:
tactic(optional): Filter by tactic namestatus(optional): Filter by status (not_evaluated,in_progress,validated,partial,not_covered)review_required(optional): Filter by review flag (true/false)
Response (200):
[
{
"id": "uuid",
"mitre_id": "T1059",
"name": "Command and Scripting Interpreter",
"tactic": "execution",
"status_global": "validated"
}
]
GET /techniques/{mitre_id}
Get a single technique with associated tests.
Response (200):
{
"id": "uuid",
"mitre_id": "T1059",
"name": "Command and Scripting Interpreter",
"description": "...",
"tactic": "execution",
"platforms": ["windows", "linux"],
"status_global": "validated",
"review_required": false,
"tests": [...]
}
POST /techniques
Create a new technique. Admin only.
Request:
{
"mitre_id": "T1059",
"name": "Command and Scripting Interpreter",
"description": "...",
"tactic": "execution",
"platforms": ["windows", "linux"]
}
PATCH /techniques/{mitre_id}
Update a technique. Admin only.
Request:
{
"name": "Updated Name",
"status_global": "validated"
}
PATCH /techniques/{mitre_id}/review
Mark a technique as reviewed. Leads/Admin only.
Tests
POST /tests
Create a new test. Red Tech/Admin only.
Request:
{
"technique_id": "uuid",
"name": "My Test",
"description": "Test description",
"platform": "windows",
"procedure_text": "Step by step...",
"tool_used": "Atomic Red Team"
}
GET /tests/{id}
Get a test with associated evidences.
PATCH /tests/{id}
Update a test. Creator/Admin only. Only allowed when state is draft or rejected.
POST /tests/{id}/validate
Validate a test. Leads/Admin only.
Request:
{
"result": "detected",
"comments": "Optional comment"
}
Valid results: detected, not_detected, partially_detected
POST /tests/{id}/reject
Reject a test. Leads/Admin only.
Evidence
POST /tests/{test_id}/evidence
Upload an evidence file.
Request: multipart/form-data with file field.
Response (201):
{
"id": "uuid",
"test_id": "uuid",
"file_name": "screenshot.png",
"sha256_hash": "abc123...",
"uploaded_at": "2024-01-01T00:00:00Z",
"download_url": "https://..."
}
GET /evidence/{id}
Get evidence metadata with presigned download URL.
Metrics
GET /metrics/summary
Get global coverage summary.
Response (200):
{
"total_techniques": 200,
"validated": 50,
"partial": 20,
"not_covered": 30,
"in_progress": 10,
"not_evaluated": 90,
"coverage_percentage": 35.0
}
GET /metrics/by-tactic
Get coverage breakdown by tactic.
Response (200):
[
{
"tactic": "execution",
"total": 15,
"validated": 5,
"partial": 2,
"not_covered": 3,
"not_evaluated": 5,
"in_progress": 0
}
]
Users (Admin Only)
GET /users
List all users.
POST /users
Create a new user.
Request:
{
"username": "newuser",
"email": "user@example.com",
"password": "securepassword",
"role": "red_tech"
}
Valid roles: admin, red_tech, blue_tech, red_lead, blue_lead, viewer
PATCH /users/{id}
Update a user.
Request:
{
"email": "new@email.com",
"role": "blue_tech",
"is_active": false,
"password": "newpassword"
}
Audit Logs (Admin Only)
GET /audit-logs
List audit logs with pagination and filters.
Query Parameters:
user_id(optional): Filter by user UUIDaction(optional): Filter by action typeentity_type(optional): Filter by entity typestart_date(optional): Filter from date (ISO format)end_date(optional): Filter to date (ISO format)offset(optional): Pagination offset (default: 0)limit(optional): Page size (default: 50, max: 100)
Response (200):
{
"items": [
{
"id": "uuid",
"user_id": "uuid",
"username": "admin",
"action": "create_technique",
"entity_type": "technique",
"entity_id": "uuid",
"timestamp": "2024-01-01T00:00:00Z",
"details": {"mitre_id": "T1059"}
}
],
"total": 100,
"offset": 0,
"limit": 50
}
GET /audit-logs/actions
List distinct action types.
GET /audit-logs/entity-types
List distinct entity types.
System (Admin Only)
POST /system/sync-mitre
Trigger MITRE ATT&CK synchronization.
Response (200):
{
"message": "MITRE sync completed",
"new": 5,
"updated": 10
}
POST /system/run-intel-scan
Trigger threat intelligence scan.
Response (200):
{
"message": "Intel scan completed",
"new_items": 3
}
GET /system/scheduler-status
Get background scheduler status.
Response (200):
{
"running": true,
"jobs": [
{
"id": "mitre_sync",
"name": "MITRE ATT&CK Sync",
"next_run_time": "2024-01-02T00:00:00Z"
}
]
}
V2 Endpoints — Red/Blue Workflow
Tests — Red/Blue Workflow
GET /api/v1/tests
List tests with advanced filters.
Query Parameters:
state(string) — Filter by test statetechnique_id(UUID) — Filter by techniqueplatform(string) — Filter by platformcreated_by(UUID) — Filter by creatorpending_validation_side(string:red/blue) — Filter tests in_review pending validationoffset(int, default 0) — Pagination offsetlimit(int, default 50, max 200) — Page size
POST /api/v1/tests/from-template
Create a test from a template. Pre-populates name, description, platform, procedure, tool, and remediation steps.
Body:
{
"template_id": "uuid",
"technique_id": "uuid"
}
PATCH /api/v1/tests/{id}/red
Red Team updates their fields. Allowed in draft and red_executing states.
Body:
{
"procedure_text": "...",
"tool_used": "...",
"attack_success": true,
"red_summary": "..."
}
PATCH /api/v1/tests/{id}/blue
Blue Team updates their fields. Allowed only in blue_evaluating state.
Body:
{
"detection_result": "detected | not_detected | partially_detected",
"blue_summary": "..."
}
PATCH /api/v1/tests/{id}/remediation
Update remediation fields on a test.
Body:
{
"remediation_steps": "Step 1: ...\nStep 2: ...",
"remediation_status": "pending | in_progress | completed | not_applicable",
"remediation_assignee": "user-uuid"
}
POST /api/v1/tests/{id}/start-execution
Transition: draft → red_executing. Sets execution_date.
POST /api/v1/tests/{id}/submit-red
Transition: red_executing → blue_evaluating. Notifies all blue_tech users.
POST /api/v1/tests/{id}/submit-blue
Transition: blue_evaluating → in_review. Notifies red_lead and blue_lead.
POST /api/v1/tests/{id}/validate-red
Red Lead approves or rejects. Triggers dual validation check.
Body:
{
"red_validation_status": "approved | rejected",
"red_validation_notes": "optional notes"
}
POST /api/v1/tests/{id}/validate-blue
Blue Lead approves or rejects. Triggers dual validation check.
Body:
{
"blue_validation_status": "approved | rejected",
"blue_validation_notes": "optional notes"
}
POST /api/v1/tests/{id}/reopen
Move a rejected test back to draft. Clears all validation fields.
Test Templates
GET /api/v1/test-templates
List templates with filters: source, platform, severity, search, mitre_technique_id, is_active.
POST /api/v1/test-templates (Admin)
Create a custom template with suggested_remediation.
GET /api/v1/test-templates/stats (Admin)
Returns catalog statistics: total, active, inactive, by source, by platform.
POST /api/v1/test-templates/{id}/toggle-active (Admin)
Toggle a template's active/inactive status.
Notifications
GET /api/v1/notifications
List notifications for the current user (paginated, newest first).
Query Parameters: offset (default 0), limit (default 20, max 100)
GET /api/v1/notifications/unread-count
Returns { "unread_count": N }.
PATCH /api/v1/notifications/{id}/read
Mark a single notification as read.
POST /api/v1/notifications/read-all
Mark all notifications for the current user as read.
Automatic Notifications:
red_executing→ notifies creatorblue_evaluating→ notifies all blue_tech usersin_review→ notifies red_lead and blue_leadrejected→ notifies creatorvalidated→ notifies creator
Reports
GET /api/v1/reports/coverage-summary
Full technique coverage report as JSON. Includes summary and technique-by-technique breakdown.
Filters: tactic, platform
GET /api/v1/reports/coverage-csv
Downloadable CSV of coverage data.
Filters: tactic, platform
GET /api/v1/reports/test-results
Test results report with state and detection breakdowns.
Filters: state, date_from (ISO), date_to (ISO)
GET /api/v1/reports/remediation-status
Remediation status report across all tests with assigned steps.
Filter: status (pending, in_progress, completed, not_applicable)
V2 Metrics
GET /api/v1/metrics/test-pipeline
Test counts by state across the pipeline.
GET /api/v1/metrics/team-activity
Red/Blue team activity: tests completed, pending.
GET /api/v1/metrics/validation-rate
Approval/rejection rates for Red Lead and Blue Lead.
GET /api/v1/metrics/recent-tests
Last 10 most recently updated tests.
Error Responses
All errors follow a consistent format:
{
"detail": "Error message",
"code": "ERROR_CODE"
}
State transition errors include additional context:
{
"detail": {
"message": "Cannot transition from 'draft' to 'validated'. Valid transitions: ['red_executing']",
"code": "INVALID_TRANSITION",
"current_state": "draft",
"target_state": "validated",
"valid_transitions": ["red_executing"]
}
}
Common HTTP status codes:
400- Bad Request (validation error, invalid transition, invalid input)401- Unauthorized (missing or invalid token)403- Forbidden (insufficient permissions)404- Not Found (resource doesn't exist)409- Conflict (duplicate resource)500- Internal Server Error
V3 Endpoints
Campaigns
| Method | Route | Auth | Description |
|---|---|---|---|
| GET | /api/v1/campaigns |
Authenticated | List campaigns (filters: status, type, search; pagination: offset, limit) |
| POST | /api/v1/campaigns |
Authenticated | Create campaign |
| GET | /api/v1/campaigns/{id} |
Authenticated | Campaign detail with tests |
| PATCH | /api/v1/campaigns/{id} |
Creator, Admin | Update campaign |
| DELETE | /api/v1/campaigns/{id} |
Creator, Admin | Delete campaign |
| POST | /api/v1/campaigns/{id}/tests |
Authenticated | Add test to campaign |
| DELETE | /api/v1/campaigns/{id}/tests/{test_id} |
Authenticated | Remove test from campaign |
| PATCH | /api/v1/campaigns/{id}/schedule |
Authenticated | Set recurring schedule |
| GET | /api/v1/campaigns/{id}/history |
Authenticated | Execution history for recurring campaigns |
Threat Actors
| Method | Route | Auth | Description |
|---|---|---|---|
| GET | /api/v1/threat-actors |
Authenticated | List threat actors (filters: country, motivation, search) |
| GET | /api/v1/threat-actors/{id} |
Authenticated | Detail with technique mappings |
Detection Rules
| Method | Route | Auth | Description |
|---|---|---|---|
| GET | /api/v1/detection-rules |
Authenticated | List rules (filters: source, mitre_technique_id, severity, search) |
| GET | /api/v1/detection-rules/{id} |
Authenticated | Rule detail |
D3FEND (Defensive Techniques)
| Method | Route | Auth | Description |
|---|---|---|---|
| GET | /api/v1/d3fend |
Authenticated | List defensive techniques |
| GET | /api/v1/d3fend/{id} |
Authenticated | Detail with ATT&CK mappings |
Compliance
| Method | Route | Auth | Description |
|---|---|---|---|
| GET | /api/v1/compliance/frameworks |
Authenticated | List compliance frameworks |
| GET | /api/v1/compliance/{framework_id}/controls |
Authenticated | List controls with coverage status |
| GET | /api/v1/compliance/{framework_id}/summary |
Authenticated | Coverage summary (total, covered, gaps) |
| GET | /api/v1/compliance/{framework_id}/gaps |
Authenticated | Gap analysis — uncovered controls |
Scores
| Method | Route | Auth | Description |
|---|---|---|---|
| GET | /api/v1/scores/technique/{mitre_id} |
Authenticated | Technique score with detailed breakdown |
| GET | /api/v1/scores/tactic/{tactic} |
Authenticated | Average tactic score |
| GET | /api/v1/scores/threat-actor/{id} |
Authenticated | Coverage score against threat actor |
| GET | /api/v1/scores/organization |
Authenticated | Overall organization score (cached 5 min) |
| GET | /api/v1/scores/history |
Authenticated | Weekly score history (period: 30d, 90d, 1y) |
| GET | /api/v1/scores/config |
Admin | Current scoring weights |
| PATCH | /api/v1/scores/config |
Admin | Update scoring weights |
Operational Metrics
| Method | Route | Auth | Description |
|---|---|---|---|
| GET | /api/v1/metrics/operational |
Authenticated | All KPIs (MTTD, MTTR, efficacy, etc.) — cached 5 min |
| GET | /api/v1/metrics/operational/trend |
Authenticated | Weekly trend (period: 30d, 90d, 1y) |
| GET | /api/v1/metrics/operational/by-team |
Authenticated | Red vs Blue team breakdown |
Heatmap
| Method | Route | Auth | Description |
|---|---|---|---|
| GET | /api/v1/heatmap |
Authenticated | Full ATT&CK Navigator-style heatmap data |
Coverage Snapshots
| Method | Route | Auth | Description |
|---|---|---|---|
| GET | /api/v1/snapshots |
Authenticated | List snapshots (pagination: offset, limit) |
| POST | /api/v1/snapshots |
Authenticated | Create new snapshot |
| GET | /api/v1/snapshots/{id} |
Authenticated | Snapshot detail with technique states |
| DELETE | /api/v1/snapshots/{id} |
Admin | Delete snapshot |
| GET | /api/v1/snapshots/compare |
Authenticated | Compare two snapshots (query: a, b) |
Re-testing
| Method | Route | Auth | Description |
|---|---|---|---|
| GET | /api/v1/tests/{id}/retest-chain |
Authenticated | Full retest chain for a test |
Data Sources
| Method | Route | Auth | Description |
|---|---|---|---|
| GET | /api/v1/data-sources |
Admin | List all data sources |
| PATCH | /api/v1/data-sources/{id} |
Admin | Update source config |
| POST | /api/v1/data-sources/{id}/sync |
Admin | Trigger manual sync |