The service that could spend anyone's credentials anywhere
A browser signs in, and the request crosses four services on its way to doing anything. The current design validates the token once at the edge and forwards the same token inward, which everyone agreed was efficient.
Then the reviews service was compromised. It was holding a valid token for every user who had recently loaded a page, and every other service accepted those tokens, because they were valid — signed correctly, unexpired, and issued to a real person. Nothing had to be forged.
- R1The browser must never hold the credential that talks to internal services. It gets a session reference, and the thing that exchanges that reference for a real credential keeps the credential on the server side.
- R2When one service calls another it must present a credential that names the service it is calling, and that names only the permissions that call needs. Presenting it to anything else must fail, so a compromised service can reach only what it could already reach.
- R3The service that owns the data decides whether the caller may have it. Validation at the edge establishes who is asking; it cannot answer whether this particular caller may read this particular record, because the edge does not own the record.
Boundaries, outermost first: OWNS THE RECORDS: The records (what everyone wants), an empty slot for the sits beside the data and says no, tier 2 Outside every boundary: Reviews service (assume it is breached; FAILED: compromised), Browser (holds a cookie), Identity provider (signs credentials), an empty slot for the keeps the real credential off the browser, tier 1, an empty slot for the issues one credential per callee, tier 1 Connections: Browser calls keeps the real credential off the browser — session cookie keeps the real credential off the browser calls issues one credential per callee issues one credential per callee calls Identity provider — exchange keeps the real credential off the browser calls Reviews service — for reviews only Reviews service calls sits beside the data and says no sits beside the data and says no calls The records