Skip to content
CommonLayer
Documentation menu
On this page

ADR-0024: A workload principal for GitHub Actions OIDC submissions

Status: Accepted (WP-01, WP-11). Implemented and wired: OIDC bearers on the submission routes become workload actors (WP-40, crates/commonlayer-app/src/workload.rs) (amended 2026-11-10).

Context

Project CI submits built digests for verification. Giving CI a long-lived API token creates a secret that can leak. GitHub Actions can mint short-lived OIDC tokens that name the repository, ref and workflow.

Decision

  • A new principal Principal::Workload represents a verified GitHub Actions identity. It holds only project.artifacts.submit on the project whose verified repository matches the token's repository_id, and is audited as system with the label github-actions:<repo>@<ref>.
  • crates/commonlayer-github/src/adapters/oidc.rs (ActionsOidcVerifier) verifies the token against GitHub's JWKS (RS256 only, issuer, audience commonlayer by default, expiry with leeway, one forced JWKS refresh per unknown key id at most every 30 s).
  • The workload may read the submissions of its project (GET /api/v1/submissions/{id}), so CI can poll for the verdict with the same identity it submitted with.

Consequences

  • No long-lived secret is needed in project CI; scripts/register.sh in the template uses the OIDC token unless CL_API_TOKEN is set.
  • A stolen OIDC token is valid only for minutes and only for submissions of one project, and a submission still has to pass the whole verification policy.
  • The authentication middleware leaves non-clt_ bearers anonymous; the composition must turn a valid OIDC bearer into the workload actor on the submission routes. Until that wiring lands, CI can submit only with an API token.

Amendment, 2026-11-10

  • The composition turns a verified OIDC bearer into the workload actor on POST /api/v1/projects/{slug}/submissions and GET /api/v1/submissions/{id} (WP-40); the acceptance test workflow_a_onboarding submits over HTTP with an OIDC bearer (verified by the test kit's verifier; the real verifier has unit tests against locally generated keys).
  • Since the security review (MEDIUM-5) the repository's numeric GitHub id is checked against GitHub at verification, and the Actions login also requires the token's owner/name to equal the verified link's. Links verified before migration 0016 are not re-checked.
  • Since MEDIUM-3 the per-project submission bucket counts only actors allowed to submit, keyed by the resolved project; other attempts count per principal.
  • No real GitHub Actions OIDC token has been verified by a deployed platform yet.