gha-github-service-proof is the GitHub Actions service/API compatibility oracle for offline CI. It classifies REST calls, gh CLI invocations, OIDC token issuance, and captured gh-log bundles as exact, simulated, or unsupported, and validates that the workflow's resolved permissions match what GitHub itself would require.
It is part of Wildmason's offline GitHub Actions proof-tool lane:
gha-workflow-proofvalidates workflow YAML structure.gha-eventsmithgenerates event/context fixtures.gha-expression-proofevaluates${{ … }}expressions.gha-cache-proofmodelsactions/cache.gha-artifact-proofmodelsactions/upload-artifactandactions/download-artifact.gha-service-proofmodels service-container networking and readiness.gha-command-proofvalidates runtime command/env-file behavior.gha-github-service-proofclassifies the GitHub API side-effect surface (this crate).
- A curated REST endpoint catalog for CI-relevant operations: repos/contents, releases/assets, issues/comments/labels, pull requests, checks, statuses, actions metadata, deployments, packages, rate-limit, user, and app-installation probes.
- Permission validation against the catalog: parses
permissions:blocks (workflow and job, including theread-all/write-allshortcuts), resolves the effective set, and checks sufficiency for each detected call. - Workflow scanning for
ghCLI usage,curl https://api.github.com/...calls,actions/github-script,softprops/action-gh-release/ncipollo/release-action, and OIDC-consuming actions (aws-actions/configure-aws-credentials,google-github-actions/auth,azure/login). - OIDC issuance: validates
id-token: writeis granted, emits a deterministic stub HS256 JWT with full GitHub-shape claims, and tags the receipt withsigning_mode: stub-localplus an explicit "not trusted by cloud providers" warning. gh-logreplay: a stable canonical JSON schema (v1) with redaction-by-contract; bundles whoseauthorizationheader is not<redacted>fail unless--unsafe-full-payloadsis set.- Classification boundary: any call outside the curated catalog returns
unsupported: rest.endpoint_not_in_catalog. The/graphqlendpoint returnsunsupported: graphql.classification_not_implementedin v1.0; operation-level GraphQL parsing is intentionally deferred to a later release.
cargo install gha-github-service-proof --version 1.0.0 --lockedScan workflow YAML for GitHub API usage and validate permissions per step:
gha-github-service-proof check-workflow `
--repo . `
--workflow .github/workflows/release.yml `
--format json `
--output target/github-service-proof.jsonWhen --workflow is omitted, the command scans every .yml / .yaml under .github/workflows.
Resolve the effective permissions: block for a workflow or a specific job:
gha-github-service-proof permissions `
--workflow .github/workflows/release.yml `
--job publish `
--format markdownClassify a single API call against the catalog and a granted permission set:
gha-github-service-proof call `
--method POST `
--path /repos/wildmason/mortar/releases `
--permissions '{"contents":"write"}' `
--format jsonPass --permissions-file for a JSON file instead of inline. Off-catalog calls return classification: unsupported with unsupported_reason: rest.endpoint_not_in_catalog.
Validate OIDC requirements and emit a deterministic local stub JWT:
gha-github-service-proof oidc `
--audience sts.amazonaws.com `
--repository wildmason/mortar `
--ref refs/heads/main `
--sha deadbeef `
--workflow release.yml `
--job deploy `
--run-id 1234567890 `
--permissions '{"id-token":"write"}' `
--format jsonThe token is signed with HS256 using a documented constant secret (gha-github-service-proof:stub-local:v1). It is not trusted by GitHub or any cloud provider. The receipt includes the full claim set, the issued token, signing_mode: stub-local, and an explicit warning.
Replay a captured canonical-JSON bundle of API calls:
gha-github-service-proof gh-log `
--log captured/calls.json `
--permissions '{"contents":"write","issues":"write"}' `
--format jsonSee docs/gh-log-schema.md for the canonical v1 schema. By contract, the authorization request header must be the literal <redacted>; bundles that contain unredacted authorization headers fail unless --unsafe-full-payloads is set.
exact— ci-forge can serve a deterministic stub whose observable output matches GitHub's. Used for read-only metadata endpoints (/rate_limit,/user,/meta, installation lookups).simulated— ci-forge serves a stub that is plausible but local-only. Used for every state-mutating endpoint in the catalog and most read endpoints whose responses depend on shared GitHub state.unsupported— ci-forge cannot meaningfully serve the call. Off-catalog endpoints returnunsupported: rest.endpoint_not_in_catalog;/graphqlreturnsunsupported: graphql.classification_not_implemented.
- uses: wildmason/gha-github-service-proof@v1
with:
command: check-workflow
repo: .
workflow: .github/workflows/release.yml
format: json
output: target/github-service-proof.jsonThe action installs the crate with Cargo unless gha-github-service-proof is already on PATH.
The command exits nonzero when any check fails. With --strict, warnings also fail the command. Receipts are valid in all three formats regardless of exit status.
Receipts are available as text, json, or markdown. JSON receipts are intended for local runners and CI systems that attach API-surface evidence to a larger workflow-run provenance record. The receipt schema is stable; new fields are additive and schema_version advances on breaking changes.