gcp-certmanager-can-sign-as

privateca.certificates.create + caPools.use lets a principal issue a cert signed by the CA private key.

derived gcp emits CanSignAs

match (effective permission)

{ "action": "privateca.certificates.create", "resource_type": "google.privateca.CaPool" }

where

principal ALSO has EFFECTIVE privateca.caPools.use on the SAME pool (both are required; both live in roles/privateca.certificateRequester) the pool contains at least one ENABLED CertificateAuthority (state == ENABLED) CA is NOT KMS-backed with an unresolved service-agent grant — for KMS-backed CAs see gcp-certmanager-sign-cmek-gate

emit

source typeIdentity
source<principal>
target<CA pool node (SigningKey)>
permissionsprivateca.certificates.create privateca.caPools.use
conditionsiam_permission
state logicACTIVE if both privateca.certificates.create AND privateca.caPools.use resolve on the pool AND the pool has an ENABLED CA; BLOCKED if the CA is DISABLED, or a VPC-SC perimeter / IAM deny denies certificates.create or caPools.use at the effective scope (denied_by=<perimeter/deny>).

Narrative

{principal.name} can issue certificates signed by CA pool {capool.name} (privateca.certificates.create + privateca.caPools.use / roles/privateca.certificateRequester).

Raw rule rules/derived/gcp/certmanager.yaml

id: gcp-certmanager-can-sign-as
emits: CanSignAs
description: privateca.certificates.create + caPools.use lets a principal issue a cert signed by the CA
  private key.
match_effective_permission:
  action: privateca.certificates.create
  resource_type: google.privateca.CaPool
where:
- principal ALSO has EFFECTIVE privateca.caPools.use on the SAME pool (both are required; both live in
  roles/privateca.certificateRequester)
- the pool contains at least one ENABLED CertificateAuthority (state == ENABLED)
- "CA is NOT KMS-backed with an unresolved service-agent grant \u2014 for KMS-backed CAs see gcp-certmanager-sign-cmek-gate"
emit:
  source_type: Identity
  source: <principal>
  target: <CA pool node (SigningKey)>
  permissions:
  - privateca.certificates.create
  - privateca.caPools.use
  conditions:
  - iam_permission
  state_logic: ACTIVE if both privateca.certificates.create AND privateca.caPools.use resolve on the pool
    AND the pool has an ENABLED CA; BLOCKED if the CA is DISABLED, or a VPC-SC perimeter / IAM deny denies
    certificates.create or caPools.use at the effective scope (denied_by=<perimeter/deny>).
  confidence: min(contributing_confidences) * 0.97
  derived_from:
  - <effective privateca.certificates.create grant>
  - <effective privateca.caPools.use grant>
  false_positive_note: "REQUIRES BOTH certificates.create AND caPools.use on the SAME pool \u2014 a principal\
    \ with only certificates.create cannot issue. This edge asserts only that the principal can obtain\
    \ a signature (sign SOMETHING); it does NOT by itself mean arbitrary-subject forgery \u2014 that is\
    \ gated by the pool issuancePolicy / certificate template (see gcp-certmanager-impersonate-via-forged-cert).\
    \ createForSelf alone (subject == caller) is not this edge's arbitrary-issuance capability. CA must\
    \ be ENABLED. Grant is per-pool unless held at an ancestor."
  narrative: '{principal.name} can issue certificates signed by CA pool {capool.name} (privateca.certificates.create
    + privateca.caPools.use / roles/privateca.certificateRequester).'
move · open · esc close