-
Notifications
You must be signed in to change notification settings - Fork 2
feat: use AsyncLocalStorage for request-scoped auth token #134
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This PR migrates BLINK_INVOCATION_AUTH_TOKEN from a global environment
variable to use Node.js AsyncLocalStorage for request-scoped context.
## Problem
Previously, auth tokens were stored in a global environment variable that
would get overwritten on each request. This created a race condition when
handling concurrent requests in the Node wrapper:
Request A: setAuthToken("token-A")
Request B: setAuthToken("token-B") ← Overwrites!
Request A: model() → reads "token-B" (WRONG TOKEN!)
## Solution
Use AsyncLocalStorage to store auth tokens in request-scoped context:
- Created `blink/internal` module with `runWithAuth()` and `getAuthToken()`
- Wrappers now call `runWithAuth(token, fn)` to establish context
- `model()` function reads token from ALS via `getAuthToken()`
For the internal API server (which makes HTTP calls to Blink Cloud API),
we use a hybrid approach: the closure-based `setAuthToken()` is kept
since HTTP requests cross async context boundaries. The ALS context is
used for direct function calls like `model()`.
## Files Changed
- `packages/blink/src/internal/`: New ALS context module
- `packages/blink/src/agent/agent.ts`: model() uses getAuthToken()
- `internal/runtime/src/`: Updated wrappers and server
- `internal/api/runtime/src/`: Mirror changes
## Tests
Added comprehensive tests for the AsyncLocalStorage context module:
- Context isolation between concurrent requests
- Nested context handling
- Async operation context preservation
Instead of the closure-based setAuthToken, this approach: 1. Patches fetch to add auth header to internal API requests 2. Internal API server reads auth token from request header 3. Uses ALS for direct function calls like model() 4. Falls back to module-level variable for HTTP boundary crossing The fetch patch reads from ALS first (for code in the same async context), then falls back to a module-level variable (for code after HTTP hop). Lambda handles requests sequentially so the fallback is safe there. For Node.js concurrent requests, ALS is used when available. Also added 'packages: bundle' to generate scripts to properly resolve workspace packages during bundling.
- Remove fallbackAuthToken from all wrappers (Node and Lambda)
- Use Symbol.for('@blink/authContext') to create global singleton ALS
- Both bundled wrapper and external blink/internal share same ALS instance
- Agent.fetch() sets up ALS context from x-blink-internal-auth header
- Test fixture now properly sets up ALS context for HTTP handlers
This simplifies the auth token flow: wrapper sets ALS context, all code
(including bundled code in generated wrappers) can read from it via
getAuthToken(). No fallbacks needed.
Move the fetch patching logic into a shared helper function in server.ts. This is used by both Node and Lambda wrappers to add the auth token header for requests to the internal API server.
- Fix typecheck error by preserving Bun's fetch.preconnect static property - Add test for concurrent request auth context isolation - Add echo-auth-token fixture for testing context propagation
The patched fetch now tries ALS context first (getAuthToken), then falls back to BLINK_INVOCATION_AUTH_TOKEN env var for backwards compatibility with older blink package versions that don't have Agent.fetch() with ALS context re-establishment. WARNING: The env var approach has race conditions with concurrent requests in Node.js. It's safe for Lambda (single request at a time) but users should upgrade to a new blink version for proper concurrent request support.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Manually tested to ensure it works. Removed a mistaken duplicate
runtimepackage atinternal/api/runtimeadded during Turbopack migration.