Skip to content
Merged
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
13 changes: 11 additions & 2 deletions specs/compiler-threat-detection-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ sidebar:

# GitHub Actions Compiler Threat Detection Specification

**Version**: 1.0.27
**Version**: 1.0.28
**Status**: Candidate Recommendation
**Latest Version**: https://github.com/github/gh-aw/blob/main/specs/compiler-threat-detection-spec.md
**Editors**: GitHub Next (GitHub, Inc.)
Expand Down Expand Up @@ -78,6 +78,7 @@ This section anchors the specification version to the minimum gh-aw binary versi

| Spec version | Minimum gh-aw binary version | Lock-file compatibility notes |
|--------------|------------------------------|-------------------------------|
| `1.0.28` | `v0.87.4` (or newer) | No new CTR rules; extends the CTR-004 Sandbox Bypass Configuration mapping to document the enclave GitHub proxy trust-surface additions (`pkg/workflow/enclaves.go`, `pkg/workflow/enclave_github_proxy.go`) that were already implemented and tested (`pkg/workflow/enclaves_test.go`, `pkg/workflow/enclave_github_proxy_test.go`) but absent from the Section 7.1 mapping table; `enclaves[].agent.github.cli: issues-read-v1` requires AWF network isolation (`validateEnclavesConfig` rejects when `isAWFNetworkIsolationEnabled` is false), gates on minimum AWF/MCPG versions, uses a dedicated read-only operation allowlist (`issues.comments.list`, `issues.get`, `issues.list`), and derives its upstream GitHub token from a chain that intentionally excludes the default `GITHUB_TOKEN` (`getEffectiveEnclaveGitHubToken`). No `.lock.yml` schema changes. |
| `1.0.27` | `v0.87.4` (or newer) | No new CTR rules; extends the CTR-006 Template Injection mapping to document `pkg/workflow/mcp_renderer_guard.go`, which uses a sentinel-based defer mechanism (`guardExprSentinel`/`renderGuardPoliciesJSON`) to emit MCP gateway guard-policy expressions as unquoted GitHub Actions runtime expressions in generated heredocs; this behavior was already implemented and tested (`pkg/workflow/template_injection_validation_test.go`, `pkg/workflow/copilot_github_mcp_test.go`) but absent from the Section 7.1 mapping table. No `.lock.yml` schema changes. |
| `1.0.26` | `v0.87.4` (or newer) | Adds CTR-026 Generated Job Timeout Expression Injection, documenting the already-implemented rejection of expression/non-positive-integer `jobs.agent.timeout-minutes` and `jobs.detection.timeout-minutes` values (`extractCustomJobTimeoutMinutes` in `pkg/workflow/compiler_custom_job_properties.go`). `.lock.yml` files now always emit a literal integer job-level `timeout-minutes` for the generated `agent` and `detection` jobs instead of a `${{ vars.GH_AW_DEFAULT_*_TIMEOUT_MINUTES || '<n>' }}` expression; recompilation of existing workflows changes these two lines but does not alter secrets or action-reference manifests (no CTR-016 impact). |
| `1.0.25` | `v0.87.1` (or newer) | No new CTR rules; the CTR-025 mapping is re-confirmed against the merged `fix-threat-detection-system-block-false-positive` changeset (`stripFrameworkSystemBlock`/`SYSTEM_BLOCK_REMOVED_MARKER` in `actions/setup/js/setup_threat_detection.cjs`), which matches the existing Section 7.1 mapping with no drift. No `.lock.yml` schema changes. |
Expand Down Expand Up @@ -292,7 +293,7 @@ Implementations MUST maintain a clear mapping from each active `CTR-*` rule to c
| CTR-001 Privilege Escalation | `pkg/workflow/*permissions*validation*.go`, `pkg/workflow/strict_mode_permissions_validation.go`, `pkg/workflow/github_app_permissions_validation.go` | `pkg/workflow/*permissions*_test.go`, `pkg/workflow/*dangerous_permissions*_test.go` |
| CTR-002 Unpinned Action Integrity | `pkg/workflow/*action*.go`, `pkg/workflow/strict_mode_validation*.go` | `pkg/workflow/*action*_test.go`, `pkg/workflow/*strict_mode*_test.go` |
| CTR-003 Unsafe Tool Scope Expansion | `pkg/workflow/tools_validation*.go`, `pkg/workflow/strict_mode_validation*.go` | `pkg/workflow/*tools*_test.go` |
| CTR-004 Sandbox Bypass Configuration | `pkg/workflow/sandbox_validation*.go`, `pkg/workflow/strict_mode_sandbox_validation*.go`, `pkg/workflow/strict_mode_permissions_validation.go` | `pkg/workflow/*sandbox*_test.go` |
| CTR-004 Sandbox Bypass Configuration | `pkg/workflow/sandbox_validation*.go`, `pkg/workflow/strict_mode_sandbox_validation*.go`, `pkg/workflow/strict_mode_permissions_validation.go`; enclave GitHub proxy network-isolation and version gating in `pkg/workflow/enclaves.go` (`validateEnclavesConfig`, `validateEnclaveGitHubIssuesVersions`) and dedicated read-only credential/operation scoping in `pkg/workflow/enclave_github_proxy.go` (`operationsForEnclaveGitHubProfile`, `getEffectiveEnclaveGitHubToken`) | `pkg/workflow/*sandbox*_test.go`, `pkg/workflow/enclaves_test.go`, `pkg/workflow/enclave_github_proxy_test.go` |
| CTR-005 Unsafe Output Route | `pkg/workflow/compiler_safe_outputs*.go`, `pkg/workflow/safe_outputs*.go`; runtime harness field allowlisting in `actions/setup/js/safe_output_type_validator.cjs` (declared-field enforcement) and patch/manifest differential-parsing hardening in `actions/setup/js/patch_path_helpers.cjs`, `actions/setup/js/manifest_file_helpers.cjs` (patch-parser vs. `git am` protected-file bypass defense) | `pkg/workflow/*safe_outputs*_test.go`, `actions/setup/js/safe_output_type_validator.test.cjs`, `actions/setup/js/patch_path_helpers.test.cjs`, `actions/setup/js/manifest_file_helpers.test.cjs` |
| CTR-006 Template Injection | `pkg/workflow/template_injection_validation.go`, `pkg/workflow/heredoc_validation.go`, `pkg/workflow/mcp_renderer_guard.go` (MCP gateway guard-policy sentinel-based expression deferral, emitting unquoted GitHub Actions runtime expressions in generated heredocs) | `pkg/workflow/template_injection_validation_test.go`, `pkg/workflow/template_injection_validation_fuzz_test.go`, `pkg/workflow/copilot_github_mcp_test.go` |
| CTR-007 Markdown Content Security | `pkg/workflow/markdown_security_scanner.go`; URL-authority allowlist parity between the stripping and filtering passes (userinfo-prefix bypass, backslash-separator normalization, embedded-whitespace discard) in `actions/setup/js/sanitize_content_core.cjs` | `pkg/workflow/markdown_security_scanner_test.go`, `pkg/workflow/secure_markdown_rendering_test.go`, `actions/setup/js/sanitize_content.test.cjs` |
Expand Down Expand Up @@ -428,6 +429,14 @@ These optimizer-protocol IDs cover Section 6 norms; they do not add or replace t

