Control template: PCI DSS v4.0
Status: Public Beta · Version: pci-dss-v4/v0.1.0-beta
A bundle of CALM control snippets covering the architectural surface
of PCI DSS v4.0. You copy these into your *.calm.json files on the
nodes that handle cardholder data (the Cardholder Data Environment,
or CDE).
This replaces the legacy framework-gated validators that fired
automatically when a node declared compliance-frameworks: ["pci"].
Why the change:
- You author what you want enforced. No surprise "ArchRails decided your service was PCI-scoped"; you decide.
- You control the rule vocabulary. Findings on the PR comment read in your language ("encryption-at-rest on cardholder-db"), not ours.
- Versioned. Pin to
v1.0.0; upgrade tov2.0.0(PCI v5 when it ships) on your schedule. - Cleaner audit story. "Customer policy as authored, enforced by ArchRails" reads better in an audit than "ArchRails opinion imposed."
What this template covers
11 of PCI DSS v4.0's 12 high-level requirements are addressed architecturally below. The remaining one (Req 5, anti-malware) is endpoint-detection territory — pair ArchRails with Crowdstrike / SentinelOne / etc. for that surface.
| PCI DSS v4 Requirement | Control alias below |
|---|---|
| Req 1 — Network segmentation | pci-network-segmentation |
| Req 2 — Secure configurations (no default credentials) | pci-no-default-credentials |
| Req 3 — Stored account-data encryption | pci-data-encryption-at-rest |
| Req 4 — Strong cryptography in transit | pci-no-unsafe-protocol + pci-tls-minimum-version |
| Req 5 — Anti-malware | Out of architectural scope |
| Req 6 — Secure SDLC / WAF | pci-waf-required |
| Req 7 — Access restrictions (RBAC) | pci-rbac-required |
| Req 8 — MFA | pci-mfa-required |
| Req 9 — Physical access | Not applicable (physical security) |
| Req 10 — Audit logging + retention | pci-audit-logging + pci-log-retention |
| Req 11 — Testing (vuln scan, IDS, pen test) | pci-vulnerability-scanning + pci-intrusion-detection + pci-penetration-testing |
| Req 12 — Incident response | pci-incident-response |
The CDE pattern
A node belongs to the Cardholder Data Environment (CDE) if it stores, processes, or transmits cardholder data. Tag those nodes explicitly in your CALM:
{
"unique-id": "payments-api",
"node-type": "service",
"name": "Payments API",
"metadata": {
"cde": true,
"data-classification": "pci"
}
}
Then attach the relevant controls below.
Control snippets
Copy each block under the controls key of the node it applies to.
Req 1 — Network segmentation (pci-network-segmentation)
CDE nodes must declare an explicit network-segmentation control — the segment they live in, peers they can reach, and how the segment is enforced (security group / VPC / firewall ruleset).
"pci-network-segmentation": {
"description": "PCI DSS v4 Req 1.2.1 — CDE network segmentation. Declare the network zone this node lives in and how the boundary is enforced.",
"requirements": [
{
"requirement-url": "https://archrails.io/catalog/req/pci-dss-v4/network-segmentation",
"config": {
"control-id": "pci-network-segmentation",
"segment": "cde-payments",
"enforcement": "aws-security-group",
"ingress-allowlist": ["edge-proxy", "audit-service"],
"egress-allowlist": ["payment-processor", "fraud-detection"]
}
}
]
}
Req 2 — No default credentials (pci-no-default-credentials)
Gap-filler new in this template. PCI DSS v4 Req 2.2 requires that
vendor-default credentials are removed or changed before deployment.
Architecturally: forbid hard-coded patterns like admin/admin,
root/changeme, postgres/postgres, etc.
"pci-no-default-credentials": {
"description": "PCI DSS v4 Req 2.2 — vendor-default credentials must not appear in code or config.",
"requirements": [
{
"requirement-url": "https://archrails.io/catalog/req/pci-dss-v4/no-default-credentials",
"config": {
"control-id": "pci-no-default-credentials",
"forbidden-fields": [
"admin:admin",
"admin:password",
"root:root",
"root:changeme",
"postgres:postgres",
"mysql:mysql",
"guest:guest",
"test:test"
]
}
}
]
}
Req 3 — Data encryption at rest (pci-data-encryption-at-rest)
Stored cardholder data must be encrypted at rest. Declare which algorithm + key-management approach this node uses.
"pci-data-encryption-at-rest": {
"description": "PCI DSS v4 Req 3.5.1 — stored cardholder data must be encrypted with industry-standard algorithms.",
"requirements": [
{
"requirement-url": "https://archrails.io/catalog/req/pci-dss-v4/data-encryption-at-rest",
"config": {
"control-id": "pci-data-encryption-at-rest",
"algorithm": "AES-256-GCM",
"key-management": "aws-kms-cmk",
"key-rotation-days": 365
}
}
]
}
Req 4 — No unsafe protocol (pci-no-unsafe-protocol)
Relationship-level control. Attach to edges that touch CDE nodes; the engine forbids the listed plaintext protocols on those edges.
// On a relationship (NOT a node):
"controls": {
"pci-no-unsafe-protocol": {
"description": "PCI DSS v4 Req 4.2.1 — CHD transmission must use strong cryptography. Plaintext protocols forbidden on CDE-touching edges.",
"requirements": [
{
"requirement-url": "https://archrails.io/catalog/req/pci-dss-v4/no-unsafe-protocol",
"config": {
"control-id": "pci-no-unsafe-protocol",
"forbidden-fields": [
"http", "ftp", "telnet", "ws",
"smtp", "imap", "pop3", "ldap",
"rsh", "rlogin", "tftp",
"amqp", "mqtt", "redis", "nats"
]
}
}
]
}
}
Req 4 — TLS minimum version (pci-tls-minimum-version)
"pci-tls-minimum-version": {
"description": "PCI DSS v4 Req 4.2.1 — TLS 1.2 minimum; TLS 1.0/1.1 forbidden.",
"requirements": [
{
"requirement-url": "https://archrails.io/catalog/req/pci-dss-v4/tls-minimum-version",
"config": {
"control-id": "pci-tls-minimum-version",
"allowed-versions": ["1.2", "1.3"]
}
}
]
}
Req 6 — WAF (pci-waf-required)
Attach to public-facing nodes (reachable from the internet).
"pci-waf-required": {
"description": "PCI DSS v4 Req 6.4.2 — public-facing CDE nodes must sit behind a WAF.",
"requirements": [
{
"requirement-url": "https://archrails.io/catalog/req/pci-dss-v4/waf-required",
"config": {
"control-id": "pci-waf-required",
"waf-provider": "aws-waf",
"ruleset": "owasp-top-10-managed"
}
}
]
}
Req 7 — RBAC (pci-rbac-required)
Gap-filler new in this template. PCI DSS v4 Req 7 requires need-to-know access restrictions. Architecturally: declare which roles can reach this node and through which authentication patterns.
"pci-rbac-required": {
"description": "PCI DSS v4 Req 7.2 — access to CDE restricted by role / need-to-know.",
"requirements": [
{
"requirement-url": "https://archrails.io/catalog/req/pci-dss-v4/rbac-required",
"config": {
"control-id": "pci-rbac-required",
"authentication-pattern": "oauth2-bearer",
"allowed-roles": ["payments-admin", "payments-service"],
"principle": "least-privilege"
}
}
]
}
Req 8 — MFA (pci-mfa-required)
"pci-mfa-required": {
"description": "PCI DSS v4 Req 8.4.2 — administrative access to CDE requires MFA.",
"requirements": [
{
"requirement-url": "https://archrails.io/catalog/req/pci-dss-v4/mfa-required",
"config": {
"control-id": "pci-mfa-required",
"factor-count": 2,
"factor-types": ["password", "totp-or-webauthn"]
}
}
]
}
Req 10 — Audit logging (pci-audit-logging)
"pci-audit-logging": {
"description": "PCI DSS v4 Req 10.2 — log all access and changes to CDE.",
"requirements": [
{
"requirement-url": "https://archrails.io/catalog/req/pci-dss-v4/audit-logging",
"config": {
"control-id": "pci-audit-logging",
"events": ["read", "write", "auth-success", "auth-failure", "config-change"],
"destination": "s3://pci-audit-bucket/<env>/",
"immutable": true
}
}
]
}
Req 10 — Log retention (pci-log-retention)
"pci-log-retention": {
"description": "PCI DSS v4 Req 10.5.1 — audit logs retained for at least 12 months, with 3 months immediately available.",
"requirements": [
{
"requirement-url": "https://archrails.io/catalog/req/pci-dss-v4/log-retention",
"config": {
"control-id": "pci-log-retention",
"retention-days": 365,
"hot-tier-days": 90
}
}
]
}
Req 11 — Vulnerability scanning (pci-vulnerability-scanning)
"pci-vulnerability-scanning": {
"description": "PCI DSS v4 Req 11.3.1 — internal and external vulnerability scans on CDE quarterly.",
"requirements": [
{
"requirement-url": "https://archrails.io/catalog/req/pci-dss-v4/vulnerability-scanning",
"config": {
"control-id": "pci-vulnerability-scanning",
"frequency": "quarterly",
"scanner": "qualys-or-tenable",
"asv-approved": true
}
}
]
}
Req 11 — Intrusion detection (pci-intrusion-detection)
"pci-intrusion-detection": {
"description": "PCI DSS v4 Req 11.5.1 — intrusion detection / prevention on the CDE perimeter.",
"requirements": [
{
"requirement-url": "https://archrails.io/catalog/req/pci-dss-v4/intrusion-detection",
"config": {
"control-id": "pci-intrusion-detection",
"deployment": "aws-guardduty",
"alerting-target": "security-soc@example.com"
}
}
]
}
Req 11 — Penetration testing (pci-penetration-testing)
Graph-level metadata — declare once per repo, not per node.
// In your top-level CALM document's metadata:
"metadata": {
"controls": {
"pci-penetration-testing": {
"description": "PCI DSS v4 Req 11.4.1 — internal + external pen tests annually and after significant changes.",
"requirements": [
{
"requirement-url": "https://archrails.io/catalog/req/pci-dss-v4/penetration-testing",
"config": {
"control-id": "pci-penetration-testing",
"frequency": "annual-and-on-significant-change",
"scope": "internal-and-external"
}
}
]
}
}
}
Req 12 — Incident response (pci-incident-response)
Graph-level metadata.
"metadata": {
"controls": {
"pci-incident-response": {
"description": "PCI DSS v4 Req 12.10.1 — formal incident-response plan tested annually.",
"requirements": [
{
"requirement-url": "https://archrails.io/catalog/req/pci-dss-v4/incident-response",
"config": {
"control-id": "pci-incident-response",
"plan-document-url": "https://internal.example.com/security/ir-plan",
"tested-annually": true,
"escalation-roster-url": "https://internal.example.com/security/oncall"
}
}
]
}
}
}
What the engine enforces
Once you've authored the controls above, ArchRails' constraint engine
evaluates them at both PR-time (the merge gate) and MCP-time
(your agent's IDE before code ships). The same engine that handles
your no-pii-in-logs control handles these — no special PCI-specific
code path.
Per-rule behavior:
- Presence-shape rules (MFA, audit logging, encryption,
segmentation, etc.): the engine fires a finding when a node tagged
cde: true does NOT declare the corresponding control. The PR
comment reads "Your pci-mfa-required control is missing on
payments-api."
- Forbidden-shape rules (no-default-credentials, no-unsafe-protocol):
the engine matches against added lines in the diff and fires when
forbidden patterns appear.
- Value-constrained rules (TLS minimum version): the engine checks
the customer's config value against the allowed enum.
Auto-include during bootstrap (coming)
A future release will let archrails bootstrap detect PCI-scoped
repos (by asking you, or by detecting cardholder / pci strings
in your CALM) and offer to auto-include this template in the
generated .archrails/config.yml. Until that ships, copy-paste from
above.
Versioning
This is pci-dss-v4/v0.1.0-beta. Pre-1.0 = beta. Bumps:
v0.x.y-beta— additive / breaking changes are both possible during beta; pinning a beta version is supported but the next beta bump may require authoring updates (we document them in the changelog).v1.0.0— graduation to GA per the criteria above. Subsequentv1.x.yfollows semver: additive changes bump the minor, breaking changes bump the major (and ship a new template path while the old one stays live for the deprecation window).
The constraint engine evaluates every version identically — beta
versus GA is metadata, not behavior. PCI DSS v5 (when it ships) gets
its own template path: pci-dss-v5/v0.1.0-beta.