diff --git a/README.md b/README.md index daf9338..a91bbff 100644 --- a/README.md +++ b/README.md @@ -140,11 +140,13 @@ this check green is also what makes the next regeneration safe — if the datastream already matches what the in-repo sources would produce, rebuilding it cannot silently revert anything. -Differences that would change a scan verdict fail; purely descriptive -ones (titles, descriptions, ``) are logged instead, -since the two copies currently disagree on some of those without -affecting any result — failing on them would mean disabling the check -rather than fixing content. +Any difference fails, reported as either functional (criteria, tests, +objects, states, variables — these change a scan verdict) or descriptive +(titles, descriptions, `` — these do not). Descriptive +differences were logged rather than failed while five embedded blocks +still carried a `` of `CIS` against the standalone +files' `Custom`; that content was corrected and the gate closed behind +it. The comparison lives in `tests/oscap-offline/internal/mirrors` alongside its own unit tests, so diff --git a/gpos/xml/scap/ssg/content/ssg-chainguard-gpos-ds.xml b/gpos/xml/scap/ssg/content/ssg-chainguard-gpos-ds.xml index d536d0b..96bbddd 100644 --- a/gpos/xml/scap/ssg/content/ssg-chainguard-gpos-ds.xml +++ b/gpos/xml/scap/ssg/content/ssg-chainguard-gpos-ds.xml @@ -6312,7 +6312,7 @@ Check for OpenSSL FIPS Packages Ensure that the necessary OpenSSL FIPS packages and configuration files are present, and that the OPENSSL_CONF environment variable is either unset or set to /etc/ssl/openssl.cnf. Additionally verify that the OpenSSH client and server FIPS policy drop-ins (/etc/ssh/ssh_config.d/10-ssh-fips.conf and /etc/ssh/sshd_config.d/10-sshd-fips.conf) are present and pin the FIPS-approved ciphers, key-exchange, MAC, and signature algorithms. The main /etc/ssh/ssh_config and /etc/ssh/sshd_config must in turn Include their respective *_config.d/*.conf drop-in directories so the policy is applied. The client checks apply only when openssh-client is installed and the server checks only when openssh-server is installed. - + Chainguard @@ -6587,7 +6587,7 @@ Check Library Permissions Ensure all libraries in /usr/lib have root:root permissions. - + Chainguard @@ -6652,7 +6652,7 @@ Check for Login-Capable Users in /etc/shadow Ensure every entry in /etc/shadow is locked (password field starts with '!' or '*'), i.e. there are no login-capable user accounts. Locked service accounts, such as those apko creates for image run-as users, cannot log in and are permitted. - + Chainguard @@ -6774,7 +6774,7 @@ No active/unlocked password field in /etc/shadow Chainguard container images must not ship interactive shadow password entries; every account must have its shadow field locked ("!" or "*"). This check FAILS if any line in /etc/shadow matches an active/unlocked password field, on the premise that hardened images have no interactive logins. - + Chainguard @@ -6812,7 +6812,7 @@ Check Var/Log Permissions Ensure /var/log has root:root permissions. - + Chainguard diff --git a/tests/oscap-offline/internal/mirrors/doc.go b/tests/oscap-offline/internal/mirrors/doc.go index 08ec4b5..1ce9e32 100644 --- a/tests/oscap-offline/internal/mirrors/doc.go +++ b/tests/oscap-offline/internal/mirrors/doc.go @@ -29,13 +29,14 @@ // variable — is an error: the two copies would evaluate the same image // differently. // -// Metadata (title, description, reference, affected) is a warning. The copies -// disagree today on a reading "Custom" in every standalone -// file and "CIS" in five embedded blocks, which changes no verdict. Since -// generation copies the standalone file verbatim, the standalone spelling is -// canonical by construction and those embedded values are simply stale, but -// correcting them is a content change to the shipped datastream and is not -// bundled with the comparison itself. +// Metadata (title, description, reference, affected) is reported separately, +// because it does not change a verdict — but it is still a failure, since the +// two copies agree on all of it. They did not always: five embedded blocks +// carried a of "CIS" against the standalone files' "Custom", +// which is why this started out as a warning. Treating a difference that +// changes no verdict as fatal while known instances existed would have meant +// disabling the check rather than fixing content, so the content was corrected +// first and the gate closed behind it. // // # Why entities, not a flat node list // diff --git a/tests/oscap-offline/internal/mirrors/mirrors_test.go b/tests/oscap-offline/internal/mirrors/mirrors_test.go index 907b00a..38142a1 100644 --- a/tests/oscap-offline/internal/mirrors/mirrors_test.go +++ b/tests/oscap-offline/internal/mirrors/mirrors_test.go @@ -379,8 +379,14 @@ func TestRepositoryMirrorsMatch(t *testing.T) { for _, f := range report.Functional { t.Errorf("functional difference: %s", f) } + // Descriptive differences fail too, now that the two copies agree on all of + // them. They were logged rather than failed while five embedded blocks still + // carried a of "CIS" against the standalone files' + // "Custom" — a difference that changes no verdict, so failing on it would + // have meant disabling this test instead of fixing content. The content is + // fixed, so the gate closes behind it. for _, f := range report.Descriptive { - t.Logf("descriptive difference (not fatal): %s", f) + t.Errorf("descriptive difference: %s", f) } // A run that paired nothing would otherwise read as success.