gcp-certmanager-can-sign-as
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 — 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>). |
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).'