Configuration Reference

Environment variables and OPA policy examples for the Release Orchestrator.

Status: Mixed reference; implemented sections identify their source of truth. Source: Architecture Advisory Section 15.2 Related Modules: Security Overview, Promotion Manager Sprint: 101_001 Foundation

Overview

This document provides the configuration reference for the Release Orchestrator, including environment variables and OPA policy examples.


Environment Variables

Core Configuration

# Database
STELLA_DATABASE_URL=postgresql://user:pass@host:5432/stella
STELLA_REDIS_URL=redis://host:6379  # Valkey (Redis-compatible)
STELLA_SECRET_KEY=base64-encoded-32-bytes
STELLA_LOG_LEVEL=info
STELLA_LOG_FORMAT=json

Authentication (Authority)

# OAuth/OIDC
STELLA_OAUTH_ISSUER=https://auth.example.com
STELLA_OAUTH_CLIENT_ID=stella-app
STELLA_OAUTH_CLIENT_SECRET=secret

Agents

# Agent TLS
STELLA_AGENT_LISTEN_PORT=8443
STELLA_AGENT_TLS_CERT=/path/to/cert.pem
STELLA_AGENT_TLS_KEY=/path/to/key.pem
STELLA_AGENT_CA_CERT=/path/to/ca.pem

Plugins

# Plugin configuration
STELLA_PLUGIN_DIR=/var/stella/plugins
STELLA_PLUGIN_SANDBOX_MEMORY=512m
STELLA_PLUGIN_SANDBOX_CPU=1

Integrations

# Vault integration
STELLA_VAULT_ADDR=https://vault.example.com
STELLA_VAULT_TOKEN=hvs.xxx

Release Environment Limits

Administrators can restrict release creation and artifact-derived successor versions to a known set of environments. This protects self-service developer updates and operator release creation from accidentally targeting environments outside the tenant’s approved release path.

The normal administrator control is persisted per tenant through GET/PUT /api/v1/release-orchestrator/release-environment-limit and the Platform Setup Defaults & Guardrails page. The configuration keys below are a bootstrap/fallback path: they apply only until a tenant-stored setting exists.

# Require every release create/update/clone/successor request to name a target environment.
ReleaseOrchestrator__ReleaseEnvironmentLimit__RequireTargetEnvironment=true

# Array form, preferred in appsettings.json and Kubernetes/compose env expansion.
ReleaseOrchestrator__ReleaseEnvironmentLimit__AllowedEnvironments__0=env-dev
ReleaseOrchestrator__ReleaseEnvironmentLimit__AllowedEnvironments__1=env-stage

# CSV fallback for simpler deployment systems.
ReleaseOrchestrator__ReleaseEnvironmentLimit__AllowedEnvironmentsCsv=env-dev,env-stage

When RequireTargetEnvironment=true and no target environment is supplied, the API returns 400 with release_target_environment_required. When an allow-list is present and the target is outside the list, the API returns 403 with release_environment_not_allowed.

Auto-deploy on approval (durable approval → deployment transition)

Status: Implemented (Sprint 20260703_002 / DTC-8). Source of truth: src/ReleaseOrchestrator/__Apps/StellaOps.ReleaseOrchestrator.WebApi/Services/DeploymentDispatchProcessor.cs, DispatchOnApprovalReleaseTruthRepository.cs, and migration StellaOps.ReleaseOrchestrator.Persistence/Migrations/008_deployment_dispatches.sql.

When a promotion approval reaches approved state (manual quorum met or auto-approved by policy), a deployment-dispatch intent is persisted into release_orchestrator.deployment_dispatches in the same transaction as the approval write. A hosted dispatcher drains due intents with bounded retry/backoff and starts the deployment through the same code path POST /releases/{id}/deploy uses (identical ReleaseTruthGuard fail-closed checks and deploy-engine entry). Terminal dispatch failure surfaces as release status dispatch_failed plus a deployment_dispatch_failed release event.

# Kill-switch (default: true). false = approvals no longer enqueue dispatch
# intents and the dispatcher stays idle; operators deploy via POST /deploy.
ReleaseOrchestrator__AutoDeployOnApproval=true

# Tuning knobs (defaults shown).
ReleaseOrchestrator__AutoDeployDispatch__PollIntervalSeconds=5
ReleaseOrchestrator__AutoDeployDispatch__MaxAttempts=5
ReleaseOrchestrator__AutoDeployDispatch__RetryBaseDelaySeconds=10   # doubles per attempt (deterministic)
ReleaseOrchestrator__AutoDeployDispatch__RetryMaxDelaySeconds=600
ReleaseOrchestrator__AutoDeployDispatch__ClaimBatchSize=10
ReleaseOrchestrator__AutoDeployDispatch__ClaimLeaseSeconds=600      # crash self-heal lease

