Skip to main content

Per-Developer Identity

By default a governed request is attributed to the client that made it — the org, tenant, and license key. That is enough to isolate one customer's data from another, but it does not tell you which developer ran a given tool call, or which AI-tool session it belonged to. Per-developer identity closes that gap: when a developer's email is supplied on a request, AxonFlow records it on the canonical audit record so the customer portal's User column, the audit User filter, and the per-user views on the Claude Code dashboard resolve to an individual instead of a shared synthetic id.

Enterprise feature

Per-developer identity is an Enterprise capability of the customer portal and audit surfaces. It is asserted, not authenticated — supplying an email improves audit visibility, it is not a login. Access to the platform is still governed by the license key; the org and tenant on every stored row come from that license, never from the supplied identity, so a developer cannot cross a tenant boundary by changing their email.

What gets recorded

Two fields land on the canonical audit_logs decision record when they are supplied:

  • user_email — the individual developer, taken from the X-User-Email request header.
  • session_id — the AI-tool session that produced the request, taken from the X-Session-Id request header. Platform migration core/129 adds a nullable session_id column to audit_logs; it is purely additive and backward-compatible.

Both are read from request headers only and are never trusted from a request body, so a payload cannot spoof another developer's identity into the audit trail. Both are recorded on both governance planes: the agent's policy-check (check_policy) path and the orchestrator's tool-call audit path.

When no email is supplied, the row falls back to the client-scoped synthetic id mcp-client:<client-id> — never a blank User column. So attribution degrades gracefully: developers who have configured an email show up by name, and everyone else rolls up under the client identity.

Client version requirement

The platform side of per-developer identity — recording user_email and session_id from the request headers, migration core/129, and the synthetic fallback — ships in platform v9.3.0. The client side that emits those headers ships in the Claude Code plugin v1.8.0 and Claude Desktop proxy v0.3.0, both of which pair with platform ≥ v9.3.0. Older clients (Claude Code plugin ≤ v1.7.0, Desktop proxy ≤ v0.2.1) do not send the headers, so their activity attributes to the synthetic mcp-client:<client-id> id rather than a named developer until you upgrade.

Configuring the Claude Code plugin

On v1.8.0 and later, the Claude Code plugin resolves a developer email in this order and sends it as the X-User-Email header on every governed request (the MCP connection and both the pre-tool and post-tool hooks):

  1. the AXONFLOW_USER_EMAIL environment variable — the supported source;
  2. best-effort fallback to git config user.email;
  3. otherwise unset — the header is omitted and the row falls back to the synthetic client id.

Set it in the developer's shell profile:

export AXONFLOW_USER_EMAIL="[email protected]"

The session_id half needs no configuration: the plugin's PreToolUse and PostToolUse hooks forward Claude Code's own session_id (from the hook input) as X-Session-Id automatically, so every audit row carries the developer alongside the session they were working in. The MCP connection itself has no per-call session id and is unchanged.

The git fallback caveat

The git config user.email fallback is best-effort. It resolves to whatever git is configured with in the working directory at the time of the call — which may be a shared bot identity on CI, a personal address that differs from the corporate directory, or unset in a fresh container. For reliable, uniform attribution across a fleet, set AXONFLOW_USER_EMAIL explicitly rather than relying on the git fallback.

Configuring the Claude Desktop proxy

On v0.3.0 and later, the Claude Desktop MCP governance proxy sends the developer identity as X-User-Email from its AXONFLOW_LEADER_EMAIL configuration value, and forwards the Desktop session as X-Session-Id. Set AXONFLOW_LEADER_EMAIL in the proxy's managed configuration so Cowork and MCP-tool activity is attributed to the leader.

Setting the email across a fleet

For a managed fleet, distribute AXONFLOW_USER_EMAIL per developer through your MDM or fleet-configuration tooling so each machine carries its own developer's address. Because the value is per-person, it must be owned by the per-login mechanism your MDM provides (a run-on-every-login command or a per-user managed setting), not a static, machine-wide policy that would apply the same address to every user of a shared host. Your fleet-deployment runbook covers the platform-specific recipe (macOS configuration profile / command, Windows registry / command, Linux command) for injecting a per-developer value.

Where the identity shows up

Once AXONFLOW_USER_EMAIL is set, per-developer attribution flows through to:

  • Audit logs — the portal User column resolves to the developer, and the User filter matches on their email. See Reading the audit logs in the portal.
  • Usage & Analytics — governed Claude Code traffic is counted per organization; per-developer identity surfaces in the audit logs and the Claude Code dashboard, not in the usage totals (usage events are org-scoped and do not carry the developer email). See Portal Operations.
  • The Claude Code dashboard — the per-user Grafana panel breaks decisions down by developer and verdict. See the Grafana Dashboard reference.