Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# ADR-004: Place Deterministic Security Gates in CI and Release Orchestration

**Status:** Accepted

**Date:** 2026-08-23

**Decision Makers:** Repository Owner, Architecture Team

**Context:** Deterministic security-scanning build loop, Baton `5ef6ea85`

---

## Context

Cognitive Mesh has an existing `ISecurityScanningPort` in the Foundation security layer but no engine or adapter that implements it. The repository also has a weekly/manual CodeQL workflow; it is not a pull-request or protected-release gate. DAST is not present.

The agentic-pattern coverage review proposed adding a security gate to `DurableWorkflowEngine`. That engine executes durable application workflows in the Agency layer. Build and release qualification, by contrast, executes before production software is admitted and depends on CI identities, immutable source/artifact references, scanner toolchains, vulnerability-data snapshots, and branch/release policy. Putting the mandatory gate inside the runtime workflow engine would make application execution responsible for proving the build that produced it and would leave non-workflow deployment paths unguarded.

## Capability Status

- **Implemented:** the port contract and weekly/manual CodeQL detection workflow.
- **Experimental:** none introduced by this decision.
- **Planned:** `SecurityScanningEngine`, scanner adapters, deterministic policy/evidence models, CI/release orchestration, DAST candidate environment, and required-check governance.
- **Blocked:** enforcement until implementation, rehearsal, and a separately approved required-check change. No current workflow is upgraded by this ADR.

## Decision

The authoritative deterministic security gate will run in CI and release orchestration. It will not be embedded in, invoked automatically by, or made a prerequisite of `DurableWorkflowEngine` runtime execution.

CI/release orchestration will call a Foundation `SecurityScanningEngine` through the existing `ISecurityScanningPort`. The engine will aggregate policy-required scan types and evaluate the build or release gate against immutable evidence. The orchestration boundary owns checkout/artifact identity, authenticated CI/release provenance, pinned tool installation, candidate-environment provisioning, report publication, and the check conclusion. Foundation adapters own scanner invocation, native-output parsing, and evidence persistence. The engine owns normalization-independent business decisions: required-result completeness, severity thresholds, suppression eligibility, and the deterministic gate verdict.

### Pull-request and protected-build boundary

SAST, dependency, secrets, and applicable IaC scanning run against the exact pull-request or protected-branch SHA. A result for an earlier SHA cannot qualify a changed head. All required results must be present and valid before the protected check passes.

### Release boundary

Container scanning, when an image exists, runs against its digest. DAST runs against an isolated candidate environment whose deployment manifest binds it to that same release artifact. Production deployment remains blocked until the complete release policy passes.

### Failure semantics

Protected gates are fail closed for security findings at or above threshold and for missing, cancelled, timed-out, malformed, unverifiable, or errored required scans. Developer-local advisory scans may fail open only when clearly marked non-qualifying. They cannot satisfy `ValidateBuildSecurityGateAsync`.

### Runtime use

An application workflow may in the future include an explicit business step that requests a scan through the Foundation port. Such a feature requires its own PRD and technical design. It cannot replace, weaken, or attest to the CI/release gate, and this ADR does not authorize it.

## Architectural Boundaries

- Reuse `FoundationLayer.Security.Ports.ISecurityScanningPort`; do not create a CI-specific parallel port with equivalent responsibility.
- Scanner implementations are Foundation adapters. A `SecurityScanningEngine` implements the existing port and owns policy and verdict behavior; it must not become a pass-through wrapper around adapters.
- CI workflow definitions are composition roots outside the application layer hierarchy; they may invoke a thin, testable command-line composition host that resolves the engine through the Foundation port.
- `DurableWorkflowEngine` remains unchanged and does not receive CI credentials, scanner configuration, or release-policy responsibility.
- Evidence storage must be reached through a Foundation-owned persistence boundary; scanner adapters must not write directly into Agency or Business layers.
- Suppression approval is external governance input. A scanner adapter or model must not self-approve a suppression.

## Consequences