Scheduled topology readiness

Status: Implemented, disabled by default. Source of truth: src/ReleaseOrchestrator/__Apps/StellaOps.ReleaseOrchestrator.WebApi/Services/TopologyReadinessScheduler.cs (section ReleaseOrchestrator:TopologyReadiness).

The optional WebApi background pass refreshes target connection health and persists readiness reports for the Environments Command view. Enabling it causes periodic outbound probes to operator-configured target or binding destinations and persistent health/readiness writes. The service validates all durations at startup; Interval and PerTargetTimeout must be positive and InitialDelay must not be negative. Positive intervals below 60 seconds are clamped to 60 seconds.

# Opt in on exactly ONE ReleaseOrchestrator WebApi replica. Default false.
ReleaseOrchestrator__TopologyReadiness__Enabled=true

# Cadence and per-target bounds (defaults shown).
ReleaseOrchestrator__TopologyReadiness__InitialDelay=00:00:45
ReleaseOrchestrator__TopologyReadiness__Interval=00:05:00
ReleaseOrchestrator__TopologyReadiness__PerTargetTimeout=00:00:12

# Independent steps (both default true when the scheduler is enabled).
ReleaseOrchestrator__TopologyReadiness__RefreshHealth=true
ReleaseOrchestrator__TopologyReadiness__EvaluateReadiness=true

There is no distributed lease for this hosted service. Do not enable it on more than one WebApi replica: each enabled replica would repeat the same probes and writes. For sealed/air-gap operation, the scheduler does not select any public endpoint itself, but configured targets and infrastructure bindings can cross a network boundary. Leave it disabled unless all destinations are local or explicitly allow-listed; operators can instead run the authenticated POST /api/v1/release-orchestrator/environments/readiness/validate-all action when a manual, bounded evaluation is appropriate. Periodic cadence is the only automatic trigger; deployment and agent-heartbeat events do not immediately run the pass.

Approval transition safety

Status: Implemented (RDT-3). Source of truth: Services/ApprovalSafetyGuard.cs, ApprovalEndpoints.cs, ReleaseControlV2Endpoints.cs, and ReleaseDashboardEndpoints.cs.

Every approval route rejects incomplete gate/evidence truth before mutating quorum. Environment protection class is persisted configuration; the optional list below adds decision-signing enforcement to selected target environments. The global OperatorDecisionEnforcement:Approve=true switch remains the all-environments equivalent.

# Per-environment signing rollout. Repeat the numeric suffix for more targets.
ReleaseOrchestrator__ApprovalSafety__SigningRequiredEnvironments__0=production

# Global all-environment approval signing (default false).
ReleaseOrchestrator__OperatorDecisionEnforcement__Approve=false

Protected or signing-required environments also require a signed, basis-bound gate decision and a genuinely verified policy-decision evidence packet. Configure trust roots under ReleaseOrchestrator__EvidenceVerification__TrustedPublicKeys__N; without a trust anchor signed evidence remains honestly recorded and the protected transition fails closed.

SBOM-readiness gate

Status: Implemented. Source of truth: src/ReleaseOrchestrator/__Apps/StellaOps.ReleaseOrchestrator.WebApi/Services/SbomReadinessGateServices.cs (SbomReadinessGateOptions, section ReleaseOrchestrator:SbomReadinessGate).

The promotion gate that blocks dispatch until the Scanner reports SBOM results for every digest-pinned release component. The gate fails closed: a probe timeout or transport error maps to failed and denies promotion, so TimeoutSeconds must comfortably exceed the Scanner’s real /api/v1/sbom-readiness latency (observed ~8s on live deployments — the historical 5s default false-blocked promotions with 409 even though the SBOMs existed).

# Master switch (default: true).
ReleaseOrchestrator__SbomReadinessGate__Enabled=true

# Scanner base address the gate probes.
ReleaseOrchestrator__SbomReadinessGate__ScannerBaseAddress=http://scanner.stella-ops.local

# HttpClient timeout (seconds) for the readiness/scan calls. Default 20.
# Fail-closed: a timeout DENIES promotion, so keep this above real scanner latency.
ReleaseOrchestrator__SbomReadinessGate__TimeoutSeconds=20

