Configuring Workload Identity Federation with OIDC
This guide shows you how to set up workload identity federation in Thalassa Cloud. This lets CI/CD pipelines and other systems use OIDC tokens instead of storing long-lived credentials.
Prerequisites
Before you start, you need:
- Access to your Thalassa Cloud organisation
- A service account with IAM roles
- An OIDC provider (GitHub Actions, GitLab CI, Google Cloud, or Azure AD)
- The OIDC provider’s issuer URL
- Understanding of token claims structure
- Permissions to create identity providers and federated identities
How Workload Identity Federation Works
Workload identity federation lets external systems use OIDC tokens to authenticate with Thalassa Cloud. Setup has two steps:
- Create an identity provider. This defines the OIDC issuer and how to find signing keys (JWKS).
- Create a federated identity. This links the provider to a service account with rules to match tokens.
Step 1: Create an Identity Provider
Step 1: Navigate to Identity Providers
- Log into your Thalassa Cloud Console
- Navigate to IAM → Identity Providers
- Click “Create Identity Provider” or “Add Identity Provider”
Step 2: Configure Basic Information
Enter a name for your identity provider. Use names like github-actions, gitlab-ci, or google-cloud. Add a description explaining what it’s used for.
Step 3: Configure OIDC Settings
Enter your OIDC provider’s issuer URL. Common URLs:
- GitHub Actions:
https://token.actions.githubusercontent.com - GitLab:
https://gitlab.com(or your GitLab instance URL) - Google Cloud:
https://accounts.google.com - Azure AD:
https://login.microsoftonline.com/{tenant-id}/v2.0
For other providers, use the issuer URL from your provider’s documentation.
Step 4: Configure JWKS Discovery
Most OIDC providers support automatic discovery. Leave the JWKS endpoint blank. Thalassa Cloud finds the JWKS endpoint automatically. This is recommended because it handles key rotation automatically.
If automatic discovery doesn’t work:
- Specify a custom JWKS endpoint URL (e.g.,
https://token.actions.githubusercontent.com/.well-known/jwks) - Or provide JWKS JSON directly for air-gapped environments
Note: If you use JWKS JSON directly, you must update it manually when keys rotate.
Step 5: Save Identity Provider
- Review your configuration
- Click “Create Identity Provider”
- The identity provider is now ready to be used by federated identities
Step 2: Create a Federated Identity
Step 1: Navigate to Service Accounts
- Navigate to IAM → Service Accounts in your Thalassa Cloud Console
- Select the service account you want to configure federation for
Step 2: Create Federated Identity
- Click “Add Federated Identity” or “Workload Identity Federation”
- You’ll be prompted to configure the federated identity
Step 3: Select Identity Provider
- Identity Provider: Select the identity provider you created in Step 1
- This links the federated identity to your configured OIDC issuer
Step 4: Configure Token Matching
The subject claim (sub) is the main field used to match tokens. Formats vary by provider:
- GitHub Actions:
repo:OWNER/REPO:ref:refs/heads/BRANCHorrepo:OWNER/REPO:environment:ENV - GitLab CI:
project_path:GROUP/PROJECT:ref_type:TYPE:ref:REF - Google Cloud:
serviceAccount:[email protected]
Examples:
- Match specific branch:
repo:myorg/myrepo:ref:refs/heads/main - Match all branches:
repo:myorg/myrepo:ref:refs/heads/* - Match environment:
repo:myorg/myrepo:environment:production
You can also match additional claims for tighter security. Common claims: repository, repository_owner, ref, environment, email. This helps restrict access to specific repositories, branches, or environments.
Step 5: Configure API Scopes
Select one or more API scopes. Scopes control what the bearer token can do:
read: Read-only accesswrite: Write accessadmin: Administrative access
Only grant scopes that your workload actually needs.
Step 6: Set Expiry (Optional)
Set an expiration date if needed. This is useful for temporary access. After expiry, token exchange fails. You’ll need to create a new federated identity if access is still needed.
Step 7: Save Federated Identity
- Review your configuration
- Click “Create Federated Identity” or “Save”
- The federated identity is now active and ready to use
Using Federated Identity
Token Exchange Flow
Once configured, you can exchange OIDC tokens for Thalassa Cloud bearer tokens:
- Obtain OIDC Token: Get an ID token from your identity provider
- Exchange Token: Send the ID token to Thalassa Cloud’s
/oidc/tokenendpoint - Receive Bearer Token: Thalassa Cloud validates the token and returns a bearer token
- Use Bearer Token: Include the bearer token in API requests or CLI commands
Basic Token Exchange
curl -X POST https://api.thalassa.cloud/oidc/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \
-d "subject_token=${OIDC_TOKEN}" \
-d "subject_token_type=urn:ietf:params:oauth:token-type:id_token" \
-d "organisation_id=${THALASSA_ORGANISATION_ID}" \
-d "service_account_id=${THALASSA_SERVICE_ACCOUNT_ID}"The response contains:
{
"access_token": "bearer-token-here",
"token_type": "Bearer",
"expires_in": 3600
}Using with tcloud CLI
BEARER_TOKEN=$(curl -X POST https://api.thalassa.cloud/oidc/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \
-d "subject_token=${OIDC_TOKEN}" \
-d "subject_token_type=urn:ietf:params:oauth:token-type:id_token" \
-d "organisation_id=${THALASSA_ORGANISATION_ID}" \
-d "service_account_id=${THALASSA_SERVICE_ACCOUNT_ID}" | jq -r '.access_token')
tcloud --token="${BEARER_TOKEN}" kubernetes listUsing with Terraform
terraform {
required_providers {
thalassa = {
source = "thalassa-cloud/thalassa"
version = "~> 0.14"
}
}
}
provider "thalassa" {
api_endpoint = "https://api.thalassa.cloud"
token = var.thalassa_token # Pass the exchanged bearer token
}Troubleshooting
Token Exchange Fails
If token exchange fails, check:
- The subject claim matches your federated identity configuration
- The issuer URL is correct
- Your OIDC token is not expired
- The token is properly formatted as a JWT
- The service account ID and organisation ID are correct
Token Matching Fails
If token matching fails:
- Decode your token:
echo "${OIDC_TOKEN}" | cut -d. -f2 | base64 -d | jq - Compare the claims with your matching rules
- Update your subject claim or additional claims to match your provider’s format
JWKS Discovery Fails
If JWKS discovery fails:
- Check that
{issuer}/.well-known/openid-configurationis accessible - Try specifying the JWKS endpoint manually
- Verify TLS certificates are valid
- Check for network restrictions
Security Best Practices
Use specific subject claims instead of broad wildcards. This reduces security risk. Only grant scopes that your workload needs. Review federated identity usage regularly using audit logs. Set expiry dates and rotate federated identities regularly. If you use custom JWKS JSON, update it when keys rotate.
Provider-Specific Guides
For detailed instructions for specific providers, see:
- GitHub Actions Configuration: Configure federation for GitHub Actions
- GitLab CI Configuration: Configure federation for GitLab CI
- Generic OIDC Configuration: Configure federation for any OIDC provider
Related Documentation
- Workload Identity Federation Overview: General overview and concepts
- Service Accounts: Learn about service accounts
- RBAC Roles: Configure permissions for service accounts