Home Database Database Security: Encryption, Auditing & Access Control
Intermediate 3 min · July 13, 2026

Database Security: Encryption, Auditing & Access Control

Learn how to secure your database with encryption at rest and in transit, auditing user activity, and implementing role-based access control.

N
Naren Founder & Principal Engineer

20+ years shipping high-throughput database systems. Lessons pulled from things that broke in production.

Follow
Production
production tested
July 13, 2026
last updated
2,165
articles · all by Naren
Before you start⏱ 15-20 min read
  • Basic knowledge of SQL (SELECT, GRANT, ALTER).
  • Access to a database (MySQL or PostgreSQL) with administrative privileges.
  • Understanding of fundamental security concepts like encryption and authentication.
 ● Production Incident 🔎 Debug Guide ⚙ Triage Commands
Quick Answer
  • Encrypt data at rest using Transparent Data Encryption (TDE) or file-level encryption.
  • Encrypt data in transit with TLS/SSL between clients and the database.
  • Implement role-based access control (RBAC) with least privilege.
  • Enable auditing to track who did what and when.
  • Regularly review and rotate encryption keys and credentials.
✦ Definition~90s read
What is Database Security?

Database security is the practice of protecting your database from unauthorized access, data breaches, and malicious attacks using encryption, auditing, and access control.

Think of your database as a high-security vault.
Plain-English First

Think of your database as a high-security vault. Encryption is like locking the vault with a strong lock and also putting each document inside a safe. Auditing is like having a camera that records everyone who opens the vault and what they take. Access control is like giving only certain people the keys to specific drawers. Together, they keep your data safe from thieves and ensure you know if something goes wrong.

Imagine you're a developer at a fintech startup. Your database holds millions of customer records, including credit card numbers and personal details. One day, a junior developer accidentally exposes the database credentials in a public GitHub repo. Panic ensues. How do you prevent a breach? This is where database security comes in.

