Why this matters
SAD storage is prohibited; accidental retention is a common path to PCI violations.
Never store CVV/CVC or other SAD after authorization in databases, caches, files, or telemetry. Schema/models must not define fields for CVV/CVC; reject writes containing cvv/cvc keys. (PCI DSS 4.0 Req. 3.2.1)
SAD storage is prohibited; accidental retention is a common path to PCI violations.
Side-by-side examples engineers can pattern-match during review.
CREATE TABLE cards(
id SERIAL,
pan_token TEXT NOT NULL,
cvv VARCHAR(4) -- ❌ forbidden
);CREATE TABLE cards(
id SERIAL,
pan_token TEXT NOT NULL -- ✅ token only, no CVV
);
-- Validate payloads drop SAD
DELETE FROM input_json WHERE key IN ('cvv','cvc','track2');{"pan_token":"tok_123","cvv":"123"}{"pan_token":"tok_123"}From the same buckets as this rule.
Never emit Primary Account Number (PAN) or Sensitive Authentication Data (SAD: CVV/CVC, full track data, PIN) to application or audit logs. Per PCI DSS 4.0 Req. 3 and 10, always mask PAN as first6last4 and fully redact SAD before logging.
Reject PRs adding real PAN/CVV in fixtures, seeds, or mocks. Only use Luhn-valid test PANs from the gateway or opaque tokens (e.g., tok_) and never include CVV. Add a check to fail if a PAN regex is matched. (PCI DSS data minimization)
On every create/read/update/delete of CHD or tokens, write a structured audit event (who, what, when, result) without full PAN, including only pan_last4. Persist to an append-only/immutable sink. (PCI DSS 4.0 Req. 10)