Skip to content

Commit 5df6c58

Browse files
committed
PG-1257 Add functions for principal key removal
Add SQL functions that allow user to remove principal key. * Database level principal key can be removed if there are no encrypted tables or if there is default key. For the first case we just drop key map file completely, for the second we perform key rotation. * Default principal key can be removed if there are no databases that use it. Readded the DELETE key function to docs based on 1257 in Architecture chapter where we also update from DROP to DELETE.
1 parent 854e1a1 commit 5df6c58

21 files changed

+506
-46
lines changed

contrib/pg_tde/Makefile

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ DATA = pg_tde--1.0-rc.sql
88
# Since meson supports skipping test suites this is a make only feature
99
ifndef TDE_MODE
1010
REGRESS_OPTS = --temp-config $(top_srcdir)/contrib/pg_tde/pg_tde.conf
11-
# create_database must run after default_principal_key which must run after
12-
# key_provider.
1311
REGRESS = access_control \
1412
alter_index \
1513
cache_alloc \
1614
change_access_method \
15+
create_database \
16+
default_principal_key \
17+
delete_principal_key \
1718
insert_update_delete \
1819
key_provider \
1920
kmip_test \
@@ -24,9 +25,7 @@ relocate \
2425
tablespace \
2526
toast_decrypt \
2627
vault_v2_test \
27-
version \
28-
default_principal_key \
29-
create_database
28+
version
3029
TAP_TESTS = 1
3130
endif
3231

contrib/pg_tde/documentation/docs/architecture/index.md

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -292,15 +292,23 @@ With `pg_tde.inherit_global_key_providers`, it is also possible to set up a defa
292292

293293
With this feature, it is possible for the entire database server to easily use the same principal key for all databases, completely disabling multi-tenency.
294294

295-
A default key can be managed with the following functions:
295+
#### Manage a default key
296296

297-
```sql
298-
pg_tde_set_default_key_using_global_key_provider('key-name', 'provider-name', 'true/false')
299-
```
297+
You can manage a default key with the following functions:
298+
299+
* `pg_tde_set_default_key_using_global_key_provider('key-name','provider-name','true/false')`
300+
* `pg_tde_delete_default_key()`
301+
302+
!!! note
303+
`pg_tde_delete_default_key()` is only possible if there's no table currently using the default principal key.
304+
Changing the default principal key will rotate the encryption of internal keys for all databases using the current default principal key.
305+
306+
#### Delete a key
300307

301-
`DROP` is only possible if there's no table currently using the default principal key.
308+
The `pg_tde_delete_key()` function removes the principal key for the current database. If the current database has any encrypted tables, and there isn’t a default principal key configured, it reports an error instead. If there are encrypted tables, but there’s also a global default principal key, internal keys will be encrypted with the default key.
302309

303-
Changing the default principal key will rotate the encryption of internal keys for all databases using the current default principal key.
310+
!!! note
311+
WAL keys **cannot** be deleted, as server keys are managed separately.
304312

305313
### Current key details
306314

