You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Per the AuthClaimTypes decision (2026-05-08), all custom JWT claim names live in SentenceStudio.Contracts.AuthClaimTypes as public const string fields. Producers (Api JwtTokenService / DevAuthHandler, WebApp ServerAuthService) and consumers (every endpoint that scopes by user, plus tests) must reference the constant.
The current sweep is correct on main as of e341484, but nothing prevents a future PR from reintroducing a literal like User.FindFirst("user_profile_id") or new Claim("user_profile_id", ...). A typo (e.g. "user_profileid") silently degrades to anonymous-user behavior with no compile-time warning — a production-only bug.
Desired enforcement
Add a CI gate that fails when the literal "user_profile_id" appears in any .cs file under src/ or tests/except the constant definition in src/SentenceStudio.Contracts/AuthClaimTypes.cs.
Two acceptable approaches — pick whichever is cheapest to maintain:
Option A — Roslyn analyzer (preferred long-term):
New analyzer project (or extend an existing one) that fires a diagnostic on any LiteralExpressionSyntax whose value matches a configured set of banned claim names.
Configurable via .editorconfig or analyzer settings so adding new banned literals is a one-line change.
Wire as <Analyzer> in Directory.Build.props so every project picks it up.
Option B — Unit test grep gate (cheaper to ship):
New xUnit test (in tests/SentenceStudio.Api.Tests/ or a dedicated lint test project) that walks src/ and tests/.cs files and asserts the literal does not appear outside the allowlisted AuthClaimTypes.cs.
Runs as part of the normal dotnet test pass, so CI catches it.
Easy to extend to other banned literals later.
Whichever path is chosen, the rule should ideally read its banned set from the AuthClaimTypes constant class (via reflection) rather than a hardcoded copy, so adding a new claim constant automatically protects the new literal.
Acceptance criteria
Adding a literal "user_profile_id" to any non-allowlisted .cs file fails the build or dotnet test.
The check is mechanical and runs in CI on every PR.
False positives are limited to the single allowlisted file (AuthClaimTypes.cs) and any documentation/string-resource use cases (which can be allowlisted explicitly).
Adding a new claim constant to AuthClaimTypes automatically protects the new literal — or, at minimum, the registration is one line in the analyzer/test config.
Context
Per the AuthClaimTypes decision (2026-05-08), all custom JWT claim names live in
SentenceStudio.Contracts.AuthClaimTypesaspublic const stringfields. Producers (ApiJwtTokenService/DevAuthHandler, WebAppServerAuthService) and consumers (every endpoint that scopes by user, plus tests) must reference the constant.The current sweep is correct on
mainas of e341484, but nothing prevents a future PR from reintroducing a literal likeUser.FindFirst("user_profile_id")ornew Claim("user_profile_id", ...). A typo (e.g."user_profileid") silently degrades to anonymous-user behavior with no compile-time warning — a production-only bug.Desired enforcement
Add a CI gate that fails when the literal
"user_profile_id"appears in any.csfile undersrc/ortests/except the constant definition insrc/SentenceStudio.Contracts/AuthClaimTypes.cs.Two acceptable approaches — pick whichever is cheapest to maintain:
Option A — Roslyn analyzer (preferred long-term):
LiteralExpressionSyntaxwhose value matches a configured set of banned claim names..editorconfigor analyzer settings so adding new banned literals is a one-line change.<Analyzer>inDirectory.Build.propsso every project picks it up.Option B — Unit test grep gate (cheaper to ship):
tests/SentenceStudio.Api.Tests/or a dedicated lint test project) that walkssrc/andtests/.csfiles and asserts the literal does not appear outside the allowlistedAuthClaimTypes.cs.dotnet testpass, so CI catches it.Whichever path is chosen, the rule should ideally read its banned set from the
AuthClaimTypesconstant class (via reflection) rather than a hardcoded copy, so adding a new claim constant automatically protects the new literal.Acceptance criteria
"user_profile_id"to any non-allowlisted.csfile fails the build ordotnet test.AuthClaimTypes.cs) and any documentation/string-resource use cases (which can be allowlisted explicitly).AuthClaimTypesautomatically protects the new literal — or, at minimum, the registration is one line in the analyzer/test config.Related
.squad/decisions/processed/2026-05-08/kaylee-authclaimtypes-constants.mdrefactor(auth): centralize AuthClaimTypes in SentenceStudio.Contracts)api-endpoint-review-checklistSIGNIFICANT Fix ContinueConversation method typo #5)Out of scope