Repository navigation
Propagate private CA certificates to threat detection #69364
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
7a1fb04
Initial plan
Copilot d42a066
Fix threat-detection CA certificate inheritance and overrides
Copilot 082783c
docs(adr): add draft ADR for private CA propagation to threat detection
github-actions[bot] 4b330c1
Prevent unsafe threat detection CA inheritance
Copilot File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
58 changes: 58 additions & 0 deletions
58
docs/adr/69364-propagate-private-ca-cert-to-threat-detection.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| # ADR-69364: Propagate Private CA Certificates to the Threat-Detection Job | ||
|
|
||
| **Date**: 2026-10-16 | ||
| **Status**: Draft (generated by the Design Decision Gate for PR #69364; not yet accepted) | ||
| **Deciders**: Not recorded; pending maintainer review of PR #69364. | ||
| **Author**: PR #69364 (`copilot/fix-ca-cert-propagation`), issue #69015 | ||
|
|
||
| ## Context | ||
|
|
||
| `sandbox.agent.ca-cert` is translated into AWF's `apiProxy.caCert` for the agent job, so an engine that talks to an upstream gateway with a private-CA certificate works there. `buildThreatDetectionWorkflowData` in `pkg/workflow/threat_detection_external.go` rebuilt the detection sandbox from scratch (`Type`, `Images` only), so the CA path was dropped. The detection job inherits the same engine id and `engine.env` and therefore calls the same upstream through its own api-proxy sidecar, which does not trust the private CA. TLS verification fails, detection fails, and safe outputs do not run (issue #69015). There was also no frontmatter key to set a certificate for detection alone, and detection runs on a *fresh* runner, so any certificate file written for the agent job does not exist there. | ||
|
|
||
| ## Decision | ||
|
|
||
| Detection resolves its API-proxy CA certificate through a single helper, `resolveThreatDetectionCACert`: | ||
|
|
||
| - A non-empty `safe-outputs.threat-detection.ca-cert` wins. | ||
| - Otherwise the detection sandbox inherits `sandbox.agent.ca-cert` (via the existing `extractAPIProxyCACert`). | ||
| - Unset or empty values inherit; the parser trims whitespace so `" "` is equivalent to unset, and `caCert` stays omitted from the AWF config when nothing is configured. | ||
|
|
||
| The new key is a plain string in the main workflow schema (`ca-cert`), parsed into `ThreatDetectionConfig.CACert`, and the detection sandbox is built as a distinct value so mutating it cannot affect the agent sandbox. The compiler deliberately does **not** copy or materialize the certificate file: documentation states that the file must be created on the detection runner through `threat-detection.steps`. | ||
|
|
||
| The primary driver is correctness with the least new surface — reuse the agent's existing CA plumbing instead of adding a second certificate mechanism — while still allowing a detection-specific override for workflows whose detection engine targets a different upstream. | ||
|
|
||
| ## Alternatives Considered | ||
|
|
||
| ### Inherit `sandbox.agent.ca-cert` only, with no override key | ||
|
|
||
| This is the minimal fix for #69015 and needs no schema change. It was rejected because detection may legitimately point at a different gateway (or a different trust anchor) than the agent, and without an override the only workarounds remain "disable threat detection" or "override every inherited `engine.env` key". | ||
|
|
||
| ### Have the compiler copy/emit the certificate into the detection job automatically | ||
|
|
||
| Generating a step that re-materializes the certificate on the detection runner would remove the documented manual `threat-detection.steps` requirement. It was rejected because the certificate content normally lives in a secret the compiler must not read or inline, and emitting secret-bearing steps implicitly would widen the compiler's security responsibility. Explicit pre-steps keep secret handling in the workflow author's hands. | ||
|
|
||
| ### Configure the certificate under `threat-detection.engine` instead | ||
|
|
||
| Issue #69015 mentioned this as an option. It was rejected because the CA path is a sandbox/proxy concern, not an engine concern; placing it on the detection config keeps it symmetric with `sandbox.agent.ca-cert` and avoids overloading engine configuration semantics. | ||
|
|
||
| ## Consequences | ||
|
|
||
| ### Positive | ||
|
|
||
| - Workflows behind a private CA no longer fail in detection while succeeding in the agent job; safe outputs run as expected. | ||
| - Detection can target a different upstream than the agent via an explicit, documented override, without touching inherited `engine.env`. | ||
| - Inheritance reuses `extractAPIProxyCACert`, so there is one resolution path for `apiProxy.caCert` rather than two divergent ones. | ||
|
|
||
| ### Negative | ||
|
|
||
| - Configuration still fails at runtime (not compile time) if the author forgets the `threat-detection.steps` that writes the certificate on the fresh detection runner; the compiler cannot validate host paths. | ||
| - Another frontmatter key expands the `safe-outputs.threat-detection` surface that must be documented, schema-validated, and kept in sync with AWF behaviour (requires AWF v0.28.10+). | ||
|
|
||
| ### Neutral | ||
|
|
||
| - Empty/whitespace values are normalized to "inherit" rather than "disable"; there is intentionally no way to suppress an inherited certificate for detection. | ||
| - Coverage added at three levels — schema validation, config parsing, and emitted AWF config for inline and external detection across `claude`/`codex`/`copilot` — including an assertion that the detection sandbox does not mutate the agent sandbox. | ||
|
|
||
| --- | ||
|
|
||
| *ADR created by [adr-writer agent]. Review and finalize before changing status from Draft to Accepted.* |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in
4b330c1:ca-cert: falseopts out while unset/empty values inherit only for matching engines. Regression tests cover different-engine detection and public endpoint overrides through both inline and external paths.