Database security isn't just about passwords. It's a multi-layered approach that includes encryption (so even if data is stolen, it's unreadable), auditing (so you can trace any suspicious activity), and access control (so only the right people have the right permissions). In this tutorial, you'll learn how to implement these three pillars using practical SQL and configuration examples. We'll cover encryption at rest and in transit, setting up fine-grained access control with roles, and enabling auditing to log all queries. By the end, you'll be able to harden your database against common threats and comply with regulations like GDPR and PCI-DSS.

1. Encryption at Rest: Protecting Stored Data

Encryption at rest ensures that data stored on disk is unreadable without the proper decryption keys. This protects against physical theft of drives, unauthorized access to backup files, and cloud provider breaches. Most modern databases offer Transparent Data Encryption (TDE), which automatically encrypts data as it is written to disk and decrypts it when read by authorized users. For example, in MySQL 8.0, you can enable TDE using the InnoDB tablespace encryption feature. Here's how to encrypt an existing table:

First, ensure the encryption plugin is active. Then, set the default encryption algorithm. Finally, alter the table to enable encryption. The key is managed by the database or an external key management system. Always back up your encryption keys separately; losing them means losing your data.

encrypt_table.sqlSQL
1
2
3
4
5
6
-- Enable InnoDB tablespace encryption (MySQL 8.0)
INSTALL PLUGIN keyring_file SONAME 'keyring_file.so';
SET GLOBAL keyring_file_data = '/var/lib/mysql-keyring/keyring';

-- Encrypt an existing table
ALTER TABLE customers ENCRYPTION='Y';
Output
Query OK, 0 rows affected (0.12 sec)
⚠ Key Management is Critical
📊 Production Insight
In production, avoid using the keyring_file plugin for serious deployments; use a centralized KMS like AWS KMS or HashiCorp Vault.
🎯 Key Takeaway
Encryption at rest protects data on disk; always back up keys separately.

2. Encryption in Transit: Securing Network Traffic

Data in transit is vulnerable to interception via man-in-the-middle attacks. Encryption in transit, typically using TLS/SSL, ensures that all communication between the database client and server is encrypted. Enable TLS on your database server and require clients to use SSL connections. For PostgreSQL, you can configure ssl = on in postgresql.conf and place the certificate files. For MySQL, set require_secure_transport = ON. Here's how to create a user that must connect via SSL:

This forces the user to use an encrypted connection. You can also enforce SSL for all connections by setting the system variable. Always use strong cipher suites and regularly update certificates.

ssl_user.sqlSQL
1
2
3
4
5
6
-- MySQL: Create user that requires SSL
CREATE USER 'app_user'@'%' IDENTIFIED BY 'strong_password' REQUIRE SSL;
GRANT SELECT, INSERT ON mydb.* TO 'app_user'@'%';

-- Verify SSL is enabled
SHOW VARIABLES LIKE '%ssl%';
Output
+---------------+----------+
| Variable_name | Value |
+---------------+----------+
| have_ssl | YES |
| ssl_ca | ca.pem |
| ssl_cert | server-cert.pem |
| ssl_key | server-key.pem |
+---------------+----------+
💡Enforce SSL for All Connections
📊 Production Insight
Use certificate-based authentication for machine-to-machine connections to avoid storing passwords in configuration files.
🎯 Key Takeaway
Always use TLS for database connections to prevent eavesdropping.

3. Role-Based Access Control (RBAC): Least Privilege

Access control ensures that users and applications have only the permissions they need. RBAC simplifies management by grouping permissions into roles. Create roles for different job functions (e.g., read_only, data_entry, admin) and assign users to those roles. Avoid using the root or superuser account for routine operations. Here's an example in PostgreSQL:

This creates a read-only role and grants it to a user. The user can only select from tables in the schema. In MySQL, roles work similarly. Always revoke unnecessary privileges and regularly audit role memberships.

rbac_postgres.sqlSQL
1
2
3
4
5
6
7
8
-- PostgreSQL: Create read-only role and assign to user
CREATE ROLE read_only;
GRANT CONNECT ON DATABASE mydb TO read_only;
GRANT USAGE ON SCHEMA public TO read_only;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only;

CREATE USER jane WITH PASSWORD 'securepass';
GRANT read_only TO jane;
Output
CREATE ROLE
GRANT
GRANT
CREATE USER
GRANT ROLE
🔥Default-Deny Principle
📊 Production Insight
In production, separate application users from human users. Application users should have minimal permissions, ideally only on specific tables.
🎯 Key Takeaway
Use roles to enforce least privilege; never use superuser for daily tasks.

4. Auditing: Tracking Database Activity

Auditing records all database events for security analysis and compliance. It helps detect unauthorized access, SQL injection attempts, and policy violations. Most databases provide built-in auditing or plugins. For MySQL, use the audit log plugin. For PostgreSQL, use the pgAudit extension. Here's how to enable basic auditing in MySQL:

This logs all queries to a file. You can filter by user, database, or event type. In PostgreSQL, pgAudit allows fine-grained logging. Regularly review audit logs and set up alerts for suspicious patterns like failed logins or unusual query volumes.

enable_audit_mysql.sqlSQL
1
2
3
4
5
6
7
-- Install audit log plugin (MySQL)
INSTALL PLUGIN audit_log SONAME 'audit_log.so';
SET GLOBAL audit_log_policy = 'ALL';
SET GLOBAL audit_log_format = 'JSON';

-- Check audit log status
SHOW VARIABLES LIKE 'audit_log%';
Output
+----------------------------+----------------+
| Variable_name | Value |
+----------------------------+----------------+
| audit_log_buffer_size | 1048576 |
| audit_log_file | /var/log/mysql/audit.log |
| audit_log_format | JSON |
| audit_log_policy | ALL |
+----------------------------+----------------+
⚠ Audit Logs Consume Disk Space
📊 Production Insight
Use JSON format for easier parsing. Integrate with tools like Elasticsearch or Splunk for real-time monitoring.
🎯 Key Takeaway
Auditing provides visibility; enable it for all sensitive databases.

5. Column-Level Encryption: Protecting Sensitive Fields

Sometimes you need to encrypt specific columns, like credit card numbers or social security numbers, even from database administrators. Column-level encryption uses application-side encryption or database functions. For example, PostgreSQL's pgcrypto extension provides encryption functions. Here's how to encrypt a column using AES-256:

This encrypts the credit_card column with a key. The key must be stored securely, ideally in a vault. Decryption requires the same key. This approach protects data even if the database is compromised, but it adds complexity to queries (you cannot search directly on encrypted data without decryption).

column_encryption.sqlSQL
1
2
3
4
5
6
7
8
9
10
-- PostgreSQL: Encrypt a column using pgcrypto
CREATE EXTENSION IF NOT EXISTS pgcrypto;

-- Insert encrypted data
INSERT INTO payments (user_id, credit_card_encrypted)
VALUES (1, pgp_sym_encrypt('4111111111111111', 'encryption_key'));

-- Decrypt when needed
SELECT pgp_sym_decrypt(credit_card_encrypted, 'encryption_key') AS credit_card
FROM payments WHERE user_id = 1;
Output
credit_card
-----------------
4111111111111111
(1 row)
💡Use Application-Level Encryption for Sensitive Data
📊 Production Insight
Be aware that encrypted columns cannot be indexed efficiently. Consider using deterministic encryption for exact lookups, but be cautious about frequency analysis.
🎯 Key Takeaway
Column-level encryption protects sensitive fields from privileged users.

6. Security Best Practices: Putting It All Together

A secure database requires a holistic approach. Combine encryption, access control, and auditing with other best practices: - Regularly update database software to patch vulnerabilities. - Use strong, unique passwords and enforce password policies. - Implement network segmentation: place databases in private subnets. - Use database firewalls or proxy servers to filter queries. - Conduct regular security audits and penetration testing. - Backup encryption keys and test recovery procedures. - Monitor for anomalies using automated tools.

Remember, security is a process, not a one-time setup. Stay informed about new threats and update your defenses accordingly.

security_checklist.sqlSQL
1
2
3
4
5
6
7
8
9
-- Quick security health check (MySQL)
-- Check for users with weak passwords
SELECT user, host, authentication_string FROM mysql.user WHERE authentication_string = '';

-- Check for anonymous accounts
SELECT user, host FROM mysql.user WHERE user = '';

-- Check for users with global privileges
SELECT user, host, Super_priv FROM mysql.user WHERE Super_priv = 'Y';
Output
Empty set (0.00 sec)
Empty set (0.00 sec)
+------------------+-----------+------------+
| user | host | Super_priv |
+------------------+-----------+------------+
| root | localhost | Y |
| admin | % | Y |
+------------------+-----------+------------+
🔥Security is Layered
📊 Production Insight
Automate security checks using scripts or tools like SQLCipher or db-validator. Integrate with CI/CD pipelines to catch misconfigurations early.
🎯 Key Takeaway
Implement multiple layers of security and regularly review configurations.
● Production incidentPOST-MORTEMseverity: high

The Exposed Backup: How Unencrypted Backups Led to a Data Leak

Symptom
Customers reported receiving phishing emails with their exact transaction history.
Assumption
The DBA assumed that since the database itself was encrypted, backups were safe.
Root cause
Backup files were stored without encryption on a misconfigured cloud storage bucket.
Fix
Implemented encrypted backups using AWS KMS and restricted bucket access with IAM policies.
Key lesson
  • Always encrypt backups, not just the live database.
  • Use separate encryption keys for backups and production data.
  • Automate backup encryption and regularly test restoration.
  • Monitor cloud storage configurations for public access.
  • Apply the principle of least privilege to backup storage.
Production debug guideSymptom to Action4 entries
Symptom · 01
Connection fails with 'SSL required' error
Fix
Check if TLS is enabled on server and client. Verify certificates and cipher suites.
Symptom · 02
User gets 'permission denied' unexpectedly
Fix
Review role assignments and privileges. Use SHOW GRANTS to see effective permissions.
Symptom · 03
Audit log shows unknown queries
Fix
Check for compromised credentials. Enable additional logging and review application code for SQL injection.
Symptom · 04
Data appears corrupted after restore
Fix
Verify backup encryption keys. Test backup integrity with checksums.
★ Quick Debug Cheat SheetCommon security symptoms and immediate actions.
SSL connection error
Immediate action
Check SSL mode in connection string
Commands
SHOW VARIABLES LIKE '%ssl%';
SELECT * FROM performance_schema.session_status WHERE VARIABLE_NAME LIKE '%ssl%';
Fix now
Enable SSL on server and update client connection string to use sslmode=require.
Access denied for user+
Immediate action
Verify user exists and has proper grants
Commands
SELECT user, host FROM mysql.user;
SHOW GRANTS FOR 'user'@'host';
Fix now
GRANT SELECT, INSERT ON database.* TO 'user'@'host';
Audit log not recording+
Immediate action
Check if audit plugin is installed and enabled
Commands
SHOW PLUGINS WHERE Name LIKE '%audit%';
SELECT * FROM performance_schema.setup_instruments WHERE NAME LIKE '%audit%';
Fix now
INSTALL PLUGIN audit_log SONAME 'audit_log.so'; SET GLOBAL audit_log_policy = 'ALL';
FeatureMySQLPostgreSQL
Encryption at Rest (TDE)InnoDB tablespace encryptionpg_tde extension (third-party)
Encryption in TransitSSL/TLS with require_secure_transportSSL/TLS with ssl=on
AuditingAudit Log PluginpgAudit extension
Column-Level EncryptionAES_ENCRYPT/AES_DECRYPT functionspgcrypto extension
RBACRoles and privilegesRoles with inheritance
⚙ Quick Reference
6 commands from this guide
FileCommand / CodePurpose
encrypt_table.sqlINSTALL PLUGIN keyring_file SONAME 'keyring_file.so';1. Encryption at Rest
ssl_user.sqlCREATE USER 'app_user'@'%' IDENTIFIED BY 'strong_password' REQUIRE SSL;2. Encryption in Transit
rbac_postgres.sqlCREATE ROLE read_only;3. Role-Based Access Control (RBAC)
enable_audit_mysql.sqlINSTALL PLUGIN audit_log SONAME 'audit_log.so';4. Auditing
column_encryption.sqlCREATE EXTENSION IF NOT EXISTS pgcrypto;5. Column-Level Encryption
security_checklist.sqlSELECT user, host, authentication_string FROM mysql.user WHERE authentication_st...6. Security Best Practices

Key takeaways

1
Encrypt data at rest and in transit to protect against unauthorized access.
2
Implement role-based access control with the principle of least privilege.
3
Enable auditing to monitor and investigate database activity.
4
Use column-level encryption for highly sensitive fields.
5
Regularly review and rotate encryption keys and credentials.

Common mistakes to avoid

4 patterns
×

Using the same encryption key for everything.

×

Granting too many privileges to application users.

×

Not enabling SSL for database connections.

×

Storing encryption keys in the database or in source code.

INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01SENIOR
Explain the difference between symmetric and asymmetric encryption in th...
Q02SENIOR
How would you design a role-based access control system for a multi-tena...
Q03SENIOR
What is Transparent Data Encryption (TDE) and how does it work?
Q01 of 03SENIOR

Explain the difference between symmetric and asymmetric encryption in the context of database security.

ANSWER
Symmetric encryption uses the same key for encryption and decryption (e.g., AES). It's fast and suitable for encrypting large volumes of data at rest. Asymmetric encryption uses a public/private key pair (e.g., RSA). It's slower but useful for key exchange and digital signatures. In databases, symmetric encryption is typically used for data encryption, while asymmetric encryption is used for securing the symmetric keys.
FAQ · 5 QUESTIONS

Frequently Asked Questions

01
What is the difference between encryption at rest and encryption in transit?
02
How do I rotate encryption keys without downtime?
03
Can auditing impact database performance?
04
What is the principle of least privilege?
05
How do I securely store database credentials in an application?
N
Naren Founder & Principal Engineer

20+ years shipping high-throughput database systems. Lessons pulled from things that broke in production.

Follow
Verified
production tested
July 13, 2026
last updated
2,165
articles · all by Naren
🔥

That's Database Design. Mark it forged?

3 min read · try the examples if you haven't

Previous
Data Lake and Lakehouse: Delta Lake, Iceberg, Hudi
21 / 21 · Database Design
Next
What is an ORM