Skip to content

OpenCode: expose cross-repository review failure when App status publication is forbidden #691

Description

@seonghobae

Problem

Central OpenCode repository_dispatch can fail closed without leaving any exact-head evidence on the target pull request when the exchanged OpenCode App token can write reviews but cannot write commit statuses.

Current-head evidence:

  • Target: fix(security,api): opaque prompt IDs and CardDAV single-decode naruon#1206 at 0ce9d0c215bd7b341a129e362ca05cc94cdbfbe6
  • Central run: https://github.com/ContextualWisdomLab/.github/actions/runs/30677743465
  • Coverage evidence: success
  • Model pool: exhausted after the bounded 30-attempt ceiling; all outputs were provider failures or failed trusted control-receipt validation
  • Review outcome correctly failed closed with MODEL_OUTPUT_UNAVAILABLE and no formal review
  • Commit-status publication then used the OpenCode App token and failed with HTTP 403 Resource not accessible by integration
  • The model-unavailable code-scanning fallback used the central github.token against the cross-repository target and likewise received HTTP 403
  • Result: naruon#1206 has no opencode-review status/comment for this run; only the central log exposes the review-tool failure

Governance classification

High-sensitivity review-governance observability and token-capability defect. It is not a source vulnerability and must not turn provider unavailability into a false clean review.

Acceptance criteria

  • Do not select the OpenCode App token for commit-status publication unless its status capability is proven.
  • When cross-repository commit-status publication is unavailable or returns 403, expose a bounded exact-head review-tool failure on the target PR using an App-authorized PR comment/update path.
  • Keep formal APPROVE/REQUEST_CHANGES authorship restricted to the OpenCode App and keep model-unavailable outcomes fail closed.
  • Do not let a secondary status-publication 403 obscure the primary model/receipt outcome in logs.
  • Detect that central github.token cannot read another repository code-scanning alerts and emit a precise bounded reason instead of a generic lookup failure.
  • Add contract/unit tests for App-token 403, cross-repository github.token limitations, exact head/run receipt, and stale-head refusal.
  • Document the optional GitHub App permissions or organization credential needed for commit statuses and code-scanning reads.

Related

