Skip to content

The Cryptic Elephant (TCE)

A Postgres extension for Transparent Column Encryption 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.

Danger

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.

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 the why chapter for a detailed analysis.

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

CREATE ROLE alice LOGIN;

-- Enable this FOR TESTING PURPOSE ONLY
SET tce.enable_fetch_from_file TO TRUE;

SECURITY LABEL FOR tce_user_key ON ROLE alice
  IS 'FETCHED FROM FILE /some/directory/alice_private_rsa_key.pem';

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.

This is done simply by modifying the fetchkey method to point to another key.

SECURITY LABEL FOR tce_user_key ON ROLE alice
  IS 'FETCHED FROM FILE /some/directory/some_rsa_private_key.pem';

-- A few moments later....

SECURITY LABEL FOR tce_user_key ON ROLE alice
  IS 'FETCHED FROM FILE /some/directory/another_rsa_private_key.pem';

NOTICE: The change applies to new sessions only. Terminate the user's current sessions to enforce immediate revocation.

Demo

make demo

Build

  1. Install PGRX

https://github.com/pgcentralfoundation/pgrx/blob/develop/README.md

  1. Build and Run
cargo pgrx run
  1. Tests
cargo pgrx test
cargo pgrx regress