# 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

```bash
curl -X POST http://localhost:8000/api/v1/auth/login \
  -d "username=admin&password=admin123"
```

Response:
```json
{
  "access_token": "eyJ...",
  "token_type": "bearer"
}
```

## Endpoints

### Authentication

#### POST /auth/login
Authenticate and receive a JWT token.

**Request** (form data):
- `username`: string
- `password`: string

**Response** (200):
```json
{
  "access_token": "string",
  "token_type": "bearer"
}
```

#### GET /auth/me
Get current authenticated user.

**Headers**: `Authorization: Bearer <token>`

**Response** (200):
```json
{
  "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 name
- `status` (optional): Filter by status (`not_evaluated`, `in_progress`, `validated`, `partial`, `not_covered`)
- `review_required` (optional): Filter by review flag (`true`/`false`)

**Response** (200):
```json
[
  {
    "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):
```json
{
  "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**:
```json
{
  "mitre_id": "T1059",
  "name": "Command and Scripting Interpreter",
  "description": "...",
  "tactic": "execution",
  "platforms": ["windows", "linux"]
}
```

#### PATCH /techniques/{mitre_id}
Update a technique. **Admin only.**

**Request**:
```json
{
  "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**:
```json
{
  "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**:
```json
{
  "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):
```json
{
  "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):
```json
{
  "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):
```json
[
  {
    "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**:
```json
{
  "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**:
```json
{
  "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 UUID
- `action` (optional): Filter by action type
- `entity_type` (optional): Filter by entity type
- `start_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):
```json
{
  "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):
```json
{
  "message": "MITRE sync completed",
  "new": 5,
  "updated": 10
}
```

#### POST /system/run-intel-scan
Trigger threat intelligence scan.

**Response** (200):
```json
{
  "message": "Intel scan completed",
  "new_items": 3
}
```

#### GET /system/scheduler-status
Get background scheduler status.

**Response** (200):
```json
{
  "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 state
- `technique_id` (UUID) — Filter by technique
- `platform` (string) — Filter by platform
- `created_by` (UUID) — Filter by creator
- `pending_validation_side` (string: `red` / `blue`) — Filter tests in_review pending validation
- `offset` (int, default 0) — Pagination offset
- `limit` (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:**
```json
{
  "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:**
```json
{
  "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:**
```json
{
  "detection_result": "detected | not_detected | partially_detected",
  "blue_summary": "..."
}
```

#### `PATCH /api/v1/tests/{id}/remediation`

Update remediation fields on a test.

**Body:**
```json
{
  "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:**
```json
{
  "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:**
```json
{
  "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 creator
- `blue_evaluating` → notifies all blue_tech users
- `in_review` → notifies red_lead and blue_lead
- `rejected` → notifies creator
- `validated` → 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:

```json
{
  "detail": "Error message",
  "code": "ERROR_CODE"
}
```

State transition errors include additional context:

```json
{
  "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 |
