Files
git.stella-ops.org/docs/modules/release-orchestrator/api/promotions.md

6.6 KiB

Promotion & Approval APIs

API endpoints for managing promotions, approvals, and gate evaluations.

Status: Planned (not yet implemented) Source: Architecture Advisory Section 6.3.5 Related Modules: Promotion Manager Module, Workflow Promotion

Overview

The Promotion API provides endpoints for requesting release promotions between environments, managing approvals, and evaluating promotion gates. Promotions enforce separation of duties (SoD) and require configured approvals before deployment proceeds.


Promotion Endpoints

Create Promotion Request

Endpoint: POST /api/v1/promotions

Initiates a promotion request for a release to a target environment.

Request:

{
  "releaseId": "uuid",
  "targetEnvironmentId": "uuid",
  "reason": "Deploying v2.3.1 with critical bug fix"
}

Response: 201 Created

{
  "id": "uuid",
  "releaseId": "uuid",
  "releaseName": "myapp-v2.3.1",
  "sourceEnvironmentId": "uuid",
  "sourceEnvironmentName": "Staging",
  "targetEnvironmentId": "uuid",
  "targetEnvironmentName": "Production",
  "status": "pending",
  "requestedBy": "user-uuid",
  "requestedAt": "2026-01-10T14:23:45Z",
  "reason": "Deploying v2.3.1 with critical bug fix"
}

Status Flow:

pending -> awaiting_approval -> approved -> deploying -> deployed
                            -> rejected
                            -> cancelled
                            -> failed
                            -> rolled_back

List Promotions

Endpoint: GET /api/v1/promotions

Query Parameters:

  • status (string): Filter by status
  • releaseId (UUID): Filter by release
  • environmentId (UUID): Filter by target environment
  • page (number): Page number

Response: 200 OK

{
  "data": [
    {
      "id": "uuid",
      "releaseName": "myapp-v2.3.1",
      "targetEnvironmentName": "Production",
      "status": "awaiting_approval",
      "requestedAt": "2026-01-10T14:23:45Z"
    }
  ],
  "meta": { "page": 1, "totalCount": 25 }
}

Get Promotion

Endpoint: GET /api/v1/promotions/{id}

Response: 200 OK - Full promotion with decision record and approvals

Approve Promotion

Endpoint: POST /api/v1/promotions/{id}/approve

Request:

{
  "comment": "Approved after reviewing security scan results"
}

Response: 200 OK

{
  "id": "uuid",
  "status": "approved",
  "approvalCount": 2,
  "requiredApprovals": 2,
  "decidedAt": "2026-01-10T14:30:00Z"
}

Notes:

  • Separation of Duties (SoD): The user who requested the promotion cannot approve it if requireSod is enabled on the environment
  • Multi-party approval: Promotion proceeds when approvalCount >= requiredApprovals

Reject Promotion

Endpoint: POST /api/v1/promotions/{id}/reject

Request:

{
  "reason": "Security vulnerabilities not addressed"
}

Response: 200 OK - Updated promotion with status: rejected

Cancel Promotion

Endpoint: POST /api/v1/promotions/{id}/cancel

Cancels a pending or awaiting_approval promotion.

Response: 200 OK - Updated promotion with status: cancelled


Decision & Evidence Endpoints

Get Decision Record

Endpoint: GET /api/v1/promotions/{id}/decision

Returns the full decision record including gate evaluations.

Response: 200 OK

{
  "promotionId": "uuid",
  "decision": "allow",
  "decidedAt": "2026-01-10T14:30:00Z",
  "gates": [
    {
      "gateName": "security-gate",
      "passed": true,
      "details": {
        "criticalCount": 0,
        "highCount": 3,
        "maxCritical": 0,
        "maxHigh": 5
      }
    },
    {
      "gateName": "freeze-window-gate",
      "passed": true,
      "details": {
        "activeFreezeWindow": null
      }
    }
  ],
  "approvals": [
    {
      "approverId": "uuid",
      "approverName": "John Doe",
      "decision": "approved",
      "comment": "LGTM",
      "approvedAt": "2026-01-10T14:28:00Z"
    }
  ]
}

Get Approvals

Endpoint: GET /api/v1/promotions/{id}/approvals

Response: 200 OK - Array of approval records

Get Evidence Packet

Endpoint: GET /api/v1/promotions/{id}/evidence

Returns the signed evidence packet for the promotion decision.

Response: 200 OK

{
  "id": "uuid",
  "type": "release_decision",
  "version": "1.0",
  "content": { ... },
  "contentHash": "sha256:abc...",
  "signature": "base64-signature",
  "signatureAlgorithm": "ECDSA-P256-SHA256",
  "signerKeyRef": "key-id",
  "generatedAt": "2026-01-10T14:30:00Z"
}

Gate Preview Endpoints

Preview Gate Evaluation

Endpoint: POST /api/v1/promotions/preview-gates

Evaluates gates without creating a promotion (dry run).

Request:

{
  "releaseId": "uuid",
  "targetEnvironmentId": "uuid"
}

Response: 200 OK

{
  "wouldPass": false,
  "gates": [
    {
      "gateName": "security-gate",
      "passed": false,
      "blocking": true,
      "message": "3 critical vulnerabilities exceed threshold (max: 0)"
    },
    {
      "gateName": "freeze-window-gate",
      "passed": true,
      "blocking": false,
      "message": "No active freeze window"
    }
  ]
}

Approval Policy Endpoints

Create Approval Policy

Endpoint: POST /api/v1/approval-policies

Request:

{
  "name": "production-policy",
  "environmentId": "uuid",
  "requiredApprovals": 2,
  "approverGroups": ["release-managers", "sre-team"],
  "requireSeparationOfDuties": true,
  "autoExpireHours": 24
}

List Approval Policies

Endpoint: GET /api/v1/approval-policies

Get Approval Policy

Endpoint: GET /api/v1/approval-policies/{id}

Update Approval Policy

Endpoint: PUT /api/v1/approval-policies/{id}

Delete Approval Policy

Endpoint: DELETE /api/v1/approval-policies/{id}


Current User Endpoints

Get My Pending Approvals

Endpoint: GET /api/v1/my/pending-approvals

Returns promotions awaiting approval from the current user.

Response: 200 OK - Array of promotions


Error Responses

Status Code Description
400 Invalid promotion request
403 User cannot approve (SoD violation or not in approver list)
404 Promotion not found
409 Promotion already decided
422 Gate evaluation failed

See Also