fix: use repo visibility for actions_get and get_job_logs secrecy#2463
fix: use repo visibility for actions_get and get_job_logs secrecy#2463
Conversation
Previously, artifact downloads (actions_get with download_workflow_run_artifact) and job logs (get_job_logs) were unconditionally labeled with [secret] secrecy. This blocked the audit workflow from reading firewall-audit-logs and job logs for public repos like github/gh-aw. Fix: use apply_repo_visibility_secrecy() for both tools, matching the pattern used by other repo-scoped resources. Public repos get empty secrecy labels, private repos get private:owner/repo scope labels. Fixes #2457 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR updates the Rust guard’s DIFC secrecy labeling for GitHub Actions artifact downloads (actions_get) and workflow run logs (get_job_logs) so they inherit secrecy from repository visibility (public => no secrecy labels; private/unknown => private-scoped labels). This unblocks audit workflows from reading artifacts/logs in public repos (e.g., github/gh-aw).
Changes:
actions_get/actions_list: remove the method-specific escalation tosecret_label()for artifact downloads; useapply_repo_visibility_secrecy()consistently.get_job_logs: switch from unconditionalsecret_label()toapply_repo_visibility_secrecy().- Update the
get_job_logsunit test assertion to match the new behavior.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
guards/github-guard/rust-guard/src/labels/tool_rules.rs |
Adjusts labeling rules for Actions artifact/log resources to follow repo visibility-based secrecy. |
guards/github-guard/rust-guard/src/labels/mod.rs |
Updates the get_job_logs test to assert the new visibility-inherited secrecy behavior. |
Comments suppressed due to low confidence (4)
guards/github-guard/rust-guard/src/labels/tool_rules.rs:452
apply_tool_labelsalready callsbackend::is_repo_private(&owner, &repo)to populaterepo_privatebefore the match, andapply_repo_visibility_secrecy()callsis_repo_private()again. With this change,get_job_logsnow triggers a second visibility lookup (even if it hits the cache), which is a small but unnecessary per-call overhead. Consider reusing the already-computedrepo_private(or refactoringapply_repo_visibility_secrecyto accept it) to avoid the duplicate backend call.
"get_job_logs" => {
// S = inherits from repo visibility (public repo logs are public)
// I = approved — CI output is system-generated, not user-controlled
secrecy = apply_repo_visibility_secrecy(&owner, &repo, repo_id, secrecy, ctx);
integrity = writer_integrity(repo_id, ctx);
guards/github-guard/rust-guard/src/labels/tool_rules.rs:452
SECRECY_TAG_SPEC.mdcurrently documentsget_job_logsassecretfor both public and private repos, but this PR changes it to inherit repo visibility. Please update the spec (and any other docs referencing job logs secrecy) so the documentation matches the new policy.
"get_job_logs" => {
// S = inherits from repo visibility (public repo logs are public)
// I = approved — CI output is system-generated, not user-controlled
secrecy = apply_repo_visibility_secrecy(&owner, &repo, repo_id, secrecy, ctx);
integrity = writer_integrity(repo_id, ctx);
guards/github-guard/rust-guard/src/labels/tool_rules.rs:320
- The new comment for the
actions_get/actions_listarm is workflow/artifact-specific, but this match arm also covers other Actions methods (e.g., secrets/variables/caches per proxy routing). Consider broadening the wording (or splitting bymethod) so the comment accurately describes the full surface area handled here.
// S(workflow/artifact) = inherits from repo visibility
// Public repos: artifacts are public. Private repos: artifacts are private-scoped.
// I(workflow/artifact) = approved - maintained by repo team
guards/github-guard/rust-guard/src/labels/tool_rules.rs:323
- This change removes the only method-specific secrecy logic for
actions_get(download_workflow_run_artifact). There currently isn’t a unit test coveringapply_tool_labels("actions_get", {method: "download_workflow_run_artifact", ...})to prevent accidentally reintroducingsecret_label()or other method-specific behavior later. Please add a focused test for this method under the labels tests.
"actions_get" | "actions_list" => {
// S(workflow/artifact) = inherits from repo visibility
// Public repos: artifacts are public. Private repos: artifacts are private-scoped.
// I(workflow/artifact) = approved - maintained by repo team
secrecy = apply_repo_visibility_secrecy(&owner, &repo, repo_id, secrecy, ctx);
integrity = writer_integrity(repo_id, ctx);
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "actions_get" | "actions_list" => { | ||
| // S(workflow/artifact) = inherits from repo secrecy | ||
| // S(workflow/artifact) = inherits from repo visibility | ||
| // Public repos: artifacts are public. Private repos: artifacts are private-scoped. | ||
| // I(workflow/artifact) = approved - maintained by repo team | ||
| secrecy = apply_repo_visibility_secrecy(&owner, &repo, repo_id, secrecy, ctx); | ||
| integrity = writer_integrity(repo_id, ctx); |
There was a problem hiding this comment.
SECRECY_TAG_SPEC.md still documents artifact downloads (actions_get with download_workflow_run_artifact) as secret for both public and private repos, but this PR changes actions_get/actions_list to inherit repo visibility. Please update the spec so the documented labeling rules match the implementation.
This issue also appears in the following locations of the same file:
- line 317
- line 318
- line 448
- line 448
Summary
actions_get(artifact downloads) andget_job_logswere unconditionally labeled with[secret]secrecy in the Rust guard. This blocked the audit workflow from reading firewall-audit-logs and job logs for public repos likegithub/gh-aw.Changes
guards/github-guard/rust-guard/src/labels/tool_rules.rsactions_get: Removed the special-case that upgraded artifact downloads tosecret_label(). Now usesapply_repo_visibility_secrecy()consistently for allactions_get/actions_listoperations.get_job_logs: Changed from unconditionalsecret_label()toapply_repo_visibility_secrecy().Both tools now follow the same pattern as other repo-scoped resources:
[](empty — no restriction)[private:owner/repo][private:owner/repo](fail-secure)guards/github-guard/rust-guard/src/labels/mod.rstest_apply_tool_labels_get_job_logsassertion to match new behavior.Motivation
The integrity filtering audit workflow (issue #2457) runs against the public
github/gh-awrepo. When it tried to downloadfirewall-audit-logsartifacts or read job logs, DIFC blocked access because the agent had no[secret]clearance — and there's no mechanism to grant it. Since the repo is public, these resources should have empty secrecy labels, just like other public repo data.Fixes #2457