Configuring Workload Identity Federation for Generic OIDC Providers

This guide explains how to configure workload identity federation with any OIDC-compliant identity provider. This is useful for custom identity providers, other cloud platforms, or enterprise identity solutions.

Prerequisites

Before configuring workload identity federation for a generic OIDC provider, ensure you have:

  • An OIDC-compliant identity provider
  • The issuer URL of your OIDC provider
  • Access to your Thalassa Cloud organisation
  • A service account created in Thalassa Cloud with appropriate IAM roles
  • Permissions to create identity providers and federated identities
  • Knowledge of your OIDC provider’s token claims structure

Step 1: Gather OIDC Provider Information

Before creating the identity provider, gather the following information from your OIDC provider:

  1. Issuer URL: The base URL of your OIDC provider (e.g., https://accounts.google.com, https://your-identity-provider.com)
  2. JWKS Endpoint: The JSON Web Key Set endpoint (can be auto-discovered)
  3. Token Claims: Understanding what claims your provider includes in tokens (especially the sub claim)
  4. Token Format: Ensure your provider issues standard OIDC ID tokens

Finding OIDC Configuration

Most OIDC providers expose a well-known configuration endpoint:

https://your-issuer-url/.well-known/openid-configuration

This endpoint contains:

  • issuer: The issuer identifier
  • jwks_uri: The JWKS endpoint URL
  • authorization_endpoint: The authorization endpoint
  • token_endpoint: The token endpoint
  • Other OIDC configuration details

Step 2: Create Identity Provider

Step 1: Navigate to Identity Providers

Navigate to IAMIdentity Providers in your Thalassa Cloud Console.

Step 2: Create Generic OIDC Identity Provider

Click “Create Identity Provider” and configure:

Basic Information:

  • Name: Choose a descriptive name (e.g., google-cloud, azure-ad, okta)
  • Description: Optional description of the identity provider’s purpose

OIDC Configuration:

  • OIDC Issuer URL: Enter your identity provider’s issuer URL
    • This must be the exact issuer URL as returned by your OIDC provider
    • Examples:
      • Google Cloud: https://accounts.google.com
      • Azure AD: https://login.microsoftonline.com/{tenant-id}/v2.0
      • Okta: https://{your-domain}.okta.com/oauth2/default

JWKS Configuration: Choose one of the following options:

Option A: Automatic Discovery (Recommended)

If your OIDC provider supports well-known configuration discovery:

  • Leave JWKS endpoint blank
  • Thalassa Cloud will automatically fetch the JWKS endpoint from: {issuer-url}/.well-known/openid-configuration
  • This works for most standard OIDC providers

Option B: Custom JWKS Endpoint

If automatic discovery doesn’t work or you need to specify a custom endpoint:

  • Specify the JWKS endpoint URL directly
  • Example: https://your-issuer-url/.well-known/jwks.json
  • Use this if your provider uses a non-standard JWKS location

Option C: Custom JWKS JSON (Offline Use)

For air-gapped environments or when you need to pin specific keys:

  • Provide the JWKS JSON content directly
  • Format:
    {
      "keys": [
        {
          "kty": "RSA",
          "use": "sig",
          "kid": "key-id",
          "n": "modulus-value",
          "e": "exponent-value"
        }
      ]
    }
  • Important: When keys rotate, you must manually update this content

Step 3: Save Identity Provider

Click “Create Identity Provider” to save the configuration.

Step 3: Create Federated Identity

Step 1: Navigate to Service Accounts

Navigate to IAMService Accounts in your Thalassa Cloud Console.

Step 2: Select Service Account

Select the service account you want to configure for OIDC federation.

Step 3: Create Federated Identity

Click “Add Federated Identity” or “Workload Identity Federation”.

Step 4: Configure Token Matching

Configure how tokens from your OIDC provider are matched:

Identity Provider:

  • Select the identity provider you created in Step 2

Token Matching:

The subject claim (sub) is the primary claim used for matching. The format varies by provider:

  • Standard Format: sub:user-id or sub:service-account-id
  • Provider-Specific Formats: Some providers use unique formats:
    • Google Cloud: serviceAccount:PROJECT-ID@PROJECT-ID.iam.gserviceaccount.com
    • Azure AD: {object-id} or {upn}
    • Okta: {user-id} or custom format

Understanding Your Provider’s Claims:

To determine the correct subject claim format:

  1. Obtain a token from your OIDC provider
  2. Decode the token to inspect claims:
    # JWT tokens have three parts separated by dots
    echo "YOUR_TOKEN" | cut -d. -f2 | base64 -d | jq
  3. Identify the sub claim and its format
  4. Use this format in your federated identity configuration

Subject Claim Examples:

  • Match specific user: user:john.doe@example.com
  • Match service account: serviceAccount:my-project@my-project.iam.gserviceaccount.com
  • Match with wildcards: serviceAccount:*@my-project.iam.gserviceaccount.com
  • Match by domain: *@example.com

Additional Claims (optional):

Many OIDC providers include additional claims you can match:

  • email: User email address
  • aud: Audience (should match your API endpoint)
  • iss: Issuer (must match your configured issuer)
  • exp: Expiration time
  • iat: Issued at time
  • Provider-specific claims (e.g., groups, roles, tenant)

API Scopes:

  • Select the API scopes your application needs (e.g., read, write)
  • Follow the principle of least privilege

Expiry (Optional):

  • Set an expiry date if this is a temporary federation

Step 5: Save Federated Identity

Click “Create Federated Identity” to complete the setup.

Step 4: Exchange Tokens

Once configured, you can exchange OIDC tokens for Thalassa Cloud bearer tokens.

Using tcloud CLI (Recommended)

The easiest way to exchange tokens is using the tcloud CLI’s oidc token-exchange command:

tcloud oidc token-exchange \
  --subject-token "${OIDC_TOKEN}" \
  --service-account-id "${THALASSA_SERVICE_ACCOUNT_ID}" \
  --organisation-id "${THALASSA_ORGANISATION_ID}"

The command will output the access token, which you can use directly or export to an environment variable:

# Export token to environment variable
export THALASSA_TOKEN=$(tcloud oidc token-exchange \
  --subject-token "${OIDC_TOKEN}" \
  --service-account-id "${THALASSA_SERVICE_ACCOUNT_ID}" \
  --organisation-id "${THALASSA_ORGANISATION_ID}")

# Use the token with other tcloud commands
tcloud compute machines list

Environment Variables:

You can also use environment variables instead of command-line flags:

export THALASSA_ID_TOKEN="${OIDC_TOKEN}"
export THALASSA_SERVICE_ACCOUNT_ID="sa-12345678-abcd-efgh-ijkl-9876543210ab"

tcloud oidc token-exchange

Token Lifetime:

Control the access token lifetime (minimum 1 minute, maximum 24 hours, default 1 hour):

tcloud oidc token-exchange \
  --subject-token "${OIDC_TOKEN}" \
  --service-account-id "${THALASSA_SERVICE_ACCOUNT_ID}" \
  --access-token-lifetime "2h"

For complete documentation, see the tcloud oidc token-exchange reference.

Basic Token Exchange (API)

You can also exchange tokens directly using the API:

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 will contain:

{
  "access_token": "bearer-token-here",
  "token_type": "Bearer",
  "expires_in": 3600
}

Using with Scripts

#!/bin/bash

# Get OIDC token from your provider (implementation varies)
OIDC_TOKEN=$(get_token_from_your_provider)

# Exchange for Thalassa Cloud bearer token
BEARER_TOKEN=$(curl -s -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')

# Use bearer token
export THALASSA_TOKEN="${BEARER_TOKEN}"
terraform apply

Related Documentation