Oracle TDE Key Rotation & Compliance Automation - Why Key Rotation Matters ?
Oracle TDE Key Rotation
& Compliance Automation
Master TDE Master Encryption Key rotation, automate compliance schedules for PCI-DSS, SOX, GDPR and HIPAA, and build audit-ready key management pipelines — with every command covered.
Why Key Rotation Matters — The Compliance Imperative
Transparent Data Encryption protects your data at rest, but encryption is only as strong as your key management discipline. Regulatory frameworks don't just require you to encrypt — they require you to rotate encryption keys regularly, maintain an audit trail of every rotation event, and prove that compromised keys were replaced.
PCI-DSS
Req 3.6.x: Cryptographic key rotation annually or when compromised. Full key lifecycle documentation required.
SOX
Section 404: Key management controls must be documented and tested. Rotation events require audit records.
GDPR
Art. 32: Appropriate technical measures including key rotation. Data breach scope reduced with recent key rotation.
HIPAA
§164.312(a)(2)(iv): Encryption key management. PHI must be encrypted with regularly rotated keys.
ISO 27001
A.10.1: Cryptographic key policies requiring rotation schedules, management procedures and lifecycle controls.
FIPS 140-2
AES-256 required for new rotations. Key lifecycle including creation, distribution, storage and destruction.
Understanding TDE Key Hierarchy
Before rotating keys, you must understand the two-level key hierarchy Oracle TDE uses. Confusing the two types leads to incorrect rotation procedures and compliance gaps.
| Key Type | Abbreviation | Purpose | Rotation Command | Scope |
|---|---|---|---|---|
| Master Encryption Key | MEK | Encrypts all Tablespace Encryption Keys. Stored in wallet/OKV. | ADMINISTER KEY MANAGEMENT SET KEY | CDB / PDB |
| Tablespace Encryption Key | TEK | Encrypts actual data blocks. Wrapped by the MEK. | ALTER TABLESPACE … REKEY | Per tablespace |
Types of Key Rotation Operations
Scheduled MEK Rotation
Routine compliance-driven rotation of the Master Encryption Key. Required by PCI-DSS annually. Fast, runs online, no tablespace downtime. Most common operation.
Emergency MEK Rotation
Triggered when a key is suspected compromised. Must be executed immediately regardless of maintenance windows. Requires immediate Standby sync and audit documentation.
Tablespace REKEY (TEK)
Full re-encryption of all data blocks with a new Tablespace Encryption Key. Used post-breach or for algorithm upgrades (3DES → AES256). Resource-intensive — plan I/O carefully.
CDB-Wide Rotation
Rotates MEK for the CDB root and all open PDBs in a single operation using CONTAINER=ALL. Ensures consistent rotation timestamps across all pluggable databases.
MEK Rotation — Step by Step
V$ENCRYPTION_KEYS for audit trail. (4) Confirm no other keystore operation is in progress.
Step 1: Pre-Rotation Audit Snapshot
-- Capture current MEK details BEFORE rotation (for audit log) SELECT key_id, creation_time, activation_time, retired_time, keystoretype, creator, con_id FROM v$encryption_keys ORDER BY activation_time DESC; -- Verify keystore status on Primary SELECT wrl_type, status, wallet_type, fully_backed_up FROM v$encryption_wallet; -- Backup wallet (OS command — run before proceeding) -- cp -rp $WALLET_ROOT/tde /backup/tde_pre_rotation_$(date +%Y%m%d_%H%M%S)
Step 2: Rotate the Master Encryption Key
-- ═══════════════════════════════════════════════════════ -- OPTION A: Non-CDB / Single PDB Rotation -- ═══════════════════════════════════════════════════════ ADMINISTER KEY MANAGEMENT SET KEY USING TAG 'PCI_ROTATION_2024Q4' -- Audit tag for compliance IDENTIFIED BY "WalletPassword@2024" WITH BACKUP USING 'pre_rotation_2024Q4' -- Keystore backup FORCE KEYSTORE; -- ═══════════════════════════════════════════════════════ -- OPTION B: CDB-Wide Rotation (Root + All Open PDBs) -- ═══════════════════════════════════════════════════════ ALTER SESSION SET container = CDB$ROOT; ADMINISTER KEY MANAGEMENT SET KEY USING TAG 'SOX_ROTATION_2024Q4_CDB' IDENTIFIED BY "WalletPassword@2024" WITH BACKUP USING 'cdb_rotation_2024Q4' FORCE KEYSTORE CONTAINER=ALL; -- Rotates in CDB + all PDBs -- ═══════════════════════════════════════════════════════ -- OPTION C: OKV (Oracle Key Vault) — No Password Needed -- ═══════════════════════════════════════════════════════ ADMINISTER KEY MANAGEMENT SET KEY USING TAG 'GDPR_ROTATION_2024Q4' IDENTIFIED EXTERNALLY WITH BACKUP FORCE KEYSTORE CONTAINER=ALL;
Step 3: Post-Rotation Verification
-- Verify new MEK is active (activation_time should be NOW) SELECT key_id, creator, creation_time, activation_time, tag -- Shows your USING TAG value — key audit link FROM v$encryption_keys WHERE activation_time = (SELECT MAX(activation_time) FROM v$encryption_keys); -- Verify previous MEK is now RETIRED (not ACTIVE) SELECT key_id, activation_time, retired_time, tag FROM v$encryption_keys ORDER BY activation_time DESC; -- Confirm fully_backed_up = YES after rotation SELECT status, wallet_type, fully_backed_up FROM v$encryption_wallet; -- Check all tablespaces still encrypted (no regressions) SELECT tablespace_name, encrypted, encryption_algorithm FROM v$encrypted_tablespaces;
Tablespace REKEY (TEK Rotation)
TEK rotation re-encrypts every data block. Use for post-breach remediation, algorithm upgrades, or ultra-strict compliance postures. Oracle 26ai makes this online.
-- Online REKEY — tablespace stays accessible during operation ALTER TABLESPACE USERS ENCRYPTION ONLINE USING 'AES256' REKEY; -- Monitor REKEY progress SELECT tablespace_name, encryption_algorithm, rekey_status, -- IN_PROGRESS / COMPLETED / FAILED pct_rekeyed, -- Percentage complete last_rekey_time FROM v$encrypted_tablespaces WHERE rekey_status IS NOT NULL; -- Using DBMS_SPACE_ADMIN for programmatic REKEY with DG propagation EXEC DBMS_SPACE_ADMIN.TABLESPACE_REKEY( tablespace_name => 'USERS', encrypt_algo => DBMS_SPACE_ADMIN.ENCRYPT_AES256, online_mode => TRUE, dg_propagate => TRUE -- Auto-propagate to Standbys );
Compliance Automation — Scripting Key Rotation
Manual key rotation is error-prone and audit-risky. The gold standard is an automated rotation pipeline triggered by a scheduler (DBMS_SCHEDULER, cron, or OEM) with built-in pre/post checks and audit logging.
Automated Rotation Procedure — PL/SQL
-- ═══════════════════════════════════════════════════════════ -- CREATE AUDIT TABLE (run once) -- ═══════════════════════════════════════════════════════════ CREATE TABLE dba_tde_rotation_log ( log_id NUMBER GENERATED ALWAYS AS IDENTITY, rotation_date DATE DEFAULT SYSDATE, rotation_type VARCHAR2(20), -- MEK / TEK / CDB_MEK compliance_tag VARCHAR2(100), old_key_id VARCHAR2(100), new_key_id VARCHAR2(100), rotated_by VARCHAR2(50) DEFAULT SYS_CONTEXT('USERENV','OS_USER'), status VARCHAR2(20), -- SUCCESS / FAILED error_msg VARCHAR2(4000), CONSTRAINT pk_tde_log PRIMARY KEY (log_id) ); -- ═══════════════════════════════════════════════════════════ -- AUTOMATED ROTATION PROCEDURE -- ═══════════════════════════════════════════════════════════ CREATE OR REPLACE PROCEDURE sp_tde_rotate_mek ( p_wallet_pwd IN VARCHAR2, p_compliance_tag IN VARCHAR2 DEFAULT 'SCHEDULED_ROTATION', p_cdb_wide IN BOOLEAN DEFAULT FALSE ) AS v_old_key_id VARCHAR2(100); v_new_key_id VARCHAR2(100); v_wallet_open VARCHAR2(10); v_sql VARCHAR2(4000); BEGIN -- Pre-check: verify keystore is open SELECT status INTO v_wallet_open FROM v$encryption_wallet WHERE ROWNUM = 1; IF v_wallet_open NOT IN ('OPEN','OPEN_NO_MASTER_KEY') THEN RAISE_APPLICATION_ERROR(-20001, 'Keystore not open. Status: ' || v_wallet_open); END IF; -- Capture current (old) key ID SELECT key_id INTO v_old_key_id FROM v$encryption_keys WHERE activation_time = (SELECT MAX(activation_time) FROM v$encryption_keys) AND ROWNUM = 1; -- Build rotation SQL with compliance tag IF p_cdb_wide THEN v_sql := 'ADMINISTER KEY MANAGEMENT SET KEY ' || 'USING TAG ''' || p_compliance_tag || ''' ' || 'IDENTIFIED BY "' || p_wallet_pwd || '" ' || 'WITH BACKUP FORCE KEYSTORE CONTAINER=ALL'; ELSE v_sql := 'ADMINISTER KEY MANAGEMENT SET KEY ' || 'USING TAG ''' || p_compliance_tag || ''' ' || 'IDENTIFIED BY "' || p_wallet_pwd || '" ' || 'WITH BACKUP FORCE KEYSTORE'; END IF; -- Execute the rotation EXECUTE IMMEDIATE v_sql; -- Capture new key ID SELECT key_id INTO v_new_key_id FROM v$encryption_keys WHERE activation_time = (SELECT MAX(activation_time) FROM v$encryption_keys) AND ROWNUM = 1; -- Write audit log entry INSERT INTO dba_tde_rotation_log (rotation_type, compliance_tag, old_key_id, new_key_id, status) VALUES (CASE WHEN p_cdb_wide THEN 'CDB_MEK' ELSE 'MEK' END, p_compliance_tag, v_old_key_id, v_new_key_id, 'SUCCESS'); COMMIT; EXCEPTION WHEN OTHERS THEN INSERT INTO dba_tde_rotation_log (rotation_type, compliance_tag, old_key_id, status, error_msg) VALUES ('MEK', p_compliance_tag, v_old_key_id, 'FAILED', SQLERRM); COMMIT; RAISE; END sp_tde_rotate_mek; /
DBMS_SCHEDULER — Scheduling Automated Rotation
-- Schedule annual MEK rotation — PCI-DSS requirement (rotate at least yearly) BEGIN DBMS_SCHEDULER.CREATE_JOB( job_name => 'TDE_MEK_ANNUAL_ROTATION', job_type => 'STORED_PROCEDURE', job_action => 'sp_tde_rotate_mek', number_of_arguments => 3, start_date => SYSTIMESTAMP, repeat_interval => 'FREQ=YEARLY;BYMONTH=1;BYMONTHDAY=15;BYHOUR=2;BYMINUTE=0', enabled => FALSE, comments => 'Annual TDE MEK rotation — PCI-DSS Req 3.6.x compliance' ); DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE( job_name => 'TDE_MEK_ANNUAL_ROTATION', argument_position => 1, argument_value => 'WalletPassword@2024' -- Use OKV to avoid plaintext! ); DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE( job_name => 'TDE_MEK_ANNUAL_ROTATION', argument_position => 2, argument_value => 'PCI_DSS_ANNUAL_ROTATION' ); DBMS_SCHEDULER.ENABLE('TDE_MEK_ANNUAL_ROTATION'); END; / -- Verify job scheduled correctly SELECT job_name, state, next_run_date, repeat_interval, comments FROM dba_scheduler_jobs WHERE job_name LIKE 'TDE%';
Data Guard — Key Rotation Propagation
-- After MEK rotation on Primary — verify Standby keystore sync -- Run on PRIMARY: SELECT dest_id, db_unique_name, tde_keystore_status, -- OPEN = Standby can decrypt new redo status, gap_status FROM v$archive_dest_status WHERE status = 'VALID'; -- Run on STANDBY — confirm same MEK is active SELECT key_id, activation_time, tag FROM v$encryption_keys WHERE activation_time = (SELECT MAX(activation_time) FROM v$encryption_keys); -- For Software Keystore: copy updated wallet to Standby after rotation -- scp $WALLET_ROOT/tde/ewallet.p12 oracle@standby:$WALLET_ROOT/tde/ -- scp $WALLET_ROOT/tde/cwallet.sso oracle@standby:$WALLET_ROOT/tde/ -- Then on Standby: ADMINISTER KEY MANAGEMENT SET KEYSTORE OPEN IDENTIFIED BY "pwd";
Audit Queries — Compliance Reporting
-- Complete key rotation history with age calculation SELECT key_id, tag compliance_tag, creation_time, activation_time, COALESCE(retired_time, SYSDATE) retired_or_now, ROUND(COALESCE(retired_time,SYSDATE) - activation_time) days_active, CASE WHEN retired_time IS NULL THEN 'ACTIVE' ELSE 'RETIRED' END key_state, -- Flag keys exceeding PCI 365-day limit CASE WHEN retired_time IS NULL AND SYSDATE - activation_time > 365 THEN '⚠ OVERDUE' ELSE 'OK' END pci_compliance FROM v$encryption_keys ORDER BY activation_time DESC; -- Rotation log for last 12 months (from audit table) SELECT rotation_date, rotation_type, compliance_tag, old_key_id, new_key_id, rotated_by, status FROM dba_tde_rotation_log WHERE rotation_date >= ADD_MONTHS(SYSDATE,-12) ORDER BY rotation_date DESC;
Best Practices Summary
| # | Best Practice | Compliance Driver | Priority |
|---|---|---|---|
| 1 | Tag every rotation with USING TAG for audit trail | PCI-DSS, SOX, GDPR | Critical |
| 2 | Use WITH BACKUP on every rotation — creates keystore snapshot | All frameworks | Critical |
| 3 | Automate via DBMS_SCHEDULER — eliminate manual rotation risk | SOX, ISO 27001 | High |
| 4 | Use OKV for enterprise — no plaintext passwords in scheduler | All frameworks | High |
| 5 | Rotate MEK at least annually; consider quarterly for PCI | PCI-DSS Req 3.6 | High |
| 6 | Sync wallet to ALL Standbys immediately after rotation | Availability SLA | Medium |
| 7 | Monitor V$ENCRYPTION_KEYS with alerting for overdue keys | All frameworks | Medium |
| 8 | Separate rotation privilege — use SYSKM, not SYSDBA | SOX, ISO 27001 | Medium |
Post a Comment: