Skip to content

Generate DIFC policies for GitHub App workflows - #58302

Merged
pelikhan merged 3 commits into
mainfrom
copilot/generate-difc-write-sink-policies
Sep 3, 2026
Merged

pelikhan merged 3 commits into
mainfrom
copilot/generate-difc-write-sink-policies

Conversation

Copilot AI commented Sep 3, 2026 •

Copy link
Copy Markdown
Contributor

GitHub App authentication could suppress automatic DIFC policy generation, leaving guarded GitHub MCP sources paired with an unguarded/noop safeoutputs sink. That caused safe-output writes such as dispatch, noop, and incomplete reports to be denied while the workflow appeared successful.

  • Policy generation

    • Generate automatic GitHub allow-only guard policies whenever no explicit policy is configured, including GitHub App workflows.
    • Derive the matching safeoutputs write-sink policy for the same automatic-lockdown path.
  • Behavior preserved

    • GitHub App token minting and MCP authentication remain unchanged.
    • Only DIFC source/sink policy generation changes.
  • Coverage and guidance

    • Added compiler coverage for GitHub App workflows with safe outputs to assert both source and sink policies appear in the generated lock file.
    • Updated workflow authoring/debugging guidance to inspect authentication and DIFC policies separately.

Expected generated policy shape:

"github": {
  "guard-policies": {
    "allow-only": {
      "repos": "$GITHUB_MCP_GUARD_REPOS",
      "min-integrity": "$GITHUB_MCP_GUARD_MIN_INTEGRITY"
    }
  }
},
"safeoutputs": {
  "guard-policies": {
    "write-sink": {
      "accept": ["*"],
      "sink-visibility": "${GH_AW_SINK_VISIBILITY}"
    }
  }
}

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Copilot AI changed the title [WIP] Generate DIFC write-sink policies for GitHub App workflows Generate DIFC policies for GitHub App workflows Sep 3, 2026
Copilot AI requested a review from lpcox September 3, 2026 21:15
@lpcox
lpcox marked this pull request as ready for review September 3, 2026 21:17
Copilot AI balanced review requested due to automatic review settings September 3, 2026 21:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The critical TOML/Codex source-policy omission must be fixed before approval.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Generates matching DIFC source and sink policies for GitHub App-authenticated workflows.

Changes:

  • Enables automatic GitHub allow-only and safeoutputs write-sink policies.
  • Adds compiler regression tests.
  • Expands DIFC troubleshooting guidance.
File summaries
File Review
pkg/workflow/non_github_mcp_guard_policy_test.go Updates policy derivation expectations.
pkg/workflow/mcp_renderer_github.go Critical: TOML/Codex workflows still omit the automatic GitHub source guard policy. Add TOML rendering and Codex + GitHub App coverage.
pkg/workflow/mcp_github_config.go Nits: Documentation incorrectly states automatic lockdown always sets repos=all; it is visibility-dependent.
pkg/workflow/github_mcp_app_token_test.go Verifies generated source and sink policies.
.github/aw/github-mcp-server.md Nit: Guidance presents mcp_servers as universal, although JSON configs use mcpServers.
.github/aw/debug-agentic-workflow.md Adds DIFC troubleshooting guidance.
Review details

Suppressed comments (2)

pkg/workflow/mcp_github_config.go:542

  • The auto-lockdown step does not always set repos=all: it emits repos=public for public repositories unless private-to-public-flows: allow is enabled, and repos=all for private/internal repositories (actions/setup/js/determine_automatic_lockdown.cjs:69-72). The function documentation should describe the visibility-dependent output rather than an invariant that is false.
//  2. Auto-lockdown — when the GitHub tool is present without explicit guard policies,
//     auto-lockdown detection will set repos=all at runtime, so a
//     write-sink policy with accept=["*"] is returned to match that runtime behaviour.

pkg/workflow/mcp_github_config.go:581

  • This repeats the incorrect repos=all invariant. Automatic lockdown resolves repos to public for a public repository by default, so keeping this explanation risks future changes deriving sink behavior from the wrong source-policy scope.
	// When no explicit guard policy is configured but automatic lockdown detection would run
	// (GitHub tool present and not disabled), return accept=["*"] because automatic lockdown
	// always sets repos=all at runtime. GitHub App token scope is authentication, not a
	// substitute for the DIFC sink labels enforced by the MCP gateway.
  • Files reviewed: 6/6 changed files
  • Comments generated: 2
  • Review effort level: Balanced

}
}
shouldUseStepOutputForGuardPolicy := len(explicitGuardPolicies) == 0 && !hasGitHubApp(githubTool)
shouldUseStepOutputForGuardPolicy := len(explicitGuardPolicies) == 0

> ⚠️ **Do NOT use `mode: remote`** in GitHub Actions workflows. Remote mode does not work with the GitHub Actions token (`GITHUB_TOKEN`) — it requires a special PAT or GitHub App token with MCP access. The default `mode: local` (Docker-based) works with `GITHUB_TOKEN` and should always be used.
>
> GitHub App authentication only scopes the token. It does not replace DIFC guard policy labels. When safe outputs are enabled, compile the workflow and confirm the lock file includes both `mcp_servers.github.guard-policies.allow-only` and `mcp_servers.safeoutputs.guard-policies.write-sink`.
@github-actions

