cis_extensions.dns_logging — version 1.3
Source: presets
Purpose
CIS 5.0 §2.13 — DNS query logging, as far as an org policy can carry it.
WHAT THE CONTROL ASKS. Every VPC network has a Cloud DNS policy with logging enabled, so name resolution is auditable — which is how a compromised host asking for its command-and-control domain becomes visible. New in CIS 5.0; the 4.0 catalog has no such control.
WHAT A CONSTRAINT CAN AND CANNOT DO, stated plainly because the difference decides
the claim. An org-policy constraint judges a resource being CREATED or UPDATED. It
can therefore refuse a DNS policy that has logging off, which is what this pack
enforces. It cannot require that a resource EXIST: nothing in an org policy can say
"every network must have a DNS policy attached", because the network is not the
resource being changed and carries no reference to one. So this is a contributes
claim, not an implements — no org policy discharges §2.13 on its own, and the
missing half is a network that simply has no policy at all.
THE MISSING HALF IS THE ESTATE'S. A network the estate declares gets its policy from
the estate (google_dns_policy with enable_logging = true, naming that network);
a network a customer's workload team made in their own project is where
report-compliance earns its keep — it reads the live state and names the networks
without logging. That list is the worklist; this constraint is what keeps it from
growing.
WHAT IT COSTS. DNS query logs are charged as logging volume and are small beside flow logs — one entry per query, no payload. There is no sampling knob: logging is on or off per policy.
ON BY DEFAULT, like flow logs, and for the same reason: a customer switching it off
is deciding not to see name resolution, and that decision belongs in a deviates
claim whose reason the compliance report carries.
Use it
params {
cis_dns_logging = true
}
use "presets/cis/dns-logging.satz" when cis_dns_logging
cis_dns_logging 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
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_dns_logging_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 |
cis_dns_logging |
google_org_policy_policy |
custom-cisDnsPolicyLogging |
Claims
| framework | control | title | kind | witnesses | interpretation |
|---|---|---|---|---|---|
| cis-gcp 5.0 | 2.13 | Cloud DNS logging on all VPC networks | contributes | googlegoogle |
A Cloud DNS policy cannot be created or updated with query logging off. |
What the controls ask (this project's paraphrase from the catalog — never the framework's own text):
- Cloud DNS logging on all VPC networks (cis-gcp 5.0 §2.13) — Every VPC network has a DNS policy with logging enabled so name resolution is auditable.
Manual duties (a control stays partial until each is attested):
attach-policy(cis-gcp 5.0 §2.13) — The control also asks that every VPC network HAS such a policy, which no org policy can require: the estate declares one per network it owns, and report-compliance names the networks that have none.
Every resource this pack contributes is a witness of a claim above.
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_dns_logging_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-12 | first version: CIS 5.0 §2.13, the half an org policy can carry — a custom constraint on dns.googleapis.com/Policy requiring enableLogging. ON by default. contributes, not implements: no org policy can require that a network HAS a DNS policy, only that a policy which exists logs, so the missing half is named as a duty and verified live |
The whole library's history: the changelog in presets/CHANGELOG.md.
Notes
No notes yet.