Verify Permissions on /var/log/cloud-init.log(.*) Files
Ensures /var/log/cloud-init (and its log files) is not writable by group/other and carries no execute/setuid/setgid/sticky bits.
Checked against the content of a persistent configuration file, the source of truth that survives reboots.
A mapping is a cross-reference to where each standard places this requirement, anchored and cross-validated, not a claim of equivalence. A passing check is evidence toward these references, how to read it.
Why this rule matters
cloud-init logs the entire first-boot provisioning: user-data, network config, and sometimes secrets injected at deployment (passwords, tokens, SSH keys, instance metadata). If non-root users can write to these logs they can tamper with provisioning evidence; if the logs are over-exposed, sensitive bootstrap data leaks. Access must be confined to root so this debugging detail stays with authorized personnel.
What Pavois checks
Pavois reads the effective inode mode of /var/log/cloud-init and asserts no group/other write and no special bits. Reading the live mode catches the common case where a custom cloud image or a provisioning script created the log world-readable or group-writable, drift that a static packaging manifest would never reveal.
['/var/log/cloud-init.log', '/var/log/cloud-init-output.log'].each do |f|
next unless file(f).exist?
describe file(f) do
it { should_not be_writable.by('group') }
it { should_not be_readable.by('other') }
it { should_not be_writable.by('other') }
it { should_not be_executable.by('other') }
it { should_not be_setuid }
it { should_not be_setgid }
end
endHow to verify it is applied
Run stat -c '%U %G %a' /var/log/cloud-init and stat -c '%a' /var/log/cloud-init.log. Expected: owner root, mode 640 or stricter, no write for group/other.
Inspect & investigate
Provisioning detail is in /var/log/cloud-init.log and /var/log/cloud-init-output.log; cloud-init's status is shown by cloud-init status --long and journalctl -u cloud-init. Re-check the mode after any re-run of cloud-init.
Remediation
No automated remediation ships for this rule. Tighten manually: chown root:adm /var/log/cloud-init.log && chmod 640 /var/log/cloud-init.log and apply the same to the /var/log/cloud-init directory. cloud-init's own def_log_file_mode (in /etc/cloud/cloud.cfg) can set the log mode at creation.
Pavois applies this with its own harden engine, the plan below, not a shell script:
| command | for f in /var/log/cloud-init.log /var/log/cloud-init-output.log; do [ -e "$f" ] && chmod g-wx,o-rwx "$f"; done; true |
|---|---|
| name | fileperm-var-log-cloud-init-tighten |
| not_if | ! find /var/log/cloud-init.log /var/log/cloud-init-output.log -maxdepth 0 \( -perm /g=wx -o -perm /o=rwx \) 2>/dev/null | grep -q . |
| resource | exec |
pavois harden plan localwhere the target is local, a user@host SSH alias, or a container , Docs
Impact & precautions
Over-exposed cloud-init logs can leak provisioning secrets and let attackers tamper with deployment evidence. Restricting to root/adm is safe. Precaution: on systems that re-run cloud-init (re-deploys, golden-image rebuilds), the log may be recreated with the default mode, set def_log_file_mode in cloud-init config so the hardening persists rather than being undone on the next boot.
Standards mapping
| Standard | Reference | Type | Version | Confidence |
|---|---|---|---|---|
| CIS | 6.1.4.1, 6.2.2.1 | direct | per OS, see the benchmark table | high |
Each reference is a cross-reference anchored in the upstream benchmark and cross-validated against the SCAP Security Guide and ansible-lockdown, not a claim of equivalence. Direct = a prescriptive, line-level requirement; supporting = an abstract control family (NIST) the check provides evidence toward. How to read a mapping.