azure-sub-cross-tenant-association

explicit azure emits CrossTenantTrust

match (record)

{ "field": "tenantId", "resource_type": "Microsoft.Resources/subscriptions" }

where

subscription tenantId != reference/home tenant OR an assigned principal's tenantId != subscription tenantId (B2B guest with RBAC)

emit

source<subscription's home Tenant node (tenantId)>
target<external tenant / ExternalIdentity node>

Narrative

The tenant owning subscription {subscription.name} trusts external tenant {external.name} (cross-tenant association / B2B principal with RBAC)."

Raw rule rules/explicit/azure-subscriptions.yaml

id: azure-sub-cross-tenant-association
emits: CrossTenantTrust
applies_to:
- azure
match_record:
  resource_type: Microsoft.Resources/subscriptions
  field: tenantId
where:
- subscription tenantId != reference/home tenant OR an assigned principal's tenantId != subscription tenantId
  (B2B guest with RBAC)
emit:
  source: <subscription's home Tenant node (tenantId)>
  target: <external tenant / ExternalIdentity node>
  api_source: GET /subscriptions/{id}  (tenantId) ; roleAssignments principalId tenant resolution
  evidence_field: tenantId
  note: "CrossTenantTrust source set (schema/edges.yaml) is [Tenant, ApplicationIdentity] and target [Tenant,\
    \ ExternalIdentity] \u2014 source the subscription's HOME TENANT node, NOT the Subscription boundary\
    \ node, to stay within the declared set. Feeds derived azure-sub-cross-tenant-transfer. Distinguish\
    \ the rare billing/directory transfer (CONDITIONAL, consent-gated) from the common B2B-guest-with-RBAC\
    \ case (ordinary cross-tenant assignment)."
  narrative: The tenant owning subscription {subscription.name} trusts external tenant {external.name}
    (cross-tenant association / B2B principal with RBAC)."
move · open · esc close