Security model
Every service requires a verified Keycloak access token on every path, except a short list of public paths. Each public path has its own compensating control. This page describes the design. The pages in the Internal section, when included in a build, go into risks and gaps.
Layers
| Layer | What it does |
|---|---|
| TLS at the ingress | HTTPS only, with redirect. Certificates from cert-manager. |
| Hidden management endpoints | /q (health, metrics, OpenAPI, Swagger UI) is not routed to any service. See Status page. |
| OIDC token verification | Each service validates the bearer token's signature, issuer and expiry against the realm startupos. |
| HTTP policy | In every service, the authenticated policy covers /*. Only the enumerated public paths are exempt. A new endpoint is therefore authenticated unless someone names it public. |
| Role and tenant filter | @RequiresRole is enforced by RoleEnforcementFilter, which also checks that a non-platform-wide caller's token proves the tenant. |
| In-code checks | Moderator checks, enrolment checks and ownership checks inside services. |
| Header identity off | X-User-Id, X-User-Role and X-Tenant-Id are not an identity in production. A startup guard refuses to start a production service with header identity enabled. |
Identity rules
- OIDC is enabled in all eight services in production (
QUARKUS_OIDC_ENABLED=trueandQUARKUS_OIDC_TENANT_ENABLED=trueon each Deployment). - A verified token always wins over a header.
- The principal is the token's
preferred_usernameclaim, for examplefounder-user-001. - Roles come from the token's realm roles. Default Keycloak roles (
offline_access,uma_authorization,default-roles-*) are ignored. - Service-to-service calls use a Keycloak client-credentials token. Its principal begins with
service-account-.
Pages
- Authentication model explains how a token is obtained, carried and checked.
- Public paths lists every path that skips the token check and what protects it.
- The Authentication guide shows the API consumer's view.
Sources: .agents/tasks/oidc-enforcement/finish/final-report.md, libs/common-models/src/main/java/com/rtih/startupos/common/security/, services/*/src/main/resources/application.yml, .kiro/steering/auth-rollout.md, live Deployment environment read on 2026-11-07 (names only).