federation-maps-to-identity

A realized external->internal identity mapping whose trust condition an attacker-controlled external identity can satisfy yields federation into the internal identity.

derived any cloud emits CanFederateAs

match

A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.

{'ext': None} ExternalIdentityMapsTo {'internal': None}

where

node_type(?ext) in [ExternalIdentity, FederatedIdentity] node_type(?internal) in [Role, ServiceAccount, MachineIdentity] exists TrustsExternalIdentity(?anchor -> ?ext) with condition C backing this mapping

optional

Present → upgrade the emitted state; absent → downgrade (not a hard requirement).

{'ext': None} TrustsExternalIdentity {'internal': None}

emit

source typeFederatedIdentity
target typeRole
source?ext
target?internal
conditionstrust_condition
state logicif the trust condition is BROAD/UNPINNED so an attacker can present a matching external identity (unpinned sub / wildcard or shared aud / attacker-influenceable issuer / missing cert-subject constraint) OR the attacker demonstrably controls a matching ?ext: ACTIVE. If the condition is PINNED to a specific subject/issuer/cert the attacker does NOT control: CONDITIONAL(trust_condition) — realizable only once the attacker obtains a matching external identity. Inherit weakest with the backing TrustsExternalIdentity / ExternalIdentityMapsTo: a BLOCKED trust (issuer disabled, provider deleted, condition explicitly denies) => BLOCKED.

Narrative

{ext.name} is mapped to the internal identity {internal.name} by {anchor.name}'s federation trust; because that trust's condition is {trust_condition_summary}, an identity the attacker controls satisfies it and can federate in as {internal.name} with no static credential.

Raw rule rules/derived/federation-chains.yaml

id: federation-maps-to-identity
emits: CanFederateAs
description: A realized external->internal identity mapping whose trust condition an attacker-controlled
  external identity can satisfy yields federation into the internal identity.
applies_to:
- '*'
match:
- - ext: null
  - ExternalIdentityMapsTo
  - internal: null
where:
- node_type(?ext) in [ExternalIdentity, FederatedIdentity]
- node_type(?internal) in [Role, ServiceAccount, MachineIdentity]
- exists TrustsExternalIdentity(?anchor -> ?ext) with condition C backing this mapping
optional:
- - ext: null
  - TrustsExternalIdentity
  - internal: null
emit:
  source_type: FederatedIdentity
  target_type: Role
  source: ?ext
  target: ?internal
  permissions: []
  conditions:
  - trust_condition
  state_logic: "if the trust condition is BROAD/UNPINNED so an attacker can present a matching external\
    \ identity (unpinned sub / wildcard or shared aud / attacker-influenceable issuer / missing cert-subject\
    \ constraint) OR the attacker demonstrably controls a matching ?ext: ACTIVE. If the condition is PINNED\
    \ to a specific subject/issuer/cert the attacker does NOT control: CONDITIONAL(trust_condition) \u2014\
    \ realizable only once the attacker obtains a matching external identity. Inherit weakest with the\
    \ backing TrustsExternalIdentity / ExternalIdentityMapsTo: a BLOCKED trust (issuer disabled, provider\
    \ deleted, condition explicitly denies) => BLOCKED."
  confidence: min(contributing_confidences)
  derived_from:
  - ?ext ExternalIdentityMapsTo ?internal
  - ?anchor TrustsExternalIdentity ?ext (backing trust, condition C)
  false_positive_note: "The whole judgment is in the trust CONDITION \u2014 do not emit ACTIVE for a well-pinned\
    \ trust. UNPINNED/broad => ACTIVE: e.g. an AWS OIDC role trust with no sub condition (or `sub` a wildcard),\
    \ a shared/`sts.amazonaws.com` default aud, a GitHub-Actions trust missing the repo/branch `sub` pin,\
    \ a GCP WIF provider whose attribute mapping accepts any `assertion.sub`, an Azure federated credential\
    \ with a broad issuer/subject, or an X.509 trust anchor with no cert-subject condition. PINNED =>\
    \ CONDITIONAL(trust_condition): the `sub` bound to a specific repo:owner/repo:ref, a specific SPIFFE\
    \ ID, or a specific cert CN the attacker cannot present. Do NOT treat mere existence of a federation\
    \ as compromise \u2014 a correctly pinned trust is a legitimate control. If ?internal is a plain User\
    \ (not Role/SA/MachineIdentity) the CanFederateAs target set excludes it \u2014 keep it as FederatesTo\
    \ and let identity-specific rules handle it. A disabled/deleted OIDC provider or rotated issuer key\
    \ => the adapter must not emit the trust => this rule does not fire."
  narrative: '{ext.name} is mapped to the internal identity {internal.name} by {anchor.name}''s federation
    trust; because that trust''s condition is {trust_condition_summary}, an identity the attacker controls
    satisfies it and can federate in as {internal.name} with no static credential.'
move · open · esc close