JWT Authentication
JWT (JSON Web Token) authentication enables programmatic access to Opik using externally issued tokens. This is ideal for service-to-service authentication, custom auth flows, and integration with existing JWT-based systems.
When to use JWT authentication
Section titled “When to use JWT authentication”JWT authentication is best suited for:
- Backend services that need to access Opik's API
- CI/CD pipelines running automated experiments
- Custom applications with existing JWT infrastructure
- Service-to-service communication without user interaction
For human users logging in interactively, consider SAML or OIDC SSO instead.
Prerequisites
Section titled “Prerequisites”Before configuring JWT authentication, you need:
- Organization admin access to Opik
- Enterprise plan enabled for your organization
- JWT infrastructure capable of issuing signed tokens
- JWKS endpoint (recommended) or public key for token verification
How JWT authentication works
Section titled “How JWT authentication works”┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Service/ │ │ Opik │ │ JWKS │
│ Client │ │ API │ │ Endpoint │
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
│ │ │
│ 1. Request with │ │
│ JWT in header │ │
│────────────────────>│ │
│ │ 2. Fetch keys │
│ │ (cached) │
│ │────────────────────>│
│ │<────────────────────│
│ │ │
│ │ 3. Verify JWT │
│ │ signature │
│ │ │
│ │ 4. Validate claims │
│ │ (iss, aud, sub) │
│ │ │
│ 5. API response │ │
│<────────────────────│ │- Client sends an API request with a JWT in the
Authorizationheader. - Opik fetches public keys from your JWKS endpoint (cached for performance).
- Opik verifies the JWT signature using the appropriate key.
- Opik validates claims (issuer, audience, subject).
- If valid, the request is processed as the mapped user.
Configuration options
Section titled “Configuration options”JWT authentication can be configured with either:
| Option | Description | Use case |
|---|---|---|
| JWKS URI | URL to fetch public keys dynamically | Recommended for most deployments |
| Static Public Key | Fixed public key for verification | On-premises deployments only |
Configuring JWT authentication
Section titled “Configuring JWT authentication”Step 1: Navigate to SSO settings
Section titled “Step 1: Navigate to SSO settings”- Go to Admin Dashboard > SSO Configuration.
- Select JWT Authentication (may be under advanced options).
Step 2: Choose key verification method
Section titled “Step 2: Choose key verification method”Using JWKS URI
JWKS (JSON Web Key Set) is the recommended approach as it:
- Supports automatic key rotation
- Allows multiple keys for seamless rotation
- Follows industry best practices
Configuration:
| Field | Description | Example |
|---|---|---|
| JWKS URI | URL of your JWKS endpoint | https://auth.company.com/.well-known/jwks.json |
Requirements:
- The endpoint must be publicly accessible (or accessible from Opik's servers).
- Must return valid JWKS JSON format.
- Must be unique across organizations (no two orgs can share a JWKS URI).
- Should support HTTPS.
Example JWKS response:
{
"keys": [
{
"kty": "RSA",
"kid": "key-1",
"use": "sig",
"n": "0vx7agoebGcQ...",
"e": "AQAB"
}
]
}Using static public key
Static public key configuration is simpler but requires manual key rotation:
| Field | Description | Example |
|---|---|---|
| Static Public Key | PEM-encoded public key | -----BEGIN PUBLIC KEY-----... |
Format:
The public key must be in PEM format:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----Step 3: Configure subject mapping
Section titled “Step 3: Configure subject mapping”Subject mapping determines how Opik identifies users from JWT claims:
| Field | Description | Options |
|---|---|---|
| Subject Mapping Type | How to interpret the subject claim | EMAIL or USER_NAME |
| Subject Claim Name | Which claim contains the subject | Default: sub |
Subject mapping types:
| Type | Description | Example claim value |
|---|---|---|
EMAIL |
Subject is an email address | user@company.com |
USER_NAME |
Subject is a username | jsmith |
Custom claim name:
By default, Opik reads the sub (subject) claim. If your tokens use a different claim:
{
"sub": "12345",
"email": "user@company.com",
"preferred_username": "jsmith"
}Set Subject Claim Name to email or preferred_username to use those claims instead.
Step 4: Configure optional restrictions
Section titled “Step 4: Configure optional restrictions”Allowed issuers
Section titled “Allowed issuers”Restrict which token issuers are accepted:
| Field | Description |
|---|---|
| Allowed Issuers | List of accepted iss claim values |
Example:
https://auth.company.com
https://auth.partner.comIf configured, tokens with issuers not in this list will be rejected.
Allowed audiences
Section titled “Allowed audiences”Restrict which audiences are accepted:
| Field | Description |
|---|---|
| Allowed Audiences | List of accepted aud claim values |
Example:
opik-api
https://api.opik.comIf configured, tokens without a matching audience claim will be rejected.
JWT token requirements
Section titled “JWT token requirements”Required claims
Section titled “Required claims”Your JWT tokens must include:
| Claim | Description | Example |
|---|---|---|
sub (or custom) |
Subject identifying the user | user@company.com |
iat |
Issued at timestamp | 1704067200 |
exp |
Expiration timestamp | 1704070800 |
Recommended claims
Section titled “Recommended claims”| Claim | Description | Example |
|---|---|---|
iss |
Token issuer | https://auth.company.com |
aud |
Intended audience | opik-api |
Required header
Section titled “Required header”When using JWKS with multiple keys:
| Header | Description | Example |
|---|---|---|
kid |
Key ID matching JWKS key | key-1 |
alg |
Algorithm (must match key) | RS256 |
Using JWT authentication
Section titled “Using JWT authentication”API requests
Section titled “API requests”Include the JWT in the Authorization header:
curl -X GET "https://api.opik.com/v1/projects" \
-H "Authorization: Bearer <your-jwt-token>"SDK configuration
Section titled “SDK configuration”Configure the Opik SDK to use JWT authentication:
import opik
# Configure with JWT token
client = opik.Opik(
api_key="<your-jwt-token>",
workspace="your-workspace"
)import { Opik } from 'opik';
const client = new Opik({
apiKey: '<your-jwt-token>',
workspace: 'your-workspace'
});Key caching and performance
Section titled “Key caching and performance”JWKS caching
Section titled “JWKS caching”Opik caches JWKS responses to improve performance:
- Cache duration: Keys are cached and periodically refreshed.
- Automatic refresh: Keys are fetched on cache expiry or when a new
kidis encountered. - Fallback: If JWKS endpoint is temporarily unavailable, cached keys are used.
Configuration options (on-premises)
Section titled “Configuration options (on-premises)”On-premises deployments can configure caching behavior:
| Environment variable | Description | Default |
|---|---|---|
JWKS_CACHE_UPDATE_SECONDS |
How often to refresh the cache | 300 (5 minutes) |
JWKS_FETCH_TIMEOUT_MS |
Timeout for JWKS fetch requests | 5000 (5 seconds) |
Troubleshooting
Section titled “Troubleshooting”Common issues
Section titled “Common issues”| Issue | Possible cause | Solution |
|---|---|---|
| "Invalid token signature" | Key mismatch | Verify JWKS endpoint returns correct keys |
| "Token expired" | exp claim in the past |
Issue tokens with appropriate expiration |
| "Unknown key ID" | kid not in JWKS |
Ensure token kid matches a key in JWKS |
| "Invalid issuer" | iss not in allowed list |
Add issuer to allowed issuers or remove restriction |
| "Invalid audience" | aud not in allowed list |
Add audience to allowed audiences or remove restriction |
| "User not found" | Subject doesn't map to user | Verify subject claim contains valid email/username |
Debugging JWT tokens
Section titled “Debugging JWT tokens”Decode and inspect your JWT token (do not use for production tokens containing secrets):
# Decode JWT header and payload (without verification)
echo "<your-jwt>" | cut -d'.' -f1 | base64 -d 2>/dev/null | jq .
echo "<your-jwt>" | cut -d'.' -f2 | base64 -d 2>/dev/null | jq .Or use jwt.io to inspect token contents.
Verifying JWKS endpoint
Section titled “Verifying JWKS endpoint”Test that your JWKS endpoint is accessible and returns valid JSON:
curl -s "https://auth.company.com/.well-known/jwks.json" | jq .Verify that:
- The endpoint returns HTTP 200.
- Response is valid JSON with a
keysarray. - Keys include
kid,kty, and algorithm-specific fields.
Token generation checklist
Section titled “Token generation checklist”Before integrating, verify your tokens:
- Signature: Token is signed with a key in your JWKS.
- Header: Includes
kidmatching a key in JWKS (if multiple keys). - Subject: Contains user email or username in the configured claim.
- Expiration:
expclaim is in the future. - Issuer: Matches allowed issuers (if configured).
- Audience: Matches allowed audiences (if configured).
Security best practices
Section titled “Security best practices”Token lifecycle
Section titled “Token lifecycle”- Short expiration: Use short-lived tokens (e.g., 1 hour).
- Refresh tokens: Implement token refresh for long-running processes.
- Revocation: Have a process to rotate keys if compromised.
Key management
Section titled “Key management”- Key rotation: Rotate keys periodically (e.g., every 90 days).
- Multiple keys: Maintain multiple keys in JWKS during rotation.
- Secure storage: Protect private keys used for signing.
Access restrictions
Section titled “Access restrictions”- Limit issuers: Configure allowed issuers to prevent token from unauthorized sources.
- Limit audiences: Configure allowed audiences to ensure tokens are intended for Opik.
- Monitor usage: Review authentication logs for anomalies.
Next steps
Section titled “Next steps”- Configure SAML for interactive user authentication.
- Configure OIDC for OAuth-based authentication.
- Create service accounts for an alternative programmatic access method.