github-actions Bot commented Sep 3, 2026 •

Copy link
Copy Markdown
Contributor

✅ PR Code Quality Reviewer completed the code quality review.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • github.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "github.com"

See Network Configuration for more information.

🔎 Code quality review by PR Code Quality Reviewer

@github-actions

github-actions Bot commented Sep 3, 2026 •

Copy link
Copy Markdown
Contributor

✅ Design Decision Gate 🏗️ completed the design decision gate check. See the comment below for the result and any generated ADR draft.

No ADR enforcement needed: PR does not have the 'implementation' label and has <=100 new lines of code in business logic directories.

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions

github-actions Bot commented Sep 3, 2026 •

Copy link
Copy Markdown
Contributor

✅ Test Quality Sentinel completed test quality analysis.

Warning

Threat Detection Engine Failure — The analysis engine could not complete. This is a tooling failure, not a security finding.

What happened

The threat detection engine failed to produce results.

Review the workflow run logs for details.

🧪 Test quality analysis by Test Quality Sentinel

@github-actions

github-actions Bot commented Sep 3, 2026 •

Copy link
Copy Markdown
Contributor

✅ Ponytail Reviewer completed successfully!

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • ab.chatgpt.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "ab.chatgpt.com"

See Network Configuration for more information.

Generated by Ponytail Reviewer for #58302

@github-actions

github-actions Bot commented Sep 3, 2026 •

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Comment Memory

reviewed_at: 2026-09-03T21:32:46Z
review_event: REQUEST_CHANGES
top_themes:
  - docs mention TOML guard-policy paths but omit JSON lock-file paths
files_reviewed:
  - .github/aw/debug-agentic-workflow.md
  - .github/aw/github-mcp-server.md
  - pkg/workflow/github_mcp_app_token_test.go
  - pkg/workflow/mcp_github_config.go
  - pkg/workflow/mcp_renderer_github.go
  - pkg/workflow/non_github_mcp_guard_policy_test.go
comment_count: 1

Note

This comment is managed by comment memory.

It stores persistent context for this thread in the code block at the top of this comment.
Edit only the text inside the backtick fences; workflow metadata and the footer are regenerated automatically.

Learn more about comment memory

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • github.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "github.com"

See Network Configuration for more information.

🔎 Code quality review by PR Code Quality Reviewer · copilot · gpt54 · 30.9 AIC · ⌖ 7.39 AIC · ⊞ 21.8K · ◷
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes

This fixes the source/sink policy gap for GitHub App workflows, but one of the user-facing validation instructions is still wrong for the default compiled lock format. The guidance needs to cover both JSON mcpServers locks and TOML mcp_servers locks, otherwise the exact mismatch behind this bug remains easy to miss.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • github.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "github.com"

See Network Configuration for more information.

🔎 Code quality review by PR Code Quality Reviewer · copilot · gpt54 · 30.9 AIC · ⌖ 7.39 AIC · ⊞ 21.8K
Comment /review to run again


> ⚠️ **Do NOT use `mode: remote`** in GitHub Actions workflows. Remote mode does not work with the GitHub Actions token (`GITHUB_TOKEN`) — it requires a special PAT or GitHub App token with MCP access. The default `mode: local` (Docker-based) works with `GITHUB_TOKEN` and should always be used.
>
> GitHub App authentication only scopes the token. It does not replace DIFC guard policy labels. When safe outputs are enabled, compile the workflow and confirm the lock file includes both `mcp_servers.github.guard-policies.allow-only` and `mcp_servers.safeoutputs.guard-policies.write-sink`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new doc check only mentions the TOML path (mcp_servers...), but this compiler also emits JSON lock configs under mcpServers. That leaves the primary generated format without the guidance you are adding here, so anyone validating a GitHub Actions workflow can still miss the exact source/sink policy pair this change is about.

💡 Why this matters and how to fix it

The JSON renderer is the default path for compiled lock files, and the existing review history already caught the same mismatch in this file. Update the wording so it tells authors to inspect both lock shapes, or describe the shared semantic check instead of a format-specific path. For example:

...confirm the generated lock file includes a GitHub `allow-only` guard policy and a safeoutputs `write-sink` guard policy (under `mcpServers` in JSON locks or `mcp_servers` in TOML locks).

That keeps the debugging guidance aligned with what the compiler actually emits across engines.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skills-Based Review 🧠

Applied /diagnosing-bugs and /grill-with-docs — requesting changes: the fix is incomplete for Codex/TOML workflows, and the doc guidance points at the wrong lock-file key for most engines.

📋 Key Themes & Highlights

