Capture X-Saturn-Auth-Id (token identity) into metering events#1
Open
hhuuggoo wants to merge 2 commits into
Open
Capture X-Saturn-Auth-Id (token identity) into metering events#1hhuuggoo wants to merge 2 commits into
hhuuggoo wants to merge 2 commits into
Conversation
Capture the token / API-key identity (X-Saturn-Auth-Id, the JWT sub / IdentityAuth.id) plus every other X-Saturn-* header verbatim, and record them on the metering Event. AuthID is the primary attribution key; org/user/group are resolved downstream (out of band, at rating time) from the IdentityAuth record, so the hot path never resolves a multi-org user's active-org context. - identity: add HeaderAuthID + Identity.AuthID; FromRequest reads it. - metering.Event: add AuthID, ResourceID, ResourceType (all omitempty) so no identity the edge gave us is dropped; reorganize fields with clearer docs. - proxy.emit: populate the new fields. - tests: identity capture (all-headers + all-empty), e2e proxy asserts auth_id + resource_type flow into the event. Security: Phoebe blindly trusts these headers (it does not authenticate). That is safe only because Traefik's atlas-auth ForwardAuth allowlist overwrites any client-supplied X-Saturn-* copy. X-Saturn-Auth-Id is added to that allowlist in saturn-k8s#976, and emitted by auth-server#85 — both must be live before this header is relied on for billing. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A billing product must not serve traffic it can't attribute. Add an early billing-identity gate in handleProxy that rejects with 400 if X-Saturn-Auth-Id (the token / API-key attribution key) or X-Saturn-Resource-Id (the model being billed) is absent. The error names every missing field so a header misconfiguration — auth-server not emitting it, or Traefik not allowlisting it — is immediately obvious. This replaces the prior lone resource-id check with missingBillingFields(), which reports all missing required fields at once. UserID/GroupID are NOT required here — they're resolved downstream from AuthID. A rejected request emits no billing event (verified). Tests cover each missing combination, the both-present happy path, and updated existing proxy/abort tests to supply auth-id. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Capture the token / API-key identity (
X-Saturn-Auth-Id= JWTsub= AtlasIdentityAuth.id) and every otherX-Saturn-*header verbatim, and record them on the meteringEvent.Why
The billing requirement is to tie token consumption to a specific API key.
AuthIDis that stable key — the same for browser-session and API-key tokens. Org/user/group are resolved downstream (out of band, at rating time) from theIdentityAuthrecord, so the hot path never resolves a multi-org user's active-org context (which isn't in the token).We capture everything the edge gives us so no information is lost; downstream rating decides what matters.
Changes
identity:HeaderAuthID+Identity.AuthID;FromRequestreads it.metering.Event: addAuthID,ResourceID,ResourceType(omitempty).proxy.emit: populate the new fields.auth_id/resource_typereach the event.Security / dependencies
Phoebe blindly trusts these headers (it does not authenticate). That is safe only because Traefik's
atlas-authForwardAuth allowlist overwrites any client-suppliedX-Saturn-*copy. This header is:Both must be live before this header is relied on for billing. The Phoebe code is safe in isolation (it only reads the header).