federate-inherits-capabilities
Federating in as an internal Role/ServiceAccount lets the principal act AS it, inheriting its outbound capabilities; rolled up as CanImpersonate.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?internal) in [
ServiceAccount, MachineIdentity]
node_class(?p) in [Identity]
emit
| source type | Identity |
|---|---|
| target type | ServiceAccount |
| source | ?p |
| target | ?internal |
| conditions | trust_condition |
| state logic | inherit from CanFederateAs: ACTIVE when the federation is ACTIVE, else CONDITIONAL(trust_condition); BLOCKED if the federation is BLOCKED. The impersonation is never stronger than the federation that grants it. |
Narrative
{p.name} can federate in as {internal.name} ({perm:CanFederateAs}) and thereby act as it - inheriting {internal.name}'s outbound capabilities; modeled as {p.name} CanImpersonate {internal.name}.
Raw rule rules/derived/federation-chains.yaml
id: federate-inherits-capabilities
emits: CanImpersonate
description: Federating in as an internal Role/ServiceAccount lets the principal act AS it, inheriting
its outbound capabilities; rolled up as CanImpersonate.
applies_to:
- '*'
match:
- - p: null
- CanFederateAs
- internal: null
where:
- node_type(?internal) in [ServiceAccount, MachineIdentity]
- node_class(?p) in [Identity]
emit:
source_type: Identity
target_type: ServiceAccount
source: ?p
target: ?internal
permissions: []
conditions:
- trust_condition
state_logic: 'inherit from CanFederateAs: ACTIVE when the federation is ACTIVE, else CONDITIONAL(trust_condition);
BLOCKED if the federation is BLOCKED. The impersonation is never stronger than the federation that
grants it.'
confidence: min(contributing_confidences)
derived_from:
- ?p CanFederateAs ?internal
note: "CAPABILITY INHERITANCE (traversal-feeding): once CanFederateAs(?p -> ?internal) holds, ?p effectively\
\ holds every OUTBOUND capability of ?internal \u2014 its CanReadSecret, CanExecuteAs, CanAdminister,\
\ CanDeploy, etc. This is realized by ordinary graph traversal (walk CanFederateAs, then ?internal's\
\ own outbound edges), mirroring credential-chains execute-then-read-secret. This rule additionally\
\ MATERIALIZES the CanImpersonate roll-up (for SA/MachineIdentity targets) so credential-centric reverse\
\ queries and the escalation roll-up surface ?p directly. For a Role target, no CanImpersonate is\
\ emitted (target set excludes Role) \u2014 the inheritance is traversal-only."
false_positive_note: "Only emit the CanImpersonate roll-up when ?internal is a ServiceAccount/ MachineIdentity\
\ (the CanImpersonate target set) \u2014 never for a plain Role or User. The escalation consequence\
\ (when ?internal is more privileged than ?p) is NOT re-derived here: it is produced by credential-chains.yaml's\
\ impersonate-is-escalation off this CanImpersonate \u2014 cite, do not duplicate. Do not double-count\
\ weight where both this CanImpersonate and the two-hop (CanFederateAs then ?internal's outbound)\
\ path appear on the same route. Inherits the federation's trust_condition state \u2014 a CONDITIONAL\
\ federation yields only a CONDITIONAL impersonation, never an ACTIVE one."
narrative: "{p.name} can federate in as {internal.name} ({perm:CanFederateAs}) and thereby act as it\
\ \u2014 inheriting {internal.name}'s outbound capabilities; modeled as {p.name} CanImpersonate {internal.name}."