Skip to main content

Best Practices

This guide provides best practices and recommendations for implementing and operating Oracle TDE with DuoKey KMS in production environments.

Security Best Practices​

Separation of Duties​

Implement separation of duties between database administrators and security administrators for enhanced security.

Database Administrators (DBAs):

  • Manage database operations
  • Create and modify database objects
  • Perform backups and restores
  • Monitor database performance

Security Administrators:

  • Manage encryption keys in DuoKey KMS
  • Control access to key management operations
  • Monitor audit logs for key operations
  • Enforce key rotation policies

Implementation:

-- Grant SYSKM privilege to security administrators
GRANT SYSKM TO security_admin IDENTIFIED BY password;

-- Security admin connects as SYSKM
sqlplus security_admin/password AS SYSKM

-- Perform key management operations
ADMINISTER KEY MANAGEMENT SET KEY
IDENTIFIED BY "<keystore_pin>"
CONTAINER = ALL;
Advisory PIN, not a DuoKey credential

The keystore PIN/password Oracle requires by syntax is advisory only — it is never sent to or checked against DuoKey, but it must be a literal quoted string (IDENTIFIED BY EXTERNAL STORE raises ORA-00988 against this provider). Cockpit v2 authenticates every request using the app's access_guid, carried as the bearer token in the access_token field of pkcs11.toml.

Secure Configuration Management​

Protect PKCS#11 configuration files containing DuoKey KMS credentials:

# Strict permissions on pkcs11.toml
chmod 600 /etc/duokey/pkcs11.toml
chown oracle:oinstall /etc/duokey/pkcs11.toml

# Verify permissions
ls -la /etc/duokey/pkcs11.toml
# Expected: -rw------- oracle oinstall

Never store credentials in:

  • Version control systems
  • Unencrypted backups
  • Shared network locations
  • Email or documentation

File and Directory Permissions (Linux)​

Every file the PKCS#11 library touches must be owned by the same OS user Oracle actually runs as (typically oracle, group oinstall — check with id oracle on your host, some installs use a differently named group such as dba; use whatever id oracle actually reports, not a hardcoded oinstall).

PathOwner:GroupModeWhy
/opt/oracle/extapi/64/hsm/DuoKey/ (and parents)oracle:oinstall755Directory must be traversable by the oracle process; no write access needed for anyone else
/opt/oracle/extapi/64/hsm/DuoKey/1.0/libdke_pkcs11.sooracle:oinstall755Executable/readable by oracle; keep exactly one file in this directory — Oracle's discovery scan can misbehave with more than one candidate present
/etc/duokey/pkcs11.toml (or wherever DKE_PKCS11_CONF points)oracle:oinstall600Contains the access_token bearer credential — restrict to the owner only, no group/other read
/var/log/dke-pkcs11/ (the logging_folder)oracle:oinstall755oracle must be able to create/write log files here
$ORACLE_BASE/admin/$ORACLE_SID/wallet (WALLET_ROOT)oracle:oinstall700Must exist before ALTER SYSTEM SET WALLET_ROOT — Oracle does not always create it for you, and a missing directory produces a wallet-open failure that looks unrelated to permissions
# Full setup in one pass, run as a user with sudo
sudo mkdir -p /opt/oracle/extapi/64/hsm/DuoKey/1.0
sudo cp libdke_pkcs11.so /opt/oracle/extapi/64/hsm/DuoKey/1.0/
sudo chown -R oracle:oinstall /opt/oracle/extapi
sudo chmod -R 755 /opt/oracle/extapi

sudo mkdir -p /etc/duokey
sudo cp pkcs11.toml /etc/duokey/
sudo chown oracle:oinstall /etc/duokey/pkcs11.toml
sudo chmod 600 /etc/duokey/pkcs11.toml

sudo mkdir -p /var/log/dke-pkcs11
sudo chown oracle:oinstall /var/log/dke-pkcs11
sudo chmod 755 /var/log/dke-pkcs11

sudo mkdir -p "$ORACLE_BASE/admin/$ORACLE_SID/wallet"
sudo chown oracle:oinstall "$ORACLE_BASE/admin/$ORACLE_SID/wallet"
sudo chmod 700 "$ORACLE_BASE/admin/$ORACLE_SID/wallet"

# Verify everything is owned by the user Oracle actually runs as
id oracle
ls -la /opt/oracle/extapi/64/hsm/DuoKey/1.0/
ls -la /etc/duokey/pkcs11.toml
Test as the oracle OS user, not as yourself

Permissions that look correct to root or your own sudo-capable account can still block the actual Oracle server process. Always confirm with sudo su - oracle and re-run pkcs11-tool --list-slots (see Configuration → Testing Library Connectivity) as that user before considering the setup done.

Shared servers: isolate the config per database instance

If this host runs more than one Oracle instance (a test database alongside production databases, for example), each instance needs its own pkcs11.toml pointing at its own Oracle TDE app (different access_guid) in Cockpit — do not point two instances at the same app/master key. See Key Management → Shared-server blast radius for what happens if you skip this and later destroy a key.

Key Rotation Schedule​

Establish and maintain a regular key rotation schedule:

Recommended Frequencies:

EnvironmentRotation FrequencyCompliance Driver
Production6-12 monthsPCI DSS, SOC 2
High Security3-6 monthsHIPAA, FedRAMP
DevelopmentAnnuallyInternal policy
TestingAs neededN/A

Automation Example:

#!/bin/bash
# rotate_tde_keys.sh

# Set variables
ORACLE_HOME=/u01/app/oracle/product/19c/dbhome_1
ORACLE_SID=PRODDB
# The keystore PIN is advisory only — it is not the DuoKey credential.
# Cockpit v2 authenticates every request with the access_guid bearer
# token (the pkcs11.toml access_token field), not with this value.
KEYSTORE_PIN="<keystore_pin>"

# Connect and rotate key
$ORACLE_HOME/bin/sqlplus / as sysdba <<EOF
ADMINISTER KEY MANAGEMENT SET KEY
FORCE KEYSTORE
IDENTIFIED BY "${KEYSTORE_PIN}"
CONTAINER = ALL;
EXIT;
EOF

# Verify rotation
$ORACLE_HOME/bin/sqlplus / as sysdba <<EOF
SELECT key_id, creation_time
FROM v\$encryption_keys
ORDER BY creation_time DESC
FETCH FIRST 1 ROWS ONLY;
EXIT;
EOF

Audit Logging​

Enable comprehensive audit logging:

DuoKey KMS Audit:

  • Monitor all key operations in DuoKey Cockpit
  • Export audit logs to SIEM systems
  • Set up alerts for suspicious activities
  • Retain logs per compliance requirements

Oracle Database Audit:

-- Enable unified auditing for TDE operations
CREATE AUDIT POLICY tde_audit_policy
ACTIONS
ADMINISTER KEY MANAGEMENT;

AUDIT POLICY tde_audit_policy;

-- Query TDE-related audit records
SELECT event_timestamp, dbusername, action_name, return_code
FROM unified_audit_trail
WHERE action_name LIKE '%KEY MANAGEMENT%'
ORDER BY event_timestamp DESC;

Network Security​

Secure communication between Oracle Database and DuoKey KMS:

TLS Configuration:

The provider always connects to DuoKey KMS over HTTPS. Set the endpoint in the [http_config] block of pkcs11.toml and keep certificate verification enabled. Use the API-serving hostname, not the frontend/browser one — Cockpit v2 typically separates the two (e.g. cockpit-api-<env>.duokey.cloud for the API vs cockpit-<env>.duokey.cloud for the UI); pointing at the wrong one still returns HTTP 200, just with the frontend's HTML instead of JSON:

# In pkcs11.toml
[http_config]
server_url = "https://cockpit-api-test.duokey.cloud/api/apps/APP_ID/tde/pkcs11/ACCESS_GUID"
access_token = "<access_token>"
verify_tls = true

Firewall Rules:

# Allow outbound HTTPS to the DuoKey Cockpit API host
iptables -A OUTPUT -p tcp --dport 443 \
-d cockpit-api-test.duokey.cloud -j ACCEPT

# Block other outbound traffic (if applicable)
iptables -A OUTPUT -p tcp --dport 443 -j DROP

Network Segmentation:

  • Place database servers in secure VLAN
  • Restrict access to DuoKey KMS endpoints
  • Use VPN or private network connections
  • Implement network monitoring

Performance Best Practices​

Choose Appropriate Encryption Type​

Select the right encryption type based on your use case:

When to Use:

  • Most scenarios
  • Entire database encryption required
  • OLTP workloads with frequent updates
  • Better performance than column encryption

Example:

-- Create encrypted tablespace
CREATE TABLESPACE sensitive_data_ts
DATAFILE '/u01/app/oracle/oradata/ORCL/sensitive_ts01.dbf'
SIZE 1G AUTOEXTEND ON
ENCRYPTION USING 'AES256'
DEFAULT STORAGE(ENCRYPT);

-- Move existing table to encrypted tablespace
ALTER TABLE hr.employees MOVE TABLESPACE sensitive_data_ts;

Performance Impact: 2-5% overhead

Column Encryption​

When to Use:

  • Few specific columns contain sensitive data
  • Columns are pre-identified
  • Minimal storage overhead required

Example:

-- Encrypt specific columns
CREATE TABLE employees (
employee_id NUMBER,
first_name VARCHAR2(50),
last_name VARCHAR2(50),
ssn VARCHAR2(11) ENCRYPT USING 'AES256' NO SALT,
salary NUMBER(10,2) ENCRYPT USING 'AES256' NO SALT
);

Performance Impact: 5-15% overhead for encrypted columns

SALT vs NO SALT

Use NO SALT for columns used in WHERE clauses or JOINs to enable index usage. SALT provides additional security but prevents index range scans.

Hardware Acceleration​

Leverage hardware acceleration for better performance:

# Verify AES-NI support
grep -m 1 -o aes /proc/cpuinfo
# Expected output: aes

# Check if Oracle is using AES-NI
# In Oracle 12.2+, AES-NI is automatically used if available

Performance Benefits:

  • 50-70% faster encryption/decryption
  • Reduced CPU utilization
  • Better scalability

Buffer Cache Optimization​

For heavily accessed encrypted tables:

-- Enable KEEP buffer pool for frequently accessed encrypted tables
ALTER SYSTEM SET DB_KEEP_CACHE_SIZE=2G SCOPE=BOTH;

-- Assign table to KEEP pool
ALTER TABLE hr.employees STORAGE (BUFFER_POOL KEEP);

Benefits:

  • Reduces disk I/O for encrypted data
  • Minimizes decryption operations
  • Improves query performance

Index Strategy​

Optimize indexes for encrypted columns:

For Column Encryption with SALT:

-- Index range scans don't work with SALT
-- Use NO SALT for searchable columns
ALTER TABLE employees MODIFY (ssn ENCRYPT NO SALT);

-- Create index
CREATE INDEX idx_emp_ssn ON employees(ssn);

For Tablespace Encryption:

-- Indexes work normally
CREATE INDEX idx_emp_name ON employees(last_name, first_name);

Parallel Operations​

Enable parallelism for large encrypted tables:

-- Set parallel degree for table
ALTER TABLE large_encrypted_table PARALLEL 4;

-- Use parallel hints in queries
SELECT /*+ PARALLEL(large_encrypted_table, 4) */
* FROM large_encrypted_table;

Connection Timeout Tuning​

On high-latency networks, allow more time for each request to DuoKey KMS by raising timeout_secs in the [http_config] block of pkcs11.toml:

# In pkcs11.toml
[http_config]
server_url = "https://cockpit-api-test.duokey.cloud/api/apps/APP_ID/tde/pkcs11/ACCESS_GUID"
access_token = "<access_token>"
timeout_secs = 30
verify_tls = true

The heartbeat itself is an Oracle behavior: the database Gen0 background process periodically pings the external keystore. The settings below tune Oracle's tolerance for that heartbeat, independently of the provider.

Oracle Database Settings (12.1+):

-- Increase heartbeat tolerance
ALTER SYSTEM SET "_heartbeat_period_multiplier"=20 SCOPE=SPFILE;
ALTER SYSTEM SET "_heartbeat_config"=AUTOCONNECT SCOPE=SPFILE;

-- Restart required
SHUTDOWN IMMEDIATE;
STARTUP;

