Skip to content

feat(cockpit): add a user and department dimension to usage and cost #444

Description

Context

Usage and cost can be attributed to agents but not to the people using them. Operators
running shared agents across departments cannot answer which teams drive consumption, which
is the question that governs internal chargeback and capacity planning.

This is a live need for credit-metered agents in particular, where a shared prepaid pool is
consumed by many departments with no per-department visibility.

What already exists, and why the premise changed

An earlier version of this proposal assumed per-user attribution was blocked by a shared
managed identity that gives every authenticated user the same data scope. That is no longer
accurate.

The shipped architecture already separates two credential paths. Aggregate telemetry is read
through the deployment identity with Reader and Log Analytics Reader. Protected content
is read only through the authenticated user's delegated credential, non-cacheable, with
Privileged Monitoring Data Reader explicitly invalid for the deployment identity.

/api/auth/context already validates and exposes tenant, user and group claims without
exposing token values. allowed_group_id already exists for coarse access control.

So the pattern to follow exists. The constraint is different and narrower. Per-user
delegation is currently scoped only to protected content. Extending it to usage and cost
aggregates is a deliberate widening of that boundary and is the substance of this issue.

Scope

Add a user dimension to usage and cost aggregation, sourced only from identity attributes
already present in telemetry. No identity is inferred and no directory is queried to
enrich it.

Add a department grouping derived from a group claim already available in the validated
auth context, or from an operator-supplied mapping in the configuration contract. No new
directory read is introduced.

The feature is opt-in and off by default. A deployment that does not enable it behaves
exactly as it does today.

When enabled, follow the established boundary. Aggregates remain readable through the
deployment identity. Any view that narrows to an individual person is treated as protected
and follows the delegated path, consistent with the current handling of protected content.

Extend ObserveFilters with a user dimension and a department dimension, both nullable and
both scope-validated.

Extend CoverageResult with a user attribution dimension, so a deployment whose telemetry
carries no user identity is told so explicitly.

Agent types in scope

Any runtime whose telemetry carries a user identifier.

Credit-metered agents are the strongest case, because environment-level telemetry captures
user identity when conversation detail logging is enabled, and because a shared prepaid pool
makes per-department attribution directly actionable.

Platform-hosted agents depend on whether the calling application propagates an end-user
identifier. Where it does not, the coverage dimension must say so rather than showing an
empty grouping.

Out of scope

  • Intent or workload classification of prompts and sessions. This is a separate capability
    and does not belong in an attribution issue
  • Any directory enrichment beyond claims already validated in the auth context
  • Storing user identity. The runtime remains stateless
  • Per-user access control changes. This adds a dimension, not a permission model

Acceptance criteria

  • Disabled by default, with no behavior change when disabled
  • Individual-level views follow the delegated credential path and are non-cacheable,
    consistent with existing protected content handling
  • Telemetry without user identity produces an explicit coverage result, never an empty or
    zeroed grouping
  • User and department filters round-trip through the page URL as scope-validated
    dimensions, and no raw identity value is placed in the URL
  • Enabling the feature introduces no new role assignment

Open questions

  • Is the group claim in the validated auth context sufficient for department grouping, or
    is an operator-supplied mapping required in practice?
  • Should widening delegation beyond protected content require its own deployment-time
    consent step, given that the current boundary was explicitly drawn at content?
  • Which user identifier attribute is most consistently populated across runtimes?

Dependencies

Independent of #441 and #442. Composes with #443 when both are present, producing cost
per department.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions