Skip to content

fix(policies): allow POST /graphql in agent sandbox policies - #173

Merged
rh-hemartin merged 1 commit into
mainfrom
fix/4934-allow-graphql-post-in-sandbox-policies
Jul 17, 2026
Merged

fix(policies): allow POST /graphql in agent sandbox policies#173
rh-hemartin merged 1 commit into
mainfrom
fix/4934-allow-graphql-post-in-sandbox-policies

Conversation

@rh-hemartin

@rh-hemartin rh-hemartin commented Jul 15, 2026

Copy link
Copy Markdown
Member

Summary

  • The gh CLI uses POST /graphql for all operations, including reads. Agent sandbox policies with access: read-only on a protocol: rest endpoint caused the L7 proxy to block every POST to /graphql.
  • Added a separate protocol: graphql endpoint entry scoped to path: "/graphql" with access: read-only in code.yaml, fix.yaml, retro.yaml, and review.yaml. This allows GraphQL queries but blocks mutations at the AST level. REST endpoints are unchanged.
  • Other agent policies (prioritize, triage) already use access: read-write and were unaffected. scribe has no GitHub API entry.

Root cause

Transcript analysis of run 29399089230 (retro for konflux-ci/konflux-ci#8189) shows two POST /graphql requests denied at L7 with reason POST /graphql not permitted by policy. The agent then tried curl (binary not in allowlist) and git clone (same) as fallbacks, all denied. The token was valid; the proxy killed the connection before it reached GitHub.

Test plan

  • Retro agent run on a known PR produces substantive analysis instead of "unable to access GitHub API"
  • Review agent gh pr view calls succeed in sandbox
  • Code and fix agents can use gh pr view --json for read operations

Closes fullsend-ai/fullsend#4934

🤖 Generated with Claude Code

@rh-hemartin
rh-hemartin requested a review from a team as a code owner July 15, 2026 09:06
@fullsend-ai-review

Copy link
Copy Markdown

🤖 Review · Started 9:07 AM UTC
Commit: f56acb2 · View workflow run →

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Allow POST /graphql for gh CLI in retro/review sandbox network policies

🐞 Bug fix ⚙️ Configuration changes 🕐 10-20 Minutes

Grey Divider

AI Description

• Allow path-scoped read-write access to GitHub GraphQL endpoint for gh CLI.
• Keep GitHub REST API access read-only to preserve least-privilege behavior.
• Unblock retro/review sandbox runs that rely on gh pr view / gh issue view.
Diagram

graph TD
  A["Retro/Review agent (gh)"] --> B["L7 proxy"] --> C["api.github.com"]
  D["retro.yaml + review.yaml"] --> B
  C --> E["REST API (read-only)"]
  C --> F["/graphql (read-write)"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Make all api.github.com traffic read-write
  • ➕ Simpler policy: no path scoping to maintain
  • ➕ Avoids future breakage if gh introduces additional POST-based endpoints
  • ➖ Broader permissions than necessary for read-only agents
  • ➖ Increases blast radius if a tool bypasses intended read-only semantics
2. Replace gh usage with REST-only client calls
  • ➕ Keeps GitHub policy strictly read-only at L7 (GET-only semantics)
  • ➕ Potentially tighter control over API surface area
  • ➖ Higher implementation/maintenance cost than policy tweak
  • ➖ Reimplements logic already handled by gh (pagination, auth, formatting)
3. Allow POST globally but restrict to specific HTTP methods/headers (if supported)
  • ➕ More explicit intent (permit POST only where needed)
  • ➕ Can be safer than blanket read-write depending on proxy capabilities
  • ➖ May not be supported by the policy schema/proxy enforcement model
  • ➖ More complex to reason about than path-scoped allowlist

Recommendation: Keep the PR’s approach: add a dedicated, path-scoped read-write rule for /graphql while leaving REST endpoints read-only. This preserves least privilege for retro/review agents, matches gh’s POST-only GraphQL behavior, and avoids the broader risk of making the entire GitHub API read-write.

Files changed (2) +16 / -0

Other (2) +16 / -0
retro.yamlPermit POST /graphql via path-scoped read-write GitHub API rule +8/-0

Permit POST /graphql via path-scoped read-write GitHub API rule

• Adds a second 'api.github.com' endpoint entry that grants 'read-write' access only to the '/graphql' path. Leaves the existing 'read-only' GitHub REST access intact to maintain least privilege for the retro agent.

policies/retro.yaml

review.yamlAllow gh GraphQL queries by enabling /graphql read-write access +8/-0

Allow gh GraphQL queries by enabling /graphql read-write access

• Introduces a separate 'api.github.com' endpoint stanza with 'allowed_paths: ["/graphql"]' and 'read-write' access. Keeps the rest of GitHub API access 'read-only' for the review agent sandbox.

policies/review.yaml

@rh-hemartin
rh-hemartin force-pushed the fix/4934-allow-graphql-post-in-sandbox-policies branch from f56acb2 to 80b3885 Compare July 15, 2026 09:11
@qodo-code-review

qodo-code-review Bot commented Jul 15, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (1)

Context used
✅ Compliance rules (platform): 55 rules
✅ Skills: 4 invoked
  code-review
  code-implementation
  pr-review
  docs-review

Grey Divider


Action required

1. Protected policies/ files modified 📜 Skill insight § Compliance
Description
This PR modifies files under the protected governance/infrastructure path policies/, which must
not be auto-approved and requires explicit human review. Even with a valid justification, these
changes must be treated as requiring manual approval.
Code

policies/retro.yaml[R49-56]

+      # gh CLI uses POST /graphql for all queries (GraphQL is POST-only)
+      - host: "api.github.com"
+        port: 443
+        protocol: rest
+        enforcement: enforce
+        access: read-write
+        allowed_paths:
+          - "/graphql"
Relevance

⭐⭐⭐ High

Repo has prior compliance feedback that protected paths shouldn’t be auto-approved (similar
suggestion in PR #59).

PR-#59

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 1538392 requires raising a finding whenever protected governance/infrastructure
paths (including policies/) are modified, so the PR is not auto-approved and receives human
review. The diff adds a new api.github.com endpoint entry with access: read-write and
allowed_paths: /graphql in both policies/retro.yaml and policies/review.yaml.

policies/retro.yaml[49-56]
policies/review.yaml[46-53]
Skill: pr-review

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Files under `policies/` are protected governance/infrastructure paths and must not be auto-approved.

## Issue Context
This PR changes network policy behavior by adding a `read-write` GraphQL exception for `api.github.com`.

## Fix Focus Areas
- policies/retro.yaml[49-56]
- policies/review.yaml[46-53]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Sandbox GraphQL write bypass ✓ Resolved 🐞 Bug ⛨ Security
Description
policies/retro.yaml and policies/review.yaml now allow access: read-write to
api.github.com/graphql even though the documented intent is that sandboxed agents should not have
GitHub write capability (and policies/retro.yaml documents write-scoped sandbox permissions),
enabling GraphQL mutations from inside the sandbox and weakening the safety boundary that confines
writes to the post-script/runner environment. Even if today’s sandbox token is read-only in some
environments, this change reduces defense-in-depth and makes future token-scope changes risky
because mutations would begin working without further policy edits.
Code

policies/retro.yaml[R49-56]

+      # gh CLI uses POST /graphql for all queries (GraphQL is POST-only)
+      - host: "api.github.com"
+        port: 443
+        protocol: rest
+        enforcement: enforce
+        access: read-write
+        allowed_paths:
+          - "/graphql"
Relevance

⭐⭐ Medium

No historical review evidence on GraphQL /graphql read-write; baseline policies documented read-only
for review/retro in PR #12.

PR-#12

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Both updated policies explicitly configure the /graphql endpoint with access: read-write, and
repository guidance (including the policies/review.yaml header comment and docs/review.md)
states the review sandbox has no GitHub write access; this is contradicted by permitting a
write-capable path via GraphQL, which uses the same endpoint for reads and mutations. Additionally,
policies/retro.yaml documents that the sandbox token includes issues:write and
pull_requests:write, and the sandbox environment passes GH_TOKEN through, meaning in-sandbox
tools (e.g., gh) could authenticate and successfully perform GraphQL mutations when the network
policy allows it.

policies/retro.yaml[6-11]
policies/retro.yaml[41-57]
env/retro.env[1-5]
policies/review.yaml[4-9]
policies/review.yaml[38-54]
docs/review.md[9-14]
env/review.env[1-4]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`policies/retro.yaml` and `policies/review.yaml` include a `read-write` allowance for `POST /graphql` on `api.github.com`, but GraphQL uses the same endpoint for both queries and mutations, so this can enable GitHub write operations from inside the sandbox. This contradicts the documented “no GitHub write access” boundary for review and undermines the intended safety model that confines write-capable GitHub actions to the post-script/runner environment; it also weakens defense-in-depth because future token-scope changes could immediately enable mutations without further policy edits.

## Issue Context
The policies previously relied on network/L7 restrictions (e.g., read-only semantics) to prevent REST writes even if a token had broader scopes, but allowing `/graphql` as `read-write` re-opens a write-capable path. `policies/retro.yaml` additionally documents the retro sandbox token as having `issues:write`/`pull_requests:write`, and both sandboxes pass `GH_TOKEN` through, so in-sandbox tooling like `gh` can use whatever scopes are present; the change may have been made to support `gh`, but it should not silently expand the sandbox’s ability to perform mutations.

## Fix Focus Areas
- policies/retro.yaml[4-11]
- policies/retro.yaml[41-57]
- env/retro.env[1-5]
- policies/review.yaml[4-9]
- policies/review.yaml[38-58]
- docs/review.md[9-14]
- env/review.env[1-4]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread policies/retro.yaml Outdated
Comment thread policies/retro.yaml Outdated
@fullsend-ai-review

fullsend-ai-review Bot commented Jul 15, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 9:12 AM UTC · Completed 9:22 AM UTC
Commit: 80b3885 · View workflow run →

@rh-hemartin rh-hemartin self-assigned this Jul 15, 2026
@rh-hemartin
rh-hemartin force-pushed the fix/4934-allow-graphql-post-in-sandbox-policies branch from 80b3885 to bf4dfb1 Compare July 15, 2026 09:22
@fullsend-ai-review

fullsend-ai-review Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review — comment

Summary

This PR adds protocol: graphql endpoint entries to four read-only agent sandbox policies (code, fix, retro, review), fixing a documented failure where the gh CLI's POST /graphql requests were blocked by access: read-only on protocol: rest endpoints. The agents/review.md documentation is updated to reflect the new GraphQL capability, replacing stale REST-only guidance with accurate REST+GraphQL instructions. The change is well-scoped, uses least-privilege access (read-only, path-scoped to /graphql, enforcement: enforce), and traces to a linked issue (fullsend-ai/fullsend#4934).

One medium-severity finding carries forward from the prior review (unchanged code pattern, severity anchored). Agents with access: read-write (triage, prioritize) are correctly excluded — their existing policies already permit POST /graphql via read-write REST endpoints. Scribe has no GitHub API entry and is also correctly excluded.


Findings

1. Novel protocol: graphql and endpoint-level path field lack in-repo validation

Severity: medium · Category: consumer-completeness · Files: policies/code.yaml, policies/fix.yaml, policies/retro.yaml, policies/review.yaml

protocol: graphql is introduced for the first time across all policy files — every existing endpoint entry uses protocol: rest. The endpoint-level path field is also novel; all existing path: fields appear under binaries: sections only. Since the consuming proxy lives in another repository (fullsend-ai/fullsend), this repo has no schema, validation test, or documentation confirming:

  • The proxy recognizes protocol: graphql as a valid protocol type
  • The proxy supports endpoint-level path matching
  • The proxy's failure mode for unrecognized values (fail-open vs. fail-closed)
  • The AST-level mutation blocking claimed in the inline comments is implemented

The PR's root cause evidence (POST /graphql denied at L7) demonstrates the proxy does enforce protocol-level filtering, which indirectly supports the claim. However, the correctness of protocol: graphql as a recognized value and the AST-level mutation blocking behavior remain unverifiable from this repository alone.

Remediation: Confirm the fullsend proxy supports protocol: graphql and endpoint-level path in a released version. Consider adding a policy schema to schemas/ so future structural changes are validated in CI.


2. Documentation partially omits enforcement mechanism detail

Severity: low · Category: incorrect-doc · File: agents/review.md

The updated text correctly states "GraphQL mutations are blocked by the sandbox proxy," identifying the trust boundary. However, it does not mention that enforcement uses AST-level query/mutation discrimination, which is the mechanism referenced in the policy YAML comments. Future maintainers may not know where to investigate if mutation blocking behavior changes.

Remediation: Consider adding "via AST-level query analysis" or linking to proxy documentation.


3. Permission expansion — four read-only agents

Severity: low · Category: permission-expansion · Files: policies/code.yaml, policies/fix.yaml, policies/retro.yaml, policies/review.yaml

Adding GraphQL access is a permission expansion for four agents. All entries use access: read-only with enforcement: enforce and path scoping to /graphql. The change is authorized by the linked issue. Agent-specific risk:

  • code/fix: The sandbox GH_TOKEN is read-only scoped per harness YAML headers; mutations would fail at GitHub's end regardless of proxy policy
  • review: No write-scoped token — mutations would fail at GitHub's end regardless
  • retro: Token has issues:write and pull_requests:write scopes, making it the highest-risk case; AST-level mutation blocking at the proxy is the critical control; incremental risk is low given layered controls (read-only access, enforce mode, no curl in binary allowlist)

Prior review resolution

Prior finding Status
Novel protocol: graphql lacks validation (medium, consumer-completeness) ⏳ Carried forward — unchanged code pattern, severity anchored at medium
Documentation omits enforcement mechanism (low, incorrect-doc) ⏳ Carried forward — unchanged, severity anchored at low
Permission expansion (low, permission-expansion) ⏳ Carried forward — unchanged, severity anchored at low
Previous run

Review — comment (b59276c)

Three findings: novel protocol: graphql lacks validation (medium, carried forward), documentation partially omits enforcement mechanism (low, carried forward), permission expansion (low, carried forward).

Previous run

Review — comment

Summary

This PR adds protocol: graphql endpoint entries to four read-only agent sandbox policies (code, fix, retro, review), fixing a documented failure where the gh CLI's POST /graphql requests were blocked by access: read-only on protocol: rest endpoints. The agents/review.md documentation is updated to reflect the new GraphQL capability, replacing stale REST-only guidance with accurate REST+GraphQL instructions. The change is well-scoped, uses least-privilege access (read-only, path-scoped to /graphql, enforcement: enforce), and traces to a linked issue (fullsend-ai/fullsend#4934).

One medium-severity finding carries forward from the prior review (unchanged code pattern, severity anchored). All REST API examples in agents/review.md are preserved; the doc update adds GraphQL examples alongside them. Agents with access: read-write (triage, prioritize) are correctly excluded — their existing policies already permit POST /graphql. Scribe has no GitHub API entry and is also correctly excluded.

Defense-in-depth: the code and fix agents additionally ban Bash(gh api *) via disallowedTools, making the GraphQL endpoint unreachable at the tool layer for those two agents regardless of the network policy. The retro and review agents rely on the proxy's protocol: graphql enforcement as the primary control.


Findings

1. Novel protocol: graphql and endpoint-level path field lack in-repo validation

Severity: medium · Category: consumer-completeness · Files: policies/code.yaml, policies/fix.yaml, policies/retro.yaml, policies/review.yaml

protocol: graphql is introduced for the first time across all policy files — every existing endpoint entry uses protocol: rest. The endpoint-level path field is also novel; all existing path: fields appear under binaries: sections only. Since the consuming proxy lives in another repository (fullsend-ai/fullsend), this repo has no schema, validation test, or documentation confirming:

  • The proxy recognizes protocol: graphql as a valid protocol type
  • The proxy supports endpoint-level path matching
  • The proxy's failure mode for unrecognized values (fail-open vs. fail-closed)
  • The AST-level mutation blocking claimed in the inline comments is implemented

The PR's root cause evidence (POST /graphql denied at L7) demonstrates the proxy does enforce protocol-level filtering, which indirectly supports the claim. However, the correctness of protocol: graphql as a recognized value and the AST-level mutation blocking behavior remain unverifiable from this repository alone.

If the proxy does not recognize protocol: graphql and falls through to a permissive default, the retro agent is the highest-risk case — its sandbox token has issues:write and pull_requests:write scopes, and it does not have Bash(gh api *) in its disallowedTools (unlike code and fix).

Remediation: Confirm the fullsend proxy supports protocol: graphql and endpoint-level path in a released version. Consider adding a policy schema to schemas/ so future structural changes are validated in CI.


2. Documentation partially omits enforcement mechanism detail

Severity: low · Category: incorrect-doc · File: agents/review.md

The updated text now correctly states "GraphQL mutations are blocked by the sandbox proxy," identifying the trust boundary. However, it does not mention that enforcement uses AST-level query/mutation discrimination, which is the mechanism referenced in the policy YAML comments. Future maintainers may not know where to investigate if mutation blocking behavior changes.

Remediation: Consider adding "via AST-level query analysis" or linking to proxy documentation.


3. Permission expansion — four read-only agents

Severity: low · Category: permission-expansion · Files: policies/code.yaml, policies/fix.yaml, policies/retro.yaml, policies/review.yaml

Adding GraphQL access is a permission expansion for four agents. All entries use access: read-only with enforcement: enforce and path scoping to /graphql. The change is authorized by the linked issue. Agent-specific risk:

  • code/fix: Bash(gh api *) banned via disallowedTools — GraphQL endpoint unreachable at the tool layer; policy entry is defense-in-depth documentation of intent
  • review: No write-scoped token — mutations would fail at GitHub's end regardless
  • retro: Token has issues:write and pull_requests:write scopes, making it the highest-risk case; AST-level mutation blocking is the critical control; incremental risk is low given layered controls (read-only access, enforce mode, no curl in binary allowlist)

Prior review resolution

Prior finding Status
Novel protocol: graphql lacks validation (medium, consumer-completeness) ⏳ Carried forward — unchanged code pattern, severity anchored at medium
Documentation omits enforcement mechanism (low, incorrect-doc) ⏳ Carried forward — unchanged, severity anchored at low
Permission expansion (low, permission-expansion) ⏳ Carried forward — unchanged, severity anchored at low
Previous run (2)

Review — comment (855ce38)

Three findings: novel protocol: graphql lacks validation (medium, carried forward), documentation partially omits enforcement mechanism (low, carried forward), permission expansion (low, carried forward).

Previous run (3)

Review — comment

Summary

This PR adds protocol: graphql endpoint entries to four read-only agent sandbox policies (code, fix, retro, review), fixing a documented failure where the gh CLI's POST /graphql requests were blocked by access: read-only on protocol: rest endpoints. The agents/review.md documentation is updated to reflect the new GraphQL capability, replacing stale REST-only guidance with accurate REST+GraphQL instructions. The change is well-scoped, uses least-privilege access (read-only, path-scoped to /graphql, enforcement: enforce), and traces to a linked issue (fullsend-ai/fullsend#4934).

One medium-severity finding carries forward from the prior review (unchanged code pattern, severity anchored). All REST API examples in agents/review.md are preserved; the doc update adds GraphQL examples alongside them. Agents with access: read-write (triage, prioritize) are correctly excluded — their existing policies already permit POST /graphql. Scribe has no GitHub API entry and is also correctly excluded.

Defense-in-depth: the code and fix agents additionally ban Bash(gh api *) via disallowedTools, making the GraphQL endpoint unreachable at the tool layer for those two agents regardless of the network policy. The retro and review agents rely on the proxy's protocol: graphql enforcement as the primary control.


Findings

1. Novel protocol: graphql and endpoint-level path field lack in-repo validation

Severity: medium · Category: consumer-completeness · Files: policies/code.yaml, policies/fix.yaml, policies/retro.yaml, policies/review.yaml

protocol: graphql is introduced for the first time across all policy files — every existing endpoint entry uses protocol: rest. The endpoint-level path field is also novel; all existing path: fields appear under binaries: sections only. Since the consuming proxy lives in another repository (fullsend-ai/fullsend), this repo has no schema, validation test, or documentation confirming:

  • The proxy recognizes protocol: graphql as a valid protocol type
  • The proxy supports endpoint-level path matching
  • The proxy's failure mode for unrecognized values (fail-open vs. fail-closed)
  • The AST-level mutation blocking claimed in the inline comments is implemented

The PR's root cause evidence (POST /graphql denied at L7) demonstrates the proxy does enforce protocol-level filtering, which indirectly supports the claim. However, the correctness of protocol: graphql as a recognized value and the AST-level mutation blocking behavior remain unverifiable from this repository alone.

If the proxy does not recognize protocol: graphql and falls through to a permissive default, the retro agent is the highest-risk case — its sandbox token has issues:write and pull_requests:write scopes, and it does not have Bash(gh api *) in its disallowedTools (unlike code and fix).

Remediation: Confirm the fullsend proxy supports protocol: graphql and endpoint-level path in a released version. Consider adding a policy schema to schemas/ so future structural changes are validated in CI.


2. Documentation partially omits enforcement mechanism detail

Severity: low · Category: incorrect-doc · File: agents/review.md

The updated text now correctly states "GraphQL mutations are blocked by the sandbox proxy," identifying the trust boundary (this addresses the prior review's remediation suggestion). However, it does not mention that enforcement uses AST-level query/mutation discrimination, which is the mechanism referenced in the policy YAML comments. Future maintainers may not know where to investigate if mutation blocking behavior changes.

Remediation: Consider adding "via AST-level query analysis" or linking to proxy documentation.


3. Permission expansion — four read-only agents

Severity: low · Category: permission-expansion · Files: policies/code.yaml, policies/fix.yaml, policies/retro.yaml, policies/review.yaml

Adding GraphQL access is a permission expansion for four agents. All entries use access: read-only with enforcement: enforce and path scoping to /graphql. The change is authorized by the linked issue. Agent-specific risk:

  • code/fix: Bash(gh api *) banned via disallowedTools — GraphQL endpoint unreachable at the tool layer; policy entry is defense-in-depth documentation of intent
  • review: No write-scoped token — mutations would fail at GitHub's end regardless
  • retro: Token has issues:write and pull_requests:write scopes, making it the highest-risk case; AST-level mutation blocking is the critical control; incremental risk is low given layered controls (read-only access, enforce mode, no curl in binary allowlist)

Prior review resolution

Prior finding Status
Novel protocol: graphql lacks validation (medium, consumer-completeness) ⏳ Carried forward — unchanged code pattern, severity anchored at medium
Documentation omits enforcement mechanism (low, incorrect-doc) ⏳ Carried forward (partially addressed — text now includes "by the sandbox proxy")
Permission expansion (low, permission-expansion) ⏳ Carried forward — unchanged, severity anchored at low
Previous run (4)

Review — comment (d8d4fad)

Three findings: novel protocol: graphql lacks validation (medium, carried forward), documentation omits enforcement mechanism (low, carried forward), permission expansion (low, carried forward).

Previous run (5)

Review — comment

Summary

This PR adds protocol: graphql endpoint entries to four read-only agent sandbox policies (code, fix, retro, review), fixing a documented failure where the gh CLI's POST /graphql requests were blocked by access: read-only on protocol: rest endpoints. The scope has expanded since the prior review to include policies/code.yaml and policies/fix.yaml alongside the previously reviewed policies/retro.yaml and policies/review.yaml. The agents/review.md documentation is updated to reflect the new GraphQL capability, replacing stale "REST-only" guidance. The change is well-scoped, uses least-privilege access (read-only, path-scoped to /graphql, enforcement: enforce), and traces to a linked issue (fullsend-ai/fullsend#4934).

One medium-severity finding carries forward from the prior review (unchanged code pattern, severity anchored). The scope expansion to code.yaml and fix.yaml is justified — both agents have read-only GitHub API access and the same root cause applies. Agents with access: read-write (triage, prioritize) are correctly excluded, as are agents with no GitHub API entry (scribe).


Findings

1. Novel protocol: graphql and endpoint-level path field lack in-repo validation

Severity: medium · Category: consumer-completeness · Files: policies/code.yaml, policies/fix.yaml, policies/retro.yaml, policies/review.yaml

protocol: graphql is introduced for the first time across all policy files — every existing endpoint entry uses protocol: rest. The endpoint-level path field is also novel; all existing path: fields appear under binaries: sections only. Since the consuming proxy lives in another repository (fullsend-ai/fullsend), this repo has no schema, validation test, or documentation confirming:

  • The proxy recognizes protocol: graphql as a valid protocol type
  • The proxy supports endpoint-level path matching
  • The proxy's failure mode for unrecognized values (fail-open vs. fail-closed)
  • The AST-level mutation blocking claimed in the inline comments is implemented

The PR's root cause evidence (POST /graphql denied at L7) demonstrates the proxy does enforce protocol-level filtering, which indirectly supports the claim. However, the correctness of protocol: graphql as a recognized value and the AST-level mutation blocking behavior remain unverifiable from this repository.

Remediation: Confirm the fullsend proxy supports protocol: graphql and endpoint-level path in a released version. Consider adding a policy schema to schemas/ so future structural changes are validated in CI.


2. Documentation omits enforcement mechanism for mutation blocking

Severity: low · Category: incorrect-doc · File: agents/review.md

The updated text states "GraphQL mutations are blocked" without clarifying that enforcement is delegated to the external sandbox proxy's AST-level analysis. The policy YAML comments reference "AST level" blocking, but nothing in this repository implements or tests it. Future maintainers may not know where to investigate if mutation blocking behavior changes.

Remediation: Consider qualifying with "by the sandbox proxy" to make the trust boundary explicit.


3. Permission expansion — four read-only agents

Severity: low · Category: permission-expansion · Files: policies/code.yaml, policies/fix.yaml, policies/retro.yaml, policies/review.yaml

Adding GraphQL access is a permission expansion for four agents. All entries use access: read-only with enforcement: enforce and path scoping to /graphql. The change is authorized by the linked issue. Agent-specific risk assessment:

  • review: No write-scoped token — mutations would fail at GitHub's end regardless
  • retro: Token has issues:write and pull_requests:write scopes, making it the highest-risk case. AST-level mutation blocking is the critical control. Incremental risk is low given layered controls (read-only access, enforce mode, no curl in binary allowlist)
  • code/fix: Read-only token scopes; Bash(gh api *) is additionally banned via disallowedTools, so only gh CLI subcommands like --json (which internally use POST /graphql) benefit from this change

Prior review resolution

Prior finding Status
Novel protocol: graphql lacks validation (medium, consumer-completeness) ⏳ Carried forward — unchanged code pattern, severity anchored at medium; scope expanded to code.yaml and fix.yaml
Documentation omits enforcement mechanism (low, incorrect-doc) ⏳ Carried forward — unchanged, severity anchored at low
Permission expansion retro/review (low, permission-expansion) ⏳ Carried forward — unchanged, consolidated with new code/fix expansion

Labels: PR scope expanded to modify code and fix agent sandbox policies in addition to retro and review

Previous run (6)

Review — comment (bc86827)

Four findings: novel protocol: graphql lacks validation (medium, carried forward), documentation omits enforcement mechanism (low, carried forward), permission expansion retro (low, carried forward), permission expansion review (low, carried forward). Prior stale-docs finding resolved.

Previous run (7)

Review — comment

Summary

This PR adds protocol: graphql endpoint entries to the retro and review sandbox policies, fixing a documented failure where the gh CLI's POST /graphql requests were blocked by access: read-only on protocol: rest endpoints. The L7 proxy correctly denied POST requests under the read-only REST policy — agents with access: read-write (triage, prioritize, code, fix) were unaffected. The fix adds a separate protocol: graphql entry with access: read-only and path: "/graphql", which allows GraphQL queries while blocking mutations at the AST level. The agents/review.md documentation is updated to reflect the new capability, replacing the stale REST-only guidance.

The change is well-scoped, uses least-privilege access, and traces to a linked issue (fullsend-ai/fullsend#4934). One medium-severity finding carries forward from the prior review (unchanged code, severity anchored).


Findings

1. Novel protocol: graphql and endpoint-level path field lack in-repo validation

Severity: medium · Category: consumer-completeness · Files: policies/retro.yaml, policies/review.yaml

protocol: graphql is introduced for the first time across all 7 policy files — every existing endpoint entry uses protocol: rest. The endpoint-level path field is also novel; all existing path: fields appear under binaries: sections only. Since the consuming proxy lives in another repository (fullsend-ai/fullsend), this repo has no schema, validation test, or documentation confirming:

  • The proxy recognizes protocol: graphql as a valid protocol type
  • The proxy supports endpoint-level path matching
  • The proxy's failure mode for unrecognized values (fail-open vs. fail-closed)

The PR's root cause evidence (POST /graphql denied at L7) demonstrates the proxy does enforce protocol-level filtering, which indirectly supports the claim. However, the correctness of protocol: graphql as a recognized value and the AST-level mutation blocking behavior remain unverifiable from this repository.

Remediation: Confirm the fullsend proxy supports protocol: graphql and endpoint-level path in a released version. Consider adding a policy schema to schemas/ so future structural changes are validated in CI.


2. Documentation omits enforcement mechanism for mutation blocking

Severity: low · Category: incorrect-doc · File: agents/review.md

The updated text states "GraphQL mutations are blocked" without clarifying that enforcement is delegated to the external sandbox proxy. The policy YAML comments reference "AST level" blocking, but nothing in this repository implements or tests it. Future maintainers may not know where to investigate if mutation blocking behavior changes.

Remediation: Consider qualifying with "by the sandbox proxy" to make the trust boundary explicit.


3. Permission expansion — retro agent

Severity: low · Category: permission-expansion · File: policies/retro.yaml

Adding GraphQL access is a permission expansion. The retro agent's sandbox token has issues:write and pull_requests:write scopes. The policy correctly uses access: read-only and enforcement: enforce, and the linked issue authorizes the change. The AST-level mutation blocking is the critical control — if bypassed, the token scopes would permit mutations. The incremental risk is low given the layered controls (read-only access, enforce mode, no curl in binary allowlist).


4. Permission expansion — review agent

Severity: low · Category: permission-expansion · File: policies/review.yaml

Same configuration as retro. The review agent's token has no write scopes (per the policy header: "No write access to GitHub"), making the mutation-blocking concern lower here than for the retro agent.


Prior review resolution

Prior finding Status
Novel protocol: graphql lacks validation (medium, consumer-completeness) ⏳ Carried forward — unchanged code, severity anchored at medium
Documentation omits enforcement mechanism (low, incorrect-doc) ⏳ Carried forward — unchanged code, severity anchored at low
Permission expansion (low, permission-expansion) ⏳ Carried forward — unchanged code, severity anchored at low
Previous run (8)

Review — comment (c71b59d)

Four findings: novel protocol: graphql lacks validation (medium, carried forward), documentation omits enforcement mechanism (low, carried forward), permission expansion retro (low, carried forward), permission expansion review (low, carried forward). Prior stale-docs finding resolved.

Previous run (9)

Review — comment (bf4dfb1)

Three findings: stale docs in agents/review.md (medium, resolved), novel protocol: graphql lacks validation (medium, carried forward), permission expansion (low, carried forward).

Previous run (10)

Review — comment

Summary

This PR adds protocol: graphql endpoint entries to the retro and review sandbox policies, fixing a documented failure where the gh CLI's POST /graphql requests were blocked by the REST-only network policies. The new commit also updates agents/review.md to reflect the new GraphQL capability, fully addressing the prior review's stale-documentation finding. The change is well-scoped, uses least-privilege access (access: read-only, path-scoped to /graphql), and traces to a linked issue (fullsend-ai/fullsend#4934). The YAML structure and style are consistent with existing policy files.

One medium-severity finding carries over from the prior review (unchanged code, severity anchored). Several low-severity observations are noted for the record.


Findings

1. Novel protocol: graphql and endpoint-level path field lack in-repo validation

Severity: medium · Category: consumer-completeness · Files: policies/retro.yaml, policies/review.yaml

protocol: graphql is introduced for the first time across all 7 policy files — every existing endpoint entry uses protocol: rest. The endpoint-level path field is also novel; all existing path: fields appear under binaries: sections only. Since the consuming proxy lives in another repository (fullsend-ai/fullsend), this repo has no schema, validation test, or documentation confirming:

  • The proxy recognizes protocol: graphql as a valid protocol type
  • The proxy supports endpoint-level path matching
  • The proxy's failure mode for unrecognized values (fail-open vs. fail-closed)

Notably, other agents (triage, prioritize) already successfully use gh commands that invoke GraphQL (e.g., gh pr view --json, gh issue view --json) under policies with only protocol: rest, suggesting the proxy may already pass GraphQL traffic under the rest protocol. If so, these new entries may be declarative (documenting intent) rather than functionally enforcing, and the comment claiming AST-level mutation blocking may overstate what is actually enforced.

Remediation: Confirm the fullsend proxy supports protocol: graphql and endpoint-level path in a released version. Consider adding a policy schema to schemas/ so future structural changes are validated in CI.


2. Documentation omits enforcement mechanism for mutation blocking

Severity: low · Category: incorrect-doc · File: agents/review.md

The updated text states "GraphQL mutations are blocked" without clarifying that enforcement is delegated to the external sandbox proxy. The policy YAML comments reference "AST level" blocking, but nothing in this repository implements or tests it. Future maintainers may not know where to investigate if mutation blocking behavior changes.

Remediation: Consider qualifying with "by the sandbox proxy" to make the trust boundary explicit.


3. Permission expansion — retro agent

Severity: low · Category: permission-expansion · File: policies/retro.yaml

Adding GraphQL access is a permission expansion. The retro agent's sandbox token has issues:write and pull_requests:write scopes. The policy correctly uses access: read-only and enforcement: enforce, and the linked issue authorizes the change. The incremental risk is low because the existing protocol: rest endpoint already enforces access: read-only for the same host — the security posture for write operations is unchanged.


4. Permission expansion — review agent

Severity: low · Category: permission-expansion · File: policies/review.yaml

Same configuration as retro. The review agent's token reportedly lacks write scopes entirely (per the policy header: "No write access to GitHub"), making the mutation-blocking concern lower here than for the retro agent.


Prior review resolution

Prior finding Status
Stale documentation in agents/review.md (medium, docs-currency) ✅ Resolved — new commit updates the GitHub API section to reflect GraphQL capability
Novel protocol: graphql lacks validation (medium, consumer-completeness) ⏳ Carried forward — unchanged code, severity anchored at medium
Permission expansion (low, permission-expansion) ⏳ Carried forward — unchanged code, severity anchored at low
Previous run (11)

Review — comment (bf4dfb1)

Three findings: stale docs in agents/review.md (medium, resolved), novel protocol: graphql lacks validation (medium, carried forward), permission expansion (low, carried forward).

Previous run (12)

Review — comment

Summary

This PR adds protocol: graphql endpoint entries to the retro and review sandbox policies, fixing a documented failure where the gh CLI's POST /graphql requests were blocked by the REST-only, read-only network policies. The change is well-scoped (two files, identical 8-line blocks), uses least-privilege access (read-only, path-scoped to /graphql), and traces to a linked issue (fullsend-ai/fullsend#4934). The YAML structure is valid and insertion point is correct.

Two medium-severity findings and one low-severity finding warrant attention:


Findings

1. Stale documentation in agents/review.md contradicts this policy change

Severity: medium · Category: docs-currency · File: agents/review.md:201–204

Lines 201–204 explicitly state:

The review token only has REST API permissions. Always use gh api REST endpoints to fetch PR and repository data. Do not use gh pr view --json or other --json subcommands — they use the GraphQL API and will fail with HTTP 403.

This PR enables GraphQL in the review agent's sandbox policy but does not update these instructions. This creates two issues:

  • The review agent will not benefit from this change — it reads these instructions and will continue using only REST endpoints, making the review.yaml policy expansion effectively dead configuration.
  • Documentation accuracy — the claim that GraphQL "will fail with HTTP 403" becomes incorrect after this PR merges.

Remediation: Update agents/review.md to reflect the new capability. If GraphQL is now permitted, remove the prohibition and update the examples. If the review agent should continue using REST only and the review.yaml change is future-proofing, document that rationale in the PR description.


2. Novel protocol: graphql and path field values lack in-repo validation

Severity: medium · Category: consumer-completeness · File: policies/retro.yaml, policies/review.yaml

protocol: graphql is introduced for the first time across all 7 policy files — every existing endpoint entry (46 total) uses protocol: rest. The path field on an endpoint entry is also novel; no existing endpoint uses it. Since the consuming proxy lives in another repository (fullsend-ai/fullsend), this repo has no schema definition, validation test, or documentation confirming:

  • The proxy recognizes protocol: graphql as a valid protocol type
  • The proxy implements AST-level mutation blocking as the inline comments claim
  • The proxy supports path-based endpoint matching
  • The proxy's failure mode for unrecognized values (fail-open vs. fail-closed)

The PR author likely has platform context, but the correctness of this change is unverifiable from this repository alone.

Remediation: Confirm the fullsend proxy supports protocol: graphql and path matching in a released version. Consider linking the upstream implementation in the PR description or adding a brief comment referencing it.


3. Permission expansion — properly scoped

Severity: low · Category: permission-expansion · File: policies/retro.yaml, policies/review.yaml

Adding GraphQL access is a permission expansion for two read-only agents. The expansion is justified by the linked issue, uses access: read-only (claimed to block mutations at the AST level), and is path-scoped to /graphql. The retro agent's token carries issues:write and pull_requests:write scopes, but the read-only access level should prevent GraphQL mutations. This is the least-privilege approach for enabling GraphQL queries on these agents.

No immediate action required — noting for the record that this is an intentional, authorized permission expansion.


Labels: PR modifies sandbox policies for retro and review agents to fix a GraphQL access bug

Previous run (13)

Review

Reason: stale-head

The review agent reviewed commit 80b3885da570f9047c71f5101c2c976a4d4dc73e but the PR HEAD is now bf4dfb12b05342b43fa77d84943c6434efb1eaca. This review was discarded to avoid approving unreviewed code.

@fullsend-ai-review

Copy link
Copy Markdown

/fs-review

@fullsend-ai-review

fullsend-ai-review Bot commented Jul 15, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 9:23 AM UTC · Completed 9:33 AM UTC
Commit: bf4dfb1 · View workflow run →

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review fullsend-ai-review Bot added requires-manual-review Review requires human judgment retro-agent review-agent bug Something isn't working labels Jul 15, 2026
@rh-hemartin
rh-hemartin force-pushed the fix/4934-allow-graphql-post-in-sandbox-policies branch from d8d4fad to 855ce38 Compare July 16, 2026 15:04
@fullsend-ai-review

fullsend-ai-review Bot commented Jul 16, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 3:05 PM UTC · Completed 3:15 PM UTC
Commit: 855ce38 · View workflow run →

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review fullsend-ai-review Bot added requires-manual-review Review requires human judgment and removed requires-manual-review Review requires human judgment labels Jul 16, 2026
@rh-hemartin
rh-hemartin force-pushed the fix/4934-allow-graphql-post-in-sandbox-policies branch from 855ce38 to b59276c Compare July 16, 2026 15:21
@fullsend-ai-review

fullsend-ai-review Bot commented Jul 16, 2026

Copy link
Copy Markdown

🤖 Review · ❌ Terminated · Started 3:22 PM UTC · Ended 3:30 PM UTC
Commit: 12bd957 · View workflow run →

@rh-hemartin
rh-hemartin enabled auto-merge July 16, 2026 15:24
@rh-hemartin

Copy link
Copy Markdown
Member Author

@maruiz93 I applied the change to code and fix as well

@fullsend-ai-review fullsend-ai-review Bot added requires-manual-review Review requires human judgment and removed requires-manual-review Review requires human judgment labels Jul 16, 2026
…ndboxes

The gh CLI uses POST /graphql for all operations, including reads.
The github_api policy had access: read-only on a REST endpoint, so
the L7 proxy blocked every POST. Add a separate graphql-protocol
endpoint scoped to /graphql with read-only access, which allows
queries but blocks mutations at the AST level.

Applied to code, fix, retro, and review policies. Prioritize, triage,
and scribe already use read-write access or have no GitHub API entry.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Hector Martinez <hemartin@redhat.com>
@rh-hemartin
rh-hemartin force-pushed the fix/4934-allow-graphql-post-in-sandbox-policies branch from b59276c to 055af2f Compare July 17, 2026 06:28
@fullsend-ai-review

fullsend-ai-review Bot commented Jul 17, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 6:29 AM UTC · Completed 6:35 AM UTC
Commit: 055af2f · View workflow run →

@fullsend-ai-review fullsend-ai-review Bot added requires-manual-review Review requires human judgment and removed requires-manual-review Review requires human judgment labels Jul 17, 2026
@rh-hemartin
rh-hemartin dismissed maruiz93’s stale review July 17, 2026 08:17

Addressed concerns

@rh-hemartin
rh-hemartin disabled auto-merge July 17, 2026 08:18
@rh-hemartin
rh-hemartin enabled auto-merge July 17, 2026 08:19
@rh-hemartin
rh-hemartin added this pull request to the merge queue Jul 17, 2026
Merged via the queue into main with commit def8cb5 Jul 17, 2026
18 checks passed
@rh-hemartin
rh-hemartin deleted the fix/4934-allow-graphql-post-in-sandbox-policies branch July 17, 2026 08:24
@fullsend-ai-retro

fullsend-ai-retro Bot commented Jul 17, 2026

Copy link
Copy Markdown

🤖 Finished Retro · ✅ Success · Started 8:26 AM UTC · Completed 8:34 AM UTC
Commit: 055af2f · View workflow run →

@fullsend-ai-retro

Copy link
Copy Markdown

Retro: PR #173 — allow POST /graphql in agent sandbox policies

Timeline: PR created 2026-07-15 by rh-hemartin to fix fullsend-ai/fullsend#4934. Root cause: the gh CLI uses POST /graphql for reads, but sandbox policies with protocol: rest + access: read-only blocked POST. Agents (retro confirmed) hit L7 denials, then failed fallback attempts (curl, git clone — binaries not in allowlist). The fix adds a protocol: graphql endpoint with access: read-only that uses AST-level query/mutation discrimination.

Key events:

  • Initial scope covered only retro.yaml and review.yaml (2 of 4 read-only agents)
  • waynesun09 approved with detailed technical verification (2026-07-15)
  • maruiz93 requested changes the next day, catching that code.yaml and fix.yaml (also read-only) needed the same fix
  • Author applied the broader change, PR merged 2026-07-17

Review quality: The automated reviews caught real issues — qodo flagged the security concern about a read-write graphql endpoint (resolved by switching to read-only), and fullsend-ai-review identified the protocol: graphql novel value lacking schema validation. However, neither automated reviewer caught the incomplete scope — that was the human catch.

Rework: One iteration of rework, adding ~1 day to the timeline. The 4 files changed in the final PR are identical 8-line blocks; the scope gap was mechanical, not conceptual.

Existing issue overlap: Issue #106 already covers the repeated-findings pattern (the same consumer-completeness finding was re-raised across 13 review cycles on 8 commits). Issue #130 covers distinguishing PR-introduced vs pre-existing findings. No proposal filed for those.

Note on triage/prioritize: These agents lack a protocol: graphql endpoint but have access: read-write on REST, so POST /graphql is not blocked. This is by design — they need read-write for their operations (issue labeling, project board management).

Proposals filed

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Retro agent sandbox cannot access GitHub API — blocks all workflow analysis

3 participants