Calculation:

  • Default heartbeat: 3 seconds
  • Multiplier: 20
  • Total tolerance: 20 × 3 + 3 = 63 seconds

For Oracle 11g R2:

-- Set event for heartbeat tolerance
ALTER SYSTEM SET EVENT=
'28420 trace name context forever, level 10:
28421 trace name context forever, level 3'
COMMENT='HSM heartbeat timeout and reconnect'
SCOPE=SPFILE;

-- Restart required
SHUTDOWN IMMEDIATE;
STARTUP;

Operational Best Practices​

Documentation​

Maintain comprehensive documentation:

Configuration Documentation:

  • DuoKey KMS endpoints and credentials locations
  • PKCS#11 library versions and locations
  • Database wallet configurations
  • Key rotation schedules
  • Backup and recovery procedures

Runbook Example:

# Oracle TDE with DuoKey KMS Runbook

## Configuration
- DuoKey KMS: https://duokey-prod.company.com
- PKCS#11 Version: 4.34.2503
- PKCS#11 Config: /etc/duokey/pkcs11.toml
- Wallet Location: $ORACLE_BASE/admin/$ORACLE_SID/wallet/tde

## Key Rotation Procedure
1. Verify DuoKey KMS connectivity
2. Execute key rotation SQL
3. Verify in DuoKey audit logs
4. Schedule database restart
5. Document rotation in CMDB

## Emergency Contacts
- DuoKey Support: [email protected]
- On-call DBA: [email protected]
- Security Team: [email protected]

Testing and Validation​

Establish regular testing procedures:

Pre-Production Testing:

#!/bin/bash
# test_tde_operations.sh

echo "Testing TDE Operations..."

# Test 1: Connectivity
echo "1. Testing DuoKey KMS connectivity..."
curl -v https://cockpit-api-test.duokey.cloud/api/apps/APP_ID/tde/pkcs11/ACCESS_GUID

# Test 2: Wallet status
echo "2. Checking wallet status..."
sqlplus -s / as sysdba <<EOF
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF
SELECT status FROM v\$encryption_wallet;
EXIT;
EOF

# Test 3: Create test encrypted table
echo "3. Testing encryption operations..."
sqlplus -s / as sysdba <<EOF
CREATE TABLESPACE test_tde_ts
DATAFILE '/tmp/test_tde.dbf' SIZE 10M
ENCRYPTION USING 'AES256' DEFAULT STORAGE(ENCRYPT);

DROP TABLESPACE test_tde_ts INCLUDING CONTENTS AND DATAFILES;
EXIT;
EOF

echo "TDE testing complete."

Validation Checklist:

  • Wallet opens automatically on restart
  • Encrypted data is accessible
  • Key rotation succeeds
  • Backup and restore work correctly
  • Performance meets requirements
  • Audit logs are generated

Monitoring​

Implement comprehensive monitoring:

Key Metrics to Monitor:

-- Wallet status
SELECT wrl_type, status, wallet_type
FROM v$encryption_wallet;

-- Encrypted tablespaces
SELECT tablespace_name, encrypted, bytes/1024/1024 as mb
FROM dba_tablespaces
WHERE encrypted = 'YES';

-- Encrypted columns
SELECT owner, table_name, COUNT(*) as encrypted_columns
FROM dba_encrypted_columns
GROUP BY owner, table_name;

-- Key usage
SELECT key_id, activation_time,
ROUND((SYSDATE - activation_time)) as days_active
FROM v$encryption_keys
ORDER BY activation_time DESC;

PKCS#11 Log Monitoring:

