The first time I read the PCI DSS specification, I was looking for a checklist. I wanted a list of things to do, ideally things I could delegate to the security team, so I could go back to building features. Two days later I gave up looking for the checklist, because PCI DSS is not a checklist. It's a framework that imposes constraints on how a payment system can be built, and those constraints reach into every layer of the architecture.
I've watched teams approach PCI the same way I did initially: as a tax to be paid, a hoop to jump through, a thing to "be compliant with" in the way you might be compliant with a building code. The teams that survive PCI audits with their dignity and their architecture intact are the ones that internalized something different: PCI compliance is not a goal you achieve, it's a property that emerges from how you've built the system. If you build the system right, compliance is mostly automatic. If you build the system wrong, no amount of compliance work after the fact can fix it.
What PCI actually cares about
The PCI Data Security Standard exists to protect cardholder data — primarily the Primary Account Number (PAN), but also other sensitive authentication data like CVV codes, magnetic stripe data, and PIN blocks. The standard's core requirements are about three things, in order of priority:
Don't store cardholder data unless you have to. The most defensible position is not storing PAN, CVV, or other sensitive data at all. PCI explicitly favors systems that minimize storage, and many requirements are relaxed or eliminated for systems that store nothing.
If you must transmit it, protect it. Cardholder data in transit must be encrypted with strong cryptography and secure protocols. The encryption is non-negotiable; the configuration is audited.
If you must store it, isolate it. Stored cardholder data lives in a defined, segmented environment with strict access controls, monitoring, and regular validation.
Almost everything else in the PCI DSS document — the network requirements, the access controls, the logging, the testing, the policies — flows from these three principles. Once you understand them, the document stops looking like a thousand arbitrary rules and starts looking like a coherent design philosophy.
The architectural decision that determines everything
The single most important decision for PCI compliance is the scope decision: which parts of your system are inside the cardholder data environment (CDE) and which are outside?
Anything inside the CDE is subject to the full set of PCI requirements. That includes the systems themselves, the networks they're on, the people who can access them, the development and deployment processes that touch them, the logging infrastructure, the backup systems, the dependencies — everything. The CDE is a black hole for engineering effort.
Anything outside the CDE is, in PCI terms, irrelevant. It still has to follow good security practices, but it doesn't have to meet PCI's specific requirements, doesn't get audited under PCI scope, and doesn't slow down ordinary engineering work.
The architectural goal is to make the CDE as small as possible. Every system you can keep outside the CDE is one less system that has to comply, one less engineer who needs PCI training, one less component that complicates audits. Scope reduction is the most valuable architectural work you can do for compliance purposes.
The decision to make the CDE small is not free. It requires architectural choices that route cardholder data away from your normal systems and into a narrow, contained channel. The most common technique is tokenization.
Tokenization changes everything
Tokenization is the practice of replacing cardholder data with a non-sensitive substitute — a token — that can be stored, transmitted, and processed by your application code without those systems being part of the CDE. The actual PAN lives in a separate vault, and only the vault is in scope for PCI.
The pattern is simple to describe: at the moment cardholder data enters your system (typically from the POS terminal or a payment form), it goes directly to a tokenization service that returns a token. From that point on, every other component of your system uses the token. When the token needs to be used for an actual payment operation, it's sent to the processor connector along with operation parameters; the connector resolves the token, makes the call, and discards the resolved data.
The catch is that "directly" is doing a lot of work in that description. The cardholder data has to flow from the entry point (a card reader, an iframe, a hosted payment page) to the tokenization service without ever transiting application code that handles other concerns. If a single component sees the PAN — even briefly, even in memory, even by accident — that component is in scope, and so is everything connected to it.
Achieving this requires specific architectural patterns:
Hosted payment fields. For web checkout, the card number entry field is an iframe served directly from the tokenization provider. The merchant's website never receives the card number, even client-side. The tokenization provider returns a token to the merchant's frontend, which sends only the token to the merchant's backend.
Direct-to-vault terminals. For physical POS, card readers connect directly to a payment gateway or vault, bypassing the POS application entirely for the moment of card data capture. The POS sends a request to start a payment, the terminal handles the card data, the gateway returns a token, and the POS uses the token from then on.
Network segmentation. The systems that do handle cardholder data — the vault, the processor connector, certain admin tools — live on a separate network with firewall rules that prevent any other system from communicating with them except through controlled interfaces. The segmentation is what allows the rest of the network to be considered out-of-scope.
These patterns are not optional if you want a small CDE. They're constraints that have to be designed in from the start.
The downstream effects on architecture
PCI's requirements ripple outward from the CDE in ways that affect even systems that are nominally out-of-scope.
Logging. Anything inside the CDE has to log access events, retain logs for at least a year, and protect the logs from tampering. The logging infrastructure for the CDE often becomes its own subsystem, separate from the application logging used elsewhere, because mixing the two would either pull the application logging into scope or fail to meet the CDE requirements.
Authentication. Access to the CDE requires multi-factor authentication, role-based access controls, and regular access reviews. The team that operates the CDE has to be small and identifiable — every person with access is someone who needs to be tracked, audited, and revoked when they leave. This often means a separate IAM system for CDE access, different from the SSO used for the rest of the company.
Change management. Changes to CDE systems require formal approval, testing, and documentation. The development workflow for CDE code is slower and more rigorous than for non-CDE code. Many teams set up entirely separate repositories and CI/CD pipelines for CDE code to keep the friction contained.
Vulnerability management. CDE systems require regular vulnerability scans, penetration tests, and patching within defined windows. The dependencies of CDE code have to be tracked, audited, and updated promptly when CVEs appear. This is a meaningful operational burden that scales with the size of the CDE codebase.
Incident response. PCI requires a documented incident response plan, with specific notification timelines for cardholder data breaches. The plan has to be tested annually. Even if you never have an incident, the planning and testing takes time.
Each of these requirements is manageable when scoped to a small CDE. Each becomes overwhelming when the CDE includes large parts of the application. The smaller you can make the CDE, the cheaper compliance becomes — not just at audit time, but every day, in every change you make to the system.
The merchant-of-record question
Some platforms reduce their PCI scope further by structuring themselves so that they never actually become the merchant of record for any transaction. A POS platform might integrate with a payment facilitator or marketplace processor that handles the actual money movement, with the platform acting as an intermediary that never touches funds directly.
This approach can dramatically reduce PCI scope, sometimes to the point where the platform qualifies for the lowest level of PCI compliance and avoids most of the audit overhead. But it also constrains the business model — the platform can't directly control payment economics, can't customize the payment experience as freely, and is dependent on the facilitator's policies.
Whether this tradeoff makes sense depends on the platform. For early-stage POS startups, it almost always makes sense. For large platforms with complex payment needs, the loss of control becomes prohibitive. The decision should be made deliberately, not by default, and it should be revisited as the platform grows.
What fails an audit
Audits focus on a few specific things, and most failures fall into a small number of categories.
Scope creep. A system that was nominally out-of-scope turns out to handle cardholder data in some unanticipated way — maybe a log line that captured a PAN, maybe a debugging feature that displayed card numbers, maybe a backup that included a CDE database. The audit identifies this, expands the scope, and the audit becomes much larger and more painful.
Inadequate segmentation. The CDE is supposed to be isolated from the rest of the network. The audit tests this with penetration tests, port scans, and traffic analysis. If the segmentation has gaps — a firewall rule that allows broader access than intended, a service that bridges the segments unexpectedly — the audit fails or expands.
Incomplete logging. The CDE systems are supposed to log every access, and the logs are supposed to be tamper-evident and retained. Audits sample log entries and check whether they correspond to authorized actions. Gaps in coverage or unexplained access events cause findings.
Stale access. Former employees who still have CDE access. Service accounts with broader permissions than they need. Access reviews that haven't happened on schedule. These are the easiest findings for an auditor to identify and the most embarrassing for the team being audited.
Missing documentation. PCI requires documented policies, procedures, and architectural diagrams. Many teams build the system correctly but fail the audit because they can't produce a coherent description of what they built. The auditor needs to be able to understand the system from the documentation, and "ask the engineer who built it" is not an acceptable answer.
The pattern across all of these is that the failures are operational, not architectural. Teams that built the system right still fail audits because they didn't maintain the operational discipline required to keep it compliant. The architecture is necessary but not sufficient; the operations matter equally.
What I've learned
PCI compliance is at its core a discipline of restraint. The compliant system is the one that touches as little cardholder data as possible, in as few places as possible, with as few people as possible. Every architectural decision should be filtered through the question: does this expand the CDE, and if so, is the expansion worth the cost?
The teams that get this right have a few habits in common. They tokenize at the edge, before any application code sees PAN. They keep the CDE in a separate codebase, on a separate network, with a separate deployment pipeline. They make CDE access a chore, intentionally, so that engineers don't ask for it casually. They run reconciliation between their own access logs and the CDE access logs to catch drift. They treat audit prep as a continuous activity, not a quarterly fire drill.
The teams that get this wrong treat PCI as someone else's problem. The engineering team builds whatever it wants, the security team writes documentation that describes a different system than the one that exists, and at audit time, the gap between the two becomes everyone's problem. The fix usually requires rearchitecting parts of the system under deadline pressure, which is the worst time to do any architectural work.
PCI is not optional. The card networks require it, the processors require it, and the consequences of non-compliance — fines, increased rates, loss of payment processing — are existential for any business that takes card payments. The choice is not whether to comply. The choice is whether to comply by design, with an architecture that makes compliance natural, or by retrofit, with constant friction and audit anxiety.
The honest framing
If I were starting a new POS platform tomorrow, the very first architectural decision I would make is the boundary of the CDE. I would draw it as small as possible, route every cardholder data flow through tokenization at the edge, and design every other component to operate on tokens. I would make the CDE feel like a separate product — its own repository, its own team, its own deployment process — so that everything inside it gets the attention it needs and nothing outside it gets accidentally pulled in.
This is more work upfront than building a system that handles PAN throughout and then "adding compliance later." But the upfront work has bounded cost, and the later approach has unbounded cost. I have seen teams spend years trying to retrofit PCI compliance onto an architecture that wasn't designed for it, and the work never really finishes.
PCI compliance is not a thing you do to your architecture. It is a property of your architecture. If you build the system right, you are compliant. If you build it wrong, the most dedicated compliance effort in the world will not save you. Choose your CDE boundary deliberately, make it small, and protect it like the load-bearing piece of your architecture that it is.
This is part of a series on payment systems architecture. See also the real cost of payment integration nobody talks about and why every POS platform needs a payment abstraction layer.