# Module: Auth & identity ## Purpose JWT validation for API policies. Tokens are minted exclusively by the admin service (ES256-signed); annotations is a **verifier only**. ## Components ### `JwtExtensions` (`Auth/JwtExtensions.cs`) - `AddJwtAuth(IConfiguration)` — pulls `JWT_ISSUER`, `JWT_AUDIENCE`, `JWT_JWKS_URL` via `ConfigurationResolver.ResolveRequiredOrThrow` (fail-fast at startup if any is missing). - `TokenValidationParameters` mirrors admin's verifier contract: - `ValidateIssuer = true` / `ValidateAudience = true` / `ValidateLifetime = true`. - `ValidAlgorithms = [SecurityAlgorithms.EcdsaSha256]` — pinned so an HS256-forgery using the public key as the HMAC secret cannot pass. - `RequireSignedTokens = true`, `RequireExpirationTime = true`. - `ClockSkew = 30s`. - Signing keys are fetched from admin's `/.well-known/jwks.json` via a `ConfigurationManager` backed by a minimal `IConfigurationRetriever` (admin exposes JWKS but not the full OIDC discovery document). The manager honours admin's `Cache-Control: public, max-age=3600` and refreshes on the default schedule. During key rotation both `kid`s are present in JWKS so in-flight tokens still verify. - Policies: `ANN`, `DATASET`, `ADM` — each requires claim `permissions` with that code (matches suite "Required permission: ANN" and Dataset Explorer `DATASET`). ## Dependencies Configuration (all required, no defaults): - `JWT_ISSUER` (alt `Jwt:Issuer`) — must match admin's `JwtConfig:Issuer`. - `JWT_AUDIENCE` (alt `Jwt:Audience`) — must match admin's `JwtConfig:Audience`. - `JWT_JWKS_URL` (alt `Jwt:JwksUrl`) — `https://admin.azaion.com/.well-known/jwks.json` in production. ## Consumers All `[Authorize]` controllers. ## Removed in this cycle - `Services/TokenService.cs` (HS256 minting of access tokens from refresh tokens) — deleted; refresh is now the admin service's responsibility (`POST /token/refresh`). - `Controllers/AuthController.cs` and the `POST /auth/refresh` endpoint — deleted along with `TokenService`. Detections (and any other client) must call admin's refresh endpoint and pass the returned access token to annotations. - `JWT_SECRET` env var — no longer read. ## Suite doc `01_annotations.md` §Annotation Sync (verifier role); suite `10_auth.md` for full auth story (admin = issuer, satellite-provider / annotations / flights / ui = verifiers).