Skip to content

Use @vercel/oidc utilities to reduce auth duplication#34

Draft
gr2m wants to merge 10 commits intomainfrom
vercel-oidc-update
Draft

Use @vercel/oidc utilities to reduce auth duplication#34
gr2m wants to merge 10 commits intomainfrom
vercel-oidc-update

Conversation

@gr2m
Copy link

@gr2m gr2m commented Feb 5, 2026

Summary

This PR refactors the authentication logic to use utilities from @vercel/oidc, reducing code duplication and improving maintainability.

Changes

  • Use @vercel/oidc optional parameters to reduce duplication in auth flow
  • Remove duplicate auth logic by leveraging shared utilities
  • Update dependency to local path for testing purposes
  • Update tests to reflect simplified auth logic

Related

Depends on vercel/vercel#14864 which adds the utilities to @vercel/oidc package.

Test plan

  • Existing auth tests pass
  • Manual testing of auth flows
  • Verify behavior matches previous implementation

🤖 Generated with Claude Code

gr2m added 3 commits February 4, 2026 16:06
Pass teamId and projectId to getVercelOidcToken() to enable token
refresh without needing to read from .vercel/project.json. This
removes duplication between @vercel/oidc and Sandbox's credential
management.

Changes:
- get-credentials.ts: Pass opts.teamId/projectId when calling getVercelOidcToken()
- jwt-expiry.ts: Pass payload.owner_id/project_id when refreshing tokens

Benefits:
- Token refresh works without .vercel/project.json when credentials are known
- Reduces filesystem dependencies in token refresh flow
- Maintains backward compatibility - still parses JWT for credential extraction
- All 57 tests continue to pass
Replaced Sandbox's custom auth refresh logic with @vercel/oidc's
getVercelCliToken() which handles:
- Reading auth.json
- Checking token expiry
- Refreshing with OAuth
- Saving updated tokens

Removed code:
- refreshToken() function (~30 lines)
- Imports from @vercel/sandbox/dist/auth (getAuth, updateAuthConfig, OAuth, isOAuthError)

Added:
- Import getVercelCliToken, NoAuthConfigError, TokenExpiredError, RefreshFailedError from @vercel/oidc
- Error handling to trigger login when auth is missing/expired

Benefits:
- 32 net lines removed (65 deletions, 33 insertions)
- Single source of truth for auth refresh logic
- Better error handling with specific error types
- All tests passing (6/6)
@vercel
Copy link

vercel bot commented Feb 5, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
sandbox-cli Error Error Feb 5, 2026 10:08pm
sandbox-sdk Error Error Feb 5, 2026 10:08pm
sandbox-sdk-ai-example Error Error Feb 5, 2026 10:08pm

Request Review

gr2m and others added 3 commits February 4, 2026 18:40
Follows the rename of NoAuthConfigError to NoAuthError in @vercel/oidc.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Follows the removal of TokenExpiredError in @vercel/oidc, which now
only throws NoAuthError or RefreshFailedError.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Follows the rename of NoAuthError to AccessTokenMissingError in @vercel/oidc.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
refreshed === "invalid refresh token"
// Try to get CLI token, which handles auth.json reading and refresh
try {
return await getVercelCliToken();
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need an access token? Or could we also get an OIDC token for Sandbox?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handling the access token is good idea. But then it should actually be called "access token". And we should also allow it be specified via an env var, e.g. VERCEL_TOKEN. But IMHO it shouldn't be API'd to CLI specifically.

Follows the rename of RefreshFailedError to RefreshAccessTokenFailedError
in @vercel/oidc.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Simplifies token management by using the new bufferMs option in
getVercelOidcToken() instead of maintaining a separate JwtExpiry class.
This consolidates token expiry logic in the @vercel/oidc package.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Follows the rename of bufferMs to expirationBufferMs in @vercel/oidc.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
refreshed === "invalid refresh token"
// Try to get CLI token, which handles auth.json reading and refresh
try {
return await getVercelCliToken();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handling the access token is good idea. But then it should actually be called "access token". And we should also allow it be specified via an env var, e.g. VERCEL_TOKEN. But IMHO it shouldn't be API'd to CLI specifically.

"@types/ms": "^2.1.0",
"@types/node": "^22.15.12",
"@vercel/oidc": "^3.1.0",
"@vercel/oidc": "file:../../../vercel/packages/oidc",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm working on it locally, this is a local install path for local testing. Once the @vercel/oidc PR ships I'll update it.

@gr2m
Copy link
Author

gr2m commented Feb 7, 2026

But then it should actually be called "access token". And we should also allow it be specified via an env var, e.g. VERCEL_TOKEN. But IMHO it shouldn't be API'd to CLI specifically.

I'm not sure, access token can mean anything, but here we specifically trying to get the Vercel CLI access token. E.g. gateway has its own access token independent of OIDC and CLI. I think getVercelCliToken is the right name, in future we will replace the implementation of it to use exec which will invoke the cli directly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants