skip to content

Path-Scoped Permissions

How the right to read, write or list a stored credential is expressed: over a branch of names or by label, standing or granted on approval. Asked because a store anyone can read proves nothing.

on this pageshow

questions

5

What do read, write and list rights over a secret store each permit, and why is store-wide read-only still too much?

level: juniorimportance: must knowfreq 64%

answer

  1. a right is only half a grant
  2. three rights, not one ladder
  3. names are not values
  4. read-only still has a blast radius
  5. scope the branch, not the store

basics

~20 s

Read returns one named value, write creates or replaces a value, and list returns the names under a branch without their contents. Store-wide read-only is still too much because one compromised caller then reaches every credential the estate holds.

solid answer

~40 s

A grant has two halves: the right, and the scope of names it covers. `read` hands back the contents of a named value; `write` creates or replaces a value, which lets the writer decide what some downstream consumer will authenticate with; `list` returns the names under a branch and nothing else, which makes it a disclosure in its own right rather than a weak form of read. Because the three are separate rights, a workload should hold only the ones it exercises — most services read one or two values and never write or enumerate. Scope is the other half: read-only over every name means one leaked caller credential reaches every team's credentials at once, so the grant should cover the branch the workload actually reads and stop there.

go deeper

for a junior

Be able to say what each of read, write and list returns, and to state a grant as a right plus the branch of names it covers rather than as access to the store.

for a middle

Explain why list is a separate right rather than a weak read, and why a caller able to write a value another service consumes is a confidentiality problem too.

for a senior

Show how you would derive the scope from what the workload actually reads, and what you would do about a grant that was widened once and never narrowed again.

for a principal

Frame the trade the estate is making: a broad read grant buys never editing rules again and pays for it with a blast radius that is the whole store.

## A grant is a right plus a scope A **secret store** holds values under names, and a rule grants some identity a set of **rights** over some **scope** of those names. Neither half means anything on its own: `read` with no scope named is not a grant, and a branch of names with no right named is not one either. Interviewers open here because a candidate who says *the service has access to the store* has not yet said anything checkable. The checkable sentence is of the form *this identity may `read` the names under `teams/search/prod/`, and nothing else*. ## The three rights - **`read`** returns the contents of a value the caller names. Read is aimed at a name, not at a branch — the caller has to know, or guess, what to ask for. - **`write`** creates a name that did not exist, or replaces the contents of one that did. Whether the previous contents survive as an earlier version is a property of the store, not of the right. - **`list`** returns the names that exist under a branch. It returns names, not contents; a store that handed back contents there would not be offering a separate right at all. Stores differ in how finely they cut this up — some split destroying a value from replacing it, some split creating a new name from overwriting an existing one, some add a right to read only the metadata about a value. Every design has these three in some form, and the interview answer is about the three. | right | what the holder gains | what it exposes even when the other two are denied | |---|---|---| | `read` | the credential itself | nothing about names it cannot already guess | | `write` | control over what a consumer will authenticate with | the chance to plant a value some other service will use | | `list` | the inventory of names under a branch | partners, projects, systems and environments | ## Why `list` is not a weak `read` The common junior answer treats the rights as a ladder — list is a bit of read, read is a bit of write. They are not a ladder, because **the name is itself information**. A branch listing that returns `partner-feed-acme-freight` and `project-lighthouse-api-key` has disclosed a commercial relationship and an unannounced project to a caller that could not read either value. That is why the right is split out at all, and why granting it *because it is the harmless one* is backwards. `write` is the mirror image. It is easy to file write under *integrity, not confidentiality*, but a caller who can replace the value another service reads at start-up chooses what that service will present to a downstream system — which can mean pointing it at a credential the writer already controls and can watch being used. ## Why read-only over the whole store is still too much A read-only grant over every name looks conservative: nothing is changed, nothing is destroyed. It is still the widest grant in the estate, for three reasons. 1. **Blast radius.** Whatever compromises that caller — a leaked caller credential, a flaw in the service, a stolen host — now reaches every team's credentials in one step, and each of those reaches whatever it authenticates to. 2. **The grant outlives the reason for it.** A workload that reads two values today holds a rule that will match every value any team creates tomorrow, because the rule describes a shape of names rather than a list of them. 3. **It tells you nothing.** *Who could have read this value?* answered as *every service in the estate* is not an answer anyone can act on. ## Scoping the grant 1. Name the values the workload actually reads, at start-up and at run time. 2. Grant `read` over the narrowest branch that contains them, and leave `list` and `write` off unless the workload exercises them. 3. Where the store has a deny rule, put one at the shared root so nobody enumerates across teams by accident. 4. Re-check the rule when the workload changes what it reads, rather than widening it once and forgetting. ## What this question is not Two neighbouring questions get mixed in here and are worth keeping separate. *Which identity should hold write, and whether the same person may hold read* is separation of duties. *How the rule text is authored, reviewed and applied* is rule-change control. This question is only about what each right lets its holder do, and how wide the scope under it is.

  • Why is write over a branch a confidentiality problem and not only an integrity one?
    Because the writer chooses what a downstream consumer will authenticate with. Replacing the value a service reads at start-up can point it at an account the writer controls and can observe, or at an endpoint the writer runs. The service then behaves normally while using a credential someone else picked.
  • Is there a case for granting list while denying read?
    Yes — an inventory or reconciliation job needs to know what exists, not what it is. The trade is explicit: you accept that the names leak to that caller, which is a reason to keep meaning out of names and to scope the list right to one branch rather than the root.

saying these in an interview costs you the question

  • Treats list as a harmless subset of read
  • Says read-only access is safe because nothing is changed
  • Names a right without naming the scope it covers
  • Thinks write only risks breaking things, not disclosure
  • Assumes a caller that only reads cannot cause an incident
  • Grants store-wide read so future values need no rule change
open as a page

A team holds list but not read over a shared branch of secret names — what has already leaked?

level: middleimportance: must knowfreq 50%

basics

~20 s

The inventory has leaked: which credentials exist, and therefore which partners, projects, environments and downstream systems the estate has. Denying read protects the values, not the names, and names are rarely changed, so the disclosure does not expire.

open as a page

A read rule over one branch of secret names silently matched a neighbouring branch — what about prefix matching caused that?

level: seniorimportance: should knowfreq 42%

basics

~20 s

The rule matched characters rather than whole name segments, so a pattern written for teams/search also covered teams/search-internal and teams/searchtest. Anchoring the pattern on the separator, and stating how deep it reaches, is what turns a prefix into a boundary.

open as a page

Many teams keep credentials in one shared store — what makes the boundary between two teams' branches actually hold?

level: seniorimportance: should knowfreq 38%

basics

~20 s

Rules hold the boundary, not the naming convention. It holds only when no identity's rules span both branches, list is refused at the shared root, write across the boundary is treated as seriously as read, and any shared branch is counted as belonging to everyone who can reach it.

open as a page

For a store many teams share, should rights follow the branch of names a value sits under, or its labels and owner?

level: principalimportance: nice to knowfreq 27%

basics

~20 s

Name-tree rules make the boundary visible and let a new value inherit a scope automatically, but encode only one hierarchy and turn a rename into a permission change. Label rules express cross-cutting scopes at the cost of depending on data a writer sets.

open as a page