Skip to content

test(automation): make OpenCode App token exchange executable and transport-testable #1549

Open

Description

@seonghobae

Gap

PR #1545 currently protects the scheduled organization coordinator's OIDC → short-lived OpenCode App token exchange with static workflow-source assertions. Those checks detect missing permissions, endpoint, timeout, masking, and fallback strings, but cannot execute malformed-response and shell-control-flow branches without a real GitHub job OIDC identity.

Required implementation

Extract the exchange from inline workflow shell into a trusted default-branch helper owned by .github, while keeping the workflow as the sole caller and preserving the current trust boundary.

The helper must:

  • accept the job-provided OIDC request URL/token, fixed audience, and fixed OpenCode exchange base URL through explicit inputs;
  • append audience= using ? or & correctly when the GitHub request URL already has a query;
  • use bounded connect and total timeouts for both requests;
  • require a non-empty JSON string at .value and .token respectively;
  • emit the maintainer token only through a masked GitHub output/environment channel;
  • never accept repository GITHUB_TOKEN, reviewer credentials, model-provider keys, or COPILOT_GITHUB_TOKEN as fallback;
  • redact response bodies, authorization values, URLs with sensitive query values, and tokens from errors;
  • fail nonzero for missing environment, transport failure, HTTP error, malformed JSON, empty/wrong-typed fields, and truncated responses;
  • remain callable only from the protected-default-branch scheduled coordinator contract.

Tests

Use a local fake HTTP server or injected transport to prove:

  1. OIDC request URL with no query;
  2. OIDC request URL with an existing query;
  3. connection failure and timeout on both calls;
  4. non-2xx responses;
  5. malformed, empty, wrong-typed, and oversized/truncated JSON;
  6. exact mask/output ordering;
  7. no secret value appears in stdout, stderr, exceptions, or pytest output;
  8. no repository-token fallback;
  9. workflow-to-helper argument and permission contract;
  10. current scheduled default-branch acceptance after merge.

Production statement and branch coverage, public docstrings, warning-free Python 3.14 execution, compileall, security scanning, and exact-head independent review remain mandatory.

Scope

This is a focused testability refactor, not a new authentication model. Preserve #1545's PR_REVIEW_MERGE_TOKEN preference, OIDC/App fallback, egress allowlist, and fail-closed runtime behavior. Update docs/doctoring/organization-commercial-readiness-loop.md, docs/product-technical-gap-baseline.md, and CHANGELOG.md.

Activity

  1. added
    area: ci-cdCI, GitHub Actions, checks, release, or supply chain
    area: securitySecurity boundary, hardening, or vulnerability prevention
    enhancementNew feature or request
    status: triagedOpen issue has an organization taxonomy assignment
    on Sep 2, 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: ci-cdCI, GitHub Actions, checks, release, or supply chainarea: securitySecurity boundary, hardening, or vulnerability preventionenhancementNew feature or requestpriority: highHigh-priority or P1 workstatus: triagedOpen issue has an organization taxonomy assignment

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions