cis_extensions.cmek — version 1.4
Source: presets/cis/cmek.satz
Purpose
CIS 7.2, 7.3 and 8.1 — customer-managed encryption keys.
Opt-in because once a service is listed, every NEW resource of that service must be created with a CMEK, so the key rings, the keys and the grants have to exist first. It also needs a decision the pack cannot make — which projects may supply keys.
Both constraints are plain LIST constraints, not managed booleans — verified
against a live organisation's OrgPolicy ListConstraints.
Use it
params {
cis_cmek_required = true
// the pack's own defaults — copy only the lines you change
cmek_required_services = [
"bigquery.googleapis.com",
"dataproc.googleapis.com",
]
cmek_allowed_key_projects = [
"under:organizations/{customer_organization_id}",
]
}
use "presets/cis/cmek.satz" when cis_cmek_required
cis_cmek_required is the gate: while it is falsy the pack contributes nothing — no resources, no params, no claims. It is declared by CIS_GCP_Foundation_4_0, and the estate's own binding wins.
Needs from outside the pack:
customer_organization_id— declared byestate_core; use one of them alongside, or declare it in the estate.
Params
| param | default |
|---|---|
cmek_required_services |
[ "bigquery.googleapis.com", "dataproc.googleapis.com" ] |
cmek_allowed_key_projects |
[ "under:organizations |
Questions
What to ask before this pack is configured, and what changing the answer costs.
| asks about | prompt | reversal | blast | recommends |
|---|---|---|---|---|
cmek_required_services |
The services whose new resources must be created with a customer-managed key | edit | high | — |
cmek_allowed_key_projects |
Which projects may supply the keys (resource paths: projects/ |
edit | high | — |
cmek_required_services — Every new resource of a listed service is refused without a CMEK, so the key rings, keys and service-agent grants for that service have to exist first. The default is the two services the claimed CIS controls cover.
cmek_allowed_key_projects — The default is anywhere in this organisation — the loosest useful value. Narrowing it to the KMS project later refuses every key that lives elsewhere, and a resource whose key is refused cannot be created.
Notices
What to run once this pack is switched on. satz shows each notice when the pack goes on and until the estate binds its param true; every command that writes to the organisation refuses while one whose severity is error is open.
| param | run | severity | what and why |
|---|---|---|---|
cis_cmek_required_adopted |
satz adopt <estate> --execute --import |
error | Google may already hold a policy this pack declares on the organisation, set by an administrator or by default, and an apply that creates a policy that exists stops on 409 POLICY_ALREADY_EXISTS. Run satz adopt once the pack is on, so every live policy is in the state before the apply; with --import it binds this param itself when it has run. |
Contributes
| resource type | labels |
|---|---|
google_org_policy_policy |
gcp-restrictNonCmekServices, gcp-restrict |
Claims
| framework | control | title | kind | witnesses | interpretation |
|---|---|---|---|---|---|
| cis-gcp 4.0 | 7.2 | BigQuery tables encrypted with a customer-managed key | implements | googlegoogle |
BigQuery may not create resources without a customer-managed key, and the key must come from an approved project. |
| cis-gcp 5.0 | 7.2 | BigQuery tables encrypted with a customer-managed key | implements | googlegoogle |
As for 4.0 §7.2 (5.0 §7.2, unchanged). |
| cis-gcp 4.0 | 7.3 | Default customer-managed key set for BigQuery datasets | contributes | google |
A dataset cannot be created without a CMEK, which is what makes a default key present; the default key ITSELF is a dataset attribute the org policy cannot set. |
| cis-gcp 5.0 | 7.3 | Default customer-managed key set for BigQuery datasets | contributes | google |
As for 4.0 §7.3 (5.0 §7.3, unchanged). |
| cis-gcp 4.0 | 8.1 | Dataproc clusters encrypted with a customer-managed key | implements | googlegoogle |
Dataproc may not create clusters without a customer-managed key, and the key must come from an approved project. |
| cis-gcp 5.0 | 8.1 | Dataproc clusters encrypted with a customer-managed key | implements | googlegoogle |
As for 4.0 §8.1 (5.0 §8.1, unchanged). |
What the controls ask (this project's paraphrase from the catalog — never the framework's own text):
- BigQuery tables encrypted with a customer-managed key (cis-gcp 4.0 §7.2, cis-gcp 5.0 §7.2) — BigQuery tables are protected by CMEK rather than Google-managed keys.
- Dataproc clusters encrypted with a customer-managed key (cis-gcp 4.0 §8.1, cis-gcp 5.0 §8.1) — Dataproc cluster data is protected by CMEK.
- Default customer-managed key set for BigQuery datasets (cis-gcp 4.0 §7.3, cis-gcp 5.0 §7.3) — Every BigQuery dataset carries a default CMEK, so new tables inherit it.
Manual duties (a control stays partial until each is attested):
default-key(cis-gcp 4.0 §7.3, cis-gcp 5.0 §7.3) — Set defaultEncryptionConfiguration on each dataset — the constraint forces a key to exist, not which one is the dataset default.keys-exist(cis-gcp 4.0 §7.2, cis-gcp 5.0 §7.2, cis-gcp 4.0 §8.1, cis-gcp 5.0 §8.1) — The constraint denies creation; it does not create keys. The key ring, the keys and the service agents' encrypterDecrypter grants have to be in place before this is enforced.
Every resource this pack contributes is a witness of a claim above.
History
| version | date | change |
|---|---|---|
| 1.4 | 2026-09-30 | every claim states its measure without satz: gcloud (the commands that meet the control the way the claim's resources do), gcloud_check (the commands that show whether it is met) and risk (what goes wrong without it); require and report-compliance carry them in each control's measures. Nothing emitted changes |
| 1.3 | 2026-09-20 | the notice's before = apply becomes severity = error: the same refusal, stated once by the pack instead of inside the two commands that read it — every command that writes to the organisation refuses while it is open. Nothing emitted changes, and the param that acknowledges it is unchanged |
| 1.2 | 2026-09-19 | a notice: once the pack is switched on, satz adopt <estate> --execute --import is to run before the apply, because a policy it declares may already be live and creating it stops on 409 POLICY_ALREADY_EXISTS. The estate acknowledges it with cis_cmek_required_adopted = true, which adopt --execute --import binds itself when it has run; transpile --apply and bootstrap refuse while it is open. The param is never emitted, so the plan does not move |
| 1.1 | 2026-09-10 | two question blocks: the services that must use a CMEK and the projects that may supply keys — both refuse resource creation when wrong. Nothing emitted changes |
| 1.0 | 2026-09-04 | CIS 7.2, 7.3 and 8.1, opt-in: two LIST constraints; the keys and grants must exist first, and the key-project value takes a resource PATH |
The whole library's history: the changelog in presets/CHANGELOG.md.
Notes
The key rings, the keys and the grants to the services' agents have to exist before a service is listed here: from then on every NEW resource of that service must be created with a CMEK, and one that cannot reach its key does not start.