Running MySQL on Kubernetes is increasingly common. Running it in an environment subject to regulatory scrutiny - PCI DSS, financial services mandates, gaming licensing requirements - introduces a layer of complexity that most Kubernetes tutorials and architecture guides do not address.
The challenge is not that Kubernetes or MySQL lack security capabilities. Both have mature, well-documented security primitives. The challenge is that regulatory compliance is not a feature you enable - it is an architectural property that must be designed into every layer of the system, from how pods communicate to how encryption keys are managed to how audit logs are retained and protected.
This post maps the most common regulatory concerns to specific technical controls in MySQL and Kubernetes, identifies where the gaps are, and provides practical guidance for teams building database infrastructure that must pass external audits.
The Regulatory Landscape in Brief
Different regulatory frameworks apply to different industries, but at the database layer, their technical requirements converge on a remarkably consistent set of concerns:
- PCI DSS 4.0 applies to any organization that stores, processes, or transmits payment card data. Its database-relevant requirements focus on encryption of stored cardholder data (Requirement 3), encryption of data in transit (Requirement 4), access control and least privilege (Requirements 7 and 8), and comprehensive audit logging (Requirement 10). PCI DSS is the most prescriptive of the major frameworks - it specifies minimum encryption strengths, log retention periods, and access review frequencies.
- Financial services regulations vary by jurisdiction, but share common themes. SOX mandates controls over financial reporting systems, including audit trails for data changes. Banking regulators typically require encryption at rest and in transit, strict access controls, and the ability to demonstrate data integrity over time. The specifics differ between the SEC, FCA, MAS, and other authorities, but the underlying technical requirements are broadly similar.
- Gaming and iGaming regulations are highly jurisdiction-specific - the UK Gambling Commission, New Jersey DGE, Malta Gaming Authority, and others each have their own technical standards. At the database level, common requirements include comprehensive audit trails of all wagering transactions, data integrity guarantees, encryption of player data, and system availability requirements. The GLI-GSF-1 framework, the first cybersecurity framework specifically designed for gaming, establishes controls around data protection, access management, and logging that apply directly to the database tier.
Rather than attempting to cover each framework exhaustively (which would require separate posts for each jurisdiction), this guide focuses on the six technical control areas that appear across virtually all of them: encryption at rest, encryption in transit, network segmentation, access control, audit logging, and key management.
Encryption at Rest
Regulatory requirement: sensitive data stored on disk must be encrypted so that unauthorized physical or logical access to the storage medium does not expose plaintext data. PCI DSS Requirement 3 is explicit about this for cardholder data.
MySQL Layer
MySQL's InnoDB engine supports Transparent Data Encryption (TDE), which encrypts tablespace files on disk using AES-256. TDE is transparent to the application - queries work normally, and the encryption/decryption happens at the storage engine level. The general log, slow query log, and binary logs can also be encrypted.
TDE protects against a specific threat model: someone gaining access to the raw data files (on disk, in a backup, or through a stolen volume) without having access to the running MySQL process. It does not protect against a compromised MySQL user account - if an attacker can connect to MySQL and run SELECT queries, TDE does nothing, because the data is decrypted in memory before being returned.
This distinction matters for compliance. TDE addresses the "data at rest" requirement, but access control and network segmentation address the "unauthorized access" requirement. Both are needed.
Kubernetes Layer
In Kubernetes, the storage layer adds its own encryption concerns. PersistentVolumes used by MySQL pods may be backed by cloud block storage (EBS, Persistent Disk, Azure Disk), which most cloud providers can encrypt transparently using provider-managed or customer-managed keys. This is storage-level encryption - it protects the volume if the underlying hardware is decommissioned or the volume snapshot is accessed outside the intended context.
For defense in depth, both layers should be active: MySQL TDE encrypts the data at the application level, and the cloud provider encrypts the volume at the storage level. They protect against different threat vectors and are not redundant.
Kubernetes Secrets - which are commonly used to store MySQL passwords, replication credentials, and TLS certificates - are base64-encoded by default, not encrypted. For regulated environments, etcd encryption at rest must be enabled (or a Secrets management solution like HashiCorp Vault, AWS Secrets Manager, or GCP Secret Manager must be used) so that sensitive credentials are not stored in plaintext in the cluster's backing store.
Encryption in Transit
Regulatory requirement: data must be encrypted when transmitted over networks. PCI DSS Requirement 4 mandates strong cryptography for cardholder data traversing public networks, and most financial and gaming regulations extend this to internal networks as well.
For MySQL on Kubernetes, "data in transit" occurs in several distinct paths, each of which must be encrypted separately:
-
Application to MySQL
Connections from application pods to the MySQL service must use TLS. MySQL supports TLS natively, and therequire_secure_transportserver variable can enforce it - rejecting any unencrypted connection attempt. The TLS certificates used for these connections need to be managed, rotated, and stored securely (see Key Management below). -
Replication traffic
Data flowing between MySQL primary and replicas must also be encrypted. In native MySQL replication, this is configured per replication channel using TLS. In Tungsten Cluster, all inter-component communication - including replication traffic between Tungsten Replicator instances - supports TLS encryption, which is enabled by default since version 7. -
Cluster management traffic
The communication between cluster management components (Operators, managers, health-check probes) and MySQL instances is another path that must be encrypted. This is easy to overlook because it is not application traffic, but an auditor will ask about it. -
Cross-node and cross-region traffic
Within a Kubernetes cluster, pod-to-pod traffic may traverse physical network links that are shared with other tenants (especially in cloud environments). A service mesh like Istio can provide mutual TLS (mTLS) for all pod-to-pod communication, including database traffic, without requiring application changes. For cross-region replication, the traffic traverses the public internet or a cloud provider's backbone, making encryption non-negotiable.
The common failure mode here is encrypting the application-to-MySQL path, but leaving replication or management traffic unencrypted. An auditor examining PCI DSS Requirement 4 compliance will check all paths, not just the ones the application team thinks about.
Network Segmentation
Regulatory requirement: systems that handle sensitive data must be isolated from untrusted networks and from systems that do not need access. PCI DSS calls this the Cardholder Data Environment (CDE) and requires that access to it be restricted to only those systems with a legitimate business need.
Kubernetes NetworkPolicies
Kubernetes NetworkPolicies are the primary mechanism for implementing network segmentation within a cluster. By default, Kubernetes allows all pod-to-pod communication - which is the opposite of what a regulated environment requires.
For MySQL in a regulated environment, NetworkPolicies should enforce that only specific application pods can connect to MySQL pods on the MySQL port (3306 or whatever port is configured), that MySQL pods can communicate with each other for replication, but not with arbitrary pods, that management and monitoring pods have access only to the specific ports they need, and that egress from MySQL pods is restricted to known, necessary destinations.
This is conceptually straightforward, but operationally demanding. NetworkPolicies must be maintained as the application topology evolves, and they must be tested - not just deployed. A NetworkPolicy that is syntactically correct, but references a label selector that no longer matches anything provides no protection.
Namespace Isolation
Running MySQL in a dedicated Kubernetes namespace, separate from application workloads, provides an additional layer of isolation. RBAC policies can then restrict which service accounts have access to the MySQL namespace, and NetworkPolicies can enforce cross-namespace communication rules.
For PCI DSS specifically, the MySQL namespace and its associated storage and secrets would be considered part of the CDE. Keeping the CDE's Kubernetes footprint as small and well-defined as possible reduces the scope of the compliance assessment - which is both a security benefit and a practical one.
Access Control
Regulatory requirement: access to sensitive data must be limited to individuals and systems with a documented business need, using the principle of least privilege. PCI DSS Requirements 7 and 8 are detailed on this point, mandating role-based access, unique user IDs, and multi-factor authentication for administrative access.
Access control in MySQL on Kubernetes operates at three layers:
-
Kubernetes RBAC
Controls who can create, modify, or delete MySQL pods, services, secrets, and persistent volumes. In a regulated environment, the ability to exec into a MySQL pod, view secrets containing database credentials, or modify NetworkPolicies must be restricted to a small set of named individuals - not granted broadly to development teams. Kubernetes RBAC policies should be audited regularly to ensure they reflect current access requirements. -
MySQL user privileges
Controls what authenticated users can do within the database. MySQL's privilege system supports fine-grained control - down to specific tables and operations - and should be configured according to least privilege. Application service accounts should have only the privileges they need (typicallySELECT,INSERT,UPDATE,DELETEon specific schemas) and should never haveSUPER,FILE, orGRANT OPTIONprivileges. -
Operator and management access
The MySQL Operator (whichever one you use) typically runs with elevated privileges within the cluster. Its service account needs permissions to manage pods, PVCs, and secrets. In a regulated environment, the Operator's RBAC permissions should be scoped as tightly as possible, and changes to the Operator's configuration should be tracked through version control and change management processes.
The interaction between these layers creates gaps that are easy to miss. A developer with kubectl exec access to a MySQL pod can bypass MySQL's access controls entirely by connecting locally as root. Kubernetes RBAC must be configured to prevent this unless explicitly authorized.
Audit Logging
Regulatory requirement: all access to systems containing sensitive data must be logged, and logs must be retained for a defined period (PCI DSS requires 12 months, with at least 3 months immediately available for analysis). Logs must be protected from tampering.
Audit logging for MySQL on Kubernetes spans multiple layers, and each must be addressed:
-
MySQL audit log
MySQL Enterprise Edition includes an audit plugin that logs all connections, queries, and administrative operations. For MySQL Community Edition, the Percona Audit Log Plugin provides similar functionality. These logs capture who connected, when, from where, and what queries they executed - which is exactly what PCI DSS Requirement 10.2 requires.
The challenge in Kubernetes is where these logs go. By default, MySQL writes logs to the local filesystem inside the container. If the pod is restarted or rescheduled, those logs are lost - which is a compliance violation if they haven't been shipped to durable storage. The log pipeline must be configured to stream audit logs to an external system (a SIEM, a log aggregator like Elasticsearch or Loki, or cloud-native logging) in near-real-time, with the external system providing tamper-evident storage and the required retention period. -
Kubernetes audit log
The Kubernetes API server can be configured to log all API requests - including who created, modified, or deleted MySQL-related resources. This provides the control-plane audit trail: who scaled the StatefulSet, who modified a Secret, who changed a NetworkPolicy. For regulated environments, the Kubernetes audit policy should be configured to log at least theRequestResponselevel for resources in the MySQL namespace. -
Replication and cluster management logs
Changes to the database replication topology - promotions, failovers, configuration changes - must also be logged. This is where the choice of Operator or cluster management tool matters for compliance. Tools that log their own actions (what decision was made, why, and what was the outcome) provide a richer audit trail than tools that operate silently. Tungsten Cluster's v7 release added audit logging in the Connector and certificate management capabilities specifically to support these requirements. -
Log integrity
PCI DSS Requirement 10.3 requires that audit logs be protected from unauthorized modification. In practice, this means logs should be written to append-only storage, signed or checksummed, and access to log management systems should be restricted and itself audited. Shipping logs to a managed SIEM or a write-once storage backend (such as S3 with Object Lock) addresses this requirement.
Key Management
Regulatory requirement: cryptographic keys must be managed securely, with documented procedures for generation, distribution, storage, rotation, and destruction. PCI DSS Requirement 3.6 is explicit about this.
Key management is arguably the hardest compliance requirement to implement correctly in a Kubernetes environment, because keys are needed in so many places:
- MySQL TDE requires a master encryption key. TLS certificates for application connections, replication, and management traffic each have their own key pairs. Kubernetes Secrets containing database passwords are themselves sensitive key material. Backup encryption requires its own keys.
- The common failure modes are storing keys alongside the data they protect (a MySQL TDE key stored on the same volume as the encrypted tablespace defeats the purpose), using the same key for multiple purposes (a single TLS certificate shared between application traffic and replication traffic increases the blast radius of a compromise), failing to rotate keys on a defined schedule (PCI DSS requires at least annual rotation for encryption keys), and lacking a documented process for revoking and replacing compromised keys.
- For Kubernetes environments, a dedicated secrets management platform - HashiCorp Vault, AWS KMS, GCP Cloud KMS, or Azure Key Vault - should be the single source of truth for all cryptographic material. MySQL TDE can be configured to use a KMS-backed keyring plugin, so the master key is never stored on the database server. TLS certificates should be issued and rotated automatically using cert-manager or a similar tool. Database passwords should be injected from the secrets manager at pod startup rather than stored in Kubernetes Secrets.
Putting It Together: A Compliance Architecture
The six control areas described above are not independent - they interact. A practical architecture for MySQL on Kubernetes in a regulated environment looks something like this:
| Control Area | PCI DSS Req | MySQL Layer | Kubernetes Layer | Cloud / External Tooling |
|---|---|---|---|---|
| Encryption at rest | Req 3 | InnoDB TDE (AES-256); binary log and redo log encryption | etcd encryption at rest for Secrets | Cloud volume encryption (EBS, PD, Azure Disk) with customer-managed keys; KMS for TDE keyring |
| Encryption in transit | Req 4 |
Native TLS for client connections (require_secure_transport); TLS for replication channels
|
Service mesh mTLS (Istio) for pod-to-pod traffic | cert-manager for certificate lifecycle; private CA |
| Network segmentation | Req 1 |
MySQL bind-address and user host restrictions
|
NetworkPolicies (ingress/egress per pod); dedicated namespace for database workloads | VPC security groups; cloud firewall rules |
| Access control | Req 7, 8 |
Per-schema, per-operation user privileges; no SUPER/FILE/GRANT OPTION for application accounts
|
RBAC restricting pod exec, Secret access, and namespace operations; service account scoping for Operators | Identity provider integration (SSO/MFA for kubectl access) |
| Audit logging | Req 10 | Audit plugin (Enterprise or Percona); general log and slow query log |
API server audit policy (RequestResponse level for DB namespace); log shipping via sidecar or DaemonSet
|
SIEM or log aggregator (Elasticsearch, Loki, Splunk); write-once storage (S3 Object Lock) for tamper resistance; 12-month retention |
| Key management | Req 3.6 | KMS-backed keyring plugin for TDE master key; separate keys per purpose | cert-manager for TLS certificate rotation; Secrets Store CSI Driver for runtime injection | KMS (AWS, GCP, Azure) or HashiCorp Vault as single source of truth; documented annual rotation schedule |
The MySQL cluster runs in a dedicated namespace with strict NetworkPolicies limiting ingress to authorized application pods and management tools. MySQL TDE encrypts data at rest, backed by a KMS-managed keyring. The underlying PersistentVolumes use cloud-provider volume encryption as a second layer. All connections - application, replication, management - use TLS with certificates managed by cert-manager and backed by a private CA. Kubernetes RBAC restricts access to the MySQL namespace, secrets, and pod exec. MySQL user privileges follow least-privilege principles per service account. The MySQL audit plugin streams all access logs to a SIEM via a sidecar or DaemonSet log collector. Kubernetes API audit logs capture all control-plane changes to MySQL-related resources. Cryptographic keys are sourced from a KMS, rotated on a defined schedule, and never stored alongside the data they protect.
No single tool provides all of these capabilities. The architecture is necessarily a composition of MySQL features, Kubernetes primitives, cloud provider services, and the cluster management or Operator layer. The role of the Operator or cluster management tool - whether that's Tungsten Cluster, Percona Operator, Oracle's MySQL Operator, or a custom solution - is to handle the MySQL-specific operational concerns (replication, failover, backups) while integrating cleanly with the security infrastructure described above.
What Auditors Actually Ask
Theory is useful, but audits are practical. In our experience working with organizations in financial services, e-commerce, and gaming, auditors consistently focus on a few specific questions:
-
"Show me that data at rest is encrypted"
They want to see MySQL TDE enabled, the keyring configuration pointing to a KMS, and volume encryption enabled on the storage backend. They may also check that backups are encrypted. -
"Show me that data in transit is encrypted"
They want to see TLS configuration on MySQL,require_secure_transportenabled, and evidence that replication and management traffic is also encrypted. If you use a service mesh, they want to see mTLS configuration. -
"Show me who has access and why"
They want to see Kubernetes RBAC policies, MySQL user privilege grants, and evidence that access is reviewed periodically. They will ask specifically about administrative access - who can exec into a pod, who can read secrets, who has root on the database. -
"Show me the audit logs"
They want to see the MySQL audit log configuration, the log shipping pipeline, the retention policy, and evidence that logs are protected from tampering. They will ask for a sample log entry and walk through what it shows. -
"Show me your key management procedures"
They want to see documented key rotation schedules, evidence that rotation has actually occurred, and confirmation that key material is stored separately from the data it protects. -
"Show me your change management process"
They want to see how changes to the database configuration, schema, and infrastructure are proposed, approved, and tracked. In Kubernetes, this typically means GitOps workflows where all changes go through version control and code review.
The organizations that pass audits smoothly are the ones that can answer these questions with specific evidence - configuration files, log samples, RBAC policies, key rotation records - rather than general descriptions of their intentions.
Summary
Running MySQL on Kubernetes in a regulated environment is achievable, but it requires deliberate architectural decisions at every layer of the stack. Encryption at rest and in transit must cover all data paths - not just the obvious ones. Network segmentation must be enforced through NetworkPolicies, not assumed. Access control must span both Kubernetes RBAC and MySQL privileges. Audit logging must be comprehensive, durable, and tamper-resistant. And key management must be centralized, automated, and documented.
The regulatory frameworks themselves - PCI DSS, financial services mandates, gaming licensing requirements - are not prescribing specific technologies. They are prescribing outcomes: data must be protected, access must be controlled, actions must be auditable, and you must be able to prove it. The technical implementation is up to you.
The gap between "we have security features" and "we can demonstrate compliance" is where most teams underestimate the work. Passing an audit is not about having the right tools - it is about having them correctly configured, consistently enforced, continuously monitored, and thoroughly documented.
Comments
Add new comment