Activity

  1. moved this from Todo to In Progress in naruon Platform Roadmapon Aug 1, 2026
  2. seonghobae commented on Aug 1, 2026

    @seonghobae
    ContributorAuthor

    Additional live current-head evidence from ContextualWisdomLab/html4tree#171 (ed928b2fb1bd49c7cdaed766ab53a8eaf669db1d): target scheduler run 30682516364 attempt 2 exchanged the OpenCode App mutation token successfully, observed completed same-head Strix and all green checks, but returned WAIT because SCHEDULER_ALLOW_CROSS_REPO_REPOSITORY_DISPATCH=false. The workflow only sets that flag when PR_REVIEW_MERGE_TOKEN or OPENCODE_APPROVE_TOKEN exists; the App token is intentionally excluded because its installation has no Actions permission. The existing Required OpenCode Review check is green but no current-head formal approval exists, so the 2-review ruleset remains correctly fail-closed. A personal manual central dispatch was separately rejected by the sender/actor identity guard, as intended. PR #692 can make the failure visible, but the remaining governance action is capability configuration: grant a bounded dispatch-capable App/PAT credential to the scheduler path without weakening the sender identity or current-head review gates.

  3. seonghobae commented on Aug 1, 2026

    @seonghobae
    ContributorAuthor

    Additional same-repository current-head evidence from .github#690 (01ae5398b64bd91aadcc43d465b09c2d5dc864d5): manual central OpenCode run 30680399774 attempt 2 completed after the model catalog was exhausted. Coverage evidence passed, the publish gate correctly emitted MODEL_OUTPUT_UNAVAILABLE, found zero reusable exact-head real-model approvals, and left formal review state unchanged. The optional opencode-review commit-status publication then selected the OpenCode App token and failed with Resource not accessible by integration (HTTP 403) even though the target is the same .github repository. This confirms the capability defect is specifically missing commit-status permission/capability on the App token, not only cross-repository github.token isolation. The source PR checks remain green; REVIEW_REQUIRED is the correct fail-closed state. This run should be a contract fixture for preserving the primary model outcome while exposing the secondary status-publication failure through an App-authorized PR surface.

  4. seonghobae commented on Aug 1, 2026

    @seonghobae
    ContributorAuthor

    Live organization capability audit (2026-08-01): organization Actions secrets contain neither PR_REVIEW_MERGE_TOKEN nor OPENCODE_APPROVE_TOKEN, which explains SCHEDULER_ALLOW_CROSS_REPO_REPOSITORY_DISPATCH=false in target scheduler runs. The installed opencode-agent App currently has pull_requests:write, but its installation permission map has no actions, checks, statuses, or security_events; this directly explains repository-dispatch unavailability, commit-status HTTP 403, and inability to use the App for current-head check/code-scanning evidence. The installed cwl-noema-review App does have pull_requests:write plus actions/checks/contents/security_events/statuses/vulnerability_alerts:read, and live naruon#1180 logs show it mints successfully but correctly skips until a primary current-head OpenCode approval exists. Thus the 2-reviewer queue is blocked at the primary reviewer capability/dispatch layer, not at Noema credential minting. No secret values were read or exposed. App/IAM permissions were not mutated by this audit.

  5. seonghobae commented on Aug 1, 2026

    @seonghobae
    ContributorAuthor

    Current-head Strix provider evidence across the central queue (2026-08-01): .github#668 head ad8322e96a583c81e11058d98310ce947643fb89, run 30688798919; .github#697 head 64df78ca2480d8bdd836e086af1d975532e13599, run 30688615882; and .github#696 head 27226f63a9f8ac35d566047d961e7175ee969562, run 30689131611. All three logs show NVIDIA NIM 429 Too Many Requests or ResourceExhausted, followed by GitHub Models 410 github_models_retirement_brownout. Each then states that no Strix vulnerability report artifact was produced and that zero vulnerabilities before provider infrastructure failure is not clean scan evidence. The final workflow wrapper nevertheless emits a backend-unavailable warning and neutral-skip behavior, so the green check conclusion must not be interpreted as a completed vulnerability scan. This is provider/capability evidence, not a source vulnerability finding; merge governance should continue to distinguish it from real scan approval.

  6. added
    area: apiAPI, protocol, event, or external contract
    area: authAuthentication, authorization, identity, or tenant isolation
    area: ci-cdCI, GitHub Actions, checks, release, or supply chain
    area: securitySecurity boundary, hardening, or vulnerability prevention
    status: triagedOpen issue has an organization taxonomy assignment
    type: featureNew or expanded product capability
    on Aug 22, 2026
  7. seonghobae commented on Aug 28, 2026

    @seonghobae
    ContributorAuthor

    Fresh same-repository Strix publication-capability evidence from the canonical dependency-review repair owner; no foreign source/ref/settings mutation from the Inkspan loop.

    Target: ContextualWisdomLab/.github#897@ec4e2af7d376e4689ab2a0f3421c2bfe383fa2be, independently resolved protected base main@cdde0d82602d9568128fd0c1e985ea40b2292710.

    Repository-dispatch Strix run 33154039624 correctly failed its primary scan in job 98792623413 (STRIX_PROVIDER_UNAVAILABLE). The follow-up job 98794476644 then attempted to publish the exact-head strix failure status to the same .github repository. OIDC/App-token exchange completed and yielded TARGET_APP_STATUS_TOKEN; the target SHA was the exact PR head above. Status publication nevertheless returned Resource not accessible by integration (HTTP 403). No PR_REVIEW_MERGE_STATUS_TOKEN or OPENCODE_APPROVE_STATUS_TOKEN was available, and because STRIX_RESULT=failure there was no legitimate pre-existing success status to reuse. The follow-up job therefore failed closed rather than manufacturing evidence.

    This revalidates the first causal boundary already identified by #691: the exchanged App credential still lacks usable commit-status capability even for a same-repository target. It now affects Strix manual evidence publication in addition to the OpenCode paths captured by the original issue. The provider outage and the status-capability defect are distinct propositions: repairing provider routing can make the scan itself authoritative, but a non-success scan still needs a bounded exact-head failure surface without a secondary 403 obscuring or dropping the target evidence.

    Smallest remedies remain central and capability-scoped: (1) grant the App the minimum commit-status permission required by the existing design, or (2) supply an approved bounded status credential through the already-supported path, or (3) where status mutation is intentionally unavailable, use an App-authorized PR comment/check surface that preserves exact target SHA/run/result and cannot be mistaken for formal approval. Do not make failed scans green, do not reuse predecessor status, and do not add a leaf-repository workaround.

    RED acceptance fixture: run 33154039624, follow-up job 98794476644, exact target head ec4e2af7d376e4689ab2a0f3421c2bfe383fa2be, same-repository status POST → HTTP 403. GREEN acceptance: rerun an unchanged/current exact target head, preserve the primary Strix outcome, and successfully expose that same-head outcome on the target through an authorized bounded surface; stale/status-only/model-only evidence remains non-passing.

  8. added
    bugSomething isn't working
    type: bugDefect or incorrect behavior
    enhancementNew feature or request
    on Sep 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: apiAPI, protocol, event, or external contractarea: authAuthentication, authorization, identity, or tenant isolationarea: ci-cdCI, GitHub Actions, checks, release, or supply chainarea: securitySecurity boundary, hardening, or vulnerability preventionenhancementNew feature or requestpriority: mediumNormal-priority or P2 workstatus: triagedOpen issue has an organization taxonomy assignmenttype: bugDefect or incorrect behaviortype: featureNew or expanded product capability

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions