[RCL-40] rcl review --attest: run-bound Harness credential from the Actions OIDC token - #54
Merged
Conversation
…un-bound Harness credential Inside the organization's gate workflow on GitHub Actions, --attest asks the runner for the job's OIDC token with the Harness origin as audience, exchanges it at POST /api/v1/reviews/attest for the run-bound credential of one pre-minted run id, and records the review under it: envelope, artifacts, model keys and model stats. Fails loudly outside Actions, without HARNESS_API_URL, off a pull request target, with telemetry off or when the exchange is refused; never falls back to another credential, implies --evidence-required, never spools. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…, bounded reads The telemetry level is resolved from the environment and the project config before any token is requested and must be full; the credential is minted again for the same run id before delivery when a long review has used up most of it; the OIDC request does not follow redirects; answers are read up to the limit, a body-read failure retries, and a malformed 2xx names its cause. The README workflow example passes inputs through the environment instead of interpolating them into the command line. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ights read, expiry validated The pre-exchange telemetry check reads the file --config names; the run-bound credential is renewed before the model-stats read as well as delivery; a credential answer must carry a parseable expiry; the attest orchestration moves out of the command handler and no longer mutates its options; the CLI tests never inherit a runner's OIDC variables. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase 3 client side of the Review Council evidence ledger (epic IO-12475, sections 4.1 and 8.5).
What.
rcl review owner/repo#N --attestruns inside the organization's gate workflow on GitHub Actions. Before any key, config or reviewer work it (1) readsACTIONS_ID_TOKEN_REQUEST_URL/_TOKEN(set by the runner only for jobs withid-token: write), (2) requests the job's OIDC token with the Harness origin (HARNESS_API_URL) as audience, (3) exchanges it atPOST /api/v1/reviews/attestwith a pre-minted UUIDv7 run id, and (4) uses the run-bound credential (rbc_…,source: 'attest') for everything that run says to Harness: model keys (GET /model-keys), model stats, the envelope, its artifacts. The run header carries the bound id, so Harness stores the run ascredential_kind: attested.Fails loudly, never falls back. Outside Actions, without
HARNESS_API_URL(TLS only), off a pull request target (a local diff or patch file cannot be attested), with--no-telemetry/RCL_TELEMETRY=off/harness.telemetry: off, or when the exchange is refused, the review does not start and the process exits 1 with the reason (401invalid_attestation, 403attestation_refusedwith a hint per reason, 409run_exists); a 5xx/network failure at the exchange is retried twice, then reported.HARNESS_API_TOKENand the stored login are never used in its place.--attestimplies--evidence-required, and an attested runtime never spools: the credential does not outlive the workflow run, so an unreachable Harness is exit 4 with nothing left in the outbox. The runner token and the OIDC token are redacted from every message.Where.
src/telemetry/attest.ts(new:attestRun,AttestError),src/telemetry/credentials.ts(source: 'attest'),src/telemetry/read-sink.ts+src/config/harness.ts(a credential already in hand replaces resolution; the attestation stands in for.harness-cli/config.json),src/telemetry/deliver.ts(RuntimeOptions.credential,TelemetryRuntime.attested, no spooling),src/index.ts(--attestonreview, validation order, run id, wiring into keys, weights, header and runtime). README (--attestsection with a workflow snippet, env table) and CHANGELOG (Unreleased).Tests.
test/telemetry/attest.test.ts(fake runner + fake Harness: the exchange, audience, headers, every refusal, retries, malformed answers, redaction),test/telemetry/attested-delivery.test.ts(keys, stats, runtime and delivery under the credential; no spool),test/review-cli.test.ts(outside Actions exits 1 with a clear message before any network; local diff and patch refused;--no-telemetrycontradiction).npm run lint && npm test: 57 files, 825 tests green.End to end. Two throwaway Actions runs on this repository (branch
rcl-40-smoke, deleted) ran--attestagainst production with a real OIDC token: the push-triggered run was refused atwrong_event(https://github.com/allocator-one/rcl/actions/runs/34270491743), theworkflow_dispatchrun atworkflow_not_allowed(https://github.com/allocator-one/rcl/actions/runs/34270561865) — each with the server reason and hint,rcl exit=1, no review started. The OIDC leg, audience, exchange and refusal mapping are verified for real; the recorded attested run follows with the allow-listed gate workflow of IO-12484 and the App'sactions: readgrant.Closes RCL-40