azure-lighthouse-enter-resource-group
A managing-tenant ExternalPrincipal named in a resource-group-scoped Lighthouse authorization has CanAdminister over that resource group.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
{'managing_tenant': None}
CrossTenantTrust {'customer_tenant': None}
{'reg_definition': None} TrustsExternalIdentity {'external_principal': None}
{'customer_rg': None} HasPolicy {'reg_assignment': None}
where
node_class(?customer_rg) == AdministrativeBoundary and node_type(?customer_rg) ==
ResourceGroup
node_class(?customer_tenant) == AdministrativeBoundary and node_type(?customer_tenant) == Tenant
?reg_assignment.properties.registrationDefinitionId == ?reg_definition.id
the registrationAssignment scope is SCOPED TO A RESOURCE GROUP (id pattern /resourceGroups/{rg})
?external_principal is in the authorizations[] of ?reg_definition (principalId from managing-tenant ?managing_tenant)
?external_principal's delegation is a PERMANENT authorization (authorizations[], not eligibleAuthorizations)
node_type(?external_principal) in [ExternalIdentity, FederatedIdentity]
authorization.roleDefinitionId != '8e3af657-a8ff-443c-a75c-2fe8c4bcb635' # Owner excluded
optional
Present → upgrade the emitted state; absent → downgrade (not a hard requirement).
{'external_principal': None}
HasPolicy {'pim_policy': None}
emit
| source type | Identity |
|---|---|
| target type | ResourceGroup |
| source | ?external_principal |
| target | ?customer_rg |
| conditions | trust_relationship service_state |
| state logic | ACTIVE when the authorization is permanent (authorizations[], not eligibleAuthorizations) and registrationAssignment provisioningState == 'Succeeded'. CONDITIONAL(pim_activation) when the authorization appears only in eligibleAuthorizations — the managing-tenant principal must activate PIM first. CONDITIONAL(service_state) if registrationAssignment provisioningState is 'Updating' or 'Creating'. BLOCKED if the registrationAssignment is removed or in a Failed state. Inherits state from the contributing CrossTenantTrust (explicit rule azure-lighthouse-cross-tenant-trust-explicit); never stronger than the weakest contributor. The delegated role determines the effective capability level (admin vs. contributor vs. reader); emit CanAdminister here as the broadest model and scope it to ?customer_rg. Hierarchy-chains propagates this down to contained resources. |
Narrative
{external_principal.name} (from managing tenant {managing_tenant.name}) is named in Lighthouse registrationDefinition {reg_definition.name} with role {delegated_role.name}; because the delegation is scoped to resource group {customer_rg.name}, {external_principal.name} has administrative control over that resource group and its contained resources, operating as themselves from their home tenant.
Raw rule rules/derived/azure/lighthouse.yaml
id: azure-lighthouse-enter-resource-group
emits: CanAdminister
description: A managing-tenant ExternalPrincipal named in a resource-group-scoped Lighthouse authorization
has CanAdminister over that resource group.
match:
- - managing_tenant: null
- CrossTenantTrust
- customer_tenant: null
- - reg_definition: null
- TrustsExternalIdentity
- external_principal: null
- - customer_rg: null
- HasPolicy
- reg_assignment: null
where:
- node_class(?customer_rg) == AdministrativeBoundary and node_type(?customer_rg) == ResourceGroup
- node_class(?customer_tenant) == AdministrativeBoundary and node_type(?customer_tenant) == Tenant
- ?reg_assignment.properties.registrationDefinitionId == ?reg_definition.id
- the registrationAssignment scope is SCOPED TO A RESOURCE GROUP (id pattern /resourceGroups/{rg})
- ?external_principal is in the authorizations[] of ?reg_definition (principalId from managing-tenant
?managing_tenant)
- ?external_principal's delegation is a PERMANENT authorization (authorizations[], not eligibleAuthorizations)
- node_type(?external_principal) in [ExternalIdentity, FederatedIdentity]
- 'authorization.roleDefinitionId != ''8e3af657-a8ff-443c-a75c-2fe8c4bcb635'' # Owner excluded'
optional:
- - external_principal: null
- HasPolicy
- pim_policy: null
emit:
source_type: Identity
target_type: ResourceGroup
source: ?external_principal
target: ?customer_rg
permissions: []
conditions:
- trust_relationship
- service_state
state_logic: "ACTIVE when the authorization is permanent (authorizations[], not eligibleAuthorizations)\
\ and registrationAssignment provisioningState == 'Succeeded'. CONDITIONAL(pim_activation) when the\
\ authorization appears only in eligibleAuthorizations \u2014 the managing-tenant principal must activate\
\ PIM first. CONDITIONAL(service_state) if registrationAssignment provisioningState is 'Updating'\
\ or 'Creating'. BLOCKED if the registrationAssignment is removed or in a Failed state. Inherits state\
\ from the contributing CrossTenantTrust (explicit rule azure-lighthouse-cross-tenant-trust-explicit);\
\ never stronger than the weakest contributor. The delegated role determines the effective capability\
\ level (admin vs. contributor vs. reader); emit CanAdminister here as the broadest model and scope\
\ it to ?customer_rg. Hierarchy-chains propagates this down to contained resources."
confidence: min(contributing_confidences) * 0.95
derived_from:
- azure-lighthouse-cross-tenant-trust-explicit (explicit CrossTenantTrust managing-tenant -> customer-tenant)
- ?reg_definition TrustsExternalIdentity ?external_principal (authorizations[] tuple)
- ?customer_rg HasPolicy ?reg_assignment (registrationAssignment binding to RG scope)
- hierarchy-chains.yaml admin-inherits-down-contains (descent to RG children)
false_positive_note: "SCOPE CHECK: only emit CanAdminister when the registrationAssignment scope is\
\ scoped TO A RESOURCE GROUP (id contains /resourceGroups/{rg}/providers/). A subscription-scoped\
\ assignment emits CanEnterSubscription (rule 2), not CanAdminister \u2014 do not mix. Resource-group-scoped\
\ delegations are narrower: the managing principal's access is confined to that RG and its child resources.\
\ The delegated role determines the actual RBAC actions available (Contributor, Reader, Owner, custom\
\ roles) \u2014 this rule models the broadest CanAdminister boundary; role-specific capabilities (e.g.,\
\ CanGrantPermission for UAA within the RG scope) are derived by rule 3b with a RG scope_of constraint.\
\ Owner (8e3af657) cannot be delegated; if present, skip."
narrative: '{external_principal.name} (from managing tenant {managing_tenant.name}) is named in Lighthouse
registrationDefinition {reg_definition.name} with role {delegated_role.name}; because the delegation
is scoped to resource group {customer_rg.name}, {external_principal.name} has administrative control
over that resource group and its contained resources, operating as themselves from their home tenant.'