ASVS 5.0 V14.2.4 is a Level 2 requirement. The controls for encryption, integrity verification, retention, logging, log access and privacy techniques must actually be implemented as your documentation defines for each data protection level.
It is the check that closes the loop between V14.1.2 (what you wrote) and what runs in production.
Why it matters
Documentation drifts. A policy that says restricted data is never logged is worthless if a debug statement prints it. Reviewers and attackers both judge the system, not the document.
How to implement it
Turn each documented rule into a check that can fail.
# Test: restricted fields never appear in logs
def test_restricted_fields_not_logged(caplog):
client.post("/payments", json={"card_number": "4111111111111111"})
assert "4111111111111111" not in caplog.text
-- Retention rule: no restricted records older than 90 days
SELECT count(*) FROM payment_tokens WHERE created_at < now() - interval '90 days';
-- expected: 0
For encryption at rest, assert it in infrastructure code (for example a storage resource that requires a managed key) and run a policy check in the pipeline. For integrity, verify signatures or checksums on read and test that a tampered record is rejected.
Assign each rule an owner and a place where the check runs, and fail the build when a check breaks.
How to test it
Pick one documented rule per protection level and demonstrate it end to end: write test data, find it in the store, the logs and backups, and confirm the stored form and lifetime match the document.
Common mistakes
- Checking configuration but not the data, so unencrypted legacy rows remain.
- Covering new code while old services keep old behavior.
- Treating retention as a plan rather than a scheduled job with proof of execution.
Quick check
What counts as evidence?
Automated test results, query output showing retention, and infrastructure policy reports, kept with the release.