Disclaimer. This article is engineering guidance, not legal advice. PCI DSS compliance is ultimately determined by your acquirer, your card brands, and a Qualified Security Assessor (QSA). Validate every control described here with your own QSA and security team before relying on it.
Introduction
A new generation of payment products is built around AI agents. A travel agent finds a flight and pays for it. A procurement agent buys office supplies. A consumer agent reorders household items every month. Behind the friendly chat interface, something concrete is happening: software is choosing a payment instrument, calling a payment API, and moving money.
The moment software touches cardholder data, the Payment Card Industry Data Security Standard applies. The current version, PCI DSS 4.0, tightens expectations for logging, anomaly detection, and continuous control assurance. Agentic systems make these expectations harder to meet because they generate more events, more credentials, and more decisions per second than the static web checkouts the standard was originally written for.
This article walks through the parts of PCI DSS 4.0 that engineers building agentic payment systems most often have to reason about: where AI agents actually touch cardholder data, how tokenization keeps the agent out of the cardholder data environment (CDE), and how Requirements 10 (logging), 11 (testing and monitoring), and 12 (security policy) map onto a real streaming pipeline. Every SQL example in this article is verified against RisingWave v2.8.0, so you can copy the queries into your own cluster and see live output.
Where AI Agents Touch Cardholder Data
PCI DSS scopes itself around the cardholder data environment, abbreviated CDE. The CDE includes any system that stores, processes, or transmits cardholder data (CHD) or sensitive authentication data (SAD), plus any system that can affect the security of those systems. The point of scoping is brutally simple: anything in the CDE inherits the full weight of the standard. Anything outside it does not.
An agentic payment system has at least four places where the agent can wander into scope:
- Decision plane. The model itself selects an instrument: "use the Visa ending in 1234." If the agent has access to the PAN, even just to display the last four digits, it is processing cardholder data. The standard does not care that you only logged the last four; the system that read the full PAN to extract them is in scope.
- Tool calls. Agents work by calling tools. A
charge_card(pan, cvv, amount)tool is the textbook way to drag the entire agent runtime into the CDE. Acharge_token(token_id, amount)tool is the textbook way to keep it out. - Memory and traces. Agent frameworks love to log everything: prompts, tool inputs, tool outputs, scratchpad reasoning. If any of that includes a PAN, your trace store, your evaluation harness, and your debugging notebooks all just joined the CDE.
- Inter-agent communication. When one agent forwards context to another, the message bus carrying that context becomes part of the data flow. If the message ever contains CHD, the bus is in scope.
The map you draw of these surfaces is called a data flow diagram, and PCI DSS 4.0 explicitly requires one (Requirement 1.2.4). For agentic systems, the data flow diagram needs to show prompts, tool inputs and outputs, and any intermediate stores like vector databases or trace logs. If you cannot show the flow, you cannot defend the scope.
A good first exercise: list every place the literal PAN can exist for a single transaction, from the moment the user authorizes the agent to the moment the merchant settles. Then ask, for each place, whether an agent or model can read it. Each "yes" is a system that is in scope unless you redesign the flow.
PCI DSS 4.0 Requirements Most Relevant to Agentic Systems
PCI DSS has twelve high-level requirements grouped into six control objectives. Several apply to all systems (firewalls, anti-malware, vulnerability management). A few are sharpened by the move to agentic architectures.
| Requirement | What it covers | Why it matters for agents |
| 3 | Protect stored cardholder data | Forces tokenization or strong cryptography for any CHD the agent persists |
| 4 | Protect CHD in transit | Every tool call to a payment API and every inter-agent message must use strong TLS |
| 7 | Restrict access by need-to-know | Each agent identity must have only the privileges it needs, not the human operator's privileges |
| 8 | Authenticate access | Agents need their own non-shared credentials, with short lifetimes and MFA where applicable |
| 10 | Log and monitor all access | Token issuance, token use, and admin actions all need tamper-evident logs |
| 11 | Test security regularly | 11.5 requires intrusion-detection and change-detection mechanisms, with alerts on suspected compromise |
| 12 | Information security policy | 4.0 introduces "targeted risk analyses" that justify the frequency of recurring activities like log review |
PCI DSS 4.0 also introduced two structural changes that hit streaming systems directly:
- Customized Approach. Organizations can implement controls differently from the prescriptive "Defined Approach" if they document a Targeted Risk Analysis (TRA) that shows the customized control meets the same objective. Streaming detection often lives in this lane: a continuous detection query can satisfy a control that the standard describes in terms of "daily review."
- More automation, less manual review. Several requirements that previously accepted "review the logs daily" now expect automated mechanisms, especially around failed access attempts and audit log integrity. Streaming SQL is a clean fit for these.
The rest of this article focuses on Requirements 10, 11.5, and 12.10, where streaming SQL gives the clearest leverage.
Tokenization and Scoping for Agentic Payments
Before any logging discussion, you have to decide whether your agent ever sees a PAN. The answer should almost always be "no."
The reference architecture for keeping an agent out of the CDE looks like this:
- Token vault. A separately operated service stores PAN-to-token mappings under hardware-backed encryption. The vault has its own network segment, its own identity provider, and a small set of human and machine principals authorized to detokenize.
- Token issuance API. When a user authorizes the agent to use a payment instrument, a card-on-file flow runs in a narrow web component (not the agent) and the vault returns a token to the user's account record.
- Agent runtime. The agent only ever sees the token. Its
chargetool takes(token_id, amount, metadata). The tool calls a payment proxy that detokenizes inside the CDE and forwards the PAN to the acquirer. - Payment proxy. A small, well-audited service that lives inside the CDE, handles detokenization, and exposes a token-only API to the outside.
In this design, the agent runtime is out of scope for storage and processing of CHD, but it is still adjacent to the CDE through the payment proxy and is therefore subject to several "connected to" controls. A QSA confirms scope; the architecture does not declare itself out of scope.
For the rest of this article we assume tokenization is in place. The events worth logging are no longer raw card numbers; they are token lifecycle events, agent actions, and admin actions on the supporting infrastructure.
Requirement 10: Audit Logs With Streaming SQL
PCI DSS Requirement 10 is the one most engineers know best. It mandates logs of who did what to which CHD-related resource, when, and from where. PCI DSS 4.0 sharpens 10.2 to require logs for all access to system components, all actions taken by individuals with administrative access, and changes to identification and authentication mechanisms.
Two things make Requirement 10 hard for agentic systems. First, the volume: a single user request can produce dozens of agent steps, each with its own tool call. Second, the heterogeneity: token events come from the vault, admin actions come from your IAM and KMS systems, agent step events come from the agent framework. Reviewers hate hopping across five tools, and "review every day" stops being realistic.
Streaming SQL collapses this into a single materialized view. The pattern is identical to the one we walked through in our streaming SQL audit log article and the agentic AI audit trail post: land each source as a table or CDC source, then UNION them into a canonical log row.
For this walkthrough we work with two source tables: aap19_token_events for token lifecycle events emitted by the payment proxy, and aap19_admin_actions for IAM, KMS, and audit-log access events emitted by the cloud control plane.
CREATE TABLE aap19_token_events (
event_id VARCHAR PRIMARY KEY,
token_id VARCHAR NOT NULL,
agent_id VARCHAR NOT NULL,
user_id VARCHAR,
event_type VARCHAR NOT NULL, -- 'issued' | 'used' | 'revoked' | 'access_attempt'
result VARCHAR NOT NULL, -- 'success' | 'denied'
event_time TIMESTAMPTZ NOT NULL
);
CREATE TABLE aap19_admin_actions (
action_id VARCHAR PRIMARY KEY,
actor_id VARCHAR NOT NULL,
action_type VARCHAR NOT NULL, -- 'rotate_key' | 'update_policy' | ...
resource VARCHAR NOT NULL,
action_time TIMESTAMPTZ NOT NULL
);
In production, both tables would be replaced by Kafka or CDC sources. Direct inserts make the example reproducible:
INSERT INTO aap19_token_events VALUES
('e001', 'tok_a1', 'agent_pay_01', 'user_501', 'issued', 'success', '2026-05-06 09:02:00+00'),
('e002', 'tok_a1', 'agent_pay_01', 'user_501', 'used', 'success', '2026-05-06 09:03:11+00'),
('e003', 'tok_a1', 'agent_pay_01', 'user_501', 'used', 'success', '2026-05-06 09:08:42+00'),
-- 24 additional rows covering normal operations and anomalies
('e027', 'tok_i1', 'agent_pay_09', 'user_510', 'issued', 'success', '2026-05-06 12:00:00+00');
INSERT INTO aap19_admin_actions VALUES
('a001', 'admin_alice', 'rotate_key', 'kms/payment-token-key', '2026-05-06 10:15:00+00'),
('a002', 'admin_bob', 'update_policy', 'iam/agent-pay-role', '2026-05-06 14:22:00+00'),
('a003', 'admin_carol', 'access_audit_log', 'audit/aap19_audit_log', '2026-05-06 02:14:00+00'),
('a004', 'admin_dave', 'create_user', 'iam/users', '2026-05-06 23:47:00+00'),
-- additional rows for off-hours coverage
('a007', 'admin_carol', 'update_policy', 'iam/agent-pay-role', '2026-05-06 15:00:00+00');
The canonical audit log is a UNION ALL across both sources, normalized to PCI's expected fields:
CREATE MATERIALIZED VIEW aap19_audit_log_mv AS
SELECT
event_id AS log_id,
event_time AS logged_at,
agent_id AS principal,
user_id AS subject,
'token.' || event_type AS action,
token_id AS resource,
result AS outcome,
'token_events' AS source_table
FROM aap19_token_events
UNION ALL
SELECT
action_id AS log_id,
action_time AS logged_at,
actor_id AS principal,
NULL AS subject,
'admin.' || action_type AS action,
resource AS resource,
'success' AS outcome,
'admin_actions' AS source_table
FROM aap19_admin_actions;
Querying the view returns a unified, time-ordered log:
SELECT log_id, logged_at, principal, action, resource, outcome
FROM aap19_audit_log_mv
ORDER BY logged_at
LIMIT 12;
log_id | logged_at | principal | action | resource | outcome
--------+---------------------------+--------------+------------------------+-----------------------+---------
a003 | 2026-05-06 02:14:00+00:00 | admin_carol | admin.access_audit_log | audit/aap19_audit_log | success
a006 | 2026-05-06 03:30:00+00:00 | admin_bob | admin.rotate_key | kms/payment-token-key | success
e001 | 2026-05-06 09:02:00+00:00 | agent_pay_01 | token.issued | tok_a1 | success
e002 | 2026-05-06 09:03:11+00:00 | agent_pay_01 | token.used | tok_a1 | success
e003 | 2026-05-06 09:08:42+00:00 | agent_pay_01 | token.used | tok_a1 | success
e004 | 2026-05-06 09:15:00+00:00 | agent_pay_01 | token.issued | tok_a2 | success
e005 | 2026-05-06 09:16:30+00:00 | agent_pay_01 | token.used | tok_a2 | success
e006 | 2026-05-06 09:20:05+00:00 | agent_pay_02 | token.issued | tok_b1 | success
e007 | 2026-05-06 09:21:00+00:00 | agent_pay_02 | token.used | tok_b1 | success
e008 | 2026-05-06 09:45:00+00:00 | agent_pay_02 | token.revoked | tok_b1 | success
e009 | 2026-05-06 10:01:00+00:00 | agent_pay_03 | token.issued | tok_c1 | success
e010 | 2026-05-06 10:02:18+00:00 | agent_pay_03 | token.used | tok_c1 | success
(12 rows)
What this gives you operationally:
- One feed for the QSA. Reviewers see one schema, one query surface, one retention policy, instead of five vendor consoles.
- Schema enforced at write time. If a new event source forgets a field, the UNION fails closed and you find out immediately.
- A single sink for SIEM and warehouse. RisingWave sinks can push the same materialized view to Splunk, an Apache Iceberg table for long-term retention, or a downstream alerting topic. Long-term retention in Iceberg matters: PCI DSS 4.0 keeps the one-year retention floor, with at least three months immediately available.
For the structural patterns behind this view (replay, schema evolution, tamper evidence), see our deeper write-ups on building audit logs with streaming SQL and CDC vs. dual writes for getting events out of operational databases without losing them.
Requirement 11.5: Anomaly Detection in Real Time
Requirement 11.5 (and 11.5.1 in 4.0) covers intrusion-detection and change-detection mechanisms. The standard expects you to detect, alert on, and address suspected compromise at the network perimeter and at critical points inside the CDE. Failed access attempts are one of the canonical signals.
Agentic systems generate a lot of failed access attempts. An agent might try a stale token, a revoked permission, or a tool that has been gated since the last training run. Most of these are harmless, but a burst of failures from a single agent identity is exactly the pattern you want to catch quickly: it can mean a compromised credential, a misconfigured policy, or an attacker probing the agent's tool surface.
A streaming materialized view turns this into a one-line control:
CREATE MATERIALIZED VIEW aap19_failed_access_alerts_mv AS
SELECT
agent_id,
COUNT(*) AS denied_attempts,
MIN(event_time) AS first_attempt,
MAX(event_time) AS last_attempt,
EXTRACT(EPOCH FROM (MAX(event_time) - MIN(event_time)))::INT AS span_seconds
FROM aap19_token_events
WHERE event_type = 'access_attempt'
AND result = 'denied'
GROUP BY agent_id
HAVING COUNT(*) >= 3;
The view only emits rows for agents with three or more denied attempts. Against the seeded events:
agent_id | denied_attempts | first_attempt | last_attempt | span_seconds
--------------+-----------------+---------------------------+---------------------------+--------------
agent_pay_04 | 5 | 2026-05-06 10:11:00+00:00 | 2026-05-06 10:13:30+00:00 | 150
agent_pay_06 | 4 | 2026-05-06 11:00:00+00:00 | 2026-05-06 11:01:55+00:00 | 115
(2 rows)
Both agents triggered five and four denials respectively in under three minutes. A reviewer or an automated playbook now has a single row per affected identity, complete with first-seen and last-seen timestamps.
A few production-grade refinements you would add on top of this skeleton:
- Bounded windows. Instead of "all time," use a tumbling or hopping window over the last 5 or 15 minutes so the view ages out old findings.
- Per-policy thresholds. Different agent roles tolerate different baselines. Joining against a
aap19_agent_policiestable lets each role have its ownmin_deniedthreshold without forking the view. - Sink to a paging system. RisingWave can sink the view to PagerDuty, Slack, or your SIEM through a Kafka or webhook sink, so the alert lifecycle does not depend on humans reading dashboards.
For more general anomaly patterns you can layer on the same data, see our write-up on real-time anomaly detection with streaming SQL, and for the broader adversary lens our account takeover detection and API abuse detection articles.
Continuous Compliance Monitoring
Requirement 12 is about policy and program management: who owns what, how often you review, and how you prove the program is working. PCI DSS 4.0's targeted risk analyses (TRAs) under 12.3.1 ask you to justify the frequency of recurring activities. "We review the audit log daily" requires evidence that daily is the right cadence given your threat model.
Streaming SQL changes the conversation. Instead of justifying a frequency, you justify a control: continuous detection over a complete event feed, with measurable open findings at any moment. The unit of evidence is the materialized view itself.
Two examples that complement the failed-access alert.
Off-hours admin activity
Insider risk is hard to detect during business hours and easy to detect at 02:14 UTC. Most legitimate administrative work fits the rhythm of a working day; activity outside that envelope is worth flagging, even if it turns out to be benign. PCI DSS 4.0 leans on this kind of contextual review for privileged actions (Requirement 10.2.1.2 and the privileged-user expectations in 7 and 8).
CREATE MATERIALIZED VIEW aap19_off_hours_actions_mv AS
SELECT
action_id,
actor_id,
action_type,
resource,
action_time,
EXTRACT(HOUR FROM action_time)::INT AS hour_utc
FROM aap19_admin_actions
WHERE EXTRACT(HOUR FROM action_time) < 8
OR EXTRACT(HOUR FROM action_time) >= 20;
Querying the view:
action_id | actor_id | action_type | resource | hour_utc | action_time
-----------+-------------+------------------+-----------------------+----------+---------------------------
a003 | admin_carol | access_audit_log | audit/aap19_audit_log | 2 | 2026-05-06 02:14:00+00:00
a006 | admin_bob | rotate_key | kms/payment-token-key | 3 | 2026-05-06 03:30:00+00:00
a004 | admin_dave | create_user | iam/users | 23 | 2026-05-06 23:47:00+00:00
(3 rows)
Three findings: an audit-log access at 02:14, a key rotation at 03:30, and a user creation at 23:47. None are conclusively malicious, but each deserves a ticket. Crucially, two of these touch the audit log and the KMS key for tokens, which are the precise resources that an insider with bad intent would attack first.
In a real deployment, "off hours" is per-team. A simple extension joins this view against a aap19_actor_schedules table that records each principal's expected working hours.
A live compliance scorecard
A scorecard view rolls up open findings per control and links each to a PCI requirement. This is what an internal compliance dashboard, or a report packaged for a QSA, should look like:
SELECT
'failed_access_alerts' AS control,
'PCI Req 11.5' AS requirement,
COUNT(*) AS open_findings
FROM aap19_failed_access_alerts_mv
UNION ALL
SELECT
'off_hours_admin_actions',
'PCI Req 10.2 / 12.5',
COUNT(*)
FROM aap19_off_hours_actions_mv
UNION ALL
SELECT
'audit_log_events_24h',
'PCI Req 10.2',
COUNT(*)
FROM aap19_audit_log_mv
WHERE logged_at >= '2026-05-06 00:00:00+00'::TIMESTAMPTZ;
control | requirement | open_findings
-------------------------+---------------------+---------------
failed_access_alerts | PCI Req 11.5 | 2
off_hours_admin_actions | PCI Req 10.2 / 12.5 | 3
audit_log_events_24h | PCI Req 10.2 | 34
(3 rows)
Every row maps a concrete PCI requirement to a live count. When you brief a QSA, you are showing them a dashboard that updates as events arrive, not a quarterly export. When you brief your own team, you are showing them work to do, not metrics to debate. The same view can drive an internal SLO: "open failed_access_alerts findings should be acknowledged within 15 minutes," which itself becomes evidence for Requirement 12.10 (incident response).
For deeper continuous-monitoring patterns, see our piece on monitoring streaming SQL pipelines and the building notification systems walkthrough, which extends the same materialized-view pattern to alert routing and escalation.
Practical Architecture Notes
A few engineering details that come up when teams operationalize the patterns above.
- Identity per agent, not per service. Give each agent role its own machine identity, ideally minted from your existing identity provider with a short TTL. Tagging audit log rows by
principalis how you make Requirement 10's "individual accountability" stick when there are no humans. - Don't log prompts into the CDE. Even if your agent is out of scope, prompt and trace stores tend to inherit data over time. Keep them in a separate environment with a redaction proxy, and log only token IDs.
- Replay matters. A streaming pipeline is only as trustworthy as your ability to rebuild it from source events. Source-of-truth events should land in Apache Iceberg (or your equivalent) with retention that satisfies Requirement 10.5.1 (one year, three months hot).
- Tamper evidence. Audit log integrity is part of Requirement 10.5. A simple chained hash column (each row hashes the previous row's hash plus its own canonical fields) lets you detect tampering at query time.
- Targeted risk analyses are deliverables. When you replace "daily review" with "continuous materialized view," write a one-page TRA that names the threat, the control, the detection latency, and the evidence retention. That is the document a QSA actually wants.
FAQ
Does PCI DSS apply to AI payment agents?
Yes. PCI DSS applies to any system component that stores, processes, or transmits cardholder data, or that can affect the security of the cardholder data environment. An AI agent that selects payment instruments, calls a payment API, or routes transaction data is in scope by default. The agent only stays out of scope if it never touches a PAN and is segmented from systems that do, and a QSA is the one who confirms that scope.
How do AI payment agents stay out of PCI scope?
The standard playbook is tokenization plus segmentation. The agent receives only opaque tokens that map to a PAN inside a separately controlled vault. The agent runs on infrastructure that cannot reach the vault directly, calls payment APIs through a narrow audited proxy, and authenticates with short-lived credentials. The proxy is in scope; the agent is "connected to" but typically out of the storage and processing scope.
What PCI DSS 4.0 requirements affect streaming systems?
Requirement 10 (audit logging and review), Requirement 11.5 (intrusion detection and change detection), and Requirement 12 (policy, with the new targeted risk analyses) are where streaming pipelines pay for themselves. PCI DSS 4.0 also adds explicit expectations for automated detection of failed authentication and audit log changes, which are natural fits for materialized-view-based detection.
How can streaming SQL support continuous PCI compliance monitoring?
You ingest token events, admin actions, and infrastructure logs into a streaming database, then express controls as materialized views: a unified audit log feed, alerts on repeated denied access, off-hours admin activity, and a scorecard view that aggregates open findings per requirement. The views update incrementally as events arrive, so dashboards, SIEM exports, and QSA reports always reflect live state without nightly batch jobs.
Conclusion
Agentic payment systems push PCI DSS 4.0 into territory the standard's drafters did not have in mind: software that decides which card to use, talks to other software, and produces an order of magnitude more events than a human-driven checkout. The good news is that the standard's intent maps cleanly onto streaming pipelines. Tokenize so the agent never sees a PAN. Land token events and admin actions in one place. Express the audit log, the failed-access detector, and the off-hours monitor as materialized views. Roll those views into a live compliance scorecard.
Each materialized view is a control. Each control is a row in your evidence. Each row is current as of seconds ago, not last quarter.
Ready to build PCI-aligned monitoring for agentic payments? Try RisingWave Cloud free and stand up the audit log, failed-access alert, and off-hours monitor in an afternoon.
Join our Slack community to compare notes with other teams building agentic payments and ask the engineers behind RisingWave how they would model your specific control set. PCI DSS compliance is ultimately a conversation with your QSA; streaming SQL just makes sure that conversation starts with live evidence instead of stale exports.

