Skip to main content
OpenID Connect (OIDC) lets your Baseten deployments authenticate to cloud resources like S3 buckets and container registries using short-lived tokens instead of long-lived credentials. Without OIDC, accessing cloud resources requires long-lived credentials: static API keys or service account keys stored as secrets in Baseten. These keys don’t expire on their own, so if they’re leaked or forgotten, they remain valid until someone manually rotates them. You’re responsible for tracking which keys exist, where they’re used, and when to rotate them. OIDC takes a different approach. Instead of static keys, Baseten issues short-lived tokens scoped to a specific deployment. There are no secrets to store, rotate, or clean up. Baseten OIDC currently supports:
  • AWS: Amazon ECR (container images) and Amazon S3 (model weights)
  • Google Cloud: Artifact Registry, GCR (container images), and Google Cloud Storage (model weights)

How Baseten OIDC works

Baseten acts as an OIDC identity provider with the following configuration:
  • Issuer: https://oidc.baseten.co
  • Audience: oidc.baseten.co
When you deploy your model, Baseten generates short-lived OIDC tokens that identify your specific workload. Your cloud provider validates these tokens against the trust relationship you configure, then grants access to the specified resources.

Token structure

Each OIDC token includes standard JWT claims and custom claims that identify the workload. Here’s an example unsigned payload:
{
  "iss": "https://oidc.baseten.co",
  "sub": "v=1:org=Mvg9jrRd:team=AviIZ0y3:model=kW9wuKFN:deployment=e5f6g7h8:environment=production:type=model_container",
  "aud": "oidc.baseten.co",
  "iat": 1700000000,
  "exp": 1700003600,
  "jti": "550e8400-e29b-41d4-a716-446655440000",
  "org": "Mvg9jrRd",
  "team": "AviIZ0y3",
  "model": "kW9wuKFN",
  "deployment": "e5f6g7h8",
  "environment": "production",
  "type": "model_container"
}
The sub claim uses a structured format that encodes the workload identity:
v=1:org={org_id}:team={team_id}:model={model_id}:deployment={deployment_id}:environment={environment}:type={workload_type}

Claim components

ComponentDescriptionExample
orgYour organization IDMvg9jrRd
teamTeam ID within your organizationAviIZ0y3
modelModel IDkW9wuKFN
deploymentSpecific deployment/version IDe5f6g7h8
environmentUser-defined environment name (max 40 characters). Defaults to <none> if not setproduction
typeWorkload type: model_build or model_containermodel_build

Workload types

  • model_build: Token used during model image building (for example, pulling base images from ECR/GCR).
  • model_container: Token used by running model containers (for example, downloading weights from S3/GCS).

Subject claim patterns

Common patterns for scoping which workloads can access your resources:
  • AWS: Use these in the IAM role trust policy under Condition.StringLike for oidc.baseten.co:sub. Wildcards (*) are supported.
  • GCP: Use these in the Workload Identity Provider attribute-condition. With the mapping google.subject=assertion.sub (see Create a Workload Identity Provider), reference the sub claim as google.subject. GCP does not support wildcards; use startsWith() (and contains() where needed).

All workloads in a team

To give every workload in your team access to a resource, match on the team ID with a wildcard for everything else.
v=1:org=Mvg9jrRd:team=AviIZ0y3:*

Specific model, all deployments

To restrict access to a single model while allowing all of its deployments and environments, match on the model ID.
v=1:org=Mvg9jrRd:team=AviIZ0y3:model=kW9wuKFN:*

Specific environment, all models

To scope access by environment, match workloads deployed to a specific environment like production.
v=1:org=Mvg9jrRd:team=AviIZ0y3:*:environment=production:*

Build-time only access

To limit access to the build phase, like pulling base images from a private registry, match on the model_build workload type.
v=1:org=Mvg9jrRd:team=AviIZ0y3:*:type=model_build

Runtime only access

To limit access to running containers, like downloading model weights, match on the model_container workload type.
v=1:org=Mvg9jrRd:team=AviIZ0y3:*:type=model_container

Specific model and environment

To apply the most restrictive access, combine model and environment matching so only a specific model in a specific environment can authenticate.
v=1:org=Mvg9jrRd:team=AviIZ0y3:model=kW9wuKFN:*:environment=production:*

Finding your OIDC identifiers

Use truss whoami --show-oidc to view your organization and team IDs, issuer, audience, and subject claim format needed for configuring cloud provider trust policies.

Cloud provider setup

Create an OIDC identity provider

Register Baseten as a trusted OIDC provider in your AWS account.
  1. Navigate to the AWS IAM Console.
  2. Go to Identity providersAdd provider.
  3. Select OpenID Connect.
  4. Configure the provider:
    • Provider URL: https://oidc.baseten.co
    • Click Get thumbprint to verify the provider.
    • Audience: oidc.baseten.co
  5. Click Add provider.
