execute-then-read-secret
Executing as a workload identity inherits that identity's ability to read a secret.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
{'principal': None}
CanExecuteAs {'workload_identity': None}
{'workload_identity': None} CanReadSecret {'secret': None}
where
node_class(?principal) == Identity
node_class(?workload_identity) == Identity
emit
| source | ?principal |
|---|---|
| target | ?secret |
| conditions | iam_permission resource_policy key_permission |
| state logic | inherit_weakest(CanExecuteAs, CanReadSecret): a CONDITIONAL CanExecuteAs (e.g. trigger_exists not yet met) OR a CONDITIONAL CanReadSecret (key_permission on a wrapped secret) yields CONDITIONAL with the union of the unmet gating conditions; any BLOCKED contributor => BLOCKED; else ACTIVE. |
Narrative
{principal.name} can execute as {workload_identity.name} ({perm:CanExecuteAs}), inheriting its ability to read {secret.name}.
Raw rule rules/derived/credential-chains.yaml
id: execute-then-read-secret
emits: CanReadSecret
description: Executing as a workload identity inherits that identity's ability to read a secret.
applies_to:
- '*'
match:
- - principal: null
- CanExecuteAs
- workload_identity: null
- - workload_identity: null
- CanReadSecret
- secret: null
where:
- node_class(?principal) == Identity
- node_class(?workload_identity) == Identity
emit:
source: ?principal
target: ?secret
permissions: []
conditions:
- iam_permission
- resource_policy
- key_permission
state_logic: 'inherit_weakest(CanExecuteAs, CanReadSecret): a CONDITIONAL CanExecuteAs (e.g. trigger_exists
not yet met) OR a CONDITIONAL CanReadSecret (key_permission on a wrapped secret) yields CONDITIONAL
with the union of the unmet gating conditions; any BLOCKED contributor => BLOCKED; else ACTIVE.'
confidence: min(contributing_confidences)
derived_from:
- ?principal CanExecuteAs ?workload_identity
- ?workload_identity CanReadSecret ?secret
false_positive_note: "Redundant with plain graph traversal (CanExecuteAs then CanReadSecret) for a generic\
\ path-finder; emitted so credential-centric reverse queries resolve the real principal. Do not double-count\
\ its weight when both this collapsed edge and the two contributing edges are present on the same\
\ path. The inherited read still carries the workload identity's own key_permission gate \u2014 if\
\ the secret is CMEK-wrapped, decrypt on the wrapping key is required against the effective identity\
\ used at read time."
narrative: '{principal.name} can execute as {workload_identity.name} ({perm:CanExecuteAs}), inheriting
its ability to read {secret.name}.'