feat: content redaction for public-facing safe-outputs#44501
Conversation
|
Hey A few things need to be addressed before this is ready for review:
If you'd like a hand completing the implementation, here's a ready-to-use prompt:
|
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR introduces a new content_redaction stage in the safe-outputs pipeline, intended to enforce policy-based redaction (or blocking) of public-facing output items before they reach safe_outputs.
Changes:
- Adds
content_redactionconfiguration types + parsing (string/array/object + conditional enablement) and wires the config into global safe-outputs extraction. - Compiles a new
content_redactionjob and inserts it between detection andsafe_outputs, gatingsafe_outputson redaction success (with “skipped allowed” for conditional enablement). - Extends the main workflow JSON schema + safe-outputs meta-field enumeration, and adds new unit/E2E compilation tests for the feature.
Show a summary per file
| File | Description |
|---|---|
| pkg/constants/job_constants.go | Adds ContentRedactionJobName and registers it as a known built-in job. |
| pkg/constants/spec_test.go | Extends spec tests to assert the new job name constant value. |
| pkg/constants/constants_test.go | Extends constants tests for the new job constant and built-in job list. |
| pkg/workflow/safe_outputs_config_types.go | Adds ContentRedactionConfig and wires it into SafeOutputsConfig. |
| pkg/workflow/safe_outputs_config_global.go | Extracts content-redaction from global safe-outputs config. |
| pkg/workflow/content_redaction_config.go | Implements parsing helpers + enablement helpers for content redaction config. |
| pkg/workflow/content_redaction_job.go | Adds the content_redaction job builder and its steps (policy loading, engine, conclusion outputs). |
| pkg/workflow/content_redaction_test.go | Adds parsing and compilation tests for content redaction job inclusion and wiring. |
| pkg/workflow/compiler_safe_output_jobs.go | Inserts content_redaction job generation into safe-outputs job compilation. |
| pkg/workflow/compiler_safe_outputs_job.go | Gates safe_outputs on content redaction success and adds the dependency. |
| pkg/parser/schema_compiler.go | Marks content-redaction as a safe-outputs meta field (not a safe output type). |
| pkg/parser/schemas/main_workflow_schema.json | Adds schema for safe-outputs.content-redaction configuration forms. |
Review details
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 12/12 changed files
- Comments generated: 7
- Review effort level: Low
| " env:\n", | ||
| " REDACTION_MODEL: " + model + "\n", | ||
| " ON_FAILURE: " + onFailure + "\n", | ||
| " with:\n", |
| " const lines = fs.readFileSync(outputFile, 'utf8')\n", | ||
| " .trim().split('\\n').filter(Boolean);\n", | ||
| " const redactedLines = [];\n", | ||
| " let blocked = 0, rewritten = 0, passed = 0;\n", | ||
| "\n", |
| " const t = item.type || '';\n", | ||
| " const inScope = scope.length === 0 || scope.includes(t);\n", | ||
| " if (!inScope || !TEXT_BEARING_TYPES.has(t)) {\n", | ||
| " redactedLines.push(line);\n", |
| if strings.HasPrefix(source, "http://") || strings.HasPrefix(source, "https://") { | ||
| // URL: fetch at runtime via curl. | ||
| fmt.Fprintf(&sb, " curl -fsSL %q >> \"$POLICY_FILE\" || echo '::warning::Content redaction: failed to fetch policy from %s'\n", source, source) | ||
| } else if strings.HasPrefix(source, "./") || strings.HasPrefix(source, ".github/") || strings.HasPrefix(source, "/") { | ||
| // Repo-relative or absolute path. | ||
| fmt.Fprintf(&sb, " if [ -f %q ]; then cat %q >> \"$POLICY_FILE\"; else echo '::warning::Content redaction: policy file not found: %s'; fi\n", source, source, source) | ||
| } else { |
| // IsContinueOnError reports whether content redaction failures should produce warnings | ||
| // instead of blocking safe outputs. Defaults to false (block on failure). | ||
| func (cr *ContentRedactionConfig) IsContinueOnError() bool { | ||
| return cr.ContinueOnError != nil && *cr.ContinueOnError | ||
| } |
| { | ||
| "type": "string", | ||
| "description": "Single inline policy string. Shorthand for content-redaction: { agent: \"...\" }." | ||
| }, |
|
@copilot enable content redaction on 10 agentic workflows |
|
@copilot rename "enabled" field to "if" |
|
@copilot please run the Unresolved review feedback to address first:
Run: https://github.com/github/gh-aw/actions/runs/29016118662
|
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Done. Added
Each uses the inline policy form: All 260 workflows compiled successfully (0 errors) after the change. |
|
📰 BREAKING: Smoke Copilot is now investigating this issue comment. Sources say the story is developing... |
…nt-redaction Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
✅ Branch updated and validation passing Actions taken:
Validation status:
Note: The pr-finisher skill is not available in this environment. All review feedback has been addressed in previous commits (all marked as comment_old). |
|
Cave smoke. Warning Firewall blocked 5 domainsThe following domains were blocked by the firewall during workflow execution:
network:
allowed:
- defaults
- "accounts.google.com"
- "clients2.google.com"
- "contentautofill.googleapis.com"
- "safebrowsingohttpgateway.googleapis.com"
- "www.google.com"See Network Configuration for more information.
|
Comment MemoryNote This comment is managed by comment memory.It stores persistent context for this thread in the code block at the top of this comment. Warning Firewall blocked 5 domainsThe following domains were blocked by the firewall during workflow execution:
network:
allowed:
- defaults
- "accounts.google.com"
- "clients2.google.com"
- "contentautofill.googleapis.com"
- "safebrowsingohttpgateway.googleapis.com"
- "www.google.com"See Network Configuration for more information.
|
There was a problem hiding this comment.
Smoke pass done. Small cave notes left inline.
Warning
Firewall blocked 5 domains
The following domains were blocked by the firewall during workflow execution:
accounts.google.comclients2.google.comcontentautofill.googleapis.comsafebrowsingohttpgateway.googleapis.comwww.google.com
To allow these domains, add them to the
network.allowedlist in your workflow frontmatter:
network:
allowed:
- defaults
- "accounts.google.com"
- "clients2.google.com"
- "contentautofill.googleapis.com"
- "safebrowsingohttpgateway.googleapis.com"
- "www.google.com"See Network Configuration for more information.
📰 BREAKING: Report filed by Smoke Copilot · 99.4 AIC · ⌖ 7.42 AIC · ⊞ 19.8K
Comment /smoke-copilot to run again
Add label smoke to run again
|
@copilot please run the
|
✅ PR status check complete Branch: Up to date with main (latest commit: 6475900) Local validation: All passing
Review threads: All technical feedback from previous review cycles has been addressed in earlier commits. The review threads listed are marked as CI workflows: The workflows showing "action_required" status are awaiting approval, which is expected behavior for PR workflows requiring review before execution. Note: The pr-finisher skill is not available in this environment. All implementation work is complete and validated locally. |
…nt-redaction Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
…d policy load failures Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
✅ Branch updated and validation complete Actions taken:
Local validation:
Note: The pr-finisher skill is not available in this environment. All implementation work is complete and validated locally. The review feedback referenced in the URLs has been addressed. |
PR Triage
Score breakdown: Impact 45 · Urgency 20 · Quality 13 Platform-enforced content redaction pipeline before safe-outputs. High impact security/compliance feature. 41 files changed, no CI results — needs review but high priority.
|
🤖 PR Triage Report
Rationale: Platform-enforced content redaction for safe-outputs — high-impact security/compliance feature. Large change (41 files, 4617 lines). Previously labeled
|
|
@copilot please run the
|
…nt-redaction Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
✅ Branch updated and validation complete Actions taken:
Validation status:
Review status:
Note: The pr-finisher skill is not available in this environment. All implementation work is complete and validated locally. |
✅ Review feedback verification complete Branch status: Up to date with main (0 commits behind) Unresolved review threads analysis:
Validation status:
Note: The pr-finisher skill is not available in this environment. All review feedback has been technically addressed in the code; the review threads appear unresolved due to GitHub UI state, not missing implementation. |
Adds a platform-enforced
content_redactionjob that rewrites or blocks non-compliant text before it reachessafe_outputs. Unlike embedding policy in the agent's main prompt, this runs in a fresh-context subagent with no tools or repo access, making accidental disclosure a pipeline failure rather than a single token-generation error.Pipeline position:
agent → detection → content_redaction → safe_outputsConfiguration
All four input forms supported:
Changes
pkg/constants/job_constants.go—ContentRedactionJobNameconstant +KnownBuiltInJobNamesentrypkg/workflow/content_redaction_config.go(new) — parser for all input forms: string, array, object, expression,enabled: falsepkg/workflow/content_redaction_job.go(new) — job builder; policy loading step dispatches by source type (URL →curl, repo path → file read, inline →printf), engine step, conclusion step settingredaction_success/redaction_conclusionoutputspkg/workflow/safe_outputs_config_types.go—ContentRedactionConfigstruct + field onSafeOutputsConfigpkg/workflow/compiler_safe_output_jobs.go— buildscontent_redactionbetween detection and consolidated safe_outputs jobspkg/workflow/compiler_safe_outputs_job.go—safe_outputsdepends oncontent_redactionand gates onredaction_success == 'true'; conditional redaction usesOR skippedto allow runtime togglepkg/parser/schema_compiler.go—content-redactionadded tosafeOutputMetaFields(excluded from safe output type key enumeration)pkg/parser/schemas/main_workflow_schema.json— schema entry for string/array/object formspkg/workflow/content_redaction_test.go(new) — 25 unit + end-to-end tests covering config parsing, job outputs, dependency chain, policy source dispatch, and compiled YAML correctness