Delegation chains and egress
How do services act for users without becoming confused deputies, and what happens after the read?
Impersonation and delegation chains
A service acting for a user usually holds more authority than that user. If the service accepts a request that merely names an object and then uses its own authority to fetch it, the user has borrowed the service's privileges. This is the confused deputy, and it is the root cause of a large share of real data-platform breaches.
Example. A report service can read all patient files. A user sends "give me the report for file 8841". The service never checks whether the user may see 8841; it only checks that 8841 exists, and uses its own key.
There are two classic fixes. They are the old split between ACLs and capabilities.
Fix 1: carry the principal forward
Each hop re-checks authorization against the original user. This is correct and auditable, but it dies at the first asynchronous boundary. A pipeline is a deferred action by construction: the person who triggered the run may be gone, or may have lost access, by the time it runs. So batch systems run as service principals, the audit log records the service, and the link between a human and a data access is cut at exactly the layer where data engineering lives. This is structural, not sloppy.
Fix 2: pass a capability
Do not name the object. Hand over an unforgeable, already-scoped reference (a capability). Then no confused deputy is possible, because the deputy has no authority beyond what it was handed. This is the vended credential again, now used for delegation: one mechanism solving a second problem.
| ACL / identity-carrying | Capability / vended | |
|---|---|---|
| Inverse query "who can read X?" | answerable | not answerable |
| Revocation | central, fairly immediate | only by expiry or key rotation |
| Confused deputy | possible | prevented by structure |
| Survives asynchronous boundaries | poorly | well (the token carries the context) |
| Audit subject | the principal | the request |
The rule that keeps chains safe
Without this rule, a chain of three harmless services combines into authority nobody granted. (Here the independence assumption fails: each service was reviewed alone, but the composition was not.)
In one sentence: delegation is safe only when authority travels with the request and shrinks at every hop.
Egress: what happens after the read
Authorization decides who may read. It says nothing about the bytes afterwards, and the most common real loss path is an authorized read followed by an unmonitored copy. The controls are borrowed from resource management but serve security: result-size governors (limits on rows or bytes a query may return), download and export restrictions, network perimeters around the data plane (credentials work only from inside), and controls on notebook and BI exports. Without them, access control decides who copies your data, not whether it is copied. Egress and exfiltration returns to this.