Off by default
CI workload identity is implemented and tested but switched off in every deployment until the DataNivra operator enables it (DATANIVRA_WORKLOAD_IDENTITY_ENABLED). While it is off, POST /v1/auth/workload/token answers 404 WORKLOAD_IDENTITY_DISABLED and no workload session is accepted. The token issuers a deployment accepts are an operator allow-list (by default https://token.actions.githubusercontent.com and https://gitlab.com).
What a workload session can do
A workload session holds a fixed, minimal permission set, whatever roles its service user has:
test_data.request— list the profiles that name it, plan, request, read and release its own test-data requests;dataset.readandjob.read— read metadata (never rows).
It cannot create raw dataset requests or leases, provision, revoke, approve anything, author or approve profiles, manage users or change settings. It is short (60–900 seconds, 600 by default) and cannot be refreshed: the job exchanges a fresh CI token when it needs one. Each trust owns a non-interactive service user that no human sign-in flow accepts.
Trust one repository (tenant administrators)
datanivra workload-identities create --name "claims CI" --provider GITHUB_ACTIONS \
--repository acme/claims-service --audience datanivra:acme \
--ref refs/heads/main --ref 'refs/pull/*'| Option | Claim checked | Notes |
|---|---|---|
--provider | issuer | GITHUB_ACTIONS or GITLAB_CI; --issuer names a self-managed GitLab that the operator allow-listed |
--audience | aud | configure the same value in the pipeline |
--repository | GitHub repository / GitLab project_path | required, compared case-insensitively |
--ref (repeatable) | ref | exact, or a trailing *; GitLab branch and tag names are normalised to refs/heads/… and refs/tags/… |
--environment (repeatable) | environment | deployment environment of the job |
--event (repeatable) | GitHub event_name / GitLab pipeline_source | pull_request_target is never accepted: it runs fork code with the base repository's credentials |
--protected-refs-only | GitLab ref_protected | require a protected branch or tag |
--token-ttl | — | workload session lifetime, 1m–15m |
A trust grants nothing on its own: a profile's automation envelope must name it before any of its requests can be considered, and requests outside every envelope are denied.
In the pipeline
GitHub Actions — grant permissions: id-token: write, then:
datanivra login --workload-identity "$DATANIVRA_WORKLOAD_IDENTITY_ID" --tenant acme --audience datanivra:acmeGitLab CI — declare the token and let the CLI read it from DATANIVRA_ID_TOKEN:
id_tokens:
DATANIVRA_ID_TOKEN:
aud: datanivra:acmeAny other system can pass the token on standard input: datanivra login --workload-identity <ID> --tenant acme --id-token-stdin. Full pipelines are in CI recipes.
What the exchange checks
The issuer must be allow-listed and equal the trust's issuer; the signature must verify against the issuer's published keys with an asymmetric algorithm; aud, expiry, not-before and issued-at are checked, and the token must be at most 10 minutes old; every token is accepted once (a replay is refused). The repository, ref, environment, event and protected-ref conditions must all hold. Every refusal is a generic 401 INVALID_CREDENTIALS; the specific reason (for example WORKLOAD_REPOSITORY_MISMATCH, WORKLOAD_TOKEN_REPLAYED) is recorded, value-free, in your audit trail as auth.workload.denied.
Emergency disable
datanivra workload-identities disable <ID> --reason-code CREDENTIAL_COMPROMISEDisabling is final. Every outstanding session of that trust is refused on its next request — there is no waiting for expiry — and new exchanges are refused. Create a new trust to start again. POST /v1/auth/logout with a workload session revokes that session immediately.