Skip to content

feat: temp access tokens - #3603

Merged
akshaydeo merged 1 commit into
devfrom
05-19-feat_temp_access_tokens_backend
May 20, 2026
Merged

feat: temp access tokens#3603
akshaydeo merged 1 commit into
devfrom
05-19-feat_temp_access_tokens_backend

Conversation

@roroghost17

@roroghost17 roroghost17 commented May 19, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a temp-access-token primitive that authorizes browser access to specific, narrow-scoped
pages without requiring a full dashboard login. The motivating case: when dashboard auth is
enabled with username/password, an end user holding only a VK couldn't complete an MCP per-user
OAuth flow because /workspace/mcp-sessions/auth?flow=<id> required a dashboard session — they
had no way to authenticate. Now the inline-401 URL the server emits carries a short-lived token
in the URL fragment (#t=…); the auth page validates that token against a per-scope route
allowlist and renders without dashboard chrome. The same primitive is reusable for any future
flow that needs "anonymous visitor with a server-emitted URL".

Changes

Backend — framework/temptoken (new package)

  • Service.Mint(scope, resourceID, ttl) → returns plaintext, persists hash + encrypted at-rest
    copy. SHA-256 lookup column, AES-256-GCM via framework/encrypt (mirrors the SessionsTable
    pattern).
  • Service.Validate(plaintext, method, path) → row lookup, expiry check, scope's allowed-routes
    check (with {id} substitution against the row's resource_id).
  • Service.DeleteByResourceID(scope, resourceID) → lifecycle-driven invalidation. Caller burns
    the token when the work it authorized completes.
  • Registry holds startup-registered Scope definitions (allowed routes, MaxTTL,
    ResourceIDInPath).

Backend — DB schema

  • New temp_tokens table: id, token (encrypted), token_hash (SHA-256, unique), scope, resource_id, expires_at, created_at, updated_at, encryption_status. Indexes on scope,
    resource_id, expires_at.
  • Migration via gormigrate (migrationAddTempTokensTable), wired into EncryptPlaintextRows for
    at-rest re-encryption.

Backend — wiring

  • mcp_auth scope registered at server boot in handlers/temp_token_scopes.go. Routes: GET /api/oauth/per-user/flows/{id} and .../start. MaxTTL 15min.
  • OAuth2Provider.InitiateUserOAuthFlow mints a mcp_auth token bound to the flow's session ID
    and appends #t=<plaintext> to the returned frontend URL. Mint failure is non-fatal —
    dashboard-authenticated callers still get a usable URL.
  • OAuth2Provider.cleanupFlow helper deletes both the flow row and any associated temp tokens on
    every terminal transition in CompleteUserOAuthFlow (success or any of 5 failure branches).
  • Per-user OAuth sweep worker also calls DeleteExpiredTempTokens (the comment claiming this
    existed was previously aspirational).
  • Auth middleware grows a temp-token fallback branch (only fires on the "no Authorization header,
    no valid cookie" path). Cookie/Bearer auth still takes precedence.
  • OAuth callback handler reads the dashboard cookie at completion time to branch the redirect:
    admins → /workspace/mcp-sessions?completed=1, anonymous temp-token visitors → new
    /workspace/mcp-sessions/auth-success.

Frontend — React

  • <TempTokenScope> wrapper: reads the #t=… fragment in a useState initializer (synchronous,
    before child effects fire), installs module-level state used by baseApi.prepareHeaders to
    attach X-Bifrost-Temp-Token, sets a global-401-suppression flag, and strips the fragment via
    history.replaceState so it doesn't leak in Referer headers on outbound navigation.
  • ClientLayout learns two staticData flags: tempTokenScoped (route is anonymous-friendly;
    per-visitor layout decision based on is-auth-enabled probe + fragment presence) and
    publicShell (always render MinimalShell, no auth probe, no API calls — for the post-OAuth
    success page).
  • New routes: /workspace/mcp-sessions/auth-success (public landing), updated
    /workspace/mcp-sessions/auth with InvalidLinkView for expired/missing tokens.
  • baseApi: attach X-Bifrost-Temp-Token when set, skip global /login redirect on 401 when
    suppression flag is active.

Notable design decisions

  • Generic primitive, not mcp_auth-specific. Scope is a declarative type with allowed routes
    and TTL. New flows register a scope at startup; the framework owns mint/validate/delete.
  • Application-layer cascade, not DB FK. cleanupFlow calls DeleteByResourceID rather than
    ON DELETE CASCADE on a foreign key. Keeps temp_tokens.resource_id opaque — future scopes that
    bind to non-OAuth resources stay clean.
  • Delete, not "mark consumed". No consumed_at column — invalidation is row deletion.
    Atomic, no Validate-side gymnastics, smaller schema. Dropped a column I'd originally added during
    scaffolding.
  • URL fragment, not query param. #t=… never reaches the server in logs or Referer. Stripped
    from the URL on mount so it doesn't survive into outbound navigation either.
  • Per-visitor layout, not per-route. tempTokenScoped advertises "this route may be visited
    anonymously"; the actual MinimalShell vs. full-chrome decision is made per-request from a cheap
    whitelisted auth probe.

Type of change

  • Feature

Affected areas

  • Core (Go) — two context keys in core/schemas/bifrost.go
  • Transports (HTTP) — middleware, OAuth handler, MCP sessions handler, server wiring
  • Providers/Integrations
  • Plugins
  • UI (React)
  • Docs (private design doc in bifrost/private/temp-tokens.md; no user-facing docs added)

How to test

# Backend
go version  # >= 1.22
cd framework
go test ./temptoken/...   # 8 tests: mint/validate/expiry/route matching/registry
go build ./...
cd ../transports/bifrost-http
go build ./...

# UI
cd ui
npm i
npx tsc --noEmit
npm run build   # rebuilds embedded UI at transports/bifrost-http/ui/

@CLAassistant

CLAassistant commented May 19, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@coderabbitai

coderabbitai Bot commented May 19, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 51b525ad-cc6d-48f8-9ff2-fc5eedb6b6ad

📥 Commits

Reviewing files that changed from the base of the PR and between 0894aaa and adb3920.

📒 Files selected for processing (11)
  • core/schemas/bifrost.go
  • framework/configstore/encryption.go
  • framework/configstore/migrations.go
  • framework/configstore/rdb.go
  • framework/configstore/store.go
  • framework/configstore/tables/temp_token.go
  • framework/oauth2/main.go
  • framework/temptoken/scope.go
  • framework/temptoken/service.go
  • framework/temptoken/service_test.go
  • framework/temptoken/sweeper.go
💤 Files with no reviewable changes (9)
  • framework/configstore/store.go
  • framework/configstore/tables/temp_token.go
  • framework/temptoken/scope.go
  • framework/temptoken/service.go
  • framework/configstore/rdb.go
  • framework/oauth2/main.go
  • framework/temptoken/sweeper.go
  • framework/configstore/migrations.go
  • framework/temptoken/service_test.go

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Temporary-token auth: minting, validation, scoped route rules, per-token expiry, background sweep worker, and middleware fallback for requests.
    • OAuth integration: tokens issued/consumed during per-user OAuth flows with consistent success/failure redirects and new post-auth pages.
    • Client & UX: minimal-shell routing, fragment-based token handling, and optional suppression of global 401 redirects for scoped flows.
  • Chores

    • Storage/migrations and at-rest token encryption support added.
  • Tests

    • Expanded unit tests for minting, validation, TTL reaping, and registry rules.

Walkthrough

Adds scoped short-lived temp tokens end-to-end: DB model with encryption and migration, ConfigStore CRUD, scope registry and mint/validate service, OAuth mint/cleanup, middleware fallback, sweep worker, frontend fragment handling and RTK Query header integration, plus tests and routes.

Changes

Temporary Token Authentication System

Layer / File(s) Summary
TempToken model and ConfigStore APIs
framework/configstore/tables/temp_token.go, framework/configstore/store.go, framework/configstore/rdb.go, core/schemas/bifrost.go
Adds TempToken GORM model with Token/TokenHash/Scope/ResourceID/ExpiresAt and encryption hooks; extends ConfigStore and RDBConfigStore with Create/GetByHash/DeleteByResourceID/DeleteExpired; adds context keys for temp-token scope and resource id.
Migrations and plaintext encryption
framework/configstore/migrations.go, framework/configstore/encryption.go
Adds migration to create/drop temp_tokens table and EncryptPlaintextRows support to batch-migrate plain-text temp tokens by re-saving rows to trigger encryption hooks.
Scope registry and Service implementation
framework/temptoken/scope.go, framework/temptoken/service.go
Implements Scope/RoutePattern and concurrency-safe Registry; Service provides Mint, Validate, DeleteExpired, DeleteByResourceID, typed errors, and secure plaintext generation.
Service tests and fakeStore
framework/temptoken/service_test.go
Adds in-memory fakeStore implementing temp-token persistence and expiry; tests cover minting validation, route/method/resource checks, expiry, unknown tokens, deletion, and registry validation.
Periodic expired-token reaper
framework/temptoken/sweeper.go
Adds SweepWorker to periodically call Service.DeleteExpired with lifecycle control and configurable interval.
OAuth2 flow: mint and cleanup
framework/oauth2/main.go
Adds SetTempTokenService, cleanupFlow, mints mcp_auth temp token in InitiateUserOAuthFlow (appends #t= fragment), and uses cleanupFlow across CompleteUserOAuthFlow paths.
Auth middleware temp-token fallback
transports/bifrost-http/handlers/middlewares.go
Extends AuthMiddleware with optional tempTokensService; tryTempTokenOrUnauthorized validates X-Bifrost-Temp-Token and injects scope/resource into request context as a last-resort auth path.
OAuth2 callback redirect logic
transports/bifrost-http/handlers/oauth2.go
Introduces perUserCallbackRedirect to route authenticated vs anonymous visitors to /workspace/mcp-sessions or /workspace/mcp-sessions/auth-success/auth-failed with error encoding.
Server bootstrap: init, scope registration, worker start
transports/bifrost-http/server/server.go
Bootstrap creates TempTokens service, registers scopes, starts SweepWorker, wires service into OAuthProvider and AuthMiddleware, and stops worker on bootstrap/shutdown cleanup paths.
mcp_auth scope definition and registration
transports/bifrost-http/handlers/temp_token_scopes.go
Defines mcpAuthScope allowlisting OAuth flow GET routes with {id} resource binding and 15-minute TTL, plus RegisterTempTokenScopes.
Test mock ConfigStore
transports/bifrost-http/lib/config_test.go
Adds stub temp-token methods to MockConfigStore for tests.
Frontend temp-token state and RTK Query integration
ui/lib/store/apis/tempToken.ts, ui/lib/store/apis/baseApi.ts
Adds module-level active token and suppress-global-401 flag; baseApi injects X-Bifrost-Temp-Token header and can suppress global 401 redirect handling when set.
TempTokenScope component
ui/components/tempTokenScope.tsx
Adds TempTokenScope that reads #t= fragment, installs token into shared state, strips fragment to avoid Referer leakage, and cleans up on unmount; includes fragment parsing helper.
ClientLayout shell selection and auth routes
ui/app/clientLayout.tsx, ui/app/workspace/mcp-sessions/*
ClientLayout chooses MinimalShell vs full dashboard for temp-token/public routes; wraps /workspace/mcp-sessions/auth in TempTokenScope; adds auth-success/auth-failed pages and shows InvalidLinkView on expired/invalid links.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested reviewers

  • akshaydeo
  • danpiths

Poem

🐰 A token so fleeting, bound to a flow,
Hops through OAuth, then away it will go—
Encrypted at rest, in context it flies,
Fifteen minutes pass and the sweeper replies. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 39.13% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: temp access tokens' clearly summarizes the main change—adding a temporary access token feature—and is concise and specific.
Description check ✅ Passed The description is comprehensive and well-structured, covering all required template sections including Summary, Changes (backend framework, DB schema, wiring, frontend), Type of change, Affected areas, How to test, and design decisions.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 05-19-feat_temp_access_tokens_backend

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies"


Comment @coderabbitai help to get the list of available commands and usage tips.

roroghost17 commented May 19, 2026

Copy link
Copy Markdown
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@roroghost17
roroghost17 force-pushed the 05-19-feat_temp_access_tokens_backend branch from af65005 to 88e9e5f Compare May 19, 2026 19:12
@Pratham-Mishra04
Pratham-Mishra04 changed the base branch from 05-18-refactor_mcp_per_user_oauth_flow_refactor to graphite-base/3603 May 19, 2026 19:24
@roroghost17
roroghost17 force-pushed the graphite-base/3603 branch from f649709 to 791502b Compare May 19, 2026 19:47
@roroghost17
roroghost17 force-pushed the 05-19-feat_temp_access_tokens_backend branch from 88e9e5f to 2dc32c9 Compare May 19, 2026 19:47
@roroghost17 roroghost17 changed the title feat: temp access tokens backend feat: temp access tokens May 19, 2026
@roroghost17
roroghost17 force-pushed the 05-19-feat_temp_access_tokens_backend branch from 2dc32c9 to 3cb1787 Compare May 19, 2026 20:09
@roroghost17
roroghost17 changed the base branch from graphite-base/3603 to 05-18-refactor_mcp_per_user_oauth_flow_refactor May 19, 2026 20:09
@Pratham-Mishra04
Pratham-Mishra04 changed the base branch from 05-18-refactor_mcp_per_user_oauth_flow_refactor to graphite-base/3603 May 19, 2026 20:10
@roroghost17
roroghost17 force-pushed the 05-19-feat_temp_access_tokens_backend branch from 3cb1787 to d6036cb Compare May 19, 2026 20:30
@roroghost17
roroghost17 force-pushed the graphite-base/3603 branch from 791502b to bb4e5d4 Compare May 19, 2026 20:30
@roroghost17
roroghost17 changed the base branch from graphite-base/3603 to 05-18-refactor_mcp_per_user_oauth_flow_refactor May 19, 2026 20:30
@roroghost17
roroghost17 marked this pull request as ready for review May 19, 2026 20:38
@coderabbitai
coderabbitai Bot requested a review from akshaydeo May 19, 2026 20:43
@greptile-apps

greptile-apps Bot commented May 19, 2026

Copy link
Copy Markdown
Contributor

Confidence Score: 5/5

This PR is safe to merge. The new temp-token path is additive — cookie and Bearer auth take strict precedence, and all existing auth flows are unmodified.

The mint/validate/delete lifecycle is carefully constructed: SHA-256 hash lookup avoids storing plaintext, AES-256-GCM at-rest encryption mirrors the established sessions pattern, and route matching is exact after resource_id substitution so a token for one flow cannot authorize another. Migration, sweep worker, and lifecycle cleanup are all correctly wired.

No files require special attention.

Important Files Changed

Filename Overview
framework/temptoken/service.go Clean mint/validate/delete service; hash-based lookup, injected clock for tests, all error paths correctly typed.
framework/temptoken/scope.go Route pattern registry with exact-match after {id} substitution; duplicate-registration and validation guards are correct.
framework/temptoken/service_test.go Good coverage of mint/validate/expiry/route-matching/registry cases using a clean in-memory fake store.
framework/configstore/tables/temp_token.go BeforeSave correctly hashes plaintext before encrypting; AfterFind decrypts only encrypted rows.
transports/bifrost-http/handlers/middlewares.go Temp-token fallback branch correctly fires only when Authorization header is absent and cookie auth has failed.
transports/bifrost-http/handlers/temp_token_scopes.go mcpAuthScope routes match the registered GET endpoints in mcp_sessions.go; MaxTTL aligns with the flow row expiry.
transports/bifrost-http/handlers/oauth2.go perUserCallbackRedirect correctly branches on dashboard-session presence.
framework/oauth2/main.go Mint called after flow row insert/update; non-fatal on failure; cleanupFlow deletes temp tokens on every terminal transition.
ui/components/tempTokenScope.tsx Uses useState initializer to install module state before child effects; Strict Mode concern noted in previous thread.
ui/app/clientLayout.tsx hadFragmentTempToken correctly snapshotted at mount; authLoading guard prevents premature useGetCoreConfigQuery call.
ui/lib/store/apis/baseApi.ts Temp token attached in prepareHeaders; suppression check correctly guards only the non-enterprise 401 redirect path.
framework/configstore/encryption.go encryptPlaintextTempTokens follows the established sessions pattern correctly.
framework/configstore/migrations.go migrationAddTempTokensTable correctly creates the table with rollback support.
framework/temptoken/sweeper.go 5-minute sweep interval, runs once on start, uses sync.Once for safe Stop().

Reviews (5): Last reviewed commit: "feat: temp access tokens backend" | Re-trigger Greptile

Comment thread ui/components/tempTokenScope.tsx Outdated
Comment thread framework/oauth2/main.go
Comment thread transports/bifrost-http/handlers/oauth2.go

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 8

🧹 Nitpick comments (4)
framework/temptoken/service_test.go (2)

75-84: ⚡ Quick win

Use MCPAuthScopeName in tests to avoid scope-name drift.

The test suite hardcodes "mcp_auth" in multiple places. Reusing the exported constant keeps tests coupled to the canonical scope contract.

♻️ Proposed fix
 func mcpAuthScope() Scope {
 	return Scope{
-		Name: "mcp_auth",
+		Name: MCPAuthScopeName,
@@
 func TestMintRejectsTTLOverMax(t *testing.T) {
 	svc, _ := newServiceWithMcpAuth(t)
-	_, err := svc.Mint(context.Background(), "mcp_auth", "flow-1", time.Hour)
+	_, err := svc.Mint(context.Background(), MCPAuthScopeName, "flow-1", time.Hour)
@@
 func TestValidateHappyPath(t *testing.T) {
 	svc, _ := newServiceWithMcpAuth(t)
-	tok, err := svc.Mint(context.Background(), "mcp_auth", "flow-abc", 5*time.Minute)
+	tok, err := svc.Mint(context.Background(), MCPAuthScopeName, "flow-abc", 5*time.Minute)

Also applies to: 99-123, 140-174

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@framework/temptoken/service_test.go` around lines 75 - 84, Replace the
hardcoded scope name "mcp_auth" in the test helper mcpAuthScope() with the
exported constant MCPAuthScopeName (i.e. set Scope{Name: MCPAuthScopeName, ...})
and likewise update any other test occurrences that directly use the literal
"mcp_auth" so tests reference the canonical MCPAuthScopeName constant; update
mcpAuthScope(), any direct string usages in assertions or setup, and imports if
needed so tests compile against the exported symbol.

192-218: ⚡ Quick win

Add unit tests for DeleteByResourceID lifecycle cleanup.

This API is part of the auth-flow invalidation contract but currently has no direct coverage.

✅ Suggested tests
+func TestDeleteByResourceIDRemovesMatchingTokens(t *testing.T) {
+	svc, _ := newServiceWithMcpAuth(t)
+	_, _ = svc.Mint(context.Background(), MCPAuthScopeName, "flow-abc", 5*time.Minute)
+	_, _ = svc.Mint(context.Background(), MCPAuthScopeName, "flow-abc", 5*time.Minute)
+	_, _ = svc.Mint(context.Background(), MCPAuthScopeName, "flow-other", 5*time.Minute)
+
+	n, err := svc.DeleteByResourceID(context.Background(), MCPAuthScopeName, "flow-abc")
+	if err != nil {
+		t.Fatalf("delete: %v", err)
+	}
+	if n != 2 {
+		t.Fatalf("expected 2 deleted, got %d", n)
+	}
+}
+
+func TestDeleteByResourceIDEmptyInputsNoOp(t *testing.T) {
+	svc, _ := newServiceWithMcpAuth(t)
+	n, err := svc.DeleteByResourceID(context.Background(), "", "flow-abc")
+	if err != nil || n != 0 {
+		t.Fatalf("expected no-op delete for empty scope, got n=%d err=%v", n, err)
+	}
+}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@framework/temptoken/service_test.go` around lines 192 - 218, Add unit tests
for the DeleteByResourceID lifecycle: create a Registry (NewRegistry), Register
a Scope that includes ResourceIDInPath (e.g., "{id}") and AllowedRoutes
containing the placeholder, Issue/Create at least two tokens tied to the same
resource ID and one tied to a different resource, then call
DeleteByResourceID(resourceID) and assert that tokens for that resource are
removed while others remain; also assert calling DeleteByResourceID on a
non-existent resource is a no-op. Use existing test helpers/patterns from
TestRegistry* (e.g., mcpAuthScope or similar scope construction) and reference
DeleteByResourceID and Registry methods so the tests exercise lifecycle cleanup
and invalidation behavior.
ui/components/tempTokenScope.tsx (1)

30-30: ⚡ Quick win

Align component filename with PascalCase convention.

The export is PascalCase, but the file is tempTokenScope.tsx. Rename to TempTokenScope.tsx for consistency with the TSX component naming rule.

As per coding guidelines, ui/**/*.tsx React component files must use PascalCase for component exports and filenames.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/components/tempTokenScope.tsx` at line 30, Rename the file from
tempTokenScope.tsx to TempTokenScope.tsx to match the exported React component
TempTokenScope and PascalCase conventions; update any imports referencing the
old filename throughout the codebase to import from "TempTokenScope" instead of
"tempTokenScope", and ensure the component export signature export default
function TempTokenScope({ name: _name, children }: TempTokenScopeProps) remains
unchanged.
ui/lib/store/apis/baseApi.ts (1)

7-7: ⚡ Quick win

Use the UI alias import for tempToken helpers.

Replace ./tempToken with @/lib/store/apis/tempToken to stay consistent with the UI import convention.

Based on learnings, prefer alias imports using @/... in UI code (e.g., @/lib/...) over relative imports.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/lib/store/apis/baseApi.ts` at line 7, In baseApi.ts replace the relative
import for the tempToken helpers with the UI alias: update the import line that
currently imports getActiveTempToken and getSuppressGlobal401 from "./tempToken"
to import them from "`@/lib/store/apis/tempToken`" so the file uses the standard
UI alias import for these helpers.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@framework/configstore/store.go`:
- Around line 258-265: The mutating temp-token methods must accept an optional
transaction so callers can join their DB transaction; change the signatures of
CreateTempToken, DeleteTempTokensByResourceID and DeleteExpiredTempTokens to
accept a variadic tx parameter (e.g. tx ...*gorm.DB) and update their
implementations to use the provided tx[0] when present or fall back to the store
DB connection otherwise; then update callers (e.g. OAuth/session lifecycle code)
to pass the active *gorm.DB transaction when creating or deleting temp tokens so
token ops commit/rollback with the business-row transaction.

In `@framework/configstore/tables/temp_token.go`:
- Around line 37-57: The BeforeSave/AfterFind hooks on TempToken currently tie
setting t.EncryptionStatus to t.Token being non-empty which breaks partial
selects; change BeforeSave so that when encrypt.IsEnabled() is true you always
set t.EncryptionStatus = EncryptionStatusEncrypted (even if t.Token == ""), but
only call encryptString(&t.Token) when t.Token != ""; likewise update AfterFind
to only call decryptString(&t.Token) when t.Token != "" while still relying on
t.EncryptionStatus to determine whether decryption should be attempted. Ensure
you modify the TempToken.BeforeSave and TempToken.AfterFind code paths and keep
references to encrypt.IsEnabled(), encryptString, decryptString, t.Token and
t.EncryptionStatus as described.

In `@framework/oauth2/main.go`:
- Around line 72-80: The cleanupFlow function currently uses the incoming
request ctx so cancellations can abort the DeleteOauthUserSession and temp token
DeleteByResourceID calls; change it to run detached from the request context by
performing the deletes using a non-cancelable context (e.g. context.Background()
or an existing provider background context like p.bgCtx) and run the cleanup in
a goroutine to ensure it always executes; keep the same calls to
p.configStore.DeleteOauthUserSession and p.tempTokens.DeleteByResourceID (with
temptoken.MCPAuthScopeName and sessionID) and retain the logger.Warn error
handling inside the goroutine.

In `@framework/temptoken/scope.go`:
- Around line 100-106: Register currently stores the AllowedRoutes slice by
reference and Lookup returns it directly, allowing callers to mutate the backing
array and race with validations; update Register (the method that assigns
r.scopes[s.Name] = s) to deep-copy s.AllowedRoutes into a new slice before
persisting the scope (copy the slice header and elements) and update Lookup to
return a copy of the AllowedRoutes slice (not the original backing slice) so
callers receive an immutable view; ensure you reference the AllowedRoutes field
on the scope value and the Register and Lookup methods when making these
changes.

In `@transports/bifrost-http/handlers/middlewares.go`:
- Around line 918-921: APIMiddleware currently treats "/api/oauth" as
whitelisted in shouldSkip(), which also matches "/api/oauth/per-user/..." and
skips auth; update shouldSkip() (in APIMiddleware) to exclude per-user OAuth
routes by either narrowing the whitelist entry for the OAuth routes or adding an
explicit early check that returns false when the request path has the prefix
"/api/oauth/per-user/". Ensure this change preserves the existing behavior for
other "/api/oauth" endpoints but forces requests to reach
m.tryTempTokenOrUnauthorized(ctx, next) (or normal session auth) for per-user
flows.

In `@transports/bifrost-http/handlers/oauth2.go`:
- Around line 86-95: The failure redirect paths need to mirror the
success-branch's session-awareness: locate the OAuth2 callback logic around
cookieToken and validateSession (use symbols cookieToken, validateSession,
ctx.Redirect and the handler that references h.store.ConfigStore) and change any
per-user failure/denial redirects that currently point to
"/workspace/mcp-sessions?...” so that when there is no valid session
(cookieToken == "" or validateSession returns false) they instead redirect to
the public fallback "/workspace/mcp-sessions/auth-success" (use the same
fasthttp.StatusFound handling), while preserving the existing dashboard redirect
for validated sessions.

In `@transports/bifrost-http/server/server.go`:
- Around line 1454-1462: When handlers.RegisterTempTokenScopes(s.TempTokens)
fails, the previously started handlers.NewSignedWSTicketStore assigned to
s.WSTicketStore must be stopped to avoid leaking the running ticket store;
modify the error path in the Bootstrap block so that on regErr != nil you call
the store's shutdown method (e.g. s.WSTicketStore.Stop() or Close(), depending
on the store API) before returning the fmt.Errorf, and handle or log any
returned error from that shutdown call; reference symbols: s.WSTicketStore,
handlers.NewSignedWSTicketStore, s.TempTokens, handlers.RegisterTempTokenScopes.

In `@ui/components/tempTokenScope.tsx`:
- Around line 42-57: The render-time side effects inside the useState
initializer must be moved to a layout effect: remove calls to setActiveTempToken
and setSuppressGlobal401 from the useState(() => { ... }) initializer and
instead compute the initial token there (or return null) and then in a
useLayoutEffect run once (checking window and parsing via
parseTokenFromFragment(window.location.hash)) call setActiveTempToken(token) and
setSuppressGlobal401(true) only when a token is present so mutations occur after
commit but before children effects; also rename the file to PascalCase
(TempTokenScope.tsx) to match the project convention.

---

Nitpick comments:
In `@framework/temptoken/service_test.go`:
- Around line 75-84: Replace the hardcoded scope name "mcp_auth" in the test
helper mcpAuthScope() with the exported constant MCPAuthScopeName (i.e. set
Scope{Name: MCPAuthScopeName, ...}) and likewise update any other test
occurrences that directly use the literal "mcp_auth" so tests reference the
canonical MCPAuthScopeName constant; update mcpAuthScope(), any direct string
usages in assertions or setup, and imports if needed so tests compile against
the exported symbol.
- Around line 192-218: Add unit tests for the DeleteByResourceID lifecycle:
create a Registry (NewRegistry), Register a Scope that includes ResourceIDInPath
(e.g., "{id}") and AllowedRoutes containing the placeholder, Issue/Create at
least two tokens tied to the same resource ID and one tied to a different
resource, then call DeleteByResourceID(resourceID) and assert that tokens for
that resource are removed while others remain; also assert calling
DeleteByResourceID on a non-existent resource is a no-op. Use existing test
helpers/patterns from TestRegistry* (e.g., mcpAuthScope or similar scope
construction) and reference DeleteByResourceID and Registry methods so the tests
exercise lifecycle cleanup and invalidation behavior.

In `@ui/components/tempTokenScope.tsx`:
- Line 30: Rename the file from tempTokenScope.tsx to TempTokenScope.tsx to
match the exported React component TempTokenScope and PascalCase conventions;
update any imports referencing the old filename throughout the codebase to
import from "TempTokenScope" instead of "tempTokenScope", and ensure the
component export signature export default function TempTokenScope({ name: _name,
children }: TempTokenScopeProps) remains unchanged.

In `@ui/lib/store/apis/baseApi.ts`:
- Line 7: In baseApi.ts replace the relative import for the tempToken helpers
with the UI alias: update the import line that currently imports
getActiveTempToken and getSuppressGlobal401 from "./tempToken" to import them
from "`@/lib/store/apis/tempToken`" so the file uses the standard UI alias import
for these helpers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: be613e15-a0b8-4a85-afdb-849a4fe440d1

📥 Commits

Reviewing files that changed from the base of the PR and between bb4e5d4 and d6036cb.

📒 Files selected for processing (24)
  • core/schemas/bifrost.go
  • framework/configstore/encryption.go
  • framework/configstore/migrations.go
  • framework/configstore/rdb.go
  • framework/configstore/store.go
  • framework/configstore/tables/temp_token.go
  • framework/oauth2/main.go
  • framework/oauth2/sync.go
  • framework/temptoken/scope.go
  • framework/temptoken/service.go
  • framework/temptoken/service_test.go
  • transports/bifrost-http/handlers/middlewares.go
  • transports/bifrost-http/handlers/oauth2.go
  • transports/bifrost-http/handlers/temp_token_scopes.go
  • transports/bifrost-http/lib/config_test.go
  • transports/bifrost-http/server/server.go
  • ui/app/clientLayout.tsx
  • ui/app/workspace/mcp-sessions/auth-success/layout.tsx
  • ui/app/workspace/mcp-sessions/auth-success/page.tsx
  • ui/app/workspace/mcp-sessions/auth/layout.tsx
  • ui/app/workspace/mcp-sessions/auth/page.tsx
  • ui/components/tempTokenScope.tsx
  • ui/lib/store/apis/baseApi.ts
  • ui/lib/store/apis/tempToken.ts

Comment thread framework/configstore/store.go
Comment thread framework/configstore/tables/temp_token.go
Comment thread framework/oauth2/main.go
Comment thread framework/temptoken/scope.go
Comment thread transports/bifrost-http/handlers/middlewares.go
Comment thread transports/bifrost-http/handlers/oauth2.go Outdated
Comment thread transports/bifrost-http/server/server.go
Comment thread ui/components/tempTokenScope.tsx Outdated
@roroghost17
roroghost17 force-pushed the 05-19-feat_temp_access_tokens_backend branch 2 times, most recently from a3710a1 to 0894aaa Compare May 19, 2026 22:24
coderabbitai[bot]
coderabbitai Bot previously approved these changes May 19, 2026
@Pratham-Mishra04
Pratham-Mishra04 changed the base branch from 05-18-refactor_mcp_per_user_oauth_flow_refactor to graphite-base/3603 May 20, 2026 04:57
Comment thread framework/oauth2/sync.go Outdated
@roroghost17
roroghost17 force-pushed the 05-19-feat_temp_access_tokens_backend branch from 0894aaa to e8a3444 Compare May 20, 2026 06:19
@roroghost17
roroghost17 force-pushed the graphite-base/3603 branch from bb4e5d4 to 5f7a5b6 Compare May 20, 2026 06:19
@roroghost17
roroghost17 changed the base branch from graphite-base/3603 to 05-18-refactor_mcp_per_user_oauth_flow_refactor May 20, 2026 06:19
@Pratham-Mishra04
Pratham-Mishra04 changed the base branch from 05-18-refactor_mcp_per_user_oauth_flow_refactor to graphite-base/3603 May 20, 2026 06:28
akshaydeo
akshaydeo previously approved these changes May 20, 2026

akshaydeo commented May 20, 2026

Copy link
Copy Markdown
Contributor

Merge activity

  • May 20, 11:01 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • May 20, 11:02 AM UTC: Graphite couldn't merge this PR because it had merge conflicts.
  • May 20, 11:36 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • May 20, 11:36 AM UTC: @akshaydeo merged this pull request with Graphite.

@akshaydeo
akshaydeo changed the base branch from graphite-base/3603 to dev May 20, 2026 11:02
@akshaydeo
akshaydeo dismissed stale reviews from coderabbitai[bot] and themself May 20, 2026 11:02

The base branch was changed.

@akshaydeo
akshaydeo requested a review from a team as a code owner May 20, 2026 11:02
@roroghost17
roroghost17 force-pushed the 05-19-feat_temp_access_tokens_backend branch from e8a3444 to adb3920 Compare May 20, 2026 11:21
@coderabbitai
coderabbitai Bot requested review from akshaydeo and danpiths May 20, 2026 11:22
@akshaydeo
akshaydeo merged commit a2dd1ef into dev May 20, 2026
15 of 16 checks passed
@akshaydeo
akshaydeo deleted the 05-19-feat_temp_access_tokens_backend branch May 20, 2026 11:36
@akshaydeo akshaydeo mentioned this pull request May 20, 2026
18 tasks
akshaydeo added a commit that referenced this pull request May 20, 2026
## Summary

This PR cuts the `v1.5.11` / `v1.3.11` release across core, framework, and all plugins, and introduces a new Claude skill (`release-checklist`) for pre-release migration safety auditing.

## Changes

- **`release-checklist` skill** — Adds `.claude/skills/release-checklist/SKILL.md`, a read-only pre-release audit tool that scans Go-defined database migrations changed in a release for high-scale deadlock/lock-contention risks and boot-time-blocking operations. It produces a structured `PASS`/`WARN`/`FAIL` report with a concrete remediation plan per finding. The skill is designed to grow via an extensible Checks Registry.
- **Version bumps** — `core` → `1.5.11`, `framework` → `1.3.11`, `transports` → `1.5.3`, `plugins/governance` → `1.5.11`, `plugins/logging` → `1.5.11`, `plugins/semanticcache` → `1.5.11`, `plugins/otel` → `1.2.11`, `plugins/maxim` → `1.6.11`, `plugins/prompts` → `1.0.11`, and remaining plugins bumped accordingly.
- **Changelogs populated** — All per-package changelogs updated with the full set of features and fixes shipping in this release.

Key highlights in this release:
- Temporary access tokens for scoped, time-limited API access
- MCP per-user OAuth flow refactor
- Bedrock Mantle inference engine support
- Azure Realtime provider with enriched session tracking
- Direct access control (DAC) and virtual key rotation
- Cluster-aware log metadata and per-node usage aggregation
- Feature flag framework
- Config-hash-based file value override of DB on restart
- Semantic cache plugin rewrite
- Numerous streaming stability, Bedrock, Anthropic, and Gemini fixes
- AWS SDK and dependency security updates

## Type of change

- [ ] Bug fix
- [ ] Feature
- [ ] Refactor
- [ ] Documentation
- [x] Chore/CI

## Affected areas

- [x] Core (Go)
- [x] Transports (HTTP)
- [x] Providers/Integrations
- [x] Plugins
- [x] UI (React)
- [ ] Docs

## How to test

```sh
# Verify version files reflect the new release
cat core/version          # expect 1.5.11
cat framework/version     # expect 1.3.11
cat transports/version    # expect 1.5.3

# Core/Transports
go test ./...
```

To exercise the new `release-checklist` skill, invoke it via Claude with:
```
/release-checklist origin/dev...HEAD
```
Expected output: a structured report with `PASS`/`WARN`/`FAIL` per check and a Remediation Plan table for any findings.

## Screenshots/Recordings

N/A

## Breaking changes

- [ ] Yes
- [x] No

## Related issues

#3603, #3565, #3489, #3334, #3335, #3435, #3554, #3590, #3444, #3198, #3581, #3610, #3599, #3567, #3382, #3461 and others listed in the changelogs.

## Security considerations

- AWS SDK and dependency security updates are included (#3461).
- `FullyRedacted()` for proxy passwords and `MarshalForStorage()` for `ProxyConfig` prevent partial secret leakage in API responses (#3445).
- The `release-checklist` skill is strictly read-only and never modifies files.

## Checklist

- [x] I read `docs/contributing/README.md` and followed the guidelines
- [x] I added/updated tests where appropriate
- [x] I updated documentation where needed
- [x] I verified builds succeed (Go and UI)
- [ ] I verified the CI pipeline passes locally if applicable
@akshaydeo akshaydeo mentioned this pull request May 20, 2026
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.

4 participants