A reporting job whose identity allows reading every store is refused on the receipts store alone — how did two permissions combine to produce that?
answer
- two sides, one decision
- closed until something says otherwise
- breadth does not outvote a refusal
- a condition that fails needs no deny
- one store out of many implicates the resource side
basics
~20 sThe request is evaluated against both sides at once. A matching explicit deny in the store's own policy ends the request no matter how broad the caller's identity permission is, and a condition on a store-side allow that the request fails to satisfy has the same effect.
solid answer
~40 sAccess is not decided by the caller's permission alone. The platform starts from default deny, gathers the allows that apply from the caller's identity permissions and from the policy attached to the store, and then applies any explicit deny that matches — which ends the request regardless of how many allows were found. So a job allowed to read every store is still refused on this one if the store's policy denies its identity, or denies everything outside a named set of accounts. A store-side allow carrying a condition the request does not satisfy produces the same refusal with no deny written anywhere. Diagnosing it means reading the store's policy, not widening the job's permissions.
go deeper
Remember that a refusal can come from the thing being called, not only from the caller's own permissions, and that an unmatched request is refused by default.
Explain the evaluation order: default deny, allows gathered from both sides, a matching explicit deny ending the request, conditions evaluated inside each rule.
Show the diagnosis. One store failing out of many points at the resource side; read its policy for a deny and for allows whose conditions fail, then check who changed it and when.
The judgment is where the refusal should live. A deny on the store is a durable guardrail readable by anyone reviewing that store; scattering the same intent across identity permissions is not.
A nightly reporting job has an identity permission allowing it to read every store in the account. It reads all of them except the receipts store, where every request is refused. Nothing about the job changed. This is the everyday shape of the two-sided permission model, and the diagnosis is a reasoning chain rather than a console tour. ## Two sources, one decision A request against an object carries an identity (or none) and names an action and a resource. The platform assembles a decision from: - **identity-attached permissions** on the caller — what this job is allowed to attempt; - the **policy attached to the store** — which callers the store itself accepts, and under what conditions. Neither side is the answer on its own, and the second is invisible to anyone who only inspects the job. ## The order that matters The standard evaluation is: 1. **Default deny.** A request matching no allow is refused. Silence is not permission. 2. **Collect allows from both sides.** An allow on either side can satisfy a same-account request; a cross-account request commonly needs one on each side, and platforms differ in exactly how much the resource side alone can do. 3. **Apply explicit denies.** A matching deny ends the request. It is not outvoted by the number or breadth of allows, which is precisely what makes it usable as a guardrail. 4. **Evaluate conditions as part of each rule.** A rule with a condition only counts when the condition holds — so a store-side allow restricted to a named set of accounts simply does not match a caller outside them. ## Why the broad grant lost | Cause on the store's policy | What you would see | What it means | |---|---|---| | An explicit deny naming the job or its account | refusal on this store only, every time | somebody guardrailed the store deliberately | | An allow whose condition the request fails | refusal on this store only, possibly intermittently | the grant exists but does not match this request | | No rule mentioning this caller at all, cross-account | consistent refusal from outside, success from inside | the resource side was never told about the caller | The reporting job's own permission is a **ceiling on what it may attempt**, not a promise that any particular store will accept it. A broad identity grant and a narrow resource policy are not in conflict — they are describing different things, and the narrower one is doing its job. ## The diagnosis, in the order that costs least 1. **Read the store's policy first**, not the job's. The symptom — one store out of many — points at the resource side by construction, because the identity side is shared across all of them. 2. **Look for an explicit deny** and read who it names. A deny scoped to "every caller except this named account" is a common shape and refuses far more callers than its author intended to think about. 3. **Check the conditions** on the store's allows. A request that fails one is refused with no deny present anywhere, which is why people conclude the policy "looks fine". 4. **Check the management audit trail** for who last changed the store's policy and when, and compare it with the first failure. That usually ends the investigation. 5. **Only then consider the identity side**, and mostly to confirm the job is attempting the action you think it is. ## The wrong fix, and why it is tempting The reflex is to widen the job's identity permission, because that is the side the job's owner controls. It cannot work — the request is not failing for want of an allow — and the attempt leaves behind a broader permission than the job ever needed, which is a real finding later. The other wrong fix is to delete the store's deny without finding out who wrote it: on a store holding user documents, that deny is frequently the only thing standing between a convenience grant and an exposure. The right outcome is usually a narrow, deliberate allow on the store's policy naming this job, with the deny left intact for everybody else. That keeps the store's answer to "who may read me" written on the store, where anyone reviewing it will find it.
- The store's policy contains no deny at all, yet the job is still refused. What else produces that?An allow that does not match. If every store-side allow carries a condition — the caller must belong to a named set of accounts, say — a request failing it matches nothing, and default deny refuses it. For a cross-account caller, the absence of any store-side grant is enough on its own, since the identity side alone cannot compel acceptance.
- Why is widening the job's identity permission the wrong first move here?Because the request is not short of an allow. A matching deny on the store ends it however broad the caller's permission is, and a failed condition is not satisfied by more permission either. The change cannot fix the symptom and leaves a permission broader than the job needs, which becomes a finding in the next review.
- Should the fix be an allow on the store's policy or removal of the deny?Usually a narrow allow naming this job, with the deny left in place for everyone else. Removing the deny fixes one caller by opening the store to a whole class of them, and it deletes a guardrail someone wrote deliberately. Find out who wrote it and why before touching it.
saying these in an interview costs you the question
- Says the caller's own permission decides the outcome
- Believes a broad enough allow overrides an explicit deny
- Assumes a refusal always means a deny was written
- Widens the job's permissions to fix a store-side refusal
- Deletes the store's deny without finding out who wrote it
- Thinks a resource policy alone can compel a cross-account read