contrib/pg_tde/expected/access_control.out

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ SET ROLE regress_pg_tde_access_control;
1010
-- should throw access denied
1111
SELECT pg_tde_set_key_using_database_key_provider('test-db-key', 'local-file-provider');
1212
ERROR: permission denied for function pg_tde_set_key_using_database_key_provider
13+
SELECT pg_tde_delete_key();
14+
ERROR: permission denied for function pg_tde_delete_key
1315
SELECT pg_tde_list_all_database_key_providers();
1416
ERROR: permission denied for function pg_tde_list_all_database_key_providers
1517
SELECT pg_tde_list_all_global_key_providers();
@@ -37,6 +39,7 @@ GRANT EXECUTE ON FUNCTION pg_tde_delete_global_key_provider(TEXT) TO regress_pg_
3739
GRANT EXECUTE ON FUNCTION pg_tde_set_default_key_using_global_key_provider(TEXT, TEXT, BOOLEAN) TO regress_pg_tde_access_control;
3840
GRANT EXECUTE ON FUNCTION pg_tde_set_key_using_global_key_provider(TEXT, TEXT, BOOLEAN) TO regress_pg_tde_access_control;
3941
GRANT EXECUTE ON FUNCTION pg_tde_set_server_key_using_global_key_provider(TEXT, TEXT, BOOLEAN) TO regress_pg_tde_access_control;
42+
GRANT EXECUTE ON FUNCTION pg_tde_delete_default_key() TO regress_pg_tde_access_control;
4043
SET ROLE regress_pg_tde_access_control;
4144
SELECT pg_tde_add_database_key_provider_file('local-file-provider', '/tmp/pg_tde_test_keyring.per');
4245
ERROR: must be superuser to modify key providers
@@ -56,5 +59,7 @@ SELECT pg_tde_set_default_key_using_global_key_provider('key1', 'global-file-pro
5659
ERROR: must be superuser to access global key providers
5760
SELECT pg_tde_set_server_key_using_global_key_provider('key1', 'global-file-provider');
5861
ERROR: must be superuser to access global key providers
62+
SELECT pg_tde_delete_default_key();
63+
ERROR: must be superuser to access global key providers
5964
RESET ROLE;
6065
DROP EXTENSION pg_tde CASCADE;

contrib/pg_tde/expected/alter_index.out

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,5 +67,17 @@ SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_ind
6767
(5 rows)
6868

6969
DROP TABLE concur_reindex_part;
70+
SELECT pg_tde_delete_key();
71+
pg_tde_delete_key
72+
-------------------
73+
74+
(1 row)
75+
76+
SELECT pg_tde_delete_database_key_provider('file-vault');
77+
pg_tde_delete_database_key_provider
78+
-------------------------------------
79+
80+
(1 row)
81+
7082
DROP EXTENSION pg_tde;
7183
RESET default_table_access_method;

contrib/pg_tde/expected/create_database.out

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,16 @@ CREATE DATABASE new_db_file_copy TEMPLATE template_db STRATEGY FILE_COPY;
102102
DROP DATABASE new_db_file_copy;
103103
DROP DATABASE new_db;
104104
DROP DATABASE template_db;
105+
SELECT pg_tde_delete_default_key();
106+
pg_tde_delete_default_key
107+
---------------------------
108+
109+
(1 row)
110+
111+
SELECT pg_tde_delete_global_key_provider('global-file-vault');
112+
pg_tde_delete_global_key_provider
113+
-----------------------------------
114+
115+
(1 row)
116+
105117
DROP EXTENSION pg_tde;

contrib/pg_tde/expected/default_principal_key.out

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,17 @@ SELECT key_provider_id, key_provider_name, key_name
3333
FROM pg_tde_default_key_info();
3434
key_provider_id | key_provider_name | key_name
3535
-----------------+-------------------+-------------
36-
-5 | file-provider | default-key
36+
-2 | file-provider | default-key
3737
(1 row)
3838

3939
-- fails
4040
SELECT pg_tde_delete_global_key_provider('file-provider');
4141
ERROR: Can't delete a provider which is currently in use
4242
SELECT id, provider_name FROM pg_tde_list_all_global_key_providers();
43-
id | provider_name
44-
----+------------------
45-
-1 | file-keyring
46-
-3 | global-provider
47-
-4 | global-provider2
48-
-5 | file-provider
49-
(4 rows)
43+
id | provider_name
44+
----+---------------
45+
-2 | file-provider
46+
(1 row)
5047

5148
-- Should fail: no principal key for the database yet
5249
SELECT key_provider_id, key_provider_name, key_name
@@ -68,7 +65,7 @@ SELECT key_provider_id, key_provider_name, key_name
6865
FROM pg_tde_key_info();
6966
key_provider_id | key_provider_name | key_name
7067
-----------------+-------------------+-------------
71-
-5 | file-provider | default-key
68+
-2 | file-provider | default-key
7269
(1 row)
7370

7471
SELECT current_database() AS regress_database
@@ -97,7 +94,7 @@ SELECT key_provider_id, key_provider_name, key_name
9794
FROM pg_tde_key_info();
9895
key_provider_id | key_provider_name | key_name
9996
-----------------+-------------------+-------------
100-
-5 | file-provider | default-key
97+
-2 | file-provider | default-key
10198
(1 row)
10299

103100
\c :regress_database
@@ -112,15 +109,15 @@ SELECT key_provider_id, key_provider_name, key_name
112109
FROM pg_tde_key_info();
113110
key_provider_id | key_provider_name | key_name
114111
-----------------+-------------------+-----------------
115-
-5 | file-provider | new-default-key
112+
-2 | file-provider | new-default-key
116113
(1 row)
117114

118115
\c regress_pg_tde_other
119116
SELECT key_provider_id, key_provider_name, key_name
120117
FROM pg_tde_key_info();
121118
key_provider_id | key_provider_name | key_name
122119
-----------------+-------------------+-----------------
123-
-5 | file-provider | new-default-key
120+
-2 | file-provider | new-default-key
124121
(1 row)
125122

126123
SELECT pg_buffercache_evict(bufferid) FROM pg_buffercache WHERE relfilenode = (SELECT relfilenode FROM pg_class WHERE oid = 'test_enc'::regclass);
@@ -155,6 +152,18 @@ SELECT * FROM test_enc;
155152
(3 rows)
156153

157154
DROP TABLE test_enc;
155+
SELECT pg_tde_delete_default_key();
156+
pg_tde_delete_default_key
157+
---------------------------
158+
159+
(1 row)
160+
161+
SELECT pg_tde_delete_global_key_provider('file-provider');
162+
pg_tde_delete_global_key_provider
163+
-----------------------------------
164+
165+
(1 row)
166+
158167
DROP EXTENSION pg_tde CASCADE;
159168
DROP EXTENSION pg_buffercache;
160169
DROP DATABASE regress_pg_tde_other;
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
CREATE EXTENSION IF NOT EXISTS pg_tde;
2+
SELECT pg_tde_add_global_key_provider_file('file-provider','/tmp/pg_tde_test_keyring.per');
3+
pg_tde_add_global_key_provider_file
4+
-------------------------------------
5+
6+
(1 row)
7+
8+
-- Set the local key and delete it without any encrypted tables
9+
-- Should succeed: nothing used the key
10+
SELECT pg_tde_set_key_using_global_key_provider('test-db-key','file-provider');
11+
pg_tde_set_key_using_global_key_provider
12+
------------------------------------------
13+
14+
(1 row)
15+
16+
SELECT key_provider_id, key_provider_name, key_name FROM pg_tde_key_info();
17+
key_provider_id | key_provider_name | key_name
18+
-----------------+-------------------+-------------
19+
-3 | file-provider | test-db-key
20+
(1 row)
21+
22+
SELECT pg_tde_delete_key();
23+
pg_tde_delete_key
24+
-------------------
25+
26+
(1 row)
27+
28+
-- Set local key, encrypt a table, and delete the key
29+
-- Should fail: the is no default key to fallback
30+
SELECT pg_tde_set_key_using_global_key_provider('test-db-key','file-provider');
31+
pg_tde_set_key_using_global_key_provider
32+
------------------------------------------
33+
34+
(1 row)
35+
36+
CREATE TABLE test_table (id int, data text) USING tde_heap;
37+
SELECT pg_tde_delete_key();
38+
ERROR: cannot delete principal key
39+
DETAIL: There are encrypted tables in the database.
40+
HINT: Set default principal key as fallback option or decrypt all tables before deleting principal key.
41+
-- Decrypt the table and delete the key
42+
-- Should succeed: there is no more encrypted tables
43+
ALTER TABLE test_table SET ACCESS METHOD heap;
44+
SELECT pg_tde_delete_key();
45+
pg_tde_delete_key
46+
-------------------
47+
48+
(1 row)
49+
50+
-- Set local key, encrypt the table then delete teable and key
51+
-- Should succeed: the table is deleted and there are no more encrypted tables
52+
SELECT pg_tde_set_key_using_global_key_provider('test-db-key','file-provider');
53+
pg_tde_set_key_using_global_key_provider
54+
------------------------------------------
55+
56+
(1 row)
57+
58+
ALTER TABLE test_table SET ACCESS METHOD tde_heap;
59+
DROP TABLE test_table;
60+
SELECT pg_tde_delete_key();
61+
pg_tde_delete_key
62+
-------------------
63+
64+
(1 row)
65+
66+
-- Set default key, set regular key, create table, delete regular key
67+
-- Should succeed: regular key will be rotated to default key
68+
SELECT pg_tde_set_default_key_using_global_key_provider('defalut-key','file-provider');
69+
pg_tde_set_default_key_using_global_key_provider
70+
--------------------------------------------------
71+
72+
(1 row)
73+
74+
SELECT pg_tde_set_key_using_global_key_provider('test-db-key','file-provider');
75+
pg_tde_set_key_using_global_key_provider
76+
------------------------------------------
77+
78+
(1 row)
79+
80+
CREATE TABLE test_table (id int, data text) USING tde_heap;
81+
SELECT pg_tde_delete_key();
82+
pg_tde_delete_key
83+
-------------------
84+
85+
(1 row)
86+
87+
SELECT key_provider_id, key_provider_name, key_name FROM pg_tde_key_info();
88+
key_provider_id | key_provider_name | key_name
89+
-----------------+-------------------+-------------
90+
-3 | file-provider | defalut-key
91+
(1 row)
92+
93+
-- Try to delete key when default key is used
94+
-- Should fail: table already uses the default key, so there is no key to fallback to
95+
SELECT pg_tde_delete_key();
96+
ERROR: cannot delete principal key
97+
DETAIL: There are encrypted tables in the database.
98+
-- Try to delete default key
99+
-- Should fail: default key is used by the table
100+
SELECT pg_tde_delete_default_key();
101+
ERROR: cannot delete default principal key
102+
HINT: There are encrypted tables in the database with id: 16384.
103+
-- Set regular principal key, delete default key
104+
-- Should succeed: the table will use the regular key
105+
SELECT pg_tde_set_key_using_global_key_provider('test-db-key','file-provider');
106+
pg_tde_set_key_using_global_key_provider
107+
------------------------------------------
108+
109+
(1 row)
110+
111+
SELECT pg_tde_delete_default_key();
112+
pg_tde_delete_default_key
113+
---------------------------
114+
115+
(1 row)
116+
117+
DROP TABLE test_table;
118+
SELECT pg_tde_delete_key();
119+
pg_tde_delete_key
120+
-------------------
121+
122+
(1 row)
123+
124+
SELECT pg_tde_delete_global_key_provider('file-provider');
125+
pg_tde_delete_global_key_provider
126+
-----------------------------------
127+
128+
(1 row)
129+
130+
DROP EXTENSION pg_tde;

contrib/pg_tde/expected/key_provider.out

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ SELECT pg_tde_add_global_key_provider_file('file-keyring2','/tmp/pg_tde_test_key
7575
SELECT id, provider_name FROM pg_tde_list_all_global_key_providers();
7676
id | provider_name
7777
----+---------------
78-
-1 | file-keyring
79-
-2 | file-keyring2
78+
-4 | file-keyring
79+
-5 | file-keyring2
8080
(2 rows)
8181

8282
-- fails
@@ -105,8 +105,8 @@ SELECT id, provider_name FROM pg_tde_list_all_database_key_providers();
105105
SELECT id, provider_name FROM pg_tde_list_all_global_key_providers();
106106
id | provider_name
107107
----+---------------
108-
-1 | file-keyring
109-
-2 | file-keyring2
108+
-4 | file-keyring
109+
-5 | file-keyring2
110110
(2 rows)
111111

112112
SELECT pg_tde_set_key_using_global_key_provider('test-db-key', 'file-keyring', false);
@@ -121,8 +121,8 @@ ERROR: Can't delete a provider which is currently in use
121121
SELECT id, provider_name FROM pg_tde_list_all_global_key_providers();
122122
id | provider_name
123123
----+---------------
124-
-1 | file-keyring
125-
-2 | file-keyring2
124+
-4 | file-keyring
125+
-5 | file-keyring2
126126
(2 rows)
127127

128128
-- works
@@ -135,7 +135,7 @@ SELECT pg_tde_delete_global_key_provider('file-keyring2');
135135
SELECT id, provider_name FROM pg_tde_list_all_global_key_providers();
136136
id | provider_name
137137
----+---------------
138-
-1 | file-keyring
138+
-4 | file-keyring
139139
(1 row)
140140

141141
-- Creating a file key provider fails if we can't open or create the file

0 commit comments

Comments
 (0)