Skip to content

feat: consolidate user identity context key and propagate user name#2760

Merged
akshaydeo merged 1 commit intov1.5.0from
feature/04-16-feat_consolidate_user_identity_context_key_and_propagate_user_name
Apr 17, 2026
Merged

feat: consolidate user identity context key and propagate user name#2760
akshaydeo merged 1 commit intov1.5.0from
feature/04-16-feat_consolidate_user_identity_context_key_and_propagate_user_name

Conversation

@danpiths
Copy link
Copy Markdown
Collaborator

@danpiths danpiths commented Apr 16, 2026

Summary

Consolidates the Bifrost context key used for user identity: removes the
governance-scoped BifrostContextKeyGovernanceUserID in favor of a single
BifrostContextKeyUserID (bifrost-user-id), and adds a companion
BifrostContextKeyUserName (bifrost-user-name). The user name is threaded
through the logging + realtime relay paths and persisted as a new user_name
column on the logs table so downstream UIs can display it without a separate
lookup.

Changes

  • core/schemas/bifrost.go: drop BifrostContextKeyGovernanceUserID; change
    BifrostContextKeyUserID value from "user_id" to "bifrost-user-id"; add
    companion BifrostContextKeyUserName next to it. Both carry matching doc
    annotations ("set by enterprise auth middleware — DO NOT SET THIS MANUALLY")
    so the pair is discoverable together.
  • Update every caller of the old governance-scoped key to use
    BifrostContextKeyUserID: core/mcp/toolmanager.go,
    framework/oauth2/main.go, plugins/governance/main.go,
    transports/bifrost-http/handlers/mcpserver.go,
    transports/bifrost-http/handlers/realtime_client_secrets.go (+ its test),
    transports/bifrost-http/handlers/webrtc_realtime.go.
  • plugins/logging/main.go + plugins/logging/writer.go: read UserName from
    context and thread it through applyOutputFieldsToEntry to the log entry.
  • transports/bifrost-http/handlers/realtime_client_secrets.go +
    webrtc_realtime.go: propagate UserName from the request context onto the
    bifrost context (and through the realtime relay context).
  • framework/logstore/tables.go: add nullable UserName *string to the Log
    model with a varchar(255) type.
  • framework/logstore/migrations.go: add
    migrationAddUserNameColumn — nullable column add, safe on Postgres (metadata
    only, no rewrite).

Type of change

  • Bug fix
  • Feature
  • Refactor
  • Documentation
  • Chore/CI

Affected areas

  • Core (Go)
  • Transports (HTTP)
  • Providers/Integrations
  • Plugins
  • UI (React)
  • Docs

How to test

# Core/Transports
go version
go test ./...

# Logstore migration smoke test: apply the migration on a pre-existing DB and
# confirm the user_name column is present on the `logs` table.

Verify end-to-end:

  1. Attach the BifrostContextKeyUserName value via the enterprise auth
    middleware (or X-Bf-User-Id / OAuth flow that sets user identity).
  2. Issue a chat completion through a governed virtual key.
  3. Inspect the resulting log row — user_name should be populated alongside
    the existing user_id.

Realtime:

  1. Mint a client secret via /v1/realtime/client_secrets with
    user-identity headers set and confirm the governance evaluation receives the
    consolidated UserID and the relay context carries both UserID and
    UserName.

No new configs or environment variables are introduced.

Screenshots/Recordings

N/A — backend-only change.

Breaking changes

  • Yes
  • No

The old BifrostContextKeyGovernanceUserID constant is removed, but it was
only documented as "set by enterprise governance plugin — DO NOT SET THIS
MANUALLY", so external callers should not be referencing it. Plugins and
handlers in this repo are updated in-place.

The BifrostContextKeyUserID string value changes from "user_id" to
"bifrost-user-id". Any external code that serialized this context key by its
raw string must be updated.

Related issues

N/A

Security considerations

  • The new user_name column stores a user-supplied display name on log rows.
    It inherits the same retention, access-control, and PII posture as the
    existing user_id column.
  • Context keys remain Bifrost-internal and are still not settable from request
    headers without explicit plugin/middleware cooperation.

