Cloud Aegis API Reference
Base URL: /api/v1 (all endpoints require JWT authentication unless noted)
List endpoints accept query parameters:
page (default: 1) — 1-indexed page number
per_page (default: 50, max: 200) — items per page
Response envelope:
{
"data": [...],
"page": 1,
"per_page": 50,
"total": 247,
"total_pages": 5
}
All errors return:
{
"code": "FINDING_NOT_FOUND",
"message": "finding not found",
"status": 404
}
Error codes: BAD_REQUEST, FORBIDDEN, NOT_FOUND, {RESOURCE}_NOT_FOUND, CONFLICT, RATE_LIMITED, SERVICE_UNAVAILABLE, INTERNAL_ERROR.
Endpoints
Health (Unauthenticated)
| Method | Path | Description |
|---|
| GET | /health | Full health check (components + status) |
| GET | /healthz | Liveness probe (always 200) |
| GET | /ready | Readiness probe (checks dependencies) |
| GET | /metrics | Prometheus metrics endpoint |
Config (Unauthenticated)
| Method | Path | Description |
|---|
| GET | /api/v1/config | Tenant branding + feature flags |
| GET | /config.json | Alias for config (frontend SPA) |
Providers (Unauthenticated)
| Method | Path | Description |
|---|
| GET | /api/v1/providers | Provider status for all integration subsystems (GRC, identity, FinOps, container, workflow, WAF, secrets) |
Findings
| Method | Path | Roles | Paginated | Description |
|---|
| GET | /api/v1/findings | viewer, operator, admin | Yes | List findings (filters: severity, provider, status) |
| GET | /api/v1/findings/query | viewer, operator, admin | Yes | RQL-based finding query |
| POST | /api/v1/findings/ingest | admin | No | Ingest new finding (dedup cache) |
| GET | /api/v1/findings/{id} | viewer, operator, admin | No | Get finding by ID (scope-enforced) |
| POST | /api/v1/findings/{id}/enrich | operator, admin | No | AI + threat intel enrichment |
| GET | /api/v1/findings/{id}/comments | viewer, requester, operator, admin | No | List finding comments |
| POST | /api/v1/findings/{id}/comments | operator, admin | No | Add comment to finding |
| DELETE | /api/v1/findings/{id}/comments/{commentId} | operator, admin | No | Delete finding comment |
| POST | /api/v1/findings/{id}/remediate | operator, admin | No | Create remediation ticket (integration layer) |
| GET | /api/v1/findings/{id}/ticket | operator, admin | No | Get linked ticket status |
| GET | /api/v1/findings/{id}/ticket/comments | viewer, operator, admin | No | List ticket comments (from integration) |
| POST | /api/v1/findings/{id}/ticket/comments | operator, admin | No | Add comment to linked ticket |
| POST | /api/v1/findings/{id}/ticket/sync | operator, admin | No | Force-refresh ticket status from integration |
| POST | /api/v1/findings/search | operator, admin | Yes | BM25 + semantic hybrid search |
POST /api/v1/findings/search
Full-text and semantic search over findings. Combines Bleve BM25 text search with TF-IDF embeddings via Reciprocal Rank Fusion (RRF).
Request body:
{
"query": "public S3 bucket",
"mode": "hybrid",
"filters": {
"severity": ["CRITICAL", "HIGH"],
"provider": ["aws"],
"status": ["open"]
},
"page": 1,
"per_page": 50
}
| Field | Type | Default | Description |
|---|
query | string | (required) | Search query (max 1000 chars) |
mode | string | hybrid | Search mode: keyword, semantic, or hybrid |
filters.severity | string[] | (none) | Filter by severity (case-insensitive) |
filters.provider | string[] | (none) | Filter by cloud provider (case-insensitive) |
filters.status | string[] | (none) | Filter by finding status (case-insensitive) |
page | int | 1 | Page number (1-indexed) |
per_page | int | 50 | Results per page (max 200) |
Response:
{
"data": [{ "finding": {...}, "score": 0.87 }],
"total": 42,
"page": 1,
"per_page": 50,
"max_score": 0.87,
"took_ms": 12,
"mode": "hybrid"
}
POST /api/v1/findings/ingest
Ingest a new finding. Deduplication is keyed on source + source_finding_id.
Request body:
{
"source": "aws-securityhub",
"source_finding_id": "arn:aws:securityhub:us-east-1:...",
"resource_id": "arn:aws:s3:::my-bucket",
"account_id": "123456789012",
"severity": "CRITICAL",
"finding_type": "Software and Configuration Checks",
"title": "S3 bucket is publicly accessible",
"description": "The S3 bucket allows public read access..."
}
| Field | Type | Required | Description |
|---|
source | string | yes | Originating scanner (e.g., aws-securityhub, azure-defender) |
source_finding_id | string | yes | Scanner-native finding ID for dedup |
resource_id | string | yes | Cloud resource ARN/ID |
account_id | string | yes | Cloud account ID |
severity | string | yes | CRITICAL, HIGH, MEDIUM, LOW, INFO |
finding_type | string | yes | Finding category |
title | string | yes | Short finding title |
description | string | yes | Detailed description |
POST /api/v1/ai/nlq
Parse a natural language query into structured finding filters.
Request body:
{ "query": "show me critical AWS findings from last week" }
POST /api/v1/graph/query
Proxy a Gremlin or Cypher query to PuppyGraph.
Request body:
{ "language": "gremlin", "query": "g.V().hasLabel('finding').count()" }
POST /api/v1/asm/scan
Trigger an external attack surface scan for a domain.
Request body:
{ "domain": "example.com" }
POST /api/v1/webhooks
Register a new webhook endpoint.
Request body:
{
"url": "https://hooks.example.com/aegis",
"secret": "whsec_...",
"events": ["finding.created", "remediation.completed"]
}
| Field | Type | Required | Description |
|---|
url | string | yes | HTTPS endpoint URL |
secret | string | yes | HMAC signing secret |
events | string[] | no | Event filter (empty = all events) |
POST /api/v1/exceptions
Create an exception request.
Request body:
{
"application_id": "app-payments",
"requestor_email": "[email protected]",
"request_type": "waiver",
"policy_violated": "REGION-001",
"resource_requested": "us-west-2 deployment for latency SLA",
"business_case": "Payment processing requires <50ms latency..."
}
| Field | Type | Required | Description |
|---|
application_id | string | yes | Target application ID |
policy_violated | string | yes | Policy code being excepted |
requestor_email | string | no | Requestor email (validated) |
request_type | string | no | waiver, extension, exemption |
resource_requested | string | no | What is being requested |
business_case | string | no | Business justification |
Compliance
| Method | Path | Roles | Paginated | Description |
|---|
| GET | /api/v1/compliance/frameworks | viewer, operator, admin | Yes | List compliance frameworks |
| GET | /api/v1/compliance/posture | viewer, operator, admin | No | Aggregated compliance posture |
| GET | /api/v1/compliance/controls/{fw} | viewer, operator, admin | No | Controls for a framework |
Agents
| Method | Path | Roles | Paginated | Description |
|---|
| GET | /api/v1/agents | viewer, operator, admin | Yes | List security agents |
| GET | /api/v1/agents/{id} | viewer, operator, admin | No | Get agent by ID |
| GET | /api/v1/agents/{id}/traces | viewer, operator, admin | No | List agent execution traces |
| Method | Path | Roles | Paginated | Description |
|---|
| GET | /api/v1/remediations | viewer, operator, admin | Yes | List remediations (filters: status, tier) |
| GET | /api/v1/remediations/{id} | viewer, operator, admin | No | Get remediation by ID |
| POST | /api/v1/remediations/{id}/execute | operator, admin | No | Execute remediation |
| PATCH | /api/v1/remediations/{id} | operator, admin | No | Update remediation status |
GRC / Exceptions
| Method | Path | Roles | Paginated | Description |
|---|
| GET | /api/v1/exceptions/pending | operator, admin | No | List pending exception approvals |
| GET | /api/v1/exceptions/expiring | operator, admin | No | List expiring exceptions |
| GET | /api/v1/exceptions/mine | requester, operator, admin | No | List user's own exceptions |
| GET | /api/v1/exceptions/{id} | operator, admin | No | Get exception by ID |
| POST | /api/v1/exceptions | admin | No | Create new exception request |
| POST | /api/v1/exceptions/{id}/approve | admin | No | Submit approval decision |
| POST | /api/v1/exceptions/{id}/withdraw | requester, operator, admin | No | Withdraw exception |
| GET | /api/v1/applications/{appId}/exceptions | operator, admin | No | List exceptions by app (ownership-scoped) |
| POST | /api/v1/validate/exception | operator, admin | No | Validate exception against policy |
Policies
| Method | Path | Roles | Paginated | Description |
|---|
| GET | /api/v1/policies | viewer, operator, admin | Yes | List policies (filters: status, category) |
| GET | /api/v1/policies/{id} | viewer, operator, admin | No | Get policy by ID |
Attack Paths
| Method | Path | Roles | Paginated | Description |
|---|
| GET | /api/v1/attack-paths | viewer, operator, admin | Yes (20/page, max 100) | List computed attack paths |
| GET | /api/v1/attack-paths/stats | viewer, operator, admin | No | Attack path statistics |
| GET | /api/v1/attack-paths/{id} | viewer, operator, admin | No | Get attack path by ID |
| GET | /api/v1/attack-paths/{id}/analysis | viewer, operator, admin | No | AI analysis of attack path |
Costs (FinOps)
| Method | Path | Roles | Paginated | Description |
|---|
| GET | /api/v1/costs/summary | viewer, operator, admin | No | Computed cost summary (all providers) |
Identity & Zero Trust
| Method | Path | Roles | Paginated | Description |
|---|
| GET | /api/v1/identity/users | viewer, operator, admin | No | List identity users (Okta/Entra ID) |
| GET | /api/v1/identity/users/{id}/risk | viewer, operator, admin | No | Get user risk score |
| GET | /api/v1/users | admin | Yes | List platform users |
Audit
| Method | Path | Roles | Paginated | Description |
|---|
| GET | /api/v1/audit-log | admin | Yes | Audit log (filters: result, actor) |
| Method | Path | Roles | Paginated | Description |
|---|
| POST | /api/v1/ai/nlq | operator, admin | No | Natural language query |
| GET | /api/v1/ai/usage | admin | No | AI usage/budget status |
Container Security
| Method | Path | Roles | Paginated | Description |
|---|
| GET | /api/v1/containers | viewer, operator, admin | No | List container workloads |
| GET | /api/v1/containers/{id} | viewer, operator, admin | No | Get container details |
| GET | /api/v1/container/scan | operator, admin | No | Scan container image |
| GET | /api/v1/container/admission | operator, admin | No | Admission policy check |
Secrets Management
| Method | Path | Roles | Paginated | Description |
|---|
| GET | /api/v1/secrets | viewer, operator, admin | No | List secrets (scope-guarded) |
| POST | /api/v1/secrets/scan | operator, admin | No | Scan content for secrets |
| POST | /api/v1/secrets/upload | operator, admin | No | Upload suspected secret (TLS-only, ephemeral) |
| GET | /api/v1/secrets/{path} | viewer, operator, admin | No | Get secret by path (scope-guarded) |
| POST | /api/v1/secrets/org-scan | admin | No | Org-wide secrets scan |
WAF
| Method | Path | Roles | Paginated | Description |
|---|
| GET | /api/v1/waf/templates | viewer, operator, admin | No | List WAF rule templates |
| GET | /api/v1/waf/compliance/{templateId} | viewer, operator, admin | No | Validate WAF compliance |
Webhooks
| Method | Path | Roles | Paginated | Description |
|---|
| POST | /api/v1/webhooks | operator, admin | No | Register webhook |
| GET | /api/v1/webhooks | operator, admin | No | List webhooks |
| DELETE | /api/v1/webhooks/{id} | operator, admin | No | Delete webhook |
| GET | /api/v1/webhooks/{id}/deliveries | operator, admin | No | List webhook deliveries |
Workflows
| Method | Path | Roles | Paginated | Description |
|---|
| GET | /api/v1/workflows | operator, admin | No | List workflows |
| GET | /api/v1/workflows/{id} | operator, admin | No | Get workflow by ID |
| POST | /api/v1/workflows/{id}/approve | operator, admin | No | Approve workflow |
Deploy Preview
| Method | Path | Roles | Paginated | Description |
|---|
| POST | /api/v1/deploy/preview | operator, admin | No | Start deploy preview |
| POST | /api/v1/deploy/preview/{id}/abort | operator, admin | No | Abort deploy preview |
Data Classification (DSPM)
| Method | Path | Roles | Paginated | Description |
|---|
| GET | /api/v1/data-classification/assets | viewer, operator, admin | No | List data assets with sensitivity |
ASM (Attack Surface Management)
| Method | Path | Roles | Paginated | Description |
|---|
| POST | /api/v1/asm/scan | operator, admin | No | Trigger ASM scan |
| GET | /api/v1/asm/assets | operator, admin | No | List discovered assets |
Catalog
| Method | Path | Roles | Paginated | Description |
|---|
| GET | /api/v1/catalog/modules | viewer, operator, admin | Yes | List Terraform modules (filters: provider, category, search) |
Graph Query
| Method | Path | Roles | Paginated | Description |
|---|
| POST | /api/v1/graph/query | operator, admin | No | PuppyGraph Gremlin query proxy |
Terminal (Operator+)
| Method | Path | Roles | Description |
|---|
| POST | /api/v1/terminal/ticket | operator, admin | Issue short-lived nonce for WebSocket auth (SA-002) |
| GET | /api/v1/terminal/ws | operator, admin | WebSocket upgrade for interactive terminal (auth via ?ticket= nonce or legacy ?token= JWT) |
The ticket endpoint returns {"ticket": "<uuid>"} valid for 60 seconds, one-time use. The WebSocket handler validates and consumes the ticket on upgrade. Legacy ?token= JWT-in-URL is retained for backward compatibility but deprecated (leaks to logs/referrer headers).
Integration Webhooks (Unauthenticated, HMAC-verified)
| Method | Path | Description |
|---|
| POST | /api/v1/webhooks/asana | Asana webhook receiver |
RBAC Roles
| Role | Rank | Description |
|---|
viewer | 0 | Read-only access to findings, compliance, agents |
requester | 1 | Viewer + exception request/withdraw |
operator | 2 | Requester + write operations (remediate, enrich, scan) |
admin | 3 | Full access (audit log, user management, approvals) |
All endpoints require at minimum viewer role. The Require() middleware enforces minimum role rank — e.g., Require(RoleOperator, RoleAdmin) allows operator and admin but denies viewer and requester.
Note: DELETE /findings/{id}/comments/{commentId} has an additional in-handler admin-only check beyond the RBAC middleware — non-admin callers receive 403 even though the middleware passes them.
RBAC Authorization Matrix (from integration tests)
| Endpoint | Unauthenticated | Requester | Operator | Admin |
|---|
| GET /api/v1/findings | 401 | 403 | 200 | 200 |
| GET /api/v1/exceptions/mine | 401 | 200 | 200 | 200 |
| GET /api/v1/exceptions/{id} | 401 | 403 | 200 | 200 |
| POST /api/v1/exceptions | 401 | 403 | 200 | 201 |
| GET /api/v1/agents | 401 | 403 | 200 | 200 |
| GET /api/v1/audit-log | 401 | 403 | 200 | 200 |
| GET /api/v1/users | 401 | 403 | 200 | 200 |
| GET /api/v1/identity/users | 401 | 403 | 200 | 200 |
| GET /api/v1/workflows | 401 | 403 | 200 | 200 |
| GET /api/v1/secrets | 401 | 403 | 200 | 200 |
| POST /api/v1/secrets/org-scan | 401 | 403 | 403 | 200 |
| POST /api/v1/terminal/ticket | 401 | 403 | 200 | 200 |
| GET /api/v1/terminal/ws | 401 | 403 | 200 | 200 |
| DELETE /findings/{id}/comments/{cid} | 401 | 403 | 403 | 204 |