gcp-acm-perimeter-has-policy

explicit gcp emits HasPolicy

match (record)

{ "field": "status", "resource_type": "google.identity.accesscontextmanager.v1.ServicePerimeter" }

where

perimeter is ENFORCED: status field is present (not only spec) AND status.resources[] is non-empty perimeterType == 'PERIMETER_TYPE_REGULAR' # bridge perimeters are permitted paths, not guardrails

emit

source typeConditionalPolicy
target typeConditionalPolicy
source<AccessPolicy ConditionalPolicy node>
target<ServicePerimeter ConditionalPolicy node>
state logicACTIVE when perimeter is enforced (status non-empty, perimeterType REGULAR); skip when DRY_RUN-only or PERIMETER_TYPE_BRIDGE.

Narrative

Access policy {accesspolicy.name} contains enforced ServicePerimeter {perimeter.name}, protecting projects {protected_projects} for services {restricted_services}.

Raw rule rules/explicit/gcp-accesscontextmanager.yaml

id: gcp-acm-perimeter-has-policy
emits: HasPolicy
applies_to:
- gcp
match_record:
  resource_type: google.identity.accesscontextmanager.v1.ServicePerimeter
  field: status
where:
- 'perimeter is ENFORCED: status field is present (not only spec) AND status.resources[] is non-empty'
- 'perimeterType == ''PERIMETER_TYPE_REGULAR''  # bridge perimeters are permitted paths, not guardrails'
emit:
  source_type: ConditionalPolicy
  target_type: ConditionalPolicy
  source: <AccessPolicy ConditionalPolicy node>
  target: <ServicePerimeter ConditionalPolicy node>
  api_source: accesscontextmanager.servicePerimeters.list / .get
  evidence_field: name, status.resources[], status.restrictedServices[], status.ingressPolicies[], status.egressPolicies[],
    perimeterType
  annotate:
    provider_type: google.identity.accesscontextmanager.v1.ServicePerimeter
    perimeter_type: PERIMETER_TYPE_REGULAR
    enforced: true
    restricted_services: <status.restrictedServices[]>
    protected_projects: "<status.resources[] \u2014 list of projects/<number>>"
  state_logic: ACTIVE when perimeter is enforced (status non-empty, perimeterType REGULAR); skip when
    DRY_RUN-only or PERIMETER_TYPE_BRIDGE.
  conditions: []
  confidence: 0.95
  derived_from:
  - "accesscontextmanager.servicePerimeters.get \u2014 status, perimeterType"
  false_positive_note: Do not emit for dry-run-only perimeters (status absent or empty resources) or PERIMETER_TYPE_BRIDGE.
  narrative: Access policy {accesspolicy.name} contains enforced ServicePerimeter {perimeter.name}, protecting
    projects {protected_projects} for services {restricted_services}.
move · open · esc close