Authenticated API call
Every service applies the same checks in the same order.
The rules
- Verified token wins. The caller is the token's
preferred_usernameclaim. A request header that names another user is ignored when a token is present. - Roles come from the token. Realm roles are mapped to the names used by
@RequiresRole. A caller who needs a role the token does not carry gets 403. - Tenant. A caller who is not platform-wide must prove a tenant claim that matches the tenant being addressed.
- Headers are not an identity. Production services do not read
X-User-Id,X-User-RoleorX-Tenant-Idas identity for an unauthenticated request. A startup guard refuses to start a production service with header identity enabled. - Some checks are in code. Enrolment checks and moderator checks happen inside the resource or service. Not every endpoint checks that a record belongs to the caller.
The paths that skip the token check are listed in Public paths.
Sources: libs/common-models/src/main/java/com/rtih/startupos/common/security/{RoleEnforcementFilter,HeaderIdentityPolicy}.java, services/lms-service/src/main/resources/application.yml (quarkus.http.auth.permission), .agents/tasks/oidc-enforcement/finish/final-report.md.