PCI DSS was written for web checkouts, call centres and point-of-sale terminals. It does not mention language models, and it does not need to: its scope rule is about data, not technology. Any system that stores, processes or transmits cardholder data, or that can affect the security of systems that do, is in scope. An LLM agent that a customer can type a card number into is therefore in scope the moment someone types one, whether or not you designed it to accept card numbers, and so is every log, trace store, vector index, evaluation set and model provider that text flows into.
This article explains how to design a payment-capable LLM application so that the model stays out of scope, what to do when card data reaches it anyway, and which PCI DSS v4.0.1 requirements matter most. It is engineering guidance, not a compliance opinion: your scope and controls are agreed with your Qualified Security Assessor or acquirer, and the standard itself is the authority. For the general machinery of detecting sensitive data, see PII detection and redaction; this page applies it to the one data type with its own industry standard.
Two kinds of card data, two different rules
The most important distinction in PCI DSS, and one that is often blurred, is between cardholder data and sensitive authentication data. They are treated very differently, and the difference drives every design choice in an LLM system.
| Category | Elements | May you store it? |
|---|---|---|
| Cardholder data (CHD) | Primary account number (PAN); with it, cardholder name, expiration date, service code | Yes, if needed and protected: PAN must be unreadable wherever stored (requirement 3.5.1) |
| Sensitive authentication data (SAD) | Full track data, card verification code (CVV2, CVC2 and similar), PIN and PIN block | No: not retained after authorization, even if encrypted (requirement 3.3.1) |
The PAN is what makes the other elements cardholder data; a name and expiry date without a PAN are not. Requirement 3.3.1.2 specifically says the card verification code is not retained after authorization, and the standard allows only issuers with a documented business need an exception. For an LLM application that means a customer typing a CVV into chat creates a problem that encryption cannot fix: if that text lands in a transcript, a log line, an embedding or a fine-tuning dataset, you are storing SAD.
Where card data leaks into an LLM system
Traditional checkouts have one entry point for card data, a form field that you control. Conversational systems have many, and most of them are side effects rather than features.
- Free-text input. Customers paste card numbers into chat, including in replies to unrelated questions, because chat feels like talking to a person.
- Voice transcripts. Speech-to-text faithfully writes down a card number read aloud, along with the CVV.
- Observability. Prompt and response logging, distributed traces and error reports capture the full context window, including earlier turns.
- Memory and retrieval. Conversation memory and vector stores embed past turns; deleting the source text does not remove what was indexed.
- Evaluation and training data. Sampled transcripts become test sets and fine-tuning corpora, copying card data into new systems and, for fine-tunes, into model weights where it cannot be deleted at all.
- The model provider. Every prompt is transmitted to the provider and may be retained for abuse monitoring under their terms.
- Tool results. A tool that returns a full payment record puts the PAN straight into the context window.
Each of these is a separate system that would join your cardholder data environment. The design goal is to make sure card data never reaches any of them, and to detect and contain it when it does.
Reference architecture: tokens in, tokens out
The pattern is the same one that shrinks scope for web checkouts. Card entry happens in fields hosted by a PCI DSS compliant payment service provider, delivered as a payment link, an iframe in your app or a secure voice flow. The provider returns a token, and your payment service uses it to charge. Whether that service stays in scope depends on whether it can detokenize or affect the payment page; agree it with your assessor. The agent sees only the token, the card brand and the last four digits, which is enough to say "charge the Visa ending 4242?" and not enough to be cardholder data.
Segmentation is what makes the agent out of scope, and segmentation is a claim you prove, not a label you apply. The agent's runtime must not be able to reach card data stores, its credentials must not grant access to the payment service's data, and it must not be able to change the security of in-scope systems. Requirement 12.5.2 asks you to document and confirm scope at least once every twelve months and after significant change; adding an agent to a payment flow is a significant change.
The inbound guard
Even with hosted fields, customers will type card numbers into chat. Put a guard in front of everything: before the model, before logging, before memory. It detects card numbers with a pattern plus the Luhn checksum that card numbers satisfy, which rejects most random digit strings such as order numbers and phone numbers, redacts them, and tells the application to steer the customer to the secure payment link.
import re
CANDIDATE = re.compile(r"(?<!\d)(?:\d[ -]?){12,18}\d(?!\d)") # 13-19 digits, spaces or dashes
def luhn_ok(digits: str) -> bool:
total, parity = 0, len(digits) % 2
for i, ch in enumerate(digits):
d = int(ch)
if i % 2 == parity:
d *= 2
if d > 9:
d -= 9
total += d
return total % 10 == 0
def redact_pan(text: str) -> tuple[str, int]:
hits = 0
def repl(m):
nonlocal hits
digits = re.sub(r"\D", "", m.group())
if 13 <= len(digits) <= 19 and luhn_ok(digits):
hits += 1
return "[CARD NUMBER REMOVED]"
return m.group()
return CANDIDATE.sub(repl, text), hits
CVV_HINT = re.compile(r"\b(cvv|cvc|cvv2|security code)\b\D{0,15}\d{3,4}\b", re.I)
def guard_inbound(text: str) -> dict:
clean, pans = redact_pan(text)
clean, cvvs = CVV_HINT.subn("[SECURITY CODE REMOVED]", clean)
return {"text": clean, "pan_hits": pans, "cvv_hits": cvvs,
"steer": pans > 0 or cvvs > 0} # reply with the secure payment linkRun the guard on raw input before it touches any log; a guard placed after the logging middleware protects nothing. Count hits as a metric without recording the matched text. Detection is imperfect: numbers get split across messages or spelled as words, and some reference numbers pass Luhn by chance. So treat the guard as a containment control on top of an architecture that does not depend on it, and scan stored logs and transcripts on a schedule for anything it missed, as you would for secrets in the context window.
Payment tools that never see a card number
Agents act through tools, and tools are where an LLM payment system can be made safe by construction. Give the agent operations on tokens, enforce limits in code, require confirmation for money movement, and make every charge idempotent so a repeated tool call cannot charge twice.
def charge_saved_card(customer_id: str, payment_method_token: str,
amount_minor: int, currency: str, idempotency_key: str) -> dict:
"""Charge a card the customer already saved through the PSP's hosted form.
The model supplies a token it obtained from list_payment_methods(); it never
sees or supplies a PAN. Amount limits and confirmation are enforced here,
not in the prompt.
"""
method = payments.get_method(customer_id, payment_method_token)
if method is None: # token must belong to this customer
return {"status": "error", "code": "UNKNOWN_METHOD"}
if not 0 < amount_minor <= policy.max_agent_charge(customer_id, currency):
return {"status": "error", "code": "AMOUNT_NOT_ALLOWED"}
if not confirmations.approved(customer_id, idempotency_key):
return {"status": "needs_confirmation",
"summary": f"Charge {amount_minor} {currency} to card ending {method.last4}"}
result = psp.charge(token=payment_method_token, amount=amount_minor,
currency=currency, idempotency_key=idempotency_key)
return {"status": result.status, "charge_id": result.id, "last4": method.last4}Check that the token belongs to the customer in the session, so a prompt-injected token from another account is rejected. Return the last four digits, never the full record. Keep amount limits and confirmation in the tool, where a manipulated model cannot talk its way past them; the tool abuse article covers the wider class of attacks this defends against.
When card data does reach the model
Some products genuinely need the model to handle card data, and some designs fail. Either way, the consequences follow directly from the standard. The model provider, if it receives PANs, is a third-party service provider for your PCI DSS purposes, and requirement 12.8 applies: maintain a list of service providers, a written agreement in which they acknowledge responsibility for the card data they handle, due diligence before engagement, monitoring of their PCI DSS compliance status at least annually, and a clear record of which requirements each party manages. Many model APIs are not offered as PCI DSS validated services; check the provider's attestation of compliance before you send a single PAN.
Everything that stores the transcripts is then in scope too. PAN must be unreadable in storage, including in logs (3.5.1); PAN shown to staff must be masked so that no more than the BIN and last four digits are visible to anyone without a business need (3.4.1); transmission over public networks needs strong cryptography (4.2.1); and audit logs must be retained for at least twelve months with three months immediately available (10.5.1). If a CVV was captured, it must be purged, and you should treat the event as an incident.
Requirements that bite hardest
| Requirement | What it says, briefly | LLM-specific angle |
|---|---|---|
| 3.3.1, 3.3.1.2 | No SAD after authorization; no card verification code | Transcripts, memory and eval sets must not hold CVVs |
| 3.4.1 | Mask PAN on display beyond BIN and last four | Agent replies and support consoles show last four only |
| 3.5.1 | PAN unreadable wherever stored | Includes logs, traces and vector stores |
| 4.2.1 | Strong cryptography for PAN over public networks | Calls to a model provider that may see PAN |
| 6.4.3, 11.6.1 | Inventory and authorise payment page scripts; detect tampering | Chat widgets embedded on payment pages are scripts |
| 10.5.1 | Retain audit logs twelve months, three immediately available | Agent tool calls are auditable actions |
| 12.5.2 | Document and confirm scope annually and on change | Adding an agent is a change; redraw the data flow |
| 12.8 | Manage third-party service providers | Model and observability vendors that see card data |
One scope detail for small merchants: in January 2025 the PCI SSC revised SAQ A, effective 31 March 2025, removing requirements 6.4.3 and 11.6.1 for SAQ A merchants and adding eligibility criteria, including that all elements of the payment page come directly from a compliant provider and that the merchant has confirmed its site is not susceptible to script attacks that could affect the e-commerce system. An AI chat widget injected into checkout pages bears directly on that confirmation.
Worked example: a subscription billing assistant
A software company adds an assistant that can explain invoices, update the payment method and retry failed charges. The initial prototype asked customers to type a new card into chat, logged every turn to an observability vendor and sent prompts to a hosted model. That puts the chat service, the vendor, the model provider and the transcript database into scope, and the CVV prompt makes the transcripts a SAD violation.
The redesign: "update payment method" returns a short-lived link to the provider's hosted card form, which posts the card directly to the provider and returns a token to the payment service by webhook. The agent's tools are list_payment_methods, which returns brand, last four and token, and retry_invoice, which takes an invoice id and a token and requires confirmation. The inbound guard runs in the gateway before logging. A weekly job scans transcripts with the same detector and alerts on any hit. The scope document now shows the agent, model provider and observability vendor outside the cardholder data environment, with the segmentation evidence the assessor asked for: network rules, service account permissions, and guard test results.
A note on AI in assessments
In March 2025 the PCI SSC published Integrating Artificial Intelligence in PCI Assessments. It is aimed at assessors who use AI to review evidence or draft reports, keeps the human assessor responsible for findings, and changes no PCI DSS requirement. It is not a guide to building LLM payment applications.
Failure modes
| Failure | How it happens | Control |
|---|---|---|
| CVV in transcripts | Prompt or customer supplies it in chat or voice | Never ask; guard redacts; purge and treat as incident |
| PAN in logs | Logging middleware before the guard | Guard at the edge; scheduled scans of stores |
| PAN in fine-tune data | Transcripts sampled for training | Scan datasets; exclude flagged conversations |
| Scope creep via memory | Vector store embeds raw turns | Embed only guarded text |
| Cross-account charge | Injected token or customer id | Token ownership check in the tool |
| Duplicate charge | Model retries a tool call | Idempotency keys passed to the provider |
Audit every payment tool call with the customer, token, amount, confirmation and result, and keep it tamper-evident, following the audit logging architecture.
What to do next
- Draw the data flow for your agent and mark every system that could receive card data, including logs, traces, memory, evals and the model provider.
- Move card entry to the provider's hosted fields or secure voice capture, and give the agent tokens and last four digits only.
- Deploy an inbound guard with Luhn detection before any logging, and schedule scans of stored transcripts.
- Remove any prompt or flow that asks for a CVV, and purge any that has been captured.
- Build payment tools that check token ownership, enforce limits, require confirmation and use idempotency keys.
- Update your scope document and service provider list, and review the segmentation evidence with your assessor.