Documentation Index
Fetch the complete documentation index at: https://docs.bytebase.com/llms.txt
Use this file to discover all available pages before exploring further.
This guide explains how to configure Workload Identity for GitLab CI/CD to authenticate with Bytebase without storing long-lived credentials.
Step 1: Create a Workload Identity in Bytebase
- Go to IAM & Admin > Users & Groups.
- Click Add User in the upper-right corner.
- Select Workload Identity as the Type.
- Fill in the configuration:
| Field | Description | Example |
|---|
| Name | Display name for this identity | GitLab CI Deploy |
| Email | Unique email prefix (automatically appended with @workload.bytebase.com) | gitlab-ci-deploy |
| Platform | Select GitLab CI | GitLab CI |
| Group / Username | GitLab group or username (required) | my-group |
| Project | Project name (leave empty to allow all projects) | my-project |
| Allowed Branches/Tags | Select branch/tag restrictions | All branches and tags |
| Roles | Assign workspace roles | GitOps Service Agent |
- Click Confirm to create the Workload Identity.
Step 2: Assign Roles
After creating the Workload Identity, assign the GitOps Service Agent role to enable automated CI/CD workflows:
- Go to your project’s Settings > Members.
- Click Grant Access.
- Enter the Workload Identity email (e.g.,
gitlab-ci-deploy@workload.bytebase.com).
- Select the GitOps Service Agent role.
- Click Confirm.
The GitOps Service Agent role is designed for automated CI/CD workflows, allowing the identity to create and execute database changes. See Roles and Permissions for details.
In your GitLab CI/CD pipeline, add the following configuration:
Request OIDC Token
Add id_tokens configuration to get the JWT token from GitLab:
stages:
- deploy
deploy-database:
stage: deploy
image: alpine:latest
id_tokens:
GITLAB_OIDC_TOKEN:
aud: https://gitlab.com
variables:
BYTEBASE_URL: https://bytebase.example.com
WORKLOAD_IDENTITY_EMAIL: gitlab-ci-deploy@workload.bytebase.com
before_script:
- apk add --no-cache curl jq
script:
- |
# Exchange GitLab OIDC token for Bytebase API token
RESPONSE=$(curl -s -X POST "${BYTEBASE_URL}/v1/auth:exchangeToken" \
-H "Content-Type: application/json" \
-d "{\"token\": \"${GITLAB_OIDC_TOKEN}\", \"email\": \"${WORKLOAD_IDENTITY_EMAIL}\"}")
ACCESS_TOKEN=$(echo "$RESPONSE" | jq -r '.accessToken')
if [ "$ACCESS_TOKEN" = "null" ] || [ -z "$ACCESS_TOKEN" ]; then
echo "Failed to get access token"
echo "$RESPONSE"
exit 1
fi
# Verify the token by calling the user info API
USER_INFO=$(curl -s "${BYTEBASE_URL}/v1/users/me" \
-H "Authorization: Bearer $ACCESS_TOKEN")
echo "Authenticated as: $USER_INFO"
rules:
- if: $CI_COMMIT_BRANCH == "main"
Complete Example
Here’s a complete GitOps workflow that uses Workload Identity to deploy database migrations:
# .gitlab-ci.yml
stages:
- review
- deploy
variables:
BYTEBASE_URL: https://bytebase.example.com
WORKLOAD_IDENTITY_EMAIL: gitlab-deploy@workload.bytebase.com
# SQL Review on merge requests
sql-review:
stage: review
image: bytebase/sql-review-action:latest
id_tokens:
GITLAB_OIDC_TOKEN:
aud: https://gitlab.com
script:
- |
# Exchange OIDC token for Bytebase token
export BYTEBASE_TOKEN=$(curl -s -X POST "${BYTEBASE_URL}/v1/auth:exchangeToken" \
-H "Content-Type: application/json" \
-d "{\"token\": \"${GITLAB_OIDC_TOKEN}\", \"email\": \"${WORKLOAD_IDENTITY_EMAIL}\"}" \
| jq -r '.accessToken')
# Run SQL review
sql-review --url ${BYTEBASE_URL} --token ${BYTEBASE_TOKEN} \
--file-pattern "migrations/**/*.sql"
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
changes:
- migrations/**
# Deploy on merge to main
rollout:
stage: deploy
image: bytebase/bytebase-action:latest
id_tokens:
GITLAB_OIDC_TOKEN:
aud: https://gitlab.com
script:
- |
# Exchange OIDC token for Bytebase token
export BYTEBASE_TOKEN=$(curl -s -X POST "${BYTEBASE_URL}/v1/auth:exchangeToken" \
-H "Content-Type: application/json" \
-d "{\"token\": \"${GITLAB_OIDC_TOKEN}\", \"email\": \"${WORKLOAD_IDENTITY_EMAIL}\"}" \
| jq -r '.accessToken')
# Create release and rollout
bytebase-action rollout \
--url ${BYTEBASE_URL} \
--token ${BYTEBASE_TOKEN} \
--file-pattern "migrations/**/*.sql" \
--project projects/my-project \
--targets instances/prod/databases/mydb
rules:
- if: $CI_COMMIT_BRANCH == "main"
changes:
- migrations/**
Self-Hosted GitLab
For self-hosted GitLab instances, update the audience (aud) to match your GitLab instance URL:
id_tokens:
GITLAB_OIDC_TOKEN:
aud: https://gitlab.your-company.com
When creating the Workload Identity in Bytebase, ensure the configuration matches your self-hosted GitLab instance.
Troubleshooting
Token Exchange Fails
If the token exchange returns an error:
-
Verify the project path and branch: Check that your pipeline’s project path and branch match the configured values in Bytebase.
-
Check the audience: Ensure the
aud in your id_tokens configuration matches your GitLab instance URL (e.g., https://gitlab.com for GitLab.com).
-
Verify OIDC is enabled: GitLab CI/CD OIDC tokens require GitLab 15.7 or later.
Permission Denied
If API calls return permission errors:
- Verify the Workload Identity has the
GitOps Service Agent role assigned.
- Check that the Workload Identity is a member of the target project.
Debug Token Claims
To inspect the OIDC token claims, decode the JWT:
script:
- |
echo "$GITLAB_OIDC_TOKEN" | cut -d. -f2 | base64 -d | jq .
This shows the token’s claims including sub, aud, namespace_path, project_path, and ref that Bytebase validates.