PCI DSS v4.x Future‑Dated Requirements Are Now In Force: Turn Compliance Into Policy‑as‑Code

If your organization touches card data, 2025 isn’t “next year’s” problem anymore. On March 31, 2025, the bulk of PCI DSS v4.x’s future‑dated controls moved from “best practice” to “required.” The PCI Security Standards Council (PCI SSC) has confirmed that 51 of the 64 new requirements are now mandatory, and the retirement of PCI DSS v3.2.1 on March 31, 2024 means v4.x is your only lane going forward. (blog.pcisecuritystandards.org)

In this piece, we’ll translate what “now mandatory” really means and show how to express high‑risk parts of PCI DSS v4.x as policy‑as‑code so you can gate changes, reduce drift, and produce auditor‑ready evidence—without turning engineers into full‑time checkbox chasers.

Note: Nothing here is legal advice; always coordinate with your QSA and acquiring bank.

Why this matters now

Three tempo changes hit at once:

One more nuance: requirement 6.4.2 supersedes 6.4.1 after March 31, 2025—so if your validation still references the old approach, your assessor will expect to see the new one. (pcisecuritystandards.org)

Think of this like switching from an acoustic set to a fully amplified show: you need the same chords (security objectives), but the rig (controls, evidence, automation) has to scale and be consistent, night after night.

The big shift in v4.x: flexibility and proof

PCI DSS v4.x introduced a “customized approach,” which lets mature teams meet control objectives using different technical methods—as long as you can prove the outcome. That proof hinges on targeted risk analyses, documentation, and testable evidence. Policy‑as‑code (PaC) is a natural companion: it turns requirements into repeatable checks that run at commit time and in production, and it leaves an audit trail every time you accept or reject a change. (blog.pcisecuritystandards.org)

From requirement to guardrail: a simple playbook

Here’s a pragmatic four‑step flow you can reuse across controls:

1) Map requirement → control intent → codified rule

2) Pick an enforcement point

3) Run it everywhere

4) Evidence on rails

Below are small, focused PaC examples tied to “now effective” concerns.

Example 1: Encrypt storage and keep buckets private (helps with protecting stored data and logging/monitoring)

Many breaches still come down to misconfigured storage. This Conftest policy (OPA/Rego) evaluates a Terraform plan and blocks merges if an S3 bucket is public or lacks encryption—simple, high‑signal guardrails aligned with protecting stored cardholder data and reducing exposure.

# policy/s3.rego
package terraform.s3

default deny = false

# Detect S3 bucket resources in Terraform plan JSON
s3 = input.resource_changes[_]
s3_type = s3.type == "aws_s3_bucket"
after = s3.change.after

# Require default encryption and block public ACLs
deny[msg] {
  s3_type
  not after.server_side_encryption_configuration
  msg := sprintf("S3 bucket %s must enable default encryption", [after.bucket])
}

deny[msg] {
  s3_type
  after.acl == "public-read"  # or public-read-write
  msg := sprintf("S3 bucket %s must not be public", [after.bucket])
}

# Optional: require access logging to a central log bucket
deny[msg] {
  s3_type
  not after.logging
  msg := sprintf("S3 bucket %s must enable server access logging", [after.bucket])
}

Run it in CI:

terraform plan -out tfplan.binary
terraform show -json tfplan.binary > tfplan.json
conftest test tfplan.json -p policy

If someone tries to add a public, unencrypted bucket, the build fails and the pull request shows exactly why—clean evidence you can hand to your assessor.

Example 2: Web attack prevention at the edge (supports the “automated” web‑attack control set)

As 6.4.x tightens browser‑side and app security, a practical infrastructure baseline is “no internet‑facing distribution without a WAF attached.” The Rego snippet below (again against a Terraform plan) fails a build if a CloudFront distribution lacks an AWS WAF association—one way to demonstrate an “automated technical solution to detect and prevent web‑based attacks.” Pair it with application‑layer controls like CSP/SRI in your frontend pipeline. (pcisecuritystandards.org)

# policy/waf.rego
package terraform.waf

default deny = false

cf = input.resource_changes[_]
cf_type = cf.type == "aws_cloudfront_distribution"
after = cf.change.after

deny[msg] {
  cf_type
  not after.web_acl_id
  msg := sprintf("CloudFront distribution %s must attach an AWS WAF (web_acl_id)", [after.comment])
}

This won’t, by itself, satisfy every testing procedure, but it gives you a visible, enforced baseline and auditable events when exceptions are made.

Example 3: Continuous enforcement in Azure (deny misconfigurations, prove it later)

Azure Policy lets you enforce security settings at scale and export compliance posture. Here’s a compact policy that denies Storage Accounts without secure transfer and TLS 1.2+. It’s not exotic, but it’s a reliable, low‑noise control you can point to during assessment.

{
  "properties": {
    "displayName": "Storage must enforce HTTPS and TLS >= 1.2",
    "policyType": "Custom",
    "mode": "All",
    "policyRule": {
      "if": {
        "allOf": [
          { "field": "type", "equals": "Microsoft.Storage/storageAccounts" },
          { "anyOf": [
              { "field": "Microsoft.Storage/storageAccounts/supportsHttpsTrafficOnly", "equals": "false" },
              { "field": "Microsoft.Storage/storageAccounts/minimumTlsVersion", "notEquals": "TLS1_2" }
          ]}
        ]
      },
      "then": { "effect": "deny" }
    }
  }
}

Assign at the subscription or management group, export compliance to your evidence repo nightly, and map the policy ID to your control register.

Example 4: Auto‑remediate drift in AWS (and leave breadcrumbs)

Prevention is great; fixing drift automatically is better. Cloud Custodian policies can close gaps and write what they did to an S3 evidence bucket.

policies:
  - name: encrypt-unencrypted-s3
    resource: aws.s3
    filters:
      - type: bucket-encryption
        state: False
    actions:
      - set-bucket-encryption:
          crypto: aws:kms
          key: alias/org-s3-kms
      - type: post-finding   # optional: send to Security Hub

Pair this with CloudTrail and a lightweight Lambda that writes “control X enforced, N resources remediated” into an audit log. Your assessor will appreciate both the control and the receipts.

Don’t forget the browser: e‑commerce changes got real

The Council has been explicit: e‑skimming and payment‑page tampering remain a big problem, and requirements around script integrity and change detection take effect in v4.0.1 as of March 31, 2025. The Council released a dedicated Information Supplement to help teams implement 6.4.3 and 11.6.1, and updated SAQ A to reflect these changes. Treat these as first‑class work items if you accept web payments. (blog.pcisecuritystandards.org)

Practical PaC hooks here include:

These checks won’t replace application testing, but they’ll keep you honest—and create the breadcrumbs assessors want to follow.

Make your assessor’s day: evidence patterns that work

Auditors love three things: clarity, consistency, and context. Bake these into your PaC pipeline:

Common gotchas (and how to dodge them)

A 30/60/90‑day plan you can actually ship

Balanced view: PaC is necessary—but not sufficient

Policy‑as‑code won’t write your incident response plan, train staff, or negotiate third‑party responsibilities. But it does three things exceptionally well:

Pair it with the Council’s guidance, especially for e‑commerce and the customized approach, and you’ll move from reactive “prove we did it” to proactive “we prevent it by default.” (blog.pcisecuritystandards.org)

Quick references to keep handy

If you treat PCI like sheet music and policy‑as‑code like your metronome, you’ll keep the whole band on time—dev, ops, and compliance together—without losing the groove.