# Monitor for errors
tail -f /var/log/dke-pkcs11/*.log | grep -i error

# Monitor for connection issues
tail -f /var/log/dke-pkcs11/*.log | grep -i "connection\|timeout"

Alerting Rules:

  • Wallet not open after restart
  • Connection failures to DuoKey KMS
  • Key rotation failures
  • Heartbeat timeouts
  • PKCS#11 library errors

Backup Strategy​

Implement comprehensive backup strategy:

What to Backup:

  1. Database (RMAN):
# Encrypted tablespaces are backed up encrypted
rman target / <<EOF
BACKUP DATABASE PLUS ARCHIVELOG;
DELETE NOPROMPT OBSOLETE;
EXIT;
EOF
  1. Wallet Files:
# Backup wallet directory
tar -czf wallet_backup_$(date +%Y%m%d).tar.gz \
$ORACLE_BASE/admin/$ORACLE_SID/wallet/tde/

# Store in secure location
scp wallet_backup_*.tar.gz backup_server:/secure/backups/
  1. PKCS#11 Configuration:
# Backup configuration
cp /etc/duokey/pkcs11.toml \
/secure/backups/pkcs11.toml.$(date +%Y%m%d)
  1. Documentation:
  • DuoKey app credentials (in secure vault)
  • Configuration documentation
  • Runbooks and procedures

Backup Frequency:

  • Database: Daily (or per RPO requirements)
  • Wallet files: After any changes
  • PKCS#11 config: After any changes
  • Documentation: After any updates

Test Restores:

# Quarterly restore test procedure
1. Restore database to test environment
2. Copy wallet files
3. Configure PKCS#11 connection
4. Open database and verify data access
5. Document results

Disaster Recovery​

Plan for disaster recovery scenarios:

Scenario 1: Database Server Failure

Recovery Steps:

  1. Provision new database server
  2. Install Oracle Database software
  3. Install DuoKey PKCS#11 library
  4. Copy wallet files from backup
  5. Copy pkcs11.toml from backup
  6. Restore database from RMAN backup
  7. Verify wallet opens and data is accessible

Scenario 2: DuoKey KMS Unavailable

Mitigation:

  • Use auto-login wallet (allows database to start)
  • Monitor PKCS#11 logs for reconnection
  • Contact DuoKey support
  • Consider secondary DuoKey instance for HA

RTO/RPO Targets:

  • RTO (Recovery Time Objective): 4 hours
  • RPO (Recovery Point Objective): 15 minutes (archive log shipping)

High Availability Best Practices​

Oracle RAC Configuration​

For Oracle RAC environments:

Installation:

# Install PKCS#11 library on all nodes
for node in node1 node2 node3; do
ssh $node "mkdir -p /opt/oracle/extapi/64/hsm/DuoKey/1.0"
scp libdke_pkcs11.so $node:/opt/oracle/extapi/64/hsm/DuoKey/1.0/
done

# Distribute wallet files
for node in node2 node3; do
scp $ORACLE_BASE/admin/$ORACLE_SID/wallet/tde/* \
$node:$ORACLE_BASE/admin/$ORACLE_SID/wallet/tde/
done

# Distribute PKCS#11 configuration
for node in node1 node2 node3; do
scp /etc/duokey/pkcs11.toml $node:/etc/duokey/
done

Configuration:

-- Set parameters for all instances
ALTER SYSTEM SET WALLET_ROOT='$ORACLE_BASE/admin/$ORACLE_SID/wallet'
SCOPE=SPFILE SID='*';

ALTER SYSTEM SET TDE_CONFIGURATION='KEYSTORE_CONFIGURATION=HSM|FILE'
SCOPE=BOTH SID='*';

Best Practices:

  • Use shared storage for wallet files (if possible)
  • Synchronize wallet files across nodes
  • Monitor all nodes independently
  • Test failover scenarios

Data Guard Configuration​

For Data Guard environments:

Standby Database Setup:

# Copy configuration from primary
scp primary:/etc/duokey/pkcs11.toml standby:/etc/duokey/
scp primary:$ORACLE_BASE/admin/$ORACLE_SID/wallet/tde/* \
standby:$ORACLE_BASE/admin/$ORACLE_SID/wallet/tde/

Verification:

-- On standby database
SELECT * FROM V$ENCRYPTION_WALLET;

-- Expected: HSM wallet open with auto-login

Failover Testing:

-- 1. Switchover primary to standby
DGMGRL> SWITCHOVER TO standby_db;

-- 2. Verify wallet opens automatically
SELECT * FROM V$ENCRYPTION_WALLET;

-- 3. Verify encrypted data accessible
SELECT * FROM encrypted_table FETCH FIRST 1 ROWS ONLY;

Compliance Best Practices​

PCI DSS Compliance​

For Payment Card Industry compliance:

Requirements:

  • Encrypt cardholder data at rest
  • Rotate encryption keys annually
  • Restrict access to keys
  • Maintain audit trail
  • Test encryption regularly

Implementation:

-- Encrypt credit card data
CREATE TABLE payments (
payment_id NUMBER PRIMARY KEY,
card_number VARCHAR2(19) ENCRYPT USING 'AES256' NO SALT,
cvv VARCHAR2(4) ENCRYPT USING 'AES256',
expiry_date VARCHAR2(5) ENCRYPT USING 'AES256'
) TABLESPACE secure_payments_ts;

HIPAA Compliance​

For Protected Health Information:

Requirements:

  • Encrypt ePHI at rest
  • Access controls and audit trails
  • Business associate agreements
  • Regular risk assessments

Implementation:

-- Encrypt patient data
CREATE TABLE patient_records (
patient_id NUMBER PRIMARY KEY,
ssn VARCHAR2(11) ENCRYPT USING 'AES256' NO SALT,
medical_history CLOB ENCRYPT USING 'AES256',
diagnosis VARCHAR2(500) ENCRYPT USING 'AES256'
) TABLESPACE phi_tablespace;

GDPR Compliance​

For EU data protection:

Requirements:

  • Encrypt personal data
  • Data minimization
  • Right to erasure (crypto-shredding)
  • Breach notification

Crypto-Shredding:

-- Create separate key per tenant/user
-- Deletion = key destruction in DuoKey KMS

-- Example: Tenant-specific encryption
CREATE TABLESPACE tenant_123_ts
ENCRYPTION USING 'AES256' DEFAULT STORAGE(ENCRYPT);

-- To "delete" data: rotate/destroy the key
-- Data becomes permanently unreadable

Troubleshooting Best Practices​

Common Issues and Solutions​

Issue 1: Wallet Not Opening After Restart

-- Check wallet status
SELECT * FROM V$ENCRYPTION_WALLET;

-- If closed, open manually
ADMINISTER KEY MANAGEMENT SET KEYSTORE OPEN
IDENTIFIED BY "<keystore_pin>"
CONTAINER = ALL;

Issue 2: Connection to DuoKey KMS Failed

# Test connectivity
curl -v https://cockpit-api-test.duokey.cloud/api/apps/APP_ID/tde/pkcs11/ACCESS_GUID

# Check PKCS#11 logs
tail -100 /var/log/dke-pkcs11/*.log

# Verify configuration
cat /etc/duokey/pkcs11.toml

Issue 3: Performance Degradation

-- Check for full table scans on encrypted tables
SELECT * FROM v$sql_plan
WHERE operation = 'TABLE ACCESS'
AND options = 'FULL'
AND object_name IN (
SELECT table_name FROM dba_encrypted_columns
);

-- Consider adding indexes or using KEEP buffer pool

Support Escalation​

When to Contact Support:

  • Cannot connect to DuoKey KMS
  • PKCS#11 library errors
  • Key rotation failures
  • Unexpected wallet closures
  • Performance issues

Information to Provide:

  • Oracle version and platform
  • PKCS#11 library version
  • Error messages and logs
  • pkcs11.toml configuration (redact credentials)
  • Database alert log excerpts

Summary Checklist​

Initial Implementation​

  • DuoKey KMS configured with group and application
  • PKCS#11 library installed and configured
  • TDE master key created in DuoKey KMS
  • Auto-login wallet configured
  • Test encryption working correctly

Security​

  • Separation of duties implemented
  • PKCS#11 configuration secured (chmod 600)
  • Audit logging enabled and monitored
  • Key rotation schedule defined
  • Network security configured

Performance​

  • Tablespace encryption chosen (if appropriate)
  • Hardware acceleration enabled
  • Indexes optimized for encrypted columns
  • Buffer cache configured appropriately
  • Performance tested and validated

Operations​

  • Documentation completed
  • Runbooks created
  • Monitoring configured
  • Backup strategy implemented
  • Disaster recovery plan documented

Compliance​

  • Regulatory requirements identified
  • Encryption scope defined
  • Audit trail configured
  • Compliance validation performed
  • Annual reviews scheduled

Additional Resources​

Support​

For assistance with Oracle TDE best practices: