Skip to content

feat: per-train authorization, principal injection, and trusted execution#28

Merged
Theauxm merged 1 commit into
mainfrom
feat/api-auth-hardening
Apr 15, 2026
Merged

feat: per-train authorization, principal injection, and trusted execution#28
Theauxm merged 1 commit into
mainfrom
feat/api-auth-hardening

Conversation

@Theauxm
Copy link
Copy Markdown
Member

@Theauxm Theauxm commented Apr 15, 2026

Summary

  • Adds AuthorizationRegistrationValidator so trains declaring [TraxAuthorize] fail at startup if no ITrainAuthorizationService is registered, rather than at request time.
  • Introduces a scoped TraxPrincipal accessor so junctions inject the authenticated user directly without IHttpContextAccessor.
  • Adds TrustedExecution scope that lets scheduler/worker-initiated runs bypass authorization cleanly.
  • Per-principal concurrency bucketing surface on TraxMediatorBuilder.PerPrincipalMaxConcurrentRun(int).
  • TrainAuthorizationException promoted to a first-class mediator type; TrainRegistration exposes required policies / roles for discovery consumers.

Dependency order

Paired with:

Merge this first; downstream packages reference the new mediator APIs.

Known issue

AuthorizationRegistrationValidator currently resolves ITrainAuthorizationService against the root provider during startup. ASP.NET Core scope validation (enabled in WebApplicationFactory E2E tests) flags this as a scoped-from-root violation. GameServer and JobHunt E2E suites fail against this. The fix is small — resolve inside a created scope — but is tracked as a follow-up so this PR can land the broader surface.

Test plan

  • dotnet build with zero warnings
  • Unit tests green (AuthorizationRegistrationValidatorTests, TrainDiscoveryAuthorizationTests, PerPrincipalConcurrencyTests, TrustedExecutionScopeTests, TrainExecutionServiceLookupTests)
  • Follow-up: fix root-provider resolution in validator so downstream E2E suites go green

…tion

Adds the mediator-side infrastructure that Trax.Api builds on:

- AuthorizationRegistrationValidator validates that any train declaring
  [TraxAuthorize] has an ITrainAuthorizationService registered in the
  container at startup, rather than failing at request time.
- Principal scope service lets junctions inject TraxPrincipal directly
  without IHttpContextAccessor plumbing.
- TrustedExecution scope marks internally-initiated train runs (scheduler,
  workers) as bypassing authorization, since there is no user principal.
- Adds per-principal concurrency bucketing surface on TraxMediatorBuilder.
- Surfaces TrainAuthorizationException as a first-class mediator type so
  callers can distinguish authz failures from other exceptions.
- Exposes registration metadata (required policies / roles) through
  TrainRegistration for downstream discovery.
@traxsharp
Copy link
Copy Markdown

traxsharp Bot commented Apr 15, 2026

This PR is included in version 1.16.0

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