Key Themes

  • Incomplete root-cause fix: deriveWriteSinkGuardPolicyFromWorkflow and RenderGitHubMCP correctly stop skipping guard policies for GitHub App workflows, but renderGitHubTOML (Codex engine) never renders explicitGuardPolicies or the automatic allow-only/write-sink policies at all — so Codex + GitHub App workflows still ship without DIFC guard policies, reproducing the bug this PR is meant to fix.
  • Doc inaccuracy: the new guidance in github-mcp-server.md tells readers to inspect mcp_servers.github.guard-policies..., but that key only applies to Codex TOML output; JSON-based engines (the majority) use mcpServers.github.guard-policies....
  • Both issues were already flagged by an existing (apparently unaddressed) reviewer pass on this PR — re-flagging here since they remain unresolved in the current diff.

Positive Highlights

  • ✅ Good, targeted removal of the hasGitHubApp short-circuit in both mcp_github_config.go and mcp_renderer_github.go for the JSON path, with clear updated comments explaining the reasoning (auth scope ≠ DIFC label).
  • ✅ Solid new test coverage in github_mcp_app_token_test.go asserting both source and sink policy shapes appear together in the JSON lock file.
  • ✅ non_github_mcp_guard_policy_test.go update correctly flips the old "no guard policy with GitHub App" expectation to the new intended behavior.

@copilot please address the review comments above.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · copilot · sonnet50 · 28.1 AIC · ⌖ 14.9 AIC · ⊞ 10.3K
Comment /matt to run again

}
}
shouldUseStepOutputForGuardPolicy := len(explicitGuardPolicies) == 0 && !hasGitHubApp(githubTool)
shouldUseStepOutputForGuardPolicy := len(explicitGuardPolicies) == 0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/diagnosing-bugs] The fix only reaches the JSON rendering path. renderGitHubTOML (Codex engine) never calls renderGitHubMCPGuardPolicies or receives GuardPolicies/GuardPoliciesFromStep at all — so for Codex-engine GitHub App workflows, neither the source nor sink guard policy is emitted, silently reproducing the exact bug this PR fixes for JSON engines.

💡 Why this matters

This mirrors an existing unresolved review comment (id 3928852995) on this same line from a previous pass — it appears not yet addressed. Since the PR title is "Generate DIFC policies for GitHub App workflows" and the new test (github_mcp_app_token_test.go) only asserts against the JSON lock content, the root cause (guard policy derivation being conditioned on hasGitHubApp) was fixed at the data layer but the TOML renderer was never wired to consume deriveWriteSinkGuardPolicyFromWorkflow/explicit guard policies at all — a pre-existing gap now more visible because GitHub App + Codex is a supported combination this PR claims to fix.

Suggested fix: thread guard-policy fields into renderGitHubTOML (and its TOML rendering helpers) the same way RenderGitHubMCP does for JSON, or explicitly document/test that Codex/TOML workflows are out of scope for this PR and file a follow-up issue.

@copilot please address this.


> ⚠️ **Do NOT use `mode: remote`** in GitHub Actions workflows. Remote mode does not work with the GitHub Actions token (`GITHUB_TOKEN`) — it requires a special PAT or GitHub App token with MCP access. The default `mode: local` (Docker-based) works with `GITHUB_TOKEN` and should always be used.
>
> GitHub App authentication only scopes the token. It does not replace DIFC guard policy labels. When safe outputs are enabled, compile the workflow and confirm the lock file includes both `mcp_servers.github.guard-policies.allow-only` and `mcp_servers.safeoutputs.guard-policies.write-sink`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/grill-with-docs] The doc instructs readers to check mcp_servers.github.guard-policies... in the lock file, but per the existing (still-unresolved) reviewer comment (id 3928853038), JSON-based engine configs use the mcpServers key (see pkg/workflow/mcp_renderer.go:140) — only Codex TOML output uses mcp_servers. Since the majority of engines render JSON, this instruction will send most readers looking for the wrong path.

💡 Suggested fix

Clarify the two shapes explicitly, e.g.:

Inspect the generated lock file for mcpServers.github.guard-policies (JSON-based engines) or mcp_servers.github guard fields (Codex TOML).

@copilot please address this.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A small bit of test-specific boilerplate can be folded into the existing guard-policy coverage, which keeps the suite easier to scan. net: -15 lines possible.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • ab.chatgpt.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "ab.chatgpt.com"

See Network Configuration for more information.

Generated by ✂️ Ponytail Reviewer for #58302 · codex · mai10 · 6.02 AIC · ⌖ 10.7 AIC · ⊞ 13.5K
Comment /ponytail to run again

// TestNonGitHubMCPServersGetGuardPoliciesWithGitHubApp verifies that non-GitHub MCP servers
// still get write-sink guard policies when a GitHub App is configured. GitHub App token scope
// is authentication, not a substitute for DIFC sink policy labels.
func TestNonGitHubMCPServersGetGuardPoliciesWithGitHubApp(t *testing.T) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pkg/workflow/non_github_mcp_guard_policy_test.go:290: yagni: dedicated GitHub App test with a single case and duplicated expectation. Fold it into the existing table-driven guard-policy tests and keep one assertion path.

@pelikhan
pelikhan merged commit 319f76c into main Sep 3, 2026
32 checks passed
@pelikhan
pelikhan deleted the copilot/generate-difc-write-sink-policies branch September 3, 2026 22:28
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.88.4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Generate DIFC write-sink policies for GitHub App workflows

4 participants