Skip to content

Quick Start

The Cryptic Elephant

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
  • OVH KMS HTTP API support
  • KMIP protocol support (not yet implemented)

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. Administrator must create a DEK to share with other roles.
-- 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`
SECURITY LABEL FOR tce_user_key ON ROLE admin
  IS 'FETCHED FROM FILE /some/directory/admin_private_rsa.key';

-- 2. create a standard role
CREATE ROLE alice LOGIN;

-- 3. Administrator can share the DEK with this new role.
-- This deciphers the administrator's DEK envelope and creates a new envelope
-- using alice's key.
SECURITY LABEL FOR tce_user_key ON ROLE alice
  IS 'FETCHED FROM FILE /some/directory/alice_private_rsa.key';

NOTICE: The configuration, specifically security labels and GUC settings, is accessible to unprivileged users. It can also 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.

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';

-- A few moments later…

SECURITY LABEL FOR tce_user_key ON ROLE alice
  IS 'HOSTED ON KMS USING alias/alice_key';

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