Checklist

  • I read docs/contributing/README.md and followed the guidelines
  • I added/updated tests where appropriate
  • I updated documentation where needed
  • I verified builds succeed (Go and UI)
  • I verified the CI pipeline passes locally if applicable

@danpiths danpiths requested a review from akshaydeo April 16, 2026 11:10
@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Copy link
Copy Markdown
Collaborator Author

danpiths commented Apr 16, 2026

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 16, 2026

📝 Walkthrough

Walkthrough

Retires BifrostContextKeyGovernanceUserID, renames BifrostContextKeyUserID to a namespaced key, adds BifrostContextKeyUserName, propagates these context-key changes across OAuth, governance, logging, and HTTP transport layers, and adds a nullable user_name column plus migration to logs.

Changes

Cohort / File(s) Summary
Context Key Definitions
core/schemas/bifrost.go
Removed BifrostContextKeyGovernanceUserID; changed BifrostContextKeyUserID value to a namespaced string; added BifrostContextKeyUserName.
Log Model & Migration
framework/logstore/tables.go, framework/logstore/migrations.go
Added UserName *string to Log model and new migration logs_add_user_name_column to add/drop user_name column.
OAuth & MCP Identity Flow
core/mcp/toolmanager.go, framework/oauth2/main.go
Switched per-user identity extraction to use BifrostContextKeyUserID for session/token lookup and OAuth flow.
Governance Plugin Hooks
plugins/governance/main.go
Updated governance hooks to read enterprise user identity from BifrostContextKeyUserID instead of the removed governance key.
Logging Plugin & Writer
plugins/logging/main.go, plugins/logging/writer.go
PostLLMHook now reads userID and userName from context; applyOutputFieldsToEntry signature updated to accept userName and conditionally set entry.UserName.
HTTP Transport Handlers & Tests
transports/bifrost-http/handlers/mcpserver.go, .../realtime_client_secrets.go, .../webrtc_realtime.go, .../realtime_client_secrets_test.go
Context propagation changed to use BifrostContextKeyUserID, added propagation of BifrostContextKeyUserName; tests adjusted to set the new keys.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I nibble keys both new and old,
Namespaced hops and a username bold,
Logs gained a name, migrations done,
Contexts leap onward—one by one,
I twitch my whiskers, then I run. 🌿

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'consolidate user identity context key and propagate user name' accurately and concisely describes the main changes in this PR.
Description check ✅ Passed PR description comprehensively covers summary, changes, type, affected areas, testing, breaking changes, and security considerations with clear examples.

✏️ 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 feature/04-16-feat_consolidate_user_identity_context_key_and_propagate_user_name

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

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 16, 2026

Confidence Score: 5/5

Safe to merge — migration is metadata-only, context propagation is consistent, and the only finding is a cosmetic variable naming nit.

All remaining findings are P2 style suggestions. The migration is safe on Postgres, the GORM model matches the DB column, and the relay/logging propagation follows established patterns throughout the codebase.

No files require special attention.

Important Files Changed

Filename Overview
core/schemas/bifrost.go Removes BifrostContextKeyGovernanceUserID, changes BifrostContextKeyUserID value to "bifrost-user-id", and adds BifrostContextKeyUserName — correct placement and documentation.
framework/logstore/migrations.go Adds migrationAddUserNameColumn at the correct position in the migration chain; nullable column add is metadata-only on Postgres — safe.
framework/logstore/tables.go Adds UserName *string with varchar(255) to the Log model; consistent with existing nullable user-identity columns.
plugins/logging/main.go Reads userName from context via BifrostContextKeyUserName and passes it to applyOutputFieldsToEntry — wired correctly in PostLLMHook.
plugins/logging/writer.go applyOutputFieldsToEntry updated to accept userName and write it to entry.UserName — follows existing nullable-pointer pattern correctly.
transports/bifrost-http/handlers/realtime_client_secrets.go Extracts BifrostContextKeyUserID and BifrostContextKeyUserName from fasthttp user values and sets them on bifrostCtx; stale variable name governanceUserID left from old code.
transports/bifrost-http/handlers/webrtc_realtime.go newRealtimeRelayContext now propagates BifrostContextKeyUserName alongside BifrostContextKeyUserID to relay context — consistent with existing propagation pattern.
plugins/governance/main.go Updated to use BifrostContextKeyUserID in all four call sites — consistent substitution for the removed BifrostContextKeyGovernanceUserID.
transports/bifrost-http/handlers/realtime_client_secrets_test.go Existing tests updated for the consolidated key; no new tests for user-name propagation (minor gap).

