Least privilege & service users
Purpose: Replace admin sessions with purpose-scoped service users — the pattern, the mapping, and the review discipline.
Who this page is for
| Audience | Why it matters to you |
|---|---|
| Backend engineers | Mandatory pattern |
| Reviewers | What to reject |
The pattern
1. Create system user phi-rating-sync (no login, no password)
2. Grant minimal ACLs read/write on /var/phi/rates ONLY
3. Map bundle+subservice → user ServiceUserMapper amendment config:
"com.academy.phi.core:rating-sync=phi-rating-sync"
4. Code obtains the resolver:
Map<String,Object> auth = Map.of(ResourceResolverFactory.SUBSERVICE, "rating-sync");
try (ResourceResolver rr = resolverFactory.getServiceResourceResolver(auth)) {
// rr can touch /var/phi/rates and nothing else
}
Why the ceremony pays
| Property | Consequence |
|---|---|
| Purpose-scoped identity | The audit log says phi-rating-sync wrote the rates — attribution for free |
| Minimal ACLs | A bug (or exploited bug) in the sync can corrupt rates, not the site |
| No credentials | System users cannot log in; nothing to leak or rotate |
| Mapping is config | Per-environment scoping possible; visible, reviewable |
Granularity rule
One subservice per capability, not per class: rating-sync (write /var/phi/rates), plan-reader (read /content/phi), form-intake (create under /var/phi/leads). A service user with ten unrelated grants is admin with extra steps.
Review discipline
getAdministrativeResourceResolver/ admin sessions /loginAdministrativeare insta-reject in review (checklist); deprecated for good reason.- Quarterly: dump service users + their ACLs; each grant justified by a running feature or removed (audit rhythm).
- Watch scope creep in PRs: "extended phi-rating-sync to also write /content" deserves the same scrutiny as a new admin account.