-
Notifications
You must be signed in to change notification settings - Fork 16
Description
Problem
Guard policies block all org-level GitHub Projects access. All 4 project read tools (list_projects, get_project, list_project_fields, list_project_items) return empty results when guard policies are active.
Upstream report: github/agentic-workflows#90
Root Cause: Two Independent Bugs
Bug 1: Scope mismatch — Project tools are unrecognized by the guard (fall through to default case in tool_rules.rs). The default case assigns unscoped baseline integrity ["none"], but the agent's tags are scoped (e.g., ["none:github"] for repos: ["github/*"]). Since tag comparison is exact string matching, "none" ≠ "none:github" → blocked.
This breaks even with min-integrity: none.
Bug 2: Integrity level — Even when scope alignment is fixed, project resources only get baseline none integrity (no author_association field). Any min-integrity above none blocks all project access.
Reproduction Matrix (from upstream issue)
| repos | min-integrity | Projects work? | Failure reason |
|---|---|---|---|
"all" |
none |
✅ Yes | Both tags are unscoped "none" — exact match |
["github/*"] |
none |
❌ No | Agent: "none:github" vs Resource: "none" — scope mismatch |
"all" |
approved |
❌ No | Agent needs "approved" but resource only has "none" |
Proposed Solution
1. Recognize Project Tools in tool_rules.rs
Add explicit match arms for:
list_projects(read)get_project(read)list_project_fields(read)list_project_items(read)
Already recognized (write operations):
add_project_item,delete_project_item(write)update_project_item(read-write)
2. Secrecy Labels
Use the project's public boolean (available in GitHub API ProjectV2 object):
- Private project →
private:<owner>(e.g.,private:github) - Public project →
[](empty, unrestricted)
For list_project_items, items inherit secrecy from their underlying repo (issues/PRs have repository_url). Draft issues inherit from the project's visibility.
3. Integrity Labels
GitHub Projects have creator fields at multiple levels (ProjectV2 and ProjectV2Item):
| Tool | Integrity Source | Level | Rationale |
|---|---|---|---|
list_projects |
Project creator |
approved:<scope> |
Creating projects requires org membership |
get_project |
Project creator |
approved:<scope> |
Same |
list_project_fields |
Project creator (inherited) |
approved:<scope> |
Field definitions are structural metadata |
list_project_items (issues/PRs) |
Issue/PR author_association |
Varies per item | Reuses existing labeling logic |
list_project_items (draft issues) |
Item creator |
approved:<scope> |
Adding items requires project access (org member) |
Creator integrity mapping: Since creating/managing projects requires org membership, creators map to approved (equivalent to MEMBER author_association).
4. Scope Alignment (Critical)
Resource integrity tags must use the same scope token as the agent. When the guard handles project tools:
- Extract
ownerfrom tool args (projects are org-scoped, not repo-scoped) - Pass through
normalize_scope(owner, ctx)to align with agent's scope token - Example: policy
repos: ["github/*"]→ agent has"none:github"→ resource gets"approved:github"(not bare"approved")
For list_project_items, each item's scope comes from its underlying repository.
5. Response Labeling in response_paths.rs
Add per-item labeling for list_project_items since it returns a heterogeneous collection:
- Issues/PRs: Label using
content.author_associationandcontent.repository_url(extract owner/repo) - Draft issues: Label using item
creatorand project owner
Implementation Scope
Guard (Rust WASM)
tool_rules.rs: Add match arms for 4 project read tools with secrecy/integrityresponse_paths.rsorresponse_items.rs: Add per-item labeling forlist_project_itemshelpers.rs: Potentially addproject_creator_integrity()helper
Testing
- Unit tests for each project tool's labeling
- Integration test with
repos: ["org/*"]+min-integrity: approvedpolicy - Verify items with different content types (issue, PR, draft) get correct labels
Notes
- Project item types: issues, pull requests, and draft issues
- Only
list_project_itemsreturns per-item repo context; the other 3 are purely org-level - The existing write tool recognition (
add_project_item,delete_project_item,update_project_item) does not need changes