Explain the confused-deputy problem in access control, give two examples from different layers of a system, and say what structurally prevents it rather than what patches each instance.
answer
- deputy has power, requester picks the target
- ambient authority is the root cause
- browser, network position, worker service account
- designation and authority travel together
- audience-bound, scoped, short-lived, propagated principal
basics
~20 sA component with more authority than its caller performs an action the caller chose, using its own ambient authority instead of the caller's. The structural fix is to carry authority with the request - a scoped, audience-bound credential representing the original principal - rather than attaching it to the deputy's identity.
solid answer
~50 sThe deputy is any component that acts on instructions from a less-privileged party while holding privilege of its own: a browser, a proxy, a background worker, an internal service. The defect is that the authority used comes from who the deputy is - its session, its network position, its service account - rather than from who asked. The requester supplies the designation; the deputy supplies the power; nothing binds the two. Two layers: a browser attaching stored credentials to a request initiated by another site, so the browser is the deputy and its ambient credential is the authority; and a server fetching a user-supplied address from inside a trusted network, where the authority is its network position rather than any credential. The structural prevention is to eliminate ambient authority: the request carries a short-lived, narrowly scoped credential naming the original principal and the intended audience, and the deputy holds the minimum authority of its own. Per-instance patches are correct but each protects one deputy.
go deeper
Define it as a privileged component being tricked into acting for someone less privileged, with one example.
Identify ambient authority as the cause and give examples from different layers.
Design principal propagation, audience binding and least-privilege deputies, and audit service-account actions.
Argue for a capability-style model across services so authority travels with the request, and treat every new intermediary as a deputy to be scoped at design time.
## The shape of the problem A confused deputy is a component tricked into misusing its own authority on behalf of someone who does not have it. It is not an authentication failure - everyone involved may be correctly identified - and it is not a missing check in the ordinary sense; the check often passes, because it is asked about the deputy rather than about the requester. The root cause is **ambient authority**: power attached to an identity, a connection or an environment, applied automatically to whatever action is performed, with no link to who requested it. ## Examples across layers - **The browser.** A page on one site causes a request to another, and the browser attaches the credentials it stores for the destination. The destination sees a properly authenticated request. The deputy is the browser; the authority is ambient because it is applied by destination rather than by intent. - **A server fetching a supplied address.** The application retrieves a resource named by the user, from inside a network where reachability itself is the privilege. The credential here is the deputy's position, which is why identity checks do not help. - **A background or scheduled worker.** A job queued 'on behalf of' a user executes later under the worker's service account, typically broad. If the queued payload names the resource but not the principal, the worker performs the user's request with the worker's rights. - **A service accepting any validly issued token.** A credential minted for one service is replayed to another that verifies integrity but not intended audience. The second service acts with its own authority on a request never addressed to it. - **A support impersonation feature.** Staff act as a customer; if the resulting actions carry staff authority rather than the customer's scope, the feature is a deputy by design. ## Why per-instance fixes are not the answer Each example has a known local patch - a request-origin token, an address allow-list, a principal field on the queue message, an audience check. Every one is correct and worth doing, and every one protects exactly one deputy. New deputies appear whenever a component starts doing work for others, so a defence that must be re-derived per deputy will lag the architecture permanently. ## The structural principle Replace ambient authority with **designation and authority carried together**. The request hands the deputy both what to act on and the right to act on it: a short-lived credential naming the original principal, stating the intended audience, and scoped to the specific action. Then the deputy cannot exceed what it was given, because it has no relevant authority of its own to be confused into using. Practically: propagate the caller's principal through every hop instead of re-asserting identity at each boundary; scope and audience-bind every credential so replaying it elsewhere fails; and reduce each deputy's standing privilege to the minimum needed for work nobody delegated. Rank the defences the usual way, from guarantee to heuristic: **structural separation** first - the deputy holds no ambient authority, so the failure is unrepresentable; then **enumerated, code-owned scoping** - audience checks and explicit principal propagation on every hop, finite and owned by your code; then **per-call validation** such as allow-listing a destination, which is open-world and only as good as the list; then **detection** - auditing what a service account actually did and alerting when privilege outruns the request that caused it. An allow-list sits below enumeration for the reason that always applies: it constrains a value while still admitting everything that matches, whereas an enumerated map of permitted targets is finite and owned by the code. ## The rule to state Authorization must be evaluated against the principal on whose behalf the action is taken, and that principal must be propagated rather than re-asserted by the deputy. Any place where a component's own rights exceed the rights of the party it is serving is a confused deputy waiting for input.
- Why does verifying that a token is validly issued fail to prevent this, and what check is missing?Integrity verification proves the credential was minted by a trusted issuer and not tampered with; it says nothing about who the credential was meant for. A service that accepts any valid credential can be handed one issued for a different service and will act with its own authority on that request. The missing check is the intended audience, plus scoping so the credential authorises only the actions it was issued for.
- How should a queued job that runs later 'on behalf of' a user be authorized?The message must carry the principal and a scoped, expiring authority for the specific action, and the worker must make the access decision as that principal rather than as itself. If the credential cannot survive the queue delay, the worker should re-derive the principal's current permissions from authoritative state before acting - which is also safer, since entitlements may have changed while the job waited.
saying these in an interview costs you the question
- Calling it 'just missing input validation' - the request is often well-formed and the checks pass.
- Relying on the deputy's own identity check while ignoring on whose behalf it is acting.
- Treating an allow-list on one deputy as a general defence for the class.
- Giving background workers and internal services broad standing privilege because 'they are internal'.