gcp-gcs-escalate-via-hmac-key
Generating an HMAC key for a Service Account with greater GCS-scoped access and using it via the S3-compatible GCS API constitutes privilege escalation (storage-scoped only, not full SA impersonation).
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
edge comes from gcp-gcs-hmac-key-create (scope_qualifier: gcs_s3_compatible_api_only)
?sa has read/write/admin permissions on GCS buckets that ?principal cannot access (as evidenced by
CanReadData/CanWriteData roles or bucket IAM bindings)
emit
| source type | Identity |
|---|---|
| target type | Identity |
| source | ?principal |
| target | ?sa |
| permissions | storage.hmacKeys.create |
| conditions | iam_permission role_compatibility |
| state logic | Inherits state from the CanCreateCredentialFor contributor (gcp-gcs-hmac-key-create): ACTIVE when hmacKeys.create is confirmed and the target SA has demonstrably greater GCS access (via sampled bucket IAM bindings or role assignments) than the calling principal; CONDITIONAL when actAs grant uncertainty downgrades CanCreateCredentialFor; BLOCKED if hmacKeys.create is denied. Scope limited to GCS S3-compatible operations (not full SA impersonation across all Google APIs — HMAC keys authenticate only to the GCS S3-compatible XML API endpoint). |
Narrative
{principal.name} can generate an HMAC key for {sa.name} (which has greater GCS-scoped access to buckets). Using the key's S3-compatible credential, {principal.name} can access buckets {sa.name} can reach - GCS storage-scoped privilege escalation (NOT full SA impersonation across Google APIs).
Raw rule rules/derived/gcp/gcs.yaml
id: gcp-gcs-escalate-via-hmac-key
emits: CanEscalateTo
description: Generating an HMAC key for a Service Account with greater GCS-scoped access and using it
via the S3-compatible GCS API constitutes privilege escalation (storage-scoped only, not full SA impersonation).
match:
- - principal: null
- CanCreateCredentialFor
- sa: null
where:
- 'edge comes from gcp-gcs-hmac-key-create (scope_qualifier: gcs_s3_compatible_api_only)'
- ?sa has read/write/admin permissions on GCS buckets that ?principal cannot access (as evidenced by CanReadData/CanWriteData
roles or bucket IAM bindings)
emit:
source_type: Identity
target_type: Identity
source: ?principal
target: ?sa
permissions:
- storage.hmacKeys.create
conditions:
- iam_permission
- role_compatibility
scope_qualifier: gcs_s3_compatible_api_only
state_logic: "Inherits state from the CanCreateCredentialFor contributor (gcp-gcs-hmac-key-create):\
\ ACTIVE when hmacKeys.create is confirmed and the target SA has demonstrably greater GCS access (via\
\ sampled bucket IAM bindings or role assignments) than the calling principal; CONDITIONAL when actAs\
\ grant uncertainty downgrades CanCreateCredentialFor; BLOCKED if hmacKeys.create is denied. Scope\
\ limited to GCS S3-compatible operations (not full SA impersonation across all Google APIs \u2014\
\ HMAC keys authenticate only to the GCS S3-compatible XML API endpoint)."
confidence: min(contributing_confidences) * 0.85
derived_from:
- '?principal CanCreateCredentialFor ?sa (via gcp-gcs-hmac-key-create, scope: gcs_s3_api)'
- ?sa has greater GCS bucket access than ?principal
false_positive_note: "CRITICAL: HMAC keys authenticate ONLY to the GCS S3-compatible XML API (s3.googleapis.com\
\ / storage.googleapis.com S3 endpoint). The JSON API at storage.googleapis.com/storage/v1 is a separate\
\ authentication domain. A HMAC key does NOT grant iam.*, cloudfunctions.*, or other GCP APIs \u2014\
\ privilege escalation is STORAGE-SCOPED ONLY, not full SA impersonation. This rule emits CanEscalateTo\
\ (not full CanImpersonate) to signal GCS-scoped escalation. DO NOT compare broad IAM privilege_level\
\ fields across different API families \u2014 instead, sample bucket IAM bindings to confirm the target\
\ SA has greater storage.objects.get / storage.objects.create reach than the principal. Escalation\
\ is spurious if both SAs have identical GCS bucket access \u2014 emit POTENTIAL or CONDITIONAL, not\
\ ACTIVE. can-control.yaml and credential-chains.yaml handle broader (full-API) escalation roll-ups;\
\ cite them for GCS-scoped findings that transition to org-level escalation, do not duplicate."
narrative: "{principal.name} can generate an HMAC key for {sa.name} (which has greater GCS-scoped access\
\ to buckets). Using the key's S3-compatible credential, {principal.name} can access buckets {sa.name}\
\ can reach \u2014 GCS storage-scoped privilege escalation (NOT full SA impersonation across Google\
\ APIs)."