cis_extensions.cloud_sql_iam_and_deletion_protection — version 1.3

Source: presets/cis/cloud-sql-iam-and-deletion-protection.satz

Purpose

CIS 5.0 §6.6 / §6.9 — Cloud SQL instances sign database users in through IAM, and cannot be deleted while deletion protection is on. Both are new in 5.0.

Two custom constraints on sqladmin.googleapis.com/Instance, each enforced by a policy on the organisation. A custom constraint is checked when an instance is created or updated, never against one that exists: an existing instance that breaks either is refused its next update, until that update fixes it.

IAM database authentication is a database flag — cloudsql.iam_authentication on PostgreSQL, cloudsql_iam_authentication on MySQL. SQL Server has no such flag, and the IAM constraint lets SQL Server instances through.

Opt-in because every Cloud SQL create and update in the organisation must then carry both settings; tooling that creates instances without them fails. Prowler has no check for either control, so report-compliance verifies them through the two policies only.

Use it

params {
  cis_cloud_sql_iam_and_deletion_protection = true
}

use "presets/cis/cloud-sql-iam-and-deletion-protection.satz" when cis_cloud_sql_iam_and_deletion_protection

cis_cloud_sql_iam_and_deletion_protection 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:

Params

None — the pack takes everything from the estate's params.

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_cloud_sql_iam_and_deletion_protection_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_custom_constraint cis_sql_iam_authentication, cis_sql_deletion_protection
google_org_policy_policy custom-cisCloudSqlIamAuthentication, custom-cisCloudSqlDeletionProtection

Claims

framework control title kind witnesses interpretation
cis-gcp 5.0 6.6 Cloud SQL IAM database authentication enabled implements google_org_policy_policy.custom_cisCloudSqlIamAuthentication A Cloud SQL instance is created or updated only with IAM database authentication on (PostgreSQL and MySQL; SQL Server has no such flag).
cis-gcp 5.0 6.9 Cloud SQL deletion protection enabled implements google_org_policy_policy.custom_cisCloudSqlDeletionProtection A Cloud SQL instance is created or updated only with deletion protection enabled.

What the controls ask (this project's paraphrase from the catalog — never the framework's own text):

Manual duties (a control stays partial until each is attested):

Not every resource this pack contributes is a witness:

History

version date change
1.3 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.2 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.1 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_cloud_sql_iam_and_deletion_protection_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.0 2026-09-11 CIS 5.0 6.6 and 6.9, opt-in: two custom constraints on Cloud SQL instances — IAM database authentication on (SQL Server exempt), deletion protection on — each enforced by a policy on the organisation

The whole library's history: the changelog in presets/CHANGELOG.md.

Notes

Custom constraints are checked when an instance is created or updated, never against one that already exists: an estate's current instances keep running and fail their next update instead. Prowler has no check for either control, so report-compliance is the only thing that reports them. CIS 5.0 only — 4.0 has no equivalent control.