skip to content

A principal may take on only one weak temporary identity, which may itself take on a third — why does reviewing each grant separately miss the escalation?

level: seniorimportance: nice to knowfreq 30%

answer

  1. each hop is correct on its own
  2. the trust condition sees only one hop back
  3. escalation is a path, not a grant
  4. build a directed graph of principals
  5. conditions do not carry to the next hop

basics

~20 s

Because each hop is narrow and correct on its own, and escalation is a property of the path, not of any single grant. Reachability has to be computed across the whole set; no document names the principal two hops away.

solid answer

~40 s

Taking on a temporary identity is transitive whenever nothing forbids it: from inside the second identity's session, the caller makes the same kind of call again. Every document involved reads narrowly — the strong identity's trust condition names only the identity one hop before it, and the weak principal's own grant names only the middle one. Neither document mentions the other end, so neither reviewer sees a problem. The only way to find it is to treat the grant set as a directed graph, with an edge wherever one principal may take on, attach, write permissions for or mint credentials for another, and ask which strong nodes are reachable from a weak one.

code

pseudocode · 18 lines
pseudocode
edges = {}
for each grant in allGrants:
    if grant allows takeOnIdentity, attachIdentity,
       writePermissionsFor or issueCredentialFor:
        edges[grant.holder].add(grant.targetPrincipal)

reachable = {}
for each start in selfServicePrincipals:
    frontier = [start]
    while frontier is not empty:
        node = frontier.removeFirst()
        for each next in edges[node]:
            if next not in reachable[start]:
                reachable[start].add(next)
                frontier.append(next)

for each start in selfServicePrincipals:
    report start, reachable[start] minus edges[start]

go deeper

for a junior

Know that one temporary identity can often take on another, and that the second one's permissions are what you end up with. The first grant you were given is not necessarily the limit.

for a middle

Explain why each document looks narrow: a trust condition names only the immediate previous hop, and the originating principal appears in no document at the far end.

for a senior

Demonstrate the review method — a directed graph with an edge per escalating verb, reachability from the principals teams actually control — and know that conditions do not carry across hops.

for a principal

Treat chain length as something to design down: identify the hub identities everything routes through, and set a standard that strong identities trust only purpose-built principals nothing else can become.

## One grant at a time is the wrong unit of review A temporary identity is taken on by a principal that a trust condition on that identity permits. From inside the resulting session the caller is, for permission purposes, the identity they took on — and that includes being permitted to take on whatever *it* may take on. The hops compose unless something explicitly stops them. So consider three principals. A weak team principal may take on a middle identity used for deployment. The middle identity may take on a stronger identity that manages a shared platform component. Read each grant on its own: - The team's grant names one identity, the deployment one. Narrow, justified, approved. - The strong identity's trust condition names one identity, the deployment one. Narrow, justified, approved. Neither document contains the other end of the path. The escalation is not written anywhere; it exists only as a property of the set. ## Why the trust document is the misleading one The instinct on review is to read the strong identity's trust condition, since that is the thing guarding the prize. It names exactly one caller, which is reassuring, and it is genuinely all the platform checks at that hop. What it cannot tell you is who may become that caller — that fact lives in a completely different document, owned by a different team, and the trust condition has no way to express it. The check the platform performs is local; the property you care about is global. ## What does and does not travel along the chain | Property | Along the chain | |---|---| | Permissions | Replaced at each hop by the identity you took on — not accumulated | | Conditions evaluated at the first hop | Applied at the first hop only, unless the next trust condition restates them | | Recorded caller at the far end | The previous hop, so the originating principal is one join away in the record | | Session lifetime | Platforms differ: some cap or shorten a session taken on from inside another, some do not | The second and third rows are where reviewers get surprised. A carefully written condition on the first hop — restricting the network path a call may come from, say — protects that hop and evaporates afterwards unless the next identity's trust condition says the same thing. ## Finding it 1. Build a node per principal. 2. Add a directed edge from A to B wherever A may take on B, attach B to a workload, write B's permissions or issue a credential for B. All four verb classes are edges; assumption is only the most obvious one. 3. Compute what is reachable from each principal your self-service teams actually control. 4. Compare the reachable set with the principal's own grant. The difference is the escalation surface. This is mechanical and it is the only form of review that finds chains, because the number of two-hop pairs grows with the square of the identity count and nobody reads them by hand. Estates that do this usually find that a small number of middle identities — the deployment identity, the platform tooling identity — are the hubs that connect almost everything, and that cutting one or two edges collapses most of the surface. ## Breaking a chain The cheapest cut is at the strong end: make the strong identity's trust condition name a principal that nothing else can become, ideally one created for that purpose and held by a separate function. The next cheapest is to remove the middle identity's ability to take on anything at all, which is usually possible because a deployment identity rarely needs to become a third thing. What does not work is documenting the intended path: the graph is what the platform evaluates, and a diagram that says the chain is not to be used has no effect on any call.

  • Does the chain give the caller the permissions of every identity along it?
    No. Each hop replaces the session rather than adding to it, so at the far end the caller holds exactly the last identity's permissions. The chain is a route, not an accumulation — though a determined caller can of course make separate calls from separate hops.
  • Where would you cut a chain like this first?
    At the strong end. Point its trust condition at a principal created for that purpose that nothing else may become, held by a separate function. Cutting the middle identity's outbound edge is the next option and is usually cheap, because a deployment identity rarely needs to become a third identity.
  • A condition on the first hop restricts which network path the call may come from. Does the far end inherit it?
    Not unless the far identity's own trust condition restates it. Each trust decision is evaluated locally against its own condition, so a restriction written at one hop constrains that hop only. This is a common source of false confidence in a carefully written first grant.

saying these in an interview costs you the question

  • Reviews each trust condition alone and calls the set narrow
  • Thinks permissions accumulate as the chain is walked
  • Assumes a condition written at the first hop applies at the second
  • Believes the far end records the original caller
  • Treats a documented intended path as a control