Repository navigation
feat(audit): record the OAuth superadmin sign-in in the audit trail (#932) - #933
Merged
Merged
Conversation
…932) The API-key sign-in is audited since #931; a superadmin signing in through Campus Auth was not, so the widest-reaching principal in the service left no trace of entering it. The OAuth flow now records every outcome, under its own event types: audit.ui.auth.success carries the campus.auth account and whether it is a superadmin, and audit.ui.auth.failed carries a reason (invalid_state, missing_code, auth_service_error, auth_service_unavailable). They are deliberately distinct from the audit.apikeys.* events of the API-key path: a Campus account is not an API key, and the trail should say which credential authenticated. The account is recorded as a label in the span's tags — campus.audit has no user store and its spans carry user_id=None by design — and the access token is never part of an event: it is exchanged server-side and kept in the session, never in a request or a response body. The new tests clean up the spans they add, so the shared traces table stays as the other unit tests expect it.
This was referenced Oct 20, 2026
ngjunsiang
added this pull request to stack #937
October 20, 2026 22:11
This was referenced Oct 20, 2026
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.
Closes #932
Summary
The API-key sign-in has been audited since #931; a superadmin signing in through Campus Auth was not, so the widest-reaching principal in the audit service left no trace of entering it. This closes that gap.
audit.ui.auth.success— the campus.auth account, and whether it is a superadminaudit.ui.auth.failed— reason:invalid_state,missing_code,auth_service_error,auth_service_unavailableThe event types are deliberately not
audit.apikeys.*: those mean "an API key authenticated", and a Campus account is not an API key. The trail should say which credential authenticated.What is recorded, and what is not
user_id=Noneby design.current_actor()'s("superadmin", user id)is the same value.superadminflag distinguishes an account on theAUDIT_ADMINSlist from one that is not. A non-superadmin can complete the OAuth flow and be refused by the pages, so the trail answers "who tried to get in", not just "who got in".Testing
New
TestAuditWebOAuthSignInEventsclass (7 tests): success event content, state mismatch, missing code, an auth-service error, an auth service that is down at/audit/login/start, a non-superadmin sign-in marked as such, and no event at all whenAUDIT_EVENTS_ENABLED=0. As in #931, the new tests clean up the spans they add so the shared traces table stays as the other unit tests expect it.Unit suite passing, contract suite passing,
ruff check .clean,pyrightclean oncampus/.Stack
This is the bottom link of a three-PR stack (see the stack description on the top PR): #932 (this PR) → #927 (the key-management page) → #918 (the role catalogue). Each PR is based on the one below it; this one is based on
weekly.Related
current_actor()), feat(audit): key-management page in the audit web UI (list/mint/scope/rotate/revoke) #927 (the key-management page, whose mutation events will use the same vocabulary)