Skip to content

Audit log for authorization decisions#5520

Draft
ramonsmits wants to merge 2 commits into
authfrom
authorizationauditlog
Draft

Audit log for authorization decisions#5520
ramonsmits wants to merge 2 commits into
authfrom
authorizationauditlog

Conversation

@ramonsmits

Copy link
Copy Markdown
Member

Adds:

  • IAuthorizationAuditLog / AuthorizationAuditLog (Infrastructure.Auth) — structured allow/deny entries on the ServiceControl.Audit category.
  • PermissionVerbHandler emits an audit entry per evaluation (subject id, display name, permission, roles, reason).
  • DI registration alongside the verb handler.
  • Unit tests + RecordingLoggerProvider test helper.

PermissionVerbHandler now resolves the calling principal's subject id
(sub claim), display name (preferred_username, falling back to name then
sub), and roles, and emits a structured "allow" or "deny" entry through
the new IAuthorizationAuditLog for every verb-level check. Both
outcomes are captured — denies alone are insufficient for most
compliance use cases — and the reason embeds the matched role(s) for
allow and the candidate role(s) for deny.

AuthorizationAuditLog writes on the stable category "ServiceControl.Audit"
via a source-generated structured log method so any ILogger-compatible
sink (Seq, OTLP, file, in-memory test double, …) can collect or filter
the trail without coupling to the concrete type name. The audit log is
registered alongside the verb handler — only when OIDC is enabled and
the handler has decisions to make.

Unauthenticated requests are skipped at the top of HandleRequirementAsync
so the audit log only records identified principals; the framework
challenges with 401 via the policy's RequireAuthenticatedUser anyway.

Ported from the keycloak-rbac-poc spike (with the namespace flattened
from Infrastructure.Auth.Rbac to Infrastructure.Auth to match the real
branch) along with a RecordingLoggerProvider test helper colocated with
the unit tests.
PermissionVerbHandler now reads the subject id and subject name from
configurable claim keys (Authentication.SubjectIdClaim, default "sub";
Authentication.SubjectNameClaim, default "preferred_username") and
throws InvalidOperationException when an authenticated principal lacks
either claim or carries an empty value — both are required for the
audit log to be meaningful and a missing value indicates an IdP
misconfiguration the operator needs to fix.

The settings are passed through AddServiceControlAuthorization, which
now takes the full OpenIdConnectSettings (the existing bool-only
overload is removed; the six callers — three RunCommand entry points
and three acceptance-test runners — pass the settings object). The
MockOidcServer test helper defaults preferred_username to the subject
value so existing OIDC acceptance tests don't have to repeat the
boilerplate.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant