PCI DSS Engineering Guide
Implement PCI DSS technical controls for payment card data protection. Covers network segmentation, encryption requirements, access controls, logging and monitoring, vulnerability management, and the patterns that make PCI compliance achievable for engineering teams.
PCI DSS (Payment Card Industry Data Security Standard) applies to every organization that stores, processes, or transmits credit card data. Non-compliance means fines up to $100,000/month, increased transaction fees, and potential loss of the ability to accept card payments. Engineering teams must understand the 12 requirements and implement them as technical controls.
PCI DSS 4.0 Requirements Map
Requirement 1: Install and maintain network security controls
Engineering: Firewall rules, WAF, network segmentation
Requirement 2: Apply secure configurations to all system components
Engineering: Hardened OS images, CIS benchmarks, no default passwords
Requirement 3: Protect stored account data
Engineering: Encrypt stored card data (AES-256), truncation, tokenization
Requirement 4: Protect cardholder data during transmission
Engineering: TLS 1.2+, certificate management, no plaintext transmission
Requirement 5: Protect against malicious software
Engineering: Endpoint protection, container scanning, SBOM
Requirement 6: Develop and maintain secure systems and software
Engineering: SDLC, code review, SAST/DAST, dependency scanning
Requirement 7: Restrict access by business need-to-know
Engineering: RBAC, least privilege, access reviews
Requirement 8: Identify users and authenticate access
Engineering: MFA, strong passwords, session management
Requirement 9: Restrict physical access to cardholder data
Engineering: Data center controls (if self-hosted)
Requirement 10: Log and monitor all access to cardholder data
Engineering: Centralized logging, SIEM, audit trails
Requirement 11: Test security of systems and networks regularly
Engineering: Vulnerability scans (quarterly), penetration tests (annual)
Requirement 12: Support information security with policies
Engineering: Document policies, incident response plan, training
Tokenization
# Tokenization: Replace card numbers with non-sensitive tokens
class CardTokenizer:
"""Replace card data with tokens to reduce PCI scope."""
def tokenize(self, card_number: str) -> str:
"""
Store card with payment processor, get token back.
Token is safe to store — not subject to PCI requirements.
"""
# Send card directly to processor (never touches our servers)
token = self.stripe.create_token(card_number)
# Store only the token and last 4 digits
self.db.save({
"token": token.id, # "tok_1234567890" (safe)
"last_four": card_number[-4:], # "4242" (safe)
"brand": token.card.brand, # "visa" (safe)
})
# Full card number NEVER stored in our systems
# PCI scope: significantly reduced
return token.id
def charge(self, token: str, amount: int):
"""Charge using token — card number never needed."""
return self.stripe.create_charge(
amount=amount,
source=token, # Token, not card number
)
Network Segmentation
PCI Cardholder Data Environment (CDE):
Isolated network segment containing:
☐ Payment processing servers
☐ Databases with card data
☐ API endpoints handling card data
Segmentation rules:
Internet ──→ WAF ──→ Load Balancer ──→ App Servers
│
┌─────────┴─────────┐
│ PCI CDE Zone │
│ │
│ Payment API │
│ Card Vault │
│ HSM │
│ │
│ Firewall rules: │
│ ✓ App → CDE: 443 │
│ ✗ CDE → Internet │
│ ✗ Dev → CDE │
│ ✓ CDE → PSP: 443 │
└───────────────────┘
Why: Everything outside CDE is out of PCI scope
Impact: Fewer systems to audit, lower compliance cost
Anti-Patterns
| Anti-Pattern | Consequence | Fix |
|---|---|---|
| Store card numbers anywhere | Entire system in PCI scope | Tokenize at the edge (Stripe.js, Elements) |
| No network segmentation | Entire network is CDE | Isolate payment systems in segment |
| Logs contain card data | Log storage becomes PCI scope | Redact PAN from all logs |
| Annual compliance only | 364 days of unknown state | Continuous compliance monitoring |
| Shared credentials for CDE | Cannot audit access | Individual accounts with MFA |
The easiest PCI compliance strategy: never let card data touch your servers. Use tokenization at the browser level (Stripe Elements, Braintree Drop-in) and your PCI scope reduces to SAQ A — the simplest self-assessment.