If your AWS account requires sts.amazonaws.com as a trusted audience, add it to the OIDC provider first, then add oidc.baseten.co as an additional audience.

Create an IAM role

Create a role that your Baseten workloads can assume via OIDC.
  1. Go to RolesCreate role.
  2. Select Web identity as the trusted entity type.
  3. Choose the OIDC provider you created.
  4. Select Audience: oidc.baseten.co, then click Next.
  5. On the next page, attach permissions policies for the resources your models need to access:

ECR access (for base images)

Attach this policy to allow pulling container images from ECR.
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ecr:GetAuthorizationToken",
        "ecr:BatchCheckLayerAvailability",
        "ecr:GetDownloadUrlForLayer",
        "ecr:BatchGetImage"
      ],
      "Resource": "*"
    }
  ]
}

S3 access (for model weights)

Attach this policy to allow reading model weights from S3.
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::my-model-weights-bucket",
        "arn:aws:s3:::my-model-weights-bucket/*"
      ]
    }
  ]
}
  1. Configure the trust policy: Edit the role’s trust policy to include subject claim conditions. After creating the role, go to the role → Trust relationshipsEdit and use a policy like this:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::<aws-account-id>:oidc-provider/oidc.baseten.co"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "oidc.baseten.co:aud": "oidc.baseten.co"
        },
        "StringLike": {
          "oidc.baseten.co:sub": "v=1:org=Mvg9jrRd:team=AviIZ0y3:*"
        }
      }
    }
  ]
}
Replace <aws-account-id> with your AWS account ID, and adjust the sub claim pattern to match your security requirements.

Using OIDC in your Truss configuration

Once you’ve completed the AWS or GCP setup above, you can configure OIDC authentication in your Truss:

Private registries (ECR, GCR)

For authenticating to private Docker registries using OIDC, see:

Model weights (S3, GCS)

For downloading model weights from cloud storage using OIDC, see:
  • AWS S3 OIDC: Configure OIDC for S3 model weights.
  • GCS OIDC: Configure OIDC for Google Cloud Storage model weights.

Best practices

Use least-privilege access

Use the most specific subject claim pattern that fits your use case. Create separate roles or Workload Identity providers for different environments, workload types, or models rather than one role with broad permissions. Always test your OIDC configuration in a non-production environment first.
Don’t grant access to v=1:org=*:team=*:*. This allows any Baseten workload to access your resources.

Monitor and audit

  • Enable CloudTrail (AWS) or Cloud Audit Logs (GCP) to track OIDC token usage.
  • Set up alerts for unexpected access patterns.
  • Regularly review which roles are being used.

Troubleshooting

Authentication failures

If your model fails to authenticate:
  1. Verify the trust relationship: Ensure your IAM role trusts the Baseten OIDC provider (https://oidc.baseten.co).
  2. Check the audience: Confirm the audience is set to oidc.baseten.co.
  3. Review subject claim conditions: Verify your sub claim pattern matches the workload identity.
  4. Inspect your identifiers: Run truss whoami --show-oidc to confirm your org and team IDs.

Permission denied errors

If authentication succeeds but operations fail:
  1. Check IAM policies: Ensure the role has the necessary permissions (for example, s3:GetObject, ecr:BatchGetImage).
  2. Verify resource ARNs: Confirm bucket names, registry URLs, and other resource identifiers are correct.
  3. Review resource policies: Some resources (like S3 buckets) have their own policies that may block access.

Common error messages

ErrorLikely CauseSolution
”Not authorized to perform sts:AssumeRoleWithWebIdentity”Trust policy doesn’t match the workloadCheck subject claim pattern in trust policy
”Access Denied”Missing permissions in IAM policyAdd required permissions to the role
”Invalid identity token”Issuer or audience mismatchVerify OIDC provider configuration
”Token has expired”Clock skew or token refresh issueContact Baseten support

Debugging with CloudWatch/Cloud Logging

Enable detailed logging to see exactly why authentication or authorization is failing: AWS CloudTrail: Look for AssumeRoleWithWebIdentity events to see token validation attempts. GCP Cloud Audit Logs: Check iam.googleapis.com logs for workload identity authentication events.

Migration from long-lived credentials

If you’re currently using long-lived AWS or GCP credentials:
  1. Set up OIDC as described above.
  2. Update your Truss configuration to use OIDC authentication.
  3. Deploy and test your model.
  4. Once confirmed working, remove the long-lived credentials.
  5. Delete any secrets containing long-lived credentials from Baseten.
Both OIDC and long-lived credential authentication methods are supported. You can migrate gradually, starting with non-production environments.

Limitations

  • OIDC tokens can’t be customized.
  • Baseten manages token lifetime and claims.
  • Only AWS and GCP services are supported.
  • GCP doesn’t support wildcard subject claims or subject-based scoping in IAM role conditions. Use the Workload Identity Provider attribute-condition instead.
  • Cloudflare R2, Azure containers, and Hugging Face aren’t yet supported.