# Require the SBOM to be attached to the EXTERNAL registry (default: false).
ReleaseOrchestrator__SbomReadinessGate__RequireExternalAttachment=false

# Internal-first fallback: read the deployment registry's OCI referrers when the
# internal store reports `absent` (default: true; fail-safe, never relaxes a DENY).
ReleaseOrchestrator__SbomReadinessGate__ExternalRegistryFallback=true
ReleaseOrchestrator__SbomReadinessGate__ExternalRegistryFallbackTimeoutSeconds=5

# Orchestrator's OWN service identity for the scanner calls (see architecture.md);
# HttpTimeoutSeconds bounds only the Authority token mint, not the readiness probe.
ReleaseOrchestrator__SbomReadinessGate__ServiceIdentity__Enabled=false
ReleaseOrchestrator__SbomReadinessGate__ServiceIdentity__HttpTimeoutSeconds=10

Full Configuration File

# stella-config.yaml

database:
  url: postgresql://user:pass@host:5432/stella
  pool_size: 20
  ssl_mode: require

redis:
  url: redis://host:6379  # Valkey (Redis-compatible)
  prefix: stella

auth:
  issuer: https://auth.example.com
  client_id: stella-app
  client_secret_ref: vault://secrets/oauth-client-secret

agents:
  listen_port: 8443
  tls:
    cert_path: /etc/stella/agent.crt
    key_path: /etc/stella/agent.key
    ca_path: /etc/stella/ca.crt
  heartbeat_interval: 30
  task_timeout: 600

plugins:
  directory: /var/stella/plugins
  sandbox:
    memory: 512m
    cpu: 1
    network: restricted

evidence:
  storage_path: /var/stella/evidence
  signing_key_ref: vault://secrets/evidence-signing-key
  retention_days: 2555  # 7 years

logging:
  level: info
  format: json
  output: stdout

telemetry:
  enabled: true
  otlp_endpoint: otel-collector:4317
  service_name: stella-release-orchestrator

OPA Policy Examples

Security Gate Policy

# security_gate.rego
package stella.gates.security

default allow = false

allow {
    input.release.components[_].security.reachable_critical == 0
    input.release.components[_].security.reachable_high == 0
}

deny[msg] {
    component := input.release.components[_]
    component.security.reachable_critical > 0
    msg := sprintf("Component %s has %d reachable critical vulnerabilities",
                   [component.name, component.security.reachable_critical])
}

Approval Gate Policy

# approval_gate.rego
package stella.gates.approval

default allow = false

allow {
    count(input.approvals) >= input.environment.required_approvals
    separation_of_duties_met
}

separation_of_duties_met {
    not input.environment.require_sod
}

separation_of_duties_met {
    input.environment.require_sod
    approver_ids := {a.approver_id | a := input.approvals[_]; a.action == "approved"}
    not input.promotion.requested_by in approver_ids
}

Freeze Window Gate Policy

# freeze_window_gate.rego
package stella.gates.freeze

default allow = true

allow = false {
    window := input.environment.freeze_windows[_]
    time.now_ns() >= time.parse_rfc3339_ns(window.start)
    time.now_ns() <= time.parse_rfc3339_ns(window.end)
    not input.promotion.requested_by in window.exceptions
}

API Error Codes

CodeHTTP StatusDescription
RELEASE_NOT_FOUND404Release with specified ID does not exist
ENVIRONMENT_NOT_FOUND404Environment with specified ID does not exist
PROMOTION_BLOCKED403Promotion blocked by policy gates
APPROVAL_REQUIRED403Additional approvals required
FREEZE_WINDOW_ACTIVE403Environment is in freeze window
DIGEST_MISMATCH400Image digest does not match expected
AGENT_OFFLINE503Required agent is offline
WORKFLOW_FAILED500Workflow execution failed
PLUGIN_ERROR500Plugin returned an error
QUOTA_EXCEEDED429Digest analysis quota exceeded
VALIDATION_ERROR400Request validation failed
UNAUTHORIZED401Authentication required
FORBIDDEN403Insufficient permissions

Default Values

SettingDefaultDescription
Agent heartbeat interval30sFrequency of agent heartbeats
Task timeout600sMaximum time for agent task
Deployment batch size25%Percentage of targets per batch
Health check timeout60sTimeout for health checks
Evidence retention7 yearsAudit compliance requirement
Max workflow steps50Maximum steps per workflow
Max parallel tasks10Per-agent concurrent tasks

See Also