GitLab CI
This setup guide is for making self-hosted GitLab CI job tokens verifiable outside your network. You point GitLab at your oidc.pub URL as the issuer, then publish its discovery document and JWKS through oidc.pub so cloud providers can validate those tokens.
GitLab CI/CD OIDC ID tokens documentation
Prerequisites
- A self-hosted GitLab instance (15.7+ for OIDC token support)
- An oidc.pub service (e.g.
gitlab.oidc.pub) - Admin access to your GitLab instance
Step 1: Update GitLab's OIDC issuer URL
Configure GitLab to use your oidc.pub subdomain as the OIDC issuer. This ensures that CI job tokens carry the correct iss claim.
# /etc/gitlab/gitlab.rb
gitlab_rails['ci_id_tokens_issuer_url'] = 'https://gitlab.oidc.pub'# /etc/gitlab/gitlab.rb
gitlab_rails['ci_id_tokens_issuer_url'] = 'https://gitlab.oidc.pub'Run sudo gitlab-ctl reconfigure after making this change. This setting tells GitLab to use your oidc.pub URL as the OIDC issuer for CI job ID tokens.
GitLab: Configure OIDC for cloud services
Step 2: Sync OIDC config to oidc.pub
Fetch the OIDC discovery document and JWKS from your GitLab instance and upload them to oidc.pub. You can do this manually or use the sync worker to keep it updated automatically.
Use a scheduled GitLab CI pipeline to run the sync worker in one-shot mode. Store OIDCPUB_API_KEY and SERVICE_SUBDOMAIN as CI/CD variables.
# .gitlab-ci.yml
sync-oidc-config:
image: registry.gitlab.com/oidc.pub/cli:latest
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
variables:
OIDC_SOURCE_URL: https://gitlab.internal
OIDCPUB_SERVICE_ID: $SERVICE_SUBDOMAIN
OIDCPUB_API_KEY: $OIDCPUB_API_KEY
script:
- oidcpub service sync# .gitlab-ci.yml
sync-oidc-config:
image: registry.gitlab.com/oidc.pub/cli:latest
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
variables:
OIDC_SOURCE_URL: https://gitlab.internal
OIDCPUB_SERVICE_ID: $SERVICE_SUBDOMAIN
OIDCPUB_API_KEY: $OIDCPUB_API_KEY
script:
- oidcpub service syncSet up a pipeline schedule (e.g. hourly) in GitLab under CI/CD → Schedules to run this job automatically.
# Fetch from GitLab
OIDC_CONFIG=$(curl -s https://gitlab.internal/.well-known/openid-configuration)
JWKS=$(curl -s https://gitlab.internal/oauth/discovery/keys)
# Upload to oidc.pub
curl -X PUT https://oidc.pub/api/services/$SERVICE_SUBDOMAIN/config \
-H "Authorization: Bearer $OIDCPUB_API_KEY" \
-H "Content-Type: application/json" \
-d "$(jq -n \
--argjson oidc "$OIDC_CONFIG" \
--argjson jwks "$JWKS" \
'{ openidConfiguration: $oidc, jwks: $jwks }'
)"
# SERVICE_SUBDOMAIN is the preferred public reference. Service IDs remain
# accepted for compatibility.# Fetch from GitLab
OIDC_CONFIG=$(curl -s https://gitlab.internal/.well-known/openid-configuration)
JWKS=$(curl -s https://gitlab.internal/oauth/discovery/keys)
# Upload to oidc.pub
curl -X PUT https://oidc.pub/api/services/$SERVICE_SUBDOMAIN/config \
-H "Authorization: Bearer $OIDCPUB_API_KEY" \
-H "Content-Type: application/json" \
-d "$(jq -n \
--argjson oidc "$OIDC_CONFIG" \
--argjson jwks "$JWKS" \
'{ openidConfiguration: $oidc, jwks: $jwks }'
)"
# SERVICE_SUBDOMAIN is the preferred public reference. Service IDs remain
# accepted for compatibility.Step 3: Verify
Within 60 seconds, your OIDC discovery endpoint is publicly reachable.
curl https://gitlab.oidc.pub/.well-known/openid-configuration | jq .curl https://gitlab.oidc.pub/.well-known/openid-configuration | jq .curl https://gitlab.oidc.pub/.well-known/jwks.json | jq .curl https://gitlab.oidc.pub/.well-known/jwks.json | jq .Next steps
- Sync Worker — configuration reference, authentication options, and one-shot mode
- Key Rotation — how OIDC providers rotate signing keys and what it means for your sync interval
- Check out one of the integration guides, for example the AWS Integration Guide — a concrete relying-party setup for identity published through oidc.pub