Skip to main content

OIDC Authentication Setup

This guide explains how to configure OpenID Connect (OIDC) authentication for Sauce Labs Mobile App Distribution API access.

Overview​

OIDC authentication allows organizations to authenticate API requests using JWT tokens from their identity provider instead of traditional API keys. It is typically used for machine-to-machine (M2M) authentication with the OAuth 2.0 Client Credentials flow.

Benefits​

  • Centralized credential management: Manage API access through your identity provider
  • Short-lived tokens: Tokens expire automatically, reducing risk of credential leakage
  • No shared secrets: API keys don't need to be distributed to CI/CD systems
  • Audit trail: Authentication events are logged in your identity provider

Supported Identity Providers​

Any OIDC-compliant identity provider that supports the Client Credentials flow:

  • Auth0
  • Okta
  • Azure AD (Microsoft Entra ID)
  • Active Directory Federation Services (AD FS)
  • Google Cloud Identity
  • Keycloak
  • PingIdentity
  • And others...

Configuration​

Step 1: Configure Your Identity Provider​

Before configuring Sauce Labs Mobile App Distribution, set up a machine-to-machine application in your identity provider.

  1. Go to Applications > Create Application
  2. Select Machine to Machine Applications
  3. Name it (e.g., "MAD CI/CD")
  4. Select or create an API with an audience identifier (e.g., https://api.testfairy.com or your custom API identifier)
  5. Grant the required scopes (if using scope validation)
  6. Note down:
    • Domain (Issuer URL): https://your-tenant.auth0.com/
    • Client ID
    • Client Secret
    • Audience: The API identifier you configured

Step 2: Configure OIDC Settings in Sauce Labs Mobile App Distribution​

  1. Log in to Sauce Labs Mobile App Distribution as an Account Owner or Org Admin
  2. Click the Profile icon, select Integrations, then click Connect in the OIDC row to open the OIDC API Authentication page
  3. Configure the following fields:
SettingDescription
Enable OIDC AuthenticationToggle to enable OIDC authentication
Authentication ModeHow to handle API key vs OIDC auth (see below)
Issuer URLYour identity provider's issuer URL (e.g., https://your-tenant.auth0.com/)
AudienceThe expected audience claim in tokens (e.g., https://api.testfairy.com)
Allowed AlgorithmsJWT signing algorithms used by your identity provider (default: RS256)
Required Scopes(Optional) Comma-separated list of scopes to validate
JWKS Cache TTLHow long to cache public keys (default: 24 hours)
Clock Skew ToleranceAllowed time difference (default: 60 seconds)

Authentication Modes​

ModeDescription
OIDC or API KeyAccept both OIDC tokens and API keys. Recommended during migration.
OIDC OnlyRequire OIDC tokens, reject API keys. Use for full OIDC enforcement.

Step 3: Test the Configuration​

  1. Click Test next to Issuer URL to verify:
    • The issuer URL is reachable
    • The OIDC discovery endpoint responds correctly
    • The JWKS (public keys) can be fetched
  2. If successful, you'll see details about the discovered configuration
  3. Enable the setting and hit Save configuration

Security Best Practices​

Config Key Security​

Each OIDC configuration is assigned a unique, unguessable config key (e.g., oidc_a1b2c3d4e5f6...). This key:

  • Is automatically generated when you save your OIDC configuration
  • Must be included in every API request via the X-OIDC-Config-Key header
  • Should be treated as a secret and stored securely (e.g., in CI/CD secrets)
  • Cannot be regenerated on its own. If it is compromised, click Delete Configuration on the OIDC settings page and save the configuration again; the new configuration gets a new key

The config key ensures that even if multiple organizations use the same OIDC provider with identical settings, they cannot accidentally access each other's data.

Token Lifetime​

Configure short-lived tokens in your identity provider:

  • Recommended: 1 hour or less
  • Maximum recommended: 24 hours

Scope Validation (Optional)​

Scope validation is optional. If you leave the "Required Scopes" field empty, scope validation is skipped entirely.

For additional security, you can configure required scopes:

  1. Define scopes in your identity provider (e.g., uploads:write, sessions:read)
  2. Add them to the "Required Scopes" field in the settings
  3. Tokens must contain at least one of the required scopes
note

If no scopes are configured, any valid token from your OIDC provider will be accepted regardless of its scope claims.

Migration Strategy​

When migrating from API keys to OIDC:

  1. Phase 1: Enable OIDC in "OIDC or API Key" mode
  2. Phase 2: Update all clients to use OIDC tokens
  3. Phase 3: Monitor for any remaining API key usage
  4. Phase 4: Switch to "OIDC Only" mode

API Usage​

Obtaining a Token​

Request an access token from your identity provider using the Client Credentials flow:

curl -X POST https://your-identity-provider.example.com/oauth/token \
-H "Content-Type: application/json" \
-d '{
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"audience": "https://api.testfairy.com",
"grant_type": "client_credentials"
}'
Sample Response
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600
}

Making API Requests​

Include the token in the Authorization header along with your OIDC config key. See Legacy API (v1) for available endpoints.

curl -X GET "https://mobile.saucelabs.com/api/1/projects/" \
-H "Authorization: Bearer <your-access-token>" \
-H "X-OIDC-Config-Key: <your-config-key>"