Reviews (5): Last reviewed commit: "feat: consolidate user identity context ..." | Re-trigger Greptile

Comment thread core/schemas/bifrost.go Outdated
Comment thread core/schemas/bifrost.go Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
plugins/governance/main.go (1)

1436-1477: ⚠️ Potential issue | 🟠 Major

User-authenticated MCP calls stop being tracked here.

Line 1441 clears virtualKey when userID is present, and Line 1446 then returns before any UsageUpdate is queued. After this key migration, MCP requests carrying schemas.BifrostContextKeyUserID will skip post-call accounting entirely, so user-scoped governance limits/cost tracking never advance.

💡 Suggested fix
 	// When user auth is present, skip VK usage tracking to avoid double-counting
 	if userID != "" {
 		virtualKey = ""
 	}

-	// Skip if no virtual key
-	if virtualKey == "" {
+	// Skip only when neither a virtual key nor a user identity is available.
+	if virtualKey == "" && userID == "" {
 		return resp, bifrostErr, nil
 	}
@@
 	usageUpdate := &UsageUpdate{
 		VirtualKey:   virtualKey,
+		UserID:       userID,
 		Success:      success,
 		Cost:         toolCost,
 		RequestID:    requestID,
 		IsStreaming:  false,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/governance/main.go` around lines 1436 - 1477, The code clears
virtualKey when userID != "" and then returns early, which prevents creating and
queuing the UsageUpdate (so user-authenticated MCP calls are never accounted);
instead, stop returning early — always build and queue the UsageUpdate even when
userID is present: preserve the existing virtualKey/clear it only for
attribution logic (or populate a new UserID field on UsageUpdate if available)
and remove the early return after setting virtualKey; ensure the UsageUpdate
(referenced by UsageUpdate, virtualKey, userID, requestID) is created and queued
regardless of userID so MCP post-call accounting runs for user-authenticated
requests.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@plugins/governance/main.go`:
- Around line 1436-1477: The code clears virtualKey when userID != "" and then
returns early, which prevents creating and queuing the UsageUpdate (so
user-authenticated MCP calls are never accounted); instead, stop returning early
— always build and queue the UsageUpdate even when userID is present: preserve
the existing virtualKey/clear it only for attribution logic (or populate a new
UserID field on UsageUpdate if available) and remove the early return after
setting virtualKey; ensure the UsageUpdate (referenced by UsageUpdate,
virtualKey, userID, requestID) is created and queued regardless of userID so MCP
post-call accounting runs for user-authenticated requests.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1211572b-2486-447f-a07b-66941298fd9d

📥 Commits

Reviewing files that changed from the base of the PR and between d56fa10 and 50ff0e0.

📒 Files selected for processing (12)
  • core/mcp/toolmanager.go
  • core/schemas/bifrost.go
  • framework/logstore/migrations.go
  • framework/logstore/tables.go
  • framework/oauth2/main.go
  • plugins/governance/main.go
  • plugins/logging/main.go
  • plugins/logging/writer.go
  • transports/bifrost-http/handlers/mcpserver.go
  • transports/bifrost-http/handlers/realtime_client_secrets.go
  • transports/bifrost-http/handlers/realtime_client_secrets_test.go
  • transports/bifrost-http/handlers/webrtc_realtime.go

coderabbitai[bot]
coderabbitai Bot previously approved these changes Apr 16, 2026
@danpiths danpiths force-pushed the feature/04-16-feat_consolidate_user_identity_context_key_and_propagate_user_name branch from 50ff0e0 to af73b47 Compare April 16, 2026 12:56
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
transports/bifrost-http/handlers/realtime_client_secrets.go (1)

100-105: Minor naming inconsistency: governanceUserID variable name is now misleading.

Since BifrostContextKeyUserID is no longer governance-scoped (after removing BifrostContextKeyGovernanceUserID), the variable name governanceUserID is slightly confusing. Consider renaming to userID for clarity.

♻️ Suggested rename for clarity
-if governanceUserID, ok := ctx.UserValue(schemas.BifrostContextKeyUserID).(string); ok && governanceUserID != "" {
-	bifrostCtx.SetValue(schemas.BifrostContextKeyUserID, governanceUserID)
+if userID, ok := ctx.UserValue(schemas.BifrostContextKeyUserID).(string); ok && userID != "" {
+	bifrostCtx.SetValue(schemas.BifrostContextKeyUserID, userID)
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@transports/bifrost-http/handlers/realtime_client_secrets.go` around lines 100
- 105, The variable name governanceUserID is misleading because
BifrostContextKeyUserID is no longer governance-scoped; rename the local
variable to userID in the block that reads
ctx.UserValue(schemas.BifrostContextKeyUserID) and then calls
bifrostCtx.SetValue(schemas.BifrostContextKeyUserID, ...), so change references
of governanceUserID to userID to improve clarity in the
realtime_client_secrets.go snippet.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@transports/bifrost-http/handlers/realtime_client_secrets.go`:
- Around line 100-105: The variable name governanceUserID is misleading because
BifrostContextKeyUserID is no longer governance-scoped; rename the local
variable to userID in the block that reads
ctx.UserValue(schemas.BifrostContextKeyUserID) and then calls
bifrostCtx.SetValue(schemas.BifrostContextKeyUserID, ...), so change references
of governanceUserID to userID to improve clarity in the
realtime_client_secrets.go snippet.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 88268575-27b2-4046-8297-2671bec02783

📥 Commits

Reviewing files that changed from the base of the PR and between 50ff0e0 and af73b47.

📒 Files selected for processing (12)
  • core/mcp/toolmanager.go
  • core/schemas/bifrost.go
  • framework/logstore/migrations.go
  • framework/logstore/tables.go
  • framework/oauth2/main.go
  • plugins/governance/main.go
  • plugins/logging/main.go
  • plugins/logging/writer.go
  • transports/bifrost-http/handlers/mcpserver.go
  • transports/bifrost-http/handlers/realtime_client_secrets.go
  • transports/bifrost-http/handlers/realtime_client_secrets_test.go
  • transports/bifrost-http/handlers/webrtc_realtime.go
✅ Files skipped from review due to trivial changes (4)
  • transports/bifrost-http/handlers/mcpserver.go
  • core/mcp/toolmanager.go
  • plugins/governance/main.go
  • framework/logstore/tables.go
🚧 Files skipped from review as they are similar to previous changes (5)
  • transports/bifrost-http/handlers/webrtc_realtime.go
  • plugins/logging/main.go
  • transports/bifrost-http/handlers/realtime_client_secrets_test.go
  • framework/logstore/migrations.go
  • core/schemas/bifrost.go

coderabbitai[bot]
coderabbitai Bot previously approved these changes Apr 16, 2026
@danpiths danpiths force-pushed the feature/04-16-feat_consolidate_user_identity_context_key_and_propagate_user_name branch 2 times, most recently from 529faf5 to 313d58b Compare April 17, 2026 07:42
@danpiths danpiths force-pushed the feature/04-16-feat_consolidate_user_identity_context_key_and_propagate_user_name branch from 313d58b to 3bd057e Compare April 17, 2026 11:05
Copy link
Copy Markdown
Contributor

akshaydeo commented Apr 17, 2026

Merge activity

  • Apr 17, 5:17 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Apr 17, 5:18 PM UTC: @akshaydeo merged this pull request with Graphite.

@akshaydeo akshaydeo merged commit 34d5d79 into v1.5.0 Apr 17, 2026
15 of 17 checks passed
@akshaydeo akshaydeo deleted the feature/04-16-feat_consolidate_user_identity_context_key_and_propagate_user_name branch April 17, 2026 17:18
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.

3 participants