### Positive

- Every build and release path can share one admission policy, including paths that never use `DurableWorkflowEngine`.
- Exact-head and exact-artifact evidence exists before production deployment.
- Runtime services do not require scanner binaries, CI credentials, vulnerability databases, or broad source access.
- DAST lifecycle and cleanup stay with the candidate environment that CI/release orchestration creates.
- The existing Foundation port remains the contract boundary.

### Negative

- CI/release orchestration needs a composition host and evidence store in addition to scanner adapters.
- Fail-closed scanner outages can delay delivery.
- Reproducibility requires retaining or reconstructing scanner and vulnerability-data snapshots.
- DAST adds candidate-environment cost and latency.

## Alternatives Considered

1. **Gate every `DurableWorkflowEngine` execution.** Rejected. It couples application runtime to build admission, misses non-workflow artifacts, expands runtime privilege, and cannot prove that the running binary passed the scan it is now invoking.
2. **Use `DurableWorkflowEngine` only to orchestrate CI scans.** Rejected for the first implementation. CI already supplies lifecycle, cancellation, logs, and exact-head context; adding the runtime engine creates a second orchestration state machine without improving the security decision. Reconsider only if cross-CI durable scan orchestration becomes a separately funded requirement.
3. **Keep CodeQL weekly/manual and rely on review.** Rejected as the target state. It cannot provide exact-head admission evidence, complete scan coverage, or pre-release DAST.
4. **Fail open when a scanner is unavailable.** Rejected for protected gates. Unavailability means the required security claim is unproven. Advisory local execution remains available but non-qualifying.
5. **Create a new CI security port.** Rejected. `ISecurityScanningPort` already owns the required responsibility; compatible contract refinements should occur there.

## Reconsideration Triggers

Revisit this ADR if Cognitive Mesh becomes the organization-wide CI control plane, if scan orchestration must survive across CI providers for days, or if an independent signed attestation service becomes the admission authority. Reconsideration must preserve pre-deployment, exact-artifact, fail-closed qualification and must not make runtime self-attestation sufficient.

## References

- `src/FoundationLayer/Security/Ports/ISecurityScanningPort.cs`
- `src/AgencyLayer/Orchestration/Execution/DurableWorkflowEngine.cs`
- `.github/workflows/build.yml`
- `.github/workflows/codeql.yml`
- `docs/prds/global-nfr.md`
- `docs/prds/01-foundational-infrastructure/deterministic-security-scanning-build-loop.md`
- `docs/spec/deterministic-security-scanning.md`
- `docs/runbooks/security-scan-failure-response.md`
3 changes: 3 additions & 0 deletions docs/prds/00-README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ Every feature, architecture layer, or widget added to the platform **must** have
docs/prds/
├── 00-README.md ← This file
├── global-nfr.md ← Global Non-Functional Requirements Appendix
├── 01-foundational-infrastructure/
│ └── deterministic-security-scanning-build-loop.md
├── plugin-dashboard.md ← Plugin-Based Dashboard Architecture PRD
├── convener-backend.md ← Convener Backend Architecture PRD
└── convener-widget.md ← Convener Widget/Plugin PRD
Expand All @@ -27,6 +29,7 @@ docs/prds/
|------|---------|
| **00-README.md** | Orientation & conventions for all PRDs. |
| **global-nfr.md** | Platform-wide security, privacy, SLA, compliance, and quality gates. All other PRDs inherit these requirements. |
| **01-foundational-infrastructure/deterministic-security-scanning-build-loop.md** | Exact-input security qualification for pull requests and protected releases. |
Comment thread
coderabbitai[bot] marked this conversation as resolved.
| **plugin-dashboard.md** | Defines the core shell & extensible plugin/widget model. |
| **convener-backend.md** | Specifies APIs/services that power Convener features (champion discovery, pulse, etc.). |
| **convener-widget.md** | UI plugin that consumes Convener backend APIs & surfaces insights in the dashboard. |
Expand Down
Loading
Loading