Files
git.stella-ops.org/docs/api/policy.md
root 68da90a11a
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Restructure solution layout by module
2025-10-28 15:10:40 +02:00

10 KiB
Raw Blame History

Policy Engine REST API

Audience: Backend integrators, platform operators, and CI engineers invoking Policy Engine services programmatically.
Base URL: /api/policy/* (internal gateway route) requires OAuth 2.0 bearer token issued by Authority with scopes listed below.

This document is the canonical reference for the Policy Engine REST surface described in Epic2 (Policy Engine v2). Use it alongside the DSL, Lifecycle, and Runs guides for end-to-end implementations.


1·Authentication & Headers

  • Auth: Bearer tokens (Authorization: Bearer <token>) with the following scopes as applicable:
  • policy:read, policy:author, policy:review, policy:approve, policy:operate, policy:run, policy:activate, policy:archive, policy:simulate, policy:runs
    • findings:read (for effective findings APIs)
    • effective:write (service identity only; not exposed to clients)
  • Service identity: Authority marks the Policy Engine client with properties.serviceIdentity: policy-engine. Tokens missing this marker cannot obtain effective:write.
  • Tenant: Supply tenant context via X-Stella-Tenant. Tokens without multi-tenant claims default to default.
  • Idempotency: For mutating endpoints, include Idempotency-Key (UUID). Retries with same key return original result.
  • Content type: All request/response bodies are application/json; charset=utf-8 unless otherwise noted.

2·Error Model

All errors use HTTP semantics plus a structured payload:

{
  "code": "ERR_POL_001",
  "message": "Policy syntax error",
  "details": [
    {"path": "rules[0].when", "error": "Unknown function foo()"}
  ],
  "traceId": "01HDV1C4E9Z4T5G6H7J8",
  "timestamp": "2025-10-26T14:07:03Z"
}
Code Meaning Notes
ERR_POL_001 Policy syntax/compile error Returned by compile, submit, simulate, run when DSL invalid.
ERR_POL_002 Policy not approved Attempted to run or activate unapproved version.
ERR_POL_003 Missing inputs Downstream service unavailable (Concelier/Excititor/SBOM).
ERR_POL_004 Determinism violation Illegal API usage (wall-clock, RNG). Triggers incident mode.
ERR_POL_005 Unauthorized materialisation Identity lacks effective:write.
ERR_POL_006 Run canceled or timed out Includes cancellation metadata.

3·Policy Management

3.1 Create Draft

POST /api/policy/policies
Scopes: policy:author

Request

{
  "policyId": "P-7",
  "name": "Default Org Policy",
  "description": "Baseline severity + VEX precedence",
  "dsl": {
    "syntax": "stella-dsl@1",
    "source": "policy \"Default Org Policy\" syntax \"stella-dsl@1\" { ... }"
  },
  "tags": ["baseline","vex"]
}

Response 201

{
  "policyId": "P-7",
  "version": 1,
  "status": "draft",
  "digest": "sha256:7e1d…",
  "createdBy": "user:ali",
  "createdAt": "2025-10-26T13:40:00Z"
}

3.2 List Policies

GET /api/policy/policies?status=approved&tenant=default&page=1&pageSize=25
Scopes: policy:read

Returns paginated list with X-Total-Count header.

3.3 Fetch Version

GET /api/policy/policies/{policyId}/versions/{version}
Scopes: policy:read

Returns full DSL, metadata, provenance, simulation artefact references.

3.4 Update Draft Version

PUT /api/policy/policies/{policyId}/versions/{version}
Scopes: policy:author

Body identical to create. Only permitted while status=draft.


4·Lifecycle Transitions

4.1 Submit for Review

POST /api/policy/policies/{policyId}/versions/{version}:submit
Scopes: policy:author

Request

{
  "reviewers": ["user:kay","group:sec-reviewers"],
  "notes": "Simulated on golden SBOM set (diff attached)",
  "simulationArtifacts": [
    "blob://policy/P-7/v3/simulations/2025-10-26.json"
  ]
}

Response 202 submission recorded. Location header points to review resource.

4.2 Review Feedback

POST /api/policy/policies/{policyId}/versions/{version}/reviews
Scopes: policy:review

Request

{
  "decision": "approve",     // approve | request_changes | comment
  "note": "Looks good, ensure incident playbook covers reachability data.",
  "blocking": false
}

4.3 Approve

POST /api/policy/policies/{policyId}/versions/{version}:approve
Scopes: policy:approve

Body requires approval note and confirmation of compliance gates:

{
  "note": "All simulations and determinism checks passed.",
  "acknowledgeDeterminism": true,
  "acknowledgeSimulation": true
}

4.4 Activate

POST /api/policy/policies/{policyId}/versions/{version}:activate
Scopes: policy:activate, policy:run

Marks version as active for tenant; triggers optional immediate full run ("runNow": true).

4.5 Archive

POST /api/policy/policies/{policyId}/versions/{version}:archive
Scopes: policy:archive

Request includes reason and optional incidentId.


5·Compilation & Validation

5.1 Compile

POST /api/policy/policies/{policyId}/versions/{version}:compile
Scopes: policy:author

Response 200

{
  "digest": "sha256:7e1d…",
  "warnings": [],
  "rules": {
    "count": 24,
    "actions": {
      "block": 5,
      "warn": 4,
      "ignore": 3,
      "requireVex": 2
    }
  }
}

5.2 Lint / Simulate Quick Check

POST /api/policy/policies/{policyId}/lint
Scopes: policy:author

Slim wrapper used by CLI; returns 204 on success or ERR_POL_001 payload.


6·Run & Simulation APIs

Schema reference: canonical policy run request/status/diff payloads ship with the Scheduler Models guide (src/Scheduler/__Libraries/StellaOps.Scheduler.Models/docs/SCHED-MODELS-20-001-POLICY-RUNS.md) and JSON fixtures under samples/api/scheduler/policy-*.json.

6.1 Trigger Run

POST /api/policy/policies/{policyId}/runs
Scopes: policy:run

Request

{
  "mode": "incremental",           // full | incremental
  "runId": "run:P-7:2025-10-26:auto",   // optional idempotency key
  "sbomSet": ["sbom:S-42","sbom:S-318"],
  "env": {"exposure": "internet"},
  "priority": "normal"             // normal | high | emergency
}

Response 202

{
  "runId": "run:P-7:2025-10-26:auto",
  "status": "queued",
  "queuedAt": "2025-10-26T14:05:00Z"
}

6.2 Get Run Status

GET /api/policy/policies/{policyId}/runs/{runId}
Scopes: policy:runs

Includes status, stats, determinism hash, failure diagnostics.

6.3 List Runs

GET /api/policy/policies/{policyId}/runs?mode=incremental&status=failed&page=1&pageSize=20
Scopes: policy:runs

Supports filtering by mode, status, from/to timestamps, tenant.

6.4 Simulate

POST /api/policy/policies/{policyId}/simulate
Scopes: policy:simulate

Request

{
  "baseVersion": 3,
  "candidateVersion": 4,
  "sbomSet": ["sbom:S-42","sbom:S-318"],
  "env": {"sealed": false},
  "explain": true
}

Response 200

{
  "diff": {
    "added": 12,
    "removed": 8,
    "unchanged": 657,
    "bySeverity": {
      "Critical": {"up": 1, "down": 0},
      "High": {"up": 3, "down": 4}
    }
  },
  "explainUri": "blob://policy/P-7/simulations/2025-10-26-4-vs-3.json"
}

6.5 Replay Run

POST /api/policy/policies/{policyId}/runs/{runId}:replay
Scopes: policy:runs, policy:simulate

Produces sealed bundle for determinism verification; returns location of bundle.


7·Effective Findings APIs

7.1 List Findings

GET /api/policy/findings/{policyId}?sbomId=S-42&status=affected&severity=High,Critical&page=1&pageSize=100
Scopes: findings:read

Response includes cursor-based pagination:

{
  "items": [
    {
      "findingId": "P-7:S-42:pkg:npm/lodash@4.17.21:CVE-2021-23337",
      "status": "affected",
      "severity": {"normalized": "High", "score": 7.5},
      "sbomId": "sbom:S-42",
      "advisoryIds": ["CVE-2021-23337"],
      "vex": {"winningStatementId": "VendorX-123"},
      "policyVersion": 4,
      "updatedAt": "2025-10-26T14:06:01Z"
    }
  ],
  "nextCursor": "eyJwYWdlIjoxfQ=="
}

7.2 Fetch Explain Trace

GET /api/policy/findings/{policyId}/{findingId}/explain?mode=verbose
Scopes: findings:read

Returns rule hit sequence:

{
  "findingId": "P-7:S-42:pkg:npm/lodash@4.17.21:CVE-2021-23337",
  "policyVersion": 4,
  "steps": [
    {"rule": "vex_precedence", "status": "not_affected", "inputs": {"statementId": "VendorX-123"}},
    {"rule": "severity_baseline", "severity": {"normalized": "Low", "score": 3.4}}
  ],
  "sealedHints": [{"message": "Using cached EPSS percentile from bundle 2025-10-20"}]
}

8·Events & Webhooks

  • policy.run.completed emitted with runId, policyId, mode, stats, determinismHash.
  • policy.run.failed includes error code, retry count, guidance.
  • policy.lifecycle.* mirrored from lifecycle APIs (see Lifecycle guide).
  • Webhook registration occurs via /api/policy/webhooks (future work, reserved). For now, integrate with Notifier streams documented in /docs/notifications/*.

9·Compliance Checklist

  • Scopes enforced: Endpoint access requires correct Authority scope mapping (see /src/Authority/StellaOps.Authority/TASKS.md).
  • Schemas current: JSON examples align with Scheduler Models (SCHED-MODELS-20-001) and Policy Engine DTOs; update when contracts change.
  • Error codes mapped: ERR_POL_* table reflects implementation and CI tests cover edge cases.
  • Pagination documented: List endpoints specify page/size and cursor semantics; responses include X-Total-Count or nextCursor.
  • Idempotency described: Mutating endpoints mandate Idempotency-Key.
  • Offline parity noted: Simulate/run endpoints explain --sealed behaviour and bundle generation.
  • Cross-links added: References to lifecycle, runs, DSL, and observability docs verified.

Last updated: 2025-10-26 (Sprint 20).