Skip to content

bug: — OIDC access token can expire during workspace bootstrap #22429

@eugeneotto

Description

@eugeneotto

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

When a workspace is created or started, data.coder_workspace_owner.me.oidc_access_token is resolved once during Terraform plan/apply via the obtainOIDCAccessToken function. This token is then injected into the workspace environment (e.g., as an env var on coder_agent).

The issue is that obtainOIDCAccessToken only refreshes the token after it has already expired:

https://github.com/coder/coder/blob/main/coderd/provisionerdserver/provisionerdserver.go#L3093

if link.OAuthExpiry.Before(dbtime.Now()) && !link.OAuthExpiry.IsZero() && link.OAuthRefreshToken != "" {

If the token is still valid at build time but close to expiry (e.g., 2 minutes remaining on a 60-minute token), it gets injected as-is. By the time the workspace finishes bootstrapping (startup scripts, dependency installs, etc.), the token has expired and any internal systems relying on it for authentication fail.

There is no way to fetch a refreshed OIDC token from within a running workspace at runtime (unlike coder external-auth access-token which exists for external auth providers).

Relevant Log Output

Expected Behavior

< if link.OAuthExpiry.Before(dbtime.Now()) && !link.OAuthExpiry.IsZero() && link.OAuthRefreshToken != "" {
---
> if link.OAuthExpiry.Before(dbtime.Now().Add(-10 * time.Minute)) && !link.OAuthExpiry.IsZero() && link.OAuthRefreshToken != "" {```


### Steps to Reproduce

1. Find a template with these properties:
  - Takes 2 minutes to provision
  - Authenticates with the OIDC token in the second minute
2. Wait until about one minute before your OIDC token expires
3. Provision the workspace

By the time the token is used, it will have expired.

### Environment

- Host OS: Ubuntu
- Coder version: v2.30.1+16408b1



### Additional Context

_No response_

Metadata

Metadata

Assignees

Labels

s2Broken use cases or features (with a workaround). Only humans may set this.

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions