Skip to content

Per-Run Pipeline Credentials

Overview

Each pipeline run checks out a Britive with its CI platform’s OIDC token. The creates a service account for that run in the target namespace, binds it to a fixed role, and returns a token that lives as long as the session. At the broker deletes the service account, which invalidates the token. No OpenShift token is stored in the CI system, and no pipeline holds standing cluster access between runs.

What this pattern gives you:

  • One identity per repository and environment, proven by the CI platform’s OIDC token, not by a stored secret
  • A credential per run: a new service account, bound to one role in one namespace, deleted at check-in
  • Environment isolation enforced by Britive policy: the dev pipeline cannot check out a prod namespace
  • An inventory of the standing access that remains in each namespace, from Resource Manager scans

How It Works

    sequenceDiagram
    participant GH as Pipeline job (self-hosted runner)
    participant BR as Britive
    participant BK as Access Broker
    participant OC as OpenShift API (private)

    GH->>BR: pybritive checkout with the job's OIDC token
    BR->>BR: Match token sub to a service identity, apply its profile policy
    BR->>BK: Checkout request (namespace, cluster, transaction ID, duration)
    BK->>OC: Create ServiceAccount gha-<txn> + RoleBinding, request token
    OC-->>BK: Bound token (session lifetime)
    BK-->>BR: server, token, namespace, CA, expiry
    BR-->>GH: Checkout response
    GH->>OC: oc login --token, run the job
    GH->>BR: pybritive checkin (always runs)
    BR->>BK: Check-in request
    BK->>OC: Delete ServiceAccount and RoleBinding (token invalid)
  

The building blocks:

ComponentRole
OIDC identity provider and service identitiesOne per repository and environment, matched on the token’s sub claim
Resource type aro-namespaceA namespace as a Resource Manager resource: fields cluster_name, api_url, namespace; checkout and check-in scripts; a scan script
Resources and labelsOne resource per namespace, labeled owner, env, cluster and britive-managed
Profile and policiesOne deployer profile for all pipelines; one policy per service identity, scoped by labels to its own namespaces
Access BrokerRuns in the cluster or next to it, in a ; holds the only standing credential, a kubeconfig whose role can create service accounts and bind exactly one ClusterRole
PipelineChecks out at the start, checks in at the end (also on failure or cancellation)

What It Removes and What Remains

RemovedRemains
OpenShift tokens stored as CI secretsThe broker’s kubeconfig, scoped by RBAC: it can create service accounts and RoleBindings in opted-in namespaces and bind only the pipeline ClusterRole (resourceNames)
Shared service accounts reused across runsThe namespace’s built-in service accounts and bindings, which the standing-access scan reports
Broad, long-lived pipeline permissions—

Observed Behavior

Measured on Azure Red Hat OpenShift 4.21 with Access Broker 3.1:

BehaviorResult
Checkout timeAbout 5 seconds from pybritive checkout to a usable token
Token after check-inRejected within 10 seconds. The service account is deleted at check-in; the API server caches successful token authentications for about 10 seconds
Cancelled jobCheck-in still runs (if: always()); nothing is left behind
Cross-environment requestDenied: the dev identity cannot see the prod resource

Design Choices

  • Identity per repository and environment. CI deployment environments (for example GitHub environments) appear in the OIDC token; job-level variables do not. Map one service identity to each repository and environment pair.
  • Inputs only from Britive. The checkout script receives the namespace, cluster, transaction ID and duration from Britive, never from the pipeline, so a pipeline cannot ask for a namespace its policy does not cover.
  • One role for pipelines. The broker can bind a single ClusterRole. Changing what pipelines may do means changing that ClusterRole, the broker’s bind rule and the permission variable together.
  • Private APIs. Runners and the broker reach the API over private networking; Britive reaches the broker through its outbound connection.

Next Steps

Last updated on