azure-sub-cross-tenant-association
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)."