Many teams keep credentials in one shared store — what makes the boundary between two teams' branches actually hold?
answer
- layout is not isolation
- take the union, not the narrowest
- check both directions of the crossing
- list at the shared root
- the shared branch belongs to everyone
basics
~20 sRules 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.
solid answer
~40 sA tenant boundary inside one store is only as real as the rule set. Three things break it in practice. First, grants are usually additive: an identity's real scope is the union of every rule it holds, so one broad legacy rule on a parent branch dissolves a carefully narrow one underneath it. Second, `list` at the shared root lets either side enumerate the other's names even with reads denied. Third, write across the boundary is a break in the other direction — planting a value a neighbour's service reads at start-up chooses what that service authenticates with. A naming convention that nobody enforces with rules is documentation, not a boundary; and the boundary's ceiling is whatever identity can grant across it, which is a separate question but worth naming aloud.
code
pseudocode · 14 linesdecide(identity, name, right):
matched = [ r for r in rules_of(identity) # direct rules and inherited ones
if right in r.rights and matches(r.nameMatch, name) ]
if any r in matched with r.effect == "deny": return DENY
if any r in matched with r.effect == "allow": return ALLOW
return DENY # nothing matched: refused
# identity: search-indexer
# rule A nameMatch "teams/search/**" rights [read] effect allow
# rule B nameMatch "teams/**" rights [read, list] effect allow <- old on-call role
#
# decide(search-indexer, "teams/payments/prod/ledger-db", read)
# matched = [B] -> no deny -> ALLOW, across the boundary, via a rule nobody looked atgo deeper
Know that the boundary lives in the rules the store evaluates per request, not in the way the names happen to be laid out.
Explain additive grants: an identity's scope is the union of all its rules, so a broad inherited one defeats a narrow specific one.
Check the boundary in both directions and all three rights, including list at the shared root, and be able to show a refusal rather than assert isolation.
Decide whether the estate needs structurally separate name spaces or can hold one tree by review, and own the cost of whatever sits in the shared branch.
## The convention is not the boundary Every shared store has a naming convention — `teams/<team>/<environment>/<system>` or something close — and it is easy to mistake that convention for isolation. It is not. The convention is a layout; the boundary is the set of rules evaluated on each request. If a team's values sit under its own first segment but three identities hold rules on the parent, the layout is tidy and the boundary does not exist. ## Grants are additive, so the widest rule decides Most designs evaluate **every** rule an identity holds, directly or through whatever roles it carries, and grant if any of them matches. That means: - An identity's real scope is the **union** of its rules, not the narrowest one. - A rule written last year for an on-call role, covering the whole `teams/` branch, silently overrides today's carefully scoped grant. - Reviewing the one rule that was just written tells you nothing about the identity's actual reach; you have to enumerate every rule attached to it. Stores differ here and it is worth knowing which you have: some union all matching rules, some take the most specific match alone, and not every store has an explicit **deny** at all. Where deny exists and beats allow, a deny at the boundary is the single most useful rule in a shared store, because it survives someone else's over-broad pattern. ## List at the shared root The second leak is enumeration. If any identity holds `list` on the root that contains both teams, it can read off the other team's inventory of names — counterparties, projects, systems — with every read denied. It is easy to grant because it looks harmless and because tooling asks for it. Deny it at the shared root, and grant it per branch to the identities that genuinely need an inventory. ## Write is a boundary break too A boundary is usually discussed as *they must not read our values*. The other direction matters as much: 1. An identity that can write under a neighbour's branch can **create** a name their service will later read. 2. It can **replace** the value their service reads at start-up, choosing what that service presents to a downstream system. 3. Neither of those fails loudly — the neighbour's service starts, authenticates and behaves normally with a credential someone else chose. So the boundary must be symmetric: neither team's identities hold read, write or list that reaches across it. ## The shared branch Nearly every shared store grows a `shared/` or `platform/` branch that both sides may read, for the message bus, the metrics endpoint, the internal registry. That branch is the boundary's honest exception, and it should be treated as such: - A credential placed there is held by **every** team that can read there, so its blast radius is the union of all of them. - Anything that should not be readable by all of them does not belong there, whatever the convenience. - Write into the shared branch is the widest write in the store, because it reaches every consumer that reads from it. ## One tree, or separate name spaces Some stores offer entirely separate name spaces, each with its own rule set and no rule able to span them; others give you one tree and expect rules to carve it up. The separate-name-space design makes the boundary structural — there is no pattern anyone can write that crosses it — at the cost of duplicating everything that genuinely is shared. One tree is more flexible and asks you to keep the boundary correct by review. Neither is universal, so say which shape you are describing. ## What to check when someone claims a boundary exists 1. Enumerate every rule attached to an identity on each side, including inherited ones, and take the union. 2. Look for any rule whose pattern matches a parent of both branches. 3. Check `list` separately from `read`, at the shared root in particular. 4. Check write and create in both directions, not only read. 5. List what sits in the shared branch and who can read it, and count that as held by all of them. 6. Ask who can add a rule that spans both branches — that identity is above the boundary regardless of everything else. The last item is the one candidates leave out. A boundary enforced by rules is only as strong as the surface that changes rules, and a good answer names that ceiling even while treating it as somebody else's question.
- Two teams' values are encrypted at rest with the same key. Does that weaken the boundary?Not in the way people mean. At-rest encryption defends a stolen disk or backup, not a caller the rules allow, so it is not what separates the tenants either way. The boundary is the rule set; the shared key matters for backup and key-compromise questions, not for whether one team can read the other's values.
- Which grant most often turns out to span the boundary?A general-purpose one attached to shared tooling or to a broad engineering role — an inventory scanner, a deployment helper, a dashboard, a break-glass role kept warm. They are written once against a parent branch, nothing about them ever fails, and they are not the rule anyone reviews when a new narrow grant is added.
- How would you demonstrate to a reviewer that the boundary holds today?Produce, per identity on each side, the union of its rules and the set of names that union matches, including a neighbour's name as an explicit refusal case. A claim that the convention separates the teams is not evidence; a refusal evaluated against the real rule set is.
saying these in an interview costs you the question
- Says the naming convention separates the teams
- Reviews the newest rule and ignores inherited ones
- Treats the narrowest matching rule as the effective scope
- Grants list at the shared root because reads are denied
- Considers only read when checking a boundary
- Claims at-rest encryption separates one tenant from another