gcp-certmanager-impersonate-via-forged-cert

Issue a cert for an attacker-chosen subject/SAN that a downstream trust accepts, impersonating that identity.

derived gcp emits CanImpersonate

match

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

{'principal': None} CanSignAs {'capool': None}

where

node_type(?capool) == CaPool (SigningKey) the pool issuancePolicy / bound certificate template ALLOWS the attacker to set the target subject/SAN: identityConstraints.allowSubjectPassthrough OR allowSubjectAltNamesPassthrough is true, OR the celExpression admits it, OR no restricting template is bound a downstream trust consumes CAS-issued certs and maps the forged subject/SAN to ?target (mTLS mesh / SPIFFE-SPIRE / VPN-LB client-cert store / device or workload cert bound to a GCP identity) node_type(?target) in [ServiceAccount, MachineIdentity, ApplicationIdentity]

emit

source typeIdentity
source<principal>
target<forged identity the consuming trust authenticates>
permissionsprivateca.certificates.create privateca.caPools.use
conditionsiam_permission condition_expression trust_relationship
state logicInherits the CanSignAs state (ACTIVE / CONDITIONAL(key_permission) for KMS- backed / BLOCKED). Then: ACTIVE only if the issuancePolicy/template confirmed permits the target subject/SAN AND a consuming trust is identified; CONDITIONAL(condition_expression) if the issuance policy is unknown/unconfirmed; CONDITIONAL(trust_relationship) if no CAS-cert consumer is identified; BLOCKED if the policy pins the subject (allowSubjectPassthrough=false + no passthrough SAN + restrictive template/celExpression) or the CanSignAs input is BLOCKED.

Narrative

{principal.name} can issue a certificate from {capool.name} for subject/SAN naming {target.name} (issuance policy permits the subject), which a downstream trust consumes to authenticate - impersonating {target.name}.

Raw rule rules/derived/gcp/certmanager.yaml

id: gcp-certmanager-impersonate-via-forged-cert
emits: CanImpersonate
description: Issue a cert for an attacker-chosen subject/SAN that a downstream trust accepts, impersonating
  that identity.
match:
- - principal: null
  - CanSignAs
  - capool: null
where:
- node_type(?capool) == CaPool (SigningKey)
- 'the pool issuancePolicy / bound certificate template ALLOWS the attacker to set the target subject/SAN:
  identityConstraints.allowSubjectPassthrough OR allowSubjectAltNamesPassthrough is true, OR the celExpression
  admits it, OR no restricting template is bound'
- a downstream trust consumes CAS-issued certs and maps the forged subject/SAN to ?target (mTLS mesh /
  SPIFFE-SPIRE / VPN-LB client-cert store / device or workload cert bound to a GCP identity)
- node_type(?target) in [ServiceAccount, MachineIdentity, ApplicationIdentity]
emit:
  source_type: Identity
  source: <principal>
  target: <forged identity the consuming trust authenticates>
  permissions:
  - privateca.certificates.create
  - privateca.caPools.use
  conditions:
  - iam_permission
  - condition_expression
  - trust_relationship
  state_logic: 'Inherits the CanSignAs state (ACTIVE / CONDITIONAL(key_permission) for KMS- backed / BLOCKED).
    Then: ACTIVE only if the issuancePolicy/template confirmed permits the target subject/SAN AND a consuming
    trust is identified; CONDITIONAL(condition_expression) if the issuance policy is unknown/unconfirmed;
    CONDITIONAL(trust_relationship) if no CAS-cert consumer is identified; BLOCKED if the policy pins
    the subject (allowSubjectPassthrough=false + no passthrough SAN + restrictive template/celExpression)
    or the CanSignAs input is BLOCKED.'
  confidence: min(contributing_confidences) * 0.8
  derived_from:
  - <CanSignAs edge_id>
  - <pool issuancePolicy / certificate template evidence>
  - <downstream CAS-cert trust evidence>
  false_positive_note: "DOUBLY CONDITIONAL. (1) Forgery gate: a pool with allowSubjectPassthrough=false\
    \ / allowSubjectAltNamesPassthrough=false and a restrictive celExpression or bound certificate template\
    \ PINS the subject \u2014 the principal can obtain a cert but NOT for an arbitrary identity; keep\
    \ CONDITIONAL(condition_expression) until the policy is confirmed permissive. (2) Trust gate: a CAS\
    \ cert authenticates to nothing unless some system trusts the CA and maps the subject to a principal;\
    \ default CONDITIONAL(trust_relationship). createForSelf (subject == caller) is NOT impersonation.\
    \ Only emit a concrete ?target when a consuming trust maps the forgeable subject to it; otherwise\
    \ emit POTENTIAL or omit."
  narrative: "{principal.name} can issue a certificate from {capool.name} for subject/SAN naming {target.name}\
    \ (issuance policy permits the subject), which a downstream trust consumes to authenticate \u2014\
    \ impersonating {target.name}."
move · open · esc close