Skip to content

Forward user identity to upstream providers for per-user cost attribution #182

@matifali

Description

@matifali

Context

An enterprise customer has requested the ability to see per-user cost breakdowns on the upstream provider side (e.g. Anthropic Console, OpenAI usage dashboard). Since AI Bridge already authenticates the Coder user and attaches Actor.ID + recorder.Metadata to every request context, we have the information — we just don't forward it to the upstream provider.

Problem

When enterprises use AI Bridge to proxy Claude Code (or other tools) to Anthropic/OpenAI, all requests appear to come from a single API key on the provider's console. There's no way for the customer to correlate provider-side cost reports with individual Coder users.

Proposed Solution

When AI Bridge proxies a request to a supported provider, inject the authenticated Coder user identifier into the provider's native user tracking field.

Provider field mapping

Provider Endpoint Field Status Docs
Anthropic POST /v1/messages metadata.user_id Stable API Reference
OpenAI POST /v1/chat/completions user Stable API Reference
OpenAI POST /v1/responses safety_identifier Stable API Reference

Anthropic example

{
  "model": "claude-sonnet-4-5-20250929",
  "max_tokens": 1024,
  "metadata": {
    "user_id": "<coder-actor-id>"
  },
  "messages": [...]
}

OpenAI /v1/chat/completions example

{
  "model": "gpt-4o",
  "user": "<coder-actor-id>",
  "messages": [...]
}

OpenAI /v1/responses example

{
  "model": "gpt-4.1",
  "safety_identifier": "<coder-actor-id>",
  "input": [...]
}

Implementation Notes

  • The Actor is already available via context.ActorFromContext(ctx) in the interceptor — this is a matter of injecting it into the request body before forwarding upstream.
  • Overwrite policy: If the client sends its own metadata.user_id / user, AI Bridge should overwrite it. The gateway is the source of truth for user identity; trusting client-supplied values would undermine attribution accuracy.
  • Value to send: Actor.ID is the simplest starting point. We may want to make this configurable later (username vs. user ID vs. email). OpenAI recommends hashing to avoid sending PII — we should consider whether to hash the Coder username/email or send the opaque Coder user ID directly.
  • OTEL correlation: Ensure the same identifier is emitted in OTEL spans (Basic tracing with OTel #26) so customers can correlate AI Bridge traces with provider-side reports. This is especially important for Anthropic where provider-side per-user reporting doesn't exist yet — our OTEL data becomes the single source of truth.
  • All three endpoints need this: /v1/messages (Anthropic), /v1/chat/completions (OpenAI), and /v1/responses (OpenAI) are all live today — the implementation should cover all three.

Scope

Phase 1 (this issue):

  • Anthropic metadata.user_id on POST /v1/messages
  • OpenAI user on POST /v1/chat/completions
  • OpenAI safety_identifier on POST /v1/responses

Phase 2:

  • Allow modifying what identifier to send.

Customer Value

Enterprises get per-user cost attribution on the provider side with zero additional configuration — AI Bridge handles it transparently. For OpenAI, this unlocks immediate per-user dashboards and Usage API grouping. For Anthropic, it provides abuse detection and positions customers for future reporting capabilities, while AI Bridge's own OTEL + Recorder serves as the primary per-user cost attribution layer.

This is low-effort, high-value: the data is already in the request context, it just needs to be attached to the upstream request body.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions