Quick Start

A Postgres extension for Transparent Column Encryption (TCE) with the following objectives:
- Fully Open-source, No Open-Core version, No Vendor Lock-in
- Support of all major versions of Postgres, No Fork needed
- Encrypt data in memory ( i.e. "data in use" encryption )
- Use Envelop Encryption to protect the Data Encryption Key (DEK)
- Store the Key Encryption Keys (KEK) in an external KMS
- Easy and fast key rotations
This extension is developed in Rust and relies heavily on Rust Crypto libraries.
DISCLAIMER: This is an early working version. As we're moving towards a beta version in the forthcoming months we may introduce breaking changes or revert some features at any time. See CONTRIBUTING.md for more details on how to help this project.
DO NOT USE IN PRODUCTION.
Sponsors
This project is sponsored by the following partners
We are open to other entities wishing to join us in this collaborative effort. Check out our Development Partners Program for more details on how to contribute!
Purpose
If you’re asking whether this extension is for you, it probably isn’t :-)
This extension is designed for database subject to very strict data protection regulations such as DORA and PCI DSS. It aims at implementing encryption of "data in use" for PostgreSQL as a complement to the classic "encryption at rest" approach.
If these regulations don't apply to your context, congratulations ! You can ignore this project and implement some basic disk-level or filesystem-level encryption, which is most certainly good enough for your Postgres instances.
See why for a detailed analysis.
Features
- Chacha20Poly1350 encryption for data and envelope keys
- RSA PKCS8 to cipher/decipher envelope keys
- Amazon KMS support
- OpenBao support
- KMIP protocol support (not yet implemented)
- OVH KMS HTTP API support
- Encrypted types:
tcetext,tceint,tcedate,tcebytea
Preconditions
The following conditions must be true for the extension to function correctly:
- The system administrators are trusted
- The postgres superusers are trusted
Install
ALTER DATABASE demo SET session_preload_libraries TO tce;
\connect demo
CREATE EXTENSION IF NOT EXISTS tce;
Configure
-- Storing private key on server disk is unsecure and may expose it.
-- Enable this **FOR TESTING PURPOSE ONLY**
SET tce.allow_unsecured_key_fetch_methods to TRUE;
-- 1. A superuser creates the DEK by sealing their own envelope.
-- This creates a ciphered envelope containing the DEK.
-- Envelope keys are unique per role and they are encrypted using
-- a user's personal RSA key pair.
--
-- This RSA key can be generated using either:
-- `openssl genrsa -out /some/directory/admin_private_rsa.key 2048`
-- `ssh-keygen -t rsa -m PKCS8 -f /some/directory/admin_private_rsa.key`
-- The caller must be a superuser, and tce.envelope must be empty.
-- The envelope is sealed for current_user.
SELECT * FROM tce.init_envelope(
'FETCHED FROM FILE /some/directory/admin_private_rsa.key'
);
-- 2. create a standard role
CREATE ROLE alice LOGIN;
-- 3. The administrator shares the DEK with this new role.
-- This opens the administrator's envelope and seals the same DEK with alice's key.
SELECT * FROM tce.generate_envelope(
'FETCHED FROM FILE /some/directory/alice_private_rsa.key',
'alice'
);
NOTICE: The key descriptor is stored in tce.envelope next to the envelope it
sealed. GUC settings can be visible to unprivileged users and can appear in
dumps depending on the utility and parameters employed.
Explicit Column Encryption
\connect demo alice
-- Given a classic table
CREATE TABLE spies (
code TEXT,
realname TEXT
);
INSERT INTO spies VALUES ('007','James Bond'), ('H21','Mata Hari');
-- Convert to TEXT column into a TCETEXT column
ALTER TABLE spies
ALTER COLUMN realname
TYPE TCETEXT
USING realname::TCETEXT;
--
-- Enjoy !
--
-- The data is now encrypted on disk
-- and displayed in plain text to all users having the secret key
--
SET tce.show_raw TO TRUE;
SELECT realname, raw(realname) FROM spies;
realname | raw
-------------+----------------------------------------------
James Bond | \x34bebe556560e7fdd4abb441fcb537b7b8c0d67733
Mata Hari | \x37bdb54762699534529bb40655fb01232e6f12
(2 rows)
Transparent Column Encryption
ALTER DATABASE demo SET tce.transparent_column_encryption TO TRUE;
\connect demo alice
-- Create the table AFTER tce is enabled
CREATE TABLE person (
id SERIAL,
firstname VARCHAR(100),
credit_card INTEGER
);
INSERT INTO person VALUES (1,'Bernard',1234567890), (2,'Bob',1234567890);
SELECT firstname, credit_card, raw(credit_card) FROM person;
firstname | credit_card | raw
-----------+-------------+-------------------------------------------------------
Bernard | 1234567890 | 3923619818820789153246812041148227241194201238
Bob | 1234567890 | 16910846692501417132462151191111121924510524618918198
User Key Rotation
Over time, the superuser may want to change the user's key.
tce.generate_envelope replaces the envelope and seals the same DEK with a new
key descriptor. tce.rotate_envelope seals a new envelope with the descriptor
already stored for that role. The DEK does not change.
SELECT * FROM tce.generate_envelope(
'FETCHED FROM FILE /some/directory/some_rsa_private.key',
'alice'
);
-- A few moments later…
SELECT * FROM tce.generate_envelope(
'HOSTED ON KMS USING alias/alice_key',
'alice'
);
NOTICE: The change applies to new sessions only. Terminate the user's current sessions to enforce immediate revocation.
Demo
Build
- Install PGRX
https://github.com/pgcentralfoundation/pgrx/blob/develop/README.md
- Build and Run
- Tests