## 10. Change Log

### 1.0.28 (2026-08-28)

- Daily optimizer review cycle. Reviewed the most recent merged compiler change: `Add read-only GitHub Issues access to agent enclaves` (#55531), which adds a compiler-owned mcpg `issues-read-v1` proxy for the `enclaves[].agent.github.cli` configuration (`pkg/workflow/enclaves.go`, `pkg/workflow/enclave_github_proxy.go`, `actions/setup/sh/start_enclave_github_proxy.sh`, `actions/setup/sh/stop_enclave_github_proxy.sh`). Evaluated the new trust surface against the existing CTR catalog: (1) **Network isolation precondition** — `validateEnclavesConfig` rejects any `enclaves:` configuration unless AWF network isolation is enabled (`isAWFNetworkIsolationEnabled`), which is the same precondition class as CTR-004 Sandbox Bypass Configuration; (2) **Version gating** — `validateEnclaveGitHubIssuesVersions` hard-rejects compilation when the effective AWF version is below `v0.28.9` or the effective MCPG version is below `v0.4.13`, preventing the proxy from being emitted against runtime components that lack its readiness/policy-enforcement guarantees; (3) **Read-only operation allowlist** — `operationsForEnclaveGitHubProxyProfile`/`enclaveGitHubProfileOperations` restrict the `issues-read-v1` profile to exactly `issues.comments.list`, `issues.get`, and `issues.list`, a fixed compiler-controlled allowlist that the author cannot widen from workflow frontmatter; (4) **Credential scoping** — `getEffectiveEnclaveGitHubToken` intentionally excludes `GITHUB_TOKEN` from its fallback chain (`GH_AW_GITHUB_MCP_SERVER_TOKEN || GH_AW_GITHUB_TOKEN` only), and the ephemeral per-run capability key (`MCP_GATEWAY_ENCLAVE_CAPABILITY_KEY`) generated in `start_enclave_github_proxy.sh` is masked and scoped to the run/attempt/job-hash identity, consistent with CTR-017 Secret Leakage via Environment Variables safe-binding expectations; (5) **Repository sensitivity/count limits** — `validateEnclaveEntry`/`validateEnclaveRepositories` cap the profile to at most one non-public repository and validate repo slugs against a strict pattern, bounding the blast radius of the read-only proxy. All five items are already implemented and covered by existing tests (`pkg/workflow/enclaves_test.go`, `pkg/workflow/enclave_github_proxy_test.go`); none introduce a threat class outside CTR-004/CTR-017 scope, so no new `CTR-*` rule is required this cycle — this is a mapping-only update.
- No `threat-detection-suppress` annotations were found in any live (non-fixture, non-documentation-example) workflow source in this review window, so no `SLA_BREACH` or expiration findings apply.
- No new threat class was identified requiring a new `CTR-*` rule.
- Extended Section 7.1 CTR-004 mapping row with `pkg/workflow/enclaves.go` and `pkg/workflow/enclave_github_proxy.go` and their test coverage (`pkg/workflow/enclaves_test.go`, `pkg/workflow/enclave_github_proxy_test.go`).
- Updated Section 2 spec-to-implementation sync table with version 1.0.28 entry.

### 1.0.27 (2026-08-26)

- Daily optimizer review cycle. Reviewed the pending `.changeset/*.md` inventory and current `pkg/workflow` source since the 1.0.26 audit. All reviewed items were found to be already covered by existing `CTR-*` rules or outside compiler-detectable scope: `patch-escape-mcp-template-expressions` (MCP gateway guard-policy expressions are escaped via the sentinel mechanism in `pkg/workflow/mcp_renderer_guard.go` — this was implemented but had not yet been added to the Section 7.1 CTR-006 mapping table, so it is added here as a mapping-only update, not a new rule); `patch-fix-heredoc-delimiter-injection` (heredoc delimiter randomization/normalization, already covered by CTR-006's `heredoc_validation.go` mapping); `patch-fix-multi-repo-configure-git-credentials-template-injection` (already reconciled in the 1.0.25 cycle, confirmed unchanged in `checkout_step_generator.go`); `patch-sanitize-template-delimiters` (Jinja2/Liquid/ERB/JS/Jekyll delimiter neutralization in `sanitize_content_core.cjs`'s `neutralizeTemplateDelimiters`, already covered by CTR-007's markdown-content-security mapping); `patch-fix-shell-escape-agent-path-injection` (already reconciled in the 1.0.24 cycle, CTR-009 mapping unchanged); `patch-fix-codex-threat-detection-proxy`, `patch-threat-detection-ghe-api-target`, `patch-skip-empty-threat-detection` (CTR-019 cache-memory gating scope, no behavior change to detection-skip gating logic), `patch-inject-difc-proxy-pre-agent-gh`, `patch-inject-git-identity-env-vars` (operational/runtime wiring correctness for detection and sandboxed execution, not new detectable compiler patterns), and `hint-jq-file-injection-safe-outputs-prompt` (documentation-only prompt guidance, no compiler detection logic).
Expand Down
Loading