gcp-kms-sign-forge-identity

Signing as a key that anchors an identity (JWKS/JWT/code-signing) forges that identity.

derived gcp emits CanImpersonate

match

A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.

{'principal': None} CanSignAs {'key': None}

where

CryptoKey.purpose == ASYMMETRIC_SIGN — a MAC key has no public key and can NEVER be a trust anchor; SKIP MAC-derived CanSignAs edges (gcp-kms-can-mac) ?key's public key is a published trust anchor for an identity (e.g. a JWKS/JWT issuer, workload-identity signer, code-signing identity) — established from evidence, not assumed the anchored identity resolves to a ServiceAccount / ApplicationIdentity

emit

source typeIdentity
source<principal>
target<identity anchored by the signing key (ServiceAccount/ApplicationIdentity)>
permissionscloudkms.cryptoKeyVersions.useToSign
conditionsiam_permission resource_policy key_permission trust_relationship
state logicInherits CanSignAs state. ACTIVE only with evidence the public key is a trust anchor accepted by a relying party; POTENTIAL when the anchor relationship is unconfirmed. BLOCKED if useToSign is denied.

Narrative

{principal.name} can sign as {key.name}, whose public key anchors {identity.name}; forging a signed token impersonates {identity.name}.

Raw rule rules/derived/gcp/kms.yaml

id: gcp-kms-sign-forge-identity
emits: CanImpersonate
description: Signing as a key that anchors an identity (JWKS/JWT/code-signing) forges that identity.
match:
- - principal: null
  - CanSignAs
  - key: null
where:
- "CryptoKey.purpose == ASYMMETRIC_SIGN \u2014 a MAC key has no public key and can NEVER be a trust anchor;\
  \ SKIP MAC-derived CanSignAs edges (gcp-kms-can-mac)"
- "?key's public key is a published trust anchor for an identity (e.g. a JWKS/JWT issuer, workload-identity\
  \ signer, code-signing identity) \u2014 established from evidence, not assumed"
- the anchored identity resolves to a ServiceAccount / ApplicationIdentity
emit:
  source_type: Identity
  source: <principal>
  target: <identity anchored by the signing key (ServiceAccount/ApplicationIdentity)>
  permissions:
  - cloudkms.cryptoKeyVersions.useToSign
  conditions:
  - iam_permission
  - resource_policy
  - key_permission
  - trust_relationship
  state_logic: Inherits CanSignAs state. ACTIVE only with evidence the public key is a trust anchor accepted
    by a relying party; POTENTIAL when the anchor relationship is unconfirmed. BLOCKED if useToSign is
    denied.
  confidence: min(contributing_confidences) * 0.75
  derived_from:
  - <CanSignAs edge_id>
  - <public-key-as-trust-anchor evidence>
  false_positive_note: "Do NOT emit merely because a key can sign \u2014 most signing keys are not identity\
    \ anchors. Requires concrete evidence (JWKS URI, OIDC config, code-signing trust) that a relying party\
    \ accepts signatures from this key AS the target identity. Otherwise keep POTENTIAL or omit."
  narrative: '{principal.name} can sign as {key.name}, whose public key anchors {identity.name}; forging
    a signed token impersonates {identity.name}.'
move · open · esc close