gcp-acm-can-modify-perimeter
match (effective permission)
{
"any_of": [
{
"action": "accesscontextmanager.servicePerimeters.update",
"resource_type": "google.identity.accesscontextmanager.v1.AccessPolicy"
},
{
"action": "accesscontextmanager.servicePerimeters.delete",
"resource_type": "google.identity.accesscontextmanager.v1.AccessPolicy"
},
{
"action": "accesscontextmanager.servicePerimeters.create",
"resource_type": "google.identity.accesscontextmanager.v1.AccessPolicy"
}
]
}
where
the target ServicePerimeter is ENFORCED (status non-empty, perimeterType REGULAR)
emit
| source type | Identity |
|---|---|
| target type | ConditionalPolicy |
| source | <principal> |
| target | <ServicePerimeter ConditionalPolicy node> |
| permissions | accesscontextmanager.servicePerimeters.update accesscontextmanager.servicePerimeters.delete accesscontextmanager.servicePerimeters.create |
| conditions | iam_permission condition_expression |
| state logic | ACTIVE when effective permission is unconditionally held; CONDITIONAL(iam_permission) when gated by an IAM condition expression; BLOCKED when an IAM deny policy denies accesscontextmanager.servicePerimeters.update / .delete — no guardrail-removal fires until the deny is lifted. |
Narrative
{principal.name} can update, delete, or create a ServicePerimeter (servicePerimeters.update / .delete / .create) - guardrail-removal capability over VPC-SC. Cite hierarchy-chains.yaml guardrail-removal-upgrades-blocked for the BLOCKED -> CONDITIONAL upgrade of CanReadData / CanExfiltrate edges.
Raw rule rules/explicit/gcp-accesscontextmanager.yaml
id: gcp-acm-can-modify-perimeter
emits: CanModifyPolicy
applies_to:
- gcp
match_effective_permission:
any_of:
- action: accesscontextmanager.servicePerimeters.update
resource_type: google.identity.accesscontextmanager.v1.AccessPolicy
- action: accesscontextmanager.servicePerimeters.delete
resource_type: google.identity.accesscontextmanager.v1.AccessPolicy
- action: accesscontextmanager.servicePerimeters.create
resource_type: google.identity.accesscontextmanager.v1.AccessPolicy
where:
- the target ServicePerimeter is ENFORCED (status non-empty, perimeterType REGULAR)
emit:
source_type: Identity
target_type: ConditionalPolicy
source: <principal>
target: <ServicePerimeter ConditionalPolicy node>
api_source: "IAM Policy Analyzer \u2014 effective accesscontextmanager.servicePerimeters.update / .delete\
\ / .create at the access policy"
permissions:
- accesscontextmanager.servicePerimeters.update
- accesscontextmanager.servicePerimeters.delete
- accesscontextmanager.servicePerimeters.create
state_logic: "ACTIVE when effective permission is unconditionally held; CONDITIONAL(iam_permission)\
\ when gated by an IAM condition expression; BLOCKED when an IAM deny policy denies accesscontextmanager.servicePerimeters.update\
\ / .delete \u2014 no guardrail-removal fires until the deny is lifted."
conditions:
- iam_permission
- condition_expression
confidence: 0.9
derived_from:
- "IAM Policy Analyzer \u2014 effective accesscontextmanager.servicePerimeters.update or .delete or\
\ .create at access policy"
false_positive_note: 'Verify the perimeter is ENFORCED and REGULAR before emitting; do not emit for
dry-run or bridge perimeters. An IAM deny policy that denies .update / .delete / .create keeps this
edge BLOCKED. The .create case is more nuanced: a created permissive perimeter may not immediately
block anything, but a bridge perimeter that routes egress to an attacker project is a direct exfil
enablement.'
narrative: "{principal.name} can update, delete, or create a ServicePerimeter (servicePerimeters.update\
\ / .delete / .create) \u2014 guardrail-removal capability over VPC-SC. Cite hierarchy-chains.yaml\
\ guardrail-removal-upgrades-blocked for the BLOCKED -> CONDITIONAL upgrade of CanReadData / CanExfiltrate\
\ edges."