For file uploads, see Upload API for all parameters:

curl -X POST "https://mobile.saucelabs.com/api/upload/" \
-H "Authorization: Bearer <your-access-token>" \
-H "X-OIDC-Config-Key: <your-config-key>" \
-F "file=@app.apk"

CI/CD Integration Examples​

name: Upload to Sauce Labs Mobile App Distribution

on:
push:
branches: [main]

jobs:
upload:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Build App
run: ./gradlew assembleRelease

- name: Get OIDC Token
id: token
run: |
TOKEN=$(curl -s -X POST ${{ secrets.OIDC_TOKEN_URL }} \
-H "Content-Type: application/json" \
-d '{
"client_id": "${{ secrets.OIDC_CLIENT_ID }}",
"client_secret": "${{ secrets.OIDC_CLIENT_SECRET }}",
"audience": "${{ secrets.TESTFAIRY_AUDIENCE }}",
"grant_type": "client_credentials"
}' | jq -r '.access_token')
echo "::add-mask::$TOKEN"
echo "token=$TOKEN" >> $GITHUB_OUTPUT

- name: Upload to MAD
run: |
curl -X POST https://mobile.saucelabs.com/api/upload/ \
-H "Authorization: Bearer ${{ steps.token.outputs.token }}" \
-H "X-OIDC-Config-Key: ${{ secrets.OIDC_CONFIG_KEY }}" \
-F "file=@app/build/outputs/apk/release/app-release.apk"

Troubleshooting​

Debugging Tips​

  1. Decode your JWT token at jwt.io to inspect claims
  2. Verify the issuer URL matches the token's iss claim (a trailing / is ignored on both sides)
  3. Check the audience matches exactly (case-sensitive)
  4. Test the OIDC discovery endpoint manually:
    curl https://your-issuer/.well-known/openid-configuration
  5. Test the JWKS endpoint manually:
    curl https://your-issuer/.well-known/jwks.json

Token Validation Checklist​

When a token is validated, the following checks are performed:

  1. Token format is valid JWT (three base64-encoded parts)
  2. Token header specifies an algorithm that matches the signing key published in your identity provider's JWKS
  3. Token signature is valid (verified using JWKS public keys)
  4. Token is not expired (exp claim)
  5. Token is not used before valid time (nbf claim, if present)
  6. Issuer (iss claim) matches the configured Issuer URL (a trailing / is ignored)
  7. Audience (aud claim) matches configured audience
  8. Required scopes are present (only if scope validation is configured)

Common Error Messages​

ErrorSolution
Missing X-OIDC-Config-Key header. OIDC JWT tokens require the X-OIDC-Config-Key header to identify the OIDC configuration.Add the X-OIDC-Config-Key header to your request.
Invalid OIDC config key.The config key is incorrect. Copy it again from the Integration Details section of the OIDC settings page.
OIDC authentication is disabled.Turn on Enable OIDC Authentication on the OIDC settings page and save.
Failed to fetch JWKS from issuer.The discovery document or JWKS could not be fetched from the Issuer URL. Check the URL and that the identity provider is reachable.
Issuer mismatch: expected "<issuer-url>", got "<iss>".The token's iss claim doesn't match the Issuer URL. Make the two identical (a trailing / is ignored).
Audience mismatch: expected "<audience>".The token's aud claim doesn't contain the configured Audience. Check it matches exactly (case-sensitive).
Token missing required scope. Required one of: <scopes>.Request a token that includes at least one of the configured Allowed Scopes, or change that field.
Token validation failed: <reason>The signature, expiry or algorithm check failed. The reason comes from the JWT library, for example Expired token or Signature verification failed. Request a new token and check it was issued by the configured provider.

The /api/v3/... endpoints return these messages as {"error": "<message>"} with HTTP 401. The legacy endpoints used in the examples above don't pass them through: /api/1/... answers 401 with {"status":"fail","code":104,"message":"User not found"}, and /api/upload answers HTTP 200 with "status":"fail" and "code": 1 or "code": 5. To see the real reason, repeat the call against /api/v3/projects.


FAQ​

Q: Can I use OIDC and API keys at the same time?

A: Yes, use the "OIDC or API Key" authentication mode during migration.

Q: What happens if my identity provider is down?

A: JWKS (public keys) are cached for the configured TTL (default 24 hours). If cached keys are available, authentication will continue to work. If cache expires and the provider is unreachable, authentication will fail.

Q: Can multiple organizations share the same OIDC provider?

A: Yes, each organization has a unique config key to prevent cross-tenant access.

Q: Do I need to store the client secret in Sauce Labs Mobile App Distribution?

A: No. The client ID and secret are only used client-side to obtain tokens. Sauce Labs Mobile App Distribution only validates the tokens using public keys from the JWKS endpoint.

Q: Which JWT algorithms are supported?

A: Mobile App Distribution doesn't restrict the algorithm. Any algorithm that matches a signing key your identity provider publishes in its JWKS works. RS256 is the most common choice and is the default value of Allowed Algorithms.

Q: Can I use HS256 (symmetric) algorithms?

A: Mobile App Distribution doesn't block any algorithm; it verifies tokens with the keys your identity provider publishes in its JWKS. Identity providers normally publish only asymmetric keys (RS*, ES*, EdDSA), so use one of those.

See Also​