IAM
Issues the tokens, and deliberately does nothing else.
IAM is an OAuth2 authorization server and nothing more. It has one user, no roles, no groups, no two-factor, no admin console (ADR-0006).
What it does
- Holds the single owner account, seeded by a Liquibase changeset with a pre-computed bcrypt cost-13 hash. Seed data is a changeset, never hand-run SQL.
- Issues access tokens whose audience is the app id. There is no separate scope model: the audience is the scope is the application (ADR-0008).
- Publishes a JWKS that every backend validates signatures against.
- Sends password-reset mail through the notification port.
What it deliberately does not do
No roles, no permissions, no entitlements, no user management screens, no invitations, no SSO federation. Each of those is a feature for organisations, and there is no organisation here.
The audience check is the whole authorisation model
A token minted for IAM presented to Finloop is rejected. That is the one security property this
estate actually has, so it is proven by a test rather than assumed — a request bearing a token whose
aud is not finloop gets a 401, and the test fails the build if it ever gets anything else.
Sessions make backends stateful
The BFF pattern means each backend stores its session in its own SPRING_SESSION tables. Two
consequences worth stating plainly:
- A backend restart logs you out.
- Those tables belong in that app's backups.