
pgaudit v19beta3
PostgreSQL-Audit-Erweiterung
pgAudit
Open-Source-Auditprotokollierung für PostgreSQL
Einführung
Die PostgreSQL-Audit-Erweiterung (pgAudit) bietet detaillierte Session- und/oder Objekt-Auditprotokollierung über die standardmäßige PostgreSQL-Protokollierungseinrichtung.
Das Ziel von pgAudit ist es, PostgreSQL-Benutzern die Möglichkeit zu geben, Audit-Logs zu erzeugen, die häufig erforderlich sind, um staatliche, finanzielle oder ISO-Zertifizierungen zu erfüllen.
Ein Audit ist eine offizielle Prüfung der Konten einer Person oder Organisation, in der Regel durch eine unabhängige Stelle. Die von pgAudit gesammelten Informationen werden korrekt als Audit-Trail oder Audit-Log bezeichnet. In dieser Dokumentation wird der Begriff Audit-Log verwendet.
Warum pgAudit?
Eine grundlegende Anweisungsprotokollierung kann mit der standardmäßigen Protokollierungseinrichtung über log_statement = all bereitgestellt werden. Dies ist für Überwachung und andere Zwecke akzeptabel, bietet jedoch nicht den Detailgrad, der für ein Audit allgemein erforderlich ist. Es reicht nicht aus, eine Liste aller an der Datenbank durchgeführten Operationen zu haben. Es muss auch möglich sein, bestimmte Anweisungen zu finden, die für einen Prüfer von Interesse sind. Die standardmäßige Protokollierungseinrichtung zeigt, was der Benutzer angefordert hat, während sich pgAudit auf die Details dessen konzentriert, was passiert ist, während die Datenbank die Anforderung ausgeführt hat.
Beispielsweise möchte ein Prüfer möglicherweise überprüfen, ob eine bestimmte Tabelle innerhalb eines dokumentierten Wartungsfensters erstellt wurde. Das scheint eine einfache Aufgabe für grep zu sein, aber was, wenn Ihnen ein Beispiel wie dieses (absichtlich verschleiert) präsentiert wird:
DO $$
BEGIN
EXECUTE 'CREATE TABLE import' || 'ant_table (id INT)';
END $$;
Die Standardprotokollierung liefert Ihnen Folgendes:
LOG: statement: DO $$
BEGIN
EXECUTE 'CREATE TABLE import' || 'ant_table (id INT)';
END $$;
Es scheint, dass das Auffinden der betreffenden Tabelle in Fällen, in denen Tabellen dynamisch erstellt werden, einige Kenntnisse des Codes erfordert. Das ist nicht ideal, da es vorzuziehen wäre, einfach nach dem Tabellennamen zu suchen. Hier kommt pgAudit ins Spiel. Für dieselbe Eingabe erzeugt es diese Ausgabe im Log:
AUDIT: SESSION,33,1,FUNCTION,DO,,,"DO $$
BEGIN
EXECUTE 'CREATE TABLE import' || 'ant_table (id INT)';
END $$;"
AUDIT: SESSION,33,2,DDL,CREATE TABLE,TABLE,public.important_table,CREATE TABLE important_table (id INT)
Nicht nur der DO-Block wird protokolliert, sondern Teilanweisung 2 enthält den vollständigen Text der CREATE TABLE mit Anweisungstyp, Objekttyp und voll qualifiziertem Namen, um die Suche zu erleichtern.
Beim Protokollieren von SELECT- und DML-Anweisungen kann pgAudit so konfiguriert werden, dass für jede in einer Anweisung referenzierte Relation ein separater Eintrag protokolliert wird. Es ist kein Parsing erforderlich, um alle Anweisungen zu finden, die eine bestimmte Tabelle betreffen. Tatsächlich ist das Ziel, dass der Anweisungstext in erster Linie für die Tiefenforensik bereitgestellt wird und für ein Audit nicht erforderlich sein sollte.
Nutzungshinweise
Abhängig von den Einstellungen kann pgAudit ein enormes Protokollvolumen erzeugen. Achten Sie darauf, genau zu bestimmen, was in Ihrer Umgebung audit-protokolliert werden muss, um eine übermäßige Protokollierung zu vermeiden.
Beispielsweise wäre es in einer OLAP-Umgebung wahrscheinlich nicht ratsam, Einfügungen in eine große Faktentabelle zu audit-protokollieren. Die Größe der Logdatei wird wahrscheinlich ein Vielfaches der tatsächlichen Datengröße der Einfügungen betragen, da die Logdatei als Text ausgegeben wird. Da Logs in der Regel zusammen mit dem Betriebssystem gespeichert werden, kann dies dazu führen, dass der Speicherplatz sehr schnell erschöpft ist. In Fällen, in denen die Auditprotokollierung nicht auf bestimmte Tabellen beschränkt werden kann, sollten Sie die Leistungsauswirkungen während des Testens bewerten und auf dem Log-Volume reichlich Platz einplanen. Dies kann auch für OLTP-Umgebungen gelten. Selbst wenn das Einfügevolumen nicht so hoch ist, kann die Leistungsbeeinträchtigung durch die Auditprotokollierung die Latenz dennoch spürbar beeinflussen.
Um die Anzahl der Relationen zu begrenzen, die für SELECT- und DML-Anweisungen audit-protokolliert werden, sollten Sie die Objekt-Auditprotokollierung in Betracht ziehen (siehe Objekt-Auditprotokollierung). Die Objekt-Auditprotokollierung ermöglicht die Auswahl der zu protokollierenden Relationen und damit eine Reduzierung des gesamten Logvolumens. Wenn jedoch neue Relationen hinzugefügt werden, müssen sie explizit in die Objekt-Auditprotokollierung aufgenommen werden. Eine programmatische Lösung, bei der bestimmte Tabellen von der Protokollierung ausgeschlossen und alle anderen einbezogen werden, kann in diesem Fall eine gute Option sein.
PostgreSQL-Versionskompatibilität
pgAudit unterstützt PostgreSQL 14 oder höher.
Um neue Funktionen zu unterstützen, die in jeder PostgreSQL-Version eingeführt werden, pflegt pgAudit einen separaten Branch für jede PostgreSQL-Hauptversion (derzeit PostgreSQL 14 - 19), der in ähnlicher Weise wie das PostgreSQL-Projekt gepflegt wird.
Abgesehen von Fehlerkorrekturen ist für stabile Branches keine weitere Entwicklung erlaubt. Neue Entwicklungen, sofern vorhanden, sind ausschließlich für die nächste unveröffentlichte Hauptversion von PostgreSQL vorgesehen.
Die pgAudit-Versionen verhalten sich zu den PostgreSQL-Hauptversionen wie folgt:
-
pgAudit v19.X ist für die Unterstützung von PostgreSQL 19 vorgesehen.
-
pgAudit v18.X ist für die Unterstützung von PostgreSQL 18 vorgesehen.
-
pgAudit v17.X ist für die Unterstützung von PostgreSQL 17 vorgesehen.
-
pgAudit v16.X ist für die Unterstützung von PostgreSQL 16 vorgesehen.
-
pgAudit v1.7.X ist für die Unterstützung von PostgreSQL 15 vorgesehen.
-
pgAudit v1.6.X ist für die Unterstützung von PostgreSQL 14 vorgesehen.
Kompilieren und Installieren
pgAudit kann mit den Entwicklungspaketen mithilfe von PGXS gegen eine installierte Kopie von PostgreSQL kompiliert werden. Die folgenden Anweisungen sollten auf den meisten Unix-ähnlichen Betriebssystemen funktionieren.
Klonen Sie die pgAudit-Erweiterung:
git clone https://github.com/pgaudit/pgaudit.git
Wechseln Sie in das pgAudit-Verzeichnis:
cd pgaudit
Checken Sie den Branch REL_19_STABLE aus (beachten Sie, dass der stabile Branch für unveröffentlichte Versionen von PostgreSQL möglicherweise nicht existiert):
git checkout REL_19_STABLE
Kompilieren und installieren Sie pgAudit:
make install USE_PGXS=1 PG_CONFIG=/usr/pgsql-19/bin/pg_config
Anweisungen für Tests und Entwicklung finden Sie in test.
Einstellungen
Einstellungen dürfen nur von einem Superuser geändert werden. Wenn normale Benutzer ihre Einstellungen ändern könnten, würde das den Zweck eines Audit-Logs zunichtemachen.
Einstellungen können global (in postgresql.conf oder mit ALTER SYSTEM ... SET), auf Datenbankebene (mit ALTER DATABASE ... SET) oder auf Rollenebene (mit ALTER ROLE ... SET) angegeben werden. Beachten Sie, dass Einstellungen nicht über die normale Rollenvererbung vererbt werden und SET ROLE die pgAudit-Einstellungen eines Benutzers nicht ändert. Dies ist eine Einschränkung des Rollensystems und nicht auf pgAudit selbst zurückzuführen.
Die pgAudit-Erweiterung muss in shared_preload_libraries geladen werden. Andernfalls wird beim Laden ein Fehler ausgelöst und es findet keine Auditprotokollierung statt.
Darüber hinaus muss CREATE EXTENSION pgaudit aufgerufen werden, bevor pgaudit.log gesetzt wird, um die ordnungsgemäße pgAudit-Funktionalität sicherzustellen. Die Erweiterung installiert Event-Trigger, die eine zusätzliche Auditierung für DDL hinzufügen. pgAudit funktioniert auch ohne installierte Erweiterung, aber DDL-Anweisungen enthalten dann keine Informationen über Objekttyp und -namen.
Wenn die Erweiterung pgaudit entfernt und neu erstellt werden muss, muss zuerst pgaudit.log zurückgesetzt werden, andernfalls wird ein Fehler ausgelöst.
pgaudit.log
Gibt an, welche Klassen von Anweisungen von der Session-Auditprotokollierung protokolliert werden. Mögliche Werte sind:
-
READ:
SELECTundCOPY, wenn die Quelle eine Relation oder eine Abfrage ist. -
WRITE:
INSERT,UPDATE,DELETE,TRUNCATEundCOPY, wenn das Ziel eine Relation ist. -
FUNCTION: Funktionsaufrufe und
DO-Blöcke. -
ROLE: Anweisungen, die sich auf Rollen und Privilegien beziehen:
GRANT,REVOKE,CREATE/ALTER/DROP ROLE. -
DDL: Das gesamte
DDL, das nicht in der KlasseROLEenthalten ist. -
MISC: Sonstige Befehle, z. B.
DISCARD,FETCH,CHECKPOINT,VACUUM,SET. -
MISC_SET: Sonstige
SET-Befehle, z. B.SET ROLE. -
ALL: Alle oben genannten einschließen.
Mehrere Klassen können als kommagetrennte Liste angegeben werden, und Klassen können subtrahiert werden, indem der Klasse ein --Zeichen vorangestellt wird (siehe Session-Auditprotokollierung).
Der Standardwert ist none.
pgaudit.log_catalog
Gibt an, dass die Session-Protokollierung für den Fall aktiviert werden soll, dass sich alle Relationen in einer Anweisung in pg_catalog befinden. Das Deaktivieren dieser Einstellung reduziert das Rauschen im Log durch Tools wie psql und PgAdmin, die das Katalog stark abfragen.
Der Standardwert ist on.
pgaudit.log_client
Gibt an, ob Logmeldungen für einen Client-Prozess wie psql sichtbar sind. Diese Einstellung sollte in der Regel deaktiviert bleiben, kann aber für Debugging oder andere Zwecke nützlich sein.
Beachten Sie, dass pgaudit.log_level nur aktiviert ist, wenn pgaudit.log_client auf on gesetzt ist.
Der Standardwert ist off.
pgaudit.log_level
Gibt die Protokollebene an, die für Logeinträge verwendet wird (siehe Schweregrade von Meldungen für gültige Ebenen); beachten Sie jedoch, dass ERROR, FATAL und PANIC nicht zulässig sind. Diese Einstellung wird für Regressionstests verwendet und kann auch für Endbenutzer zu Test- oder anderen Zwecken nützlich sein.
Beachten Sie, dass pgaudit.log_level nur aktiviert ist, wenn pgaudit.log_client auf on gesetzt ist; andernfalls wird der Standardwert verwendet.
Der Standardwert ist log.
pgaudit.log_parameter
Gibt an, dass die Auditprotokollierung die Parameter enthalten soll, die mit der Anweisung übergeben wurden. Wenn Parameter vorhanden sind, werden sie im CSV-Format nach dem Anweisungstext aufgenommen.
Der Standardwert ist off.
pgaudit.log_parameter_max_size
Gibt an, dass Parameterwerte, die länger als diese Einstellung (in Bytes) sind, nicht protokolliert, sondern durch <long param suppressed> ersetzt werden sollen. Diese Einstellung wird in Bytes und nicht in Zeichen angegeben und berücksichtigt daher keine Mehrbyte-Zeichen in der Kodierung eines Textparameters. Diese Einstellung hat keine Wirkung, wenn log_parameter auf off gesetzt ist. Wenn diese Einstellung 0 ist (der Standardwert), werden alle Parameter unabhängig von ihrer Länge protokolliert.
Der Standardwert ist 0.
pgaudit.log_relation
Gibt an, ob die Session-Auditprotokollierung für jede Relation (TABLE, VIEW usw.), die in einer SELECT- oder DML-Anweisung referenziert wird, einen separaten Logeintrag erstellen soll. Dies ist eine nützliche Abkürzung für eine vollständige Protokollierung ohne Verwendung der Objekt-Auditprotokollierung.
Der Standardwert ist off.
pgaudit.log_rows
Gibt an, dass die Auditprotokollierung die Anzahl der von einer Anweisung abgerufenen oder betroffenen Zeilen enthalten soll. Wenn diese Einstellung aktiviert ist, wird das Feld „rows“ nach dem Parameterfeld aufgenommen.
Der Standardwert ist off.
pgaudit.log_statement
Gibt an, ob die Protokollierung den Anweisungstext und die Parameter (sofern aktiviert) enthalten soll. Je nach Anforderungen benötigt ein Audit-Log dies möglicherweise nicht, und es macht die Logs weniger ausführlich.
Der Standardwert ist on.
pgaudit.log_statement_once
Gibt an, ob die Protokollierung den Anweisungstext und die Parameter mit dem ersten Logeintrag für eine Anweisungs-/Teilanweisungskombination oder mit jedem Eintrag enthalten soll. Das Aktivieren dieser Einstellung führt zu einer weniger ausführlichen Protokollierung, kann es jedoch erschweren, die Anweisung zu ermitteln, die einen Logeintrag erzeugt hat, obwohl das Anweisungs-/Teilanweisungspaar zusammen mit der Prozess-ID ausreichen sollte, um den mit einem früheren Eintrag protokollierten Anweisungstext zu identifizieren.
Der Standardwert ist off.
pgaudit.role
Gibt die Master-Rolle für die Objekt-Auditprotokollierung an. Mehrere Audit-Rollen können definiert werden, indem sie der Master-Rolle zugewiesen werden. So können mehrere Gruppen für verschiedene Aspekte der Auditprotokollierung zuständig sein.
Es gibt keinen Standardwert.
Session-Auditprotokollierung
Die Session-Auditprotokollierung erstellt detaillierte Logs aller Anweisungen, die von einem Benutzer im Backend ausgeführt werden.
Konfiguration
Die Session-Protokollierung wird mit der Einstellung pgaudit.log aktiviert.
Aktivieren Sie die Session-Protokollierung für das gesamte DML und DDL und protokollieren Sie alle Relationen in DML-Anweisungen:
set pgaudit.log = 'write, ddl';
set pgaudit.log_relation = on;
Aktivieren Sie die Session-Protokollierung für alle Befehle außer MISC und geben Sie Audit-Logmeldungen als NOTICE aus:
set pgaudit.log = 'all, -misc';
set pgaudit.log_level = notice;
Beispiel
In diesem Beispiel wird die Session-Auditprotokollierung für die Protokollierung von DDL- und SELECT-Anweisungen verwendet. Beachten Sie, dass die INSERT-Anweisung nicht protokolliert wird, da die Klasse WRITE nicht aktiviert ist.
SQL:
set pgaudit.log = 'read, ddl';
create table account
(
id int,
name text,
password text,
description text
);
insert into account (id, name, password, description)
values (1, 'user1', 'HASH1', 'blah, blah');
select *
from account;
Log-Ausgabe:
AUDIT: SESSION,1,1,DDL,CREATE TABLE,TABLE,public.account,create table account
(
id int,
name text,
password text,
description text
);,<not logged>
AUDIT: SESSION,2,1,READ,SELECT,,,select *
from account,,<not logged>
Objekt-Auditprotokollierung
Die Objekt-Auditprotokollierung protokolliert Anweisungen, die eine bestimmte Relation betreffen. Es werden nur die Befehle SELECT, INSERT, UPDATE und DELETE unterstützt. TRUNCATE ist nicht in der Objekt-Auditprotokollierung enthalten.
Die Objekt-Auditprotokollierung ist als feiner granulierte Alternative zu pgaudit.log = 'read, write' gedacht. Daher ist es möglicherweise nicht sinnvoll, beide gleichzeitig zu verwenden. Ein mögliches Szenario wäre jedoch, die Session-Protokollierung zu verwenden, um jede Anweisung zu erfassen, und diese dann durch die Objektprotokollierung zu ergänzen, um weitere Details zu bestimmten Relationen zu erhalten.
Konfiguration
Die Objekt-Auditprotokollierung wird über das Rollensystem implementiert. Die Einstellung pgaudit.role definiert die Rolle, die für die Auditprotokollierung verwendet wird. Eine Relation (TABLE, VIEW usw.) wird audit-protokolliert, wenn die Audit-Rolle über Berechtigungen für den ausgeführten Befehl verfügt oder die Berechtigungen von einer anderen Rolle erbt. Dadurch können Sie effektiv mehrere Audit-Rollen haben, obwohl es in jedem Kontext nur eine Master-Rolle gibt.
Setzen Sie pgaudit.role auf auditor und erteilen Sie die Berechtigungen SELECT und DELETE für die Tabelle account. Alle SELECT- oder DELETE-Anweisungen auf der Tabelle account werden nun protokolliert:
set pgaudit.role = 'auditor';
grant select, delete
on public.account
to auditor;
Beispiel
In diesem Beispiel wird die Objekt-Auditprotokollierung verwendet, um zu veranschaulichen, wie ein granulärer Ansatz für die Protokollierung von SELECT- und DML-Anweisungen gewählt werden kann. Beachten Sie, dass die Protokollierung der Tabelle account über Berechtigungen auf Spaltenebene gesteuert wird, während die Protokollierung der Tabelle account_role_map auf Tabellenebene erfolgt.
SQL:
set pgaudit.role = 'auditor';
create table account
(
id int,
name text,
password text,
description text
);
grant select (password)
on public.account
to auditor;
select id, name
from account;
select password
from account;
grant update (name, password)
on public.account
to auditor;
update account
set description = 'yada, yada';
update account
set password = 'HASH2';
create table account_role_map
(
account_id int,
role_id int
);
grant select
on public.account_role_map
to auditor;
select account.password,
account_role_map.role_id
from account
inner join account_role_map
on account.id = account_role_map.account_id
Log-Ausgabe:
AUDIT: OBJECT,1,1,READ,SELECT,TABLE,public.account,select password
from account,<not logged>
AUDIT: OBJECT,2,1,WRITE,UPDATE,TABLE,public.account,update account
set password = 'HASH2',<not logged>
AUDIT: OBJECT,3,1,READ,SELECT,TABLE,public.account,select account.password,
account_role_map.role_id
from account
inner join account_role_map
on account.id = account_role_map.account_id,<not logged>
AUDIT: OBJECT,3,1,READ,SELECT,TABLE,public.account_role_map,select account.password,
account_role_map.role_id
from account
inner join account_role_map
on account.id = account_role_map.account_id,<not logged>
Format
Audit-Einträge werden über die standardmäßige Protokollierungseinrichtung geschrieben und enthalten die folgenden Spalten im kommagetrennten Format. Die Ausgabe entspricht nur dann dem CSV-Format, wenn der Log-Zeilenpräfix-Teil jedes Logeintrags entfernt wird.
-
AUDIT_TYPE -
SESSIONoderOBJECT. -
STATEMENT_ID - Eindeutige Anweisungs-ID für diese Session. Jede Anweisungs-ID stellt einen Backend-Aufruf dar. Die Anweisungs-IDs sind fortlaufend, auch wenn einige Anweisungen nicht protokolliert werden. Es kann mehrere Einträge für eine Anweisungs-ID geben, wenn mehr als eine Relation protokolliert wird.
-
SUBSTATEMENT_ID - Fortlaufende ID für jede Teilanweisung innerhalb der Hauptanweisung. Zum Beispiel das Aufrufen einer Funktion aus einer Abfrage. Die IDs der Teilanweisungen sind fortlaufend, auch wenn einige Teilanweisungen nicht protokolliert werden. Es kann mehrere Einträge für eine Teilanweisungs-ID geben, wenn mehr als eine Relation protokolliert wird.
-
CLASS - z. B.
READ,ROLE(siehe pgaudit.log). -
COMMAND - z. B.
ALTER TABLE,SELECT. -
OBJECT_TYPE -
TABLE,INDEX,VIEWusw. Verfügbar fürSELECT-,DML- und die meistenDDL-Anweisungen. -
OBJECT_NAME - Der voll qualifizierte Objektname (z. B. public.account). Verfügbar für
SELECT-,DML- und die meistenDDL-Anweisungen. -
STATEMENT - Die auf dem Backend ausgeführte Anweisung.
-
PARAMETER - Wenn
pgaudit.log_parametergesetzt ist, enthält dieses Feld die Anweisungsparameter im CSV-Format mit Anführungszeichen oder<none>, wenn keine Parameter vorhanden sind. Andernfalls ist das Feld<not logged>.
Verwenden Sie log_line_prefix, um alle weiteren Felder hinzuzufügen, die zur Erfüllung Ihrer Audit-Log-Anforderungen benötigt werden. Ein typischer Log-Zeilenpräfix könnte '%m %u %d [%p]: ' sein, der Datum/Uhrzeit, Benutzername, Datenbankname und Prozess-ID für jedes Audit-Log liefert.
Einschränkungen
Die Auditprotokollierung erfolgt nach dem Best-Effort-Prinzip und ist nicht transaktional. pgAudit schreibt Audit-Einträge über die standardmäßige PostgreSQL-Protokollierungseinrichtung, die jeden Eintrag nicht synchron mit der Transaktion, die ihn erzeugt hat, auf die Festplatte schreibt und auch keine Schreibfehler an die Session zurückmeldet. Es gibt keine Garantie, dass eine festgeschriebene Transaktion einen entsprechenden Audit-Logeintrag hat. Wenn der Server abstürzt oder die Stromversorgung ausfällt oder das Log-Ziel nicht mehr verfügbar ist (z. B. weil das Log-Volume voll ist), nachdem eine Transaktion festgeschrieben wurde, aber bevor ihre Audit-Einträge dauerhaft geschrieben wurden, können diese Einträge verloren gehen. Umgekehrt wird eine Anweisung protokolliert, wenn sie ausgeführt wird, sodass ein Eintrag auch dann geschrieben werden kann, wenn seine Transaktion später zurückgerollt wird.
Objektumbenennungen werden unter dem Namen protokolliert, in den sie umbenannt wurden. Zum Beispiel erzeugt das Umbenennen einer Tabelle das folgende Ergebnis:
ALTER TABLE test RENAME TO test2;
AUDIT: SESSION,36,1,DDL,ALTER TABLE,TABLE,public.test2,ALTER TABLE test RENAME TO test2,<not logged>
Es ist möglich, dass ein Befehl mehr als einmal protokolliert wird. Wenn beispielsweise eine Tabelle mit einem zum Erstellungszeitpunkt angegebenen Primärschlüssel erstellt wird, wird der Index für den Primärschlüssel unabhängig protokolliert, und für den Index wird unter dem Erstellungseintrag ein weiteres Audit-Log erstellt. Die mehreren Einträge sind jedoch in einer Anweisungs-ID enthalten.
Autovacuum und Autoanalyze werden nicht protokolliert.
Anweisungen, die ausgeführt werden, nachdem eine Transaktion in einen abgebrochenen Zustand übergegangen ist, werden nicht audit-protokolliert. Die Anweisung, die den Fehler verursacht hat, sowie alle nachfolgenden Anweisungen, die in der abgebrochenen Transaktion ausgeführt werden, werden jedoch von der standardmäßigen Protokollierungseinrichtung als ERRORs protokolliert.
Es ist nicht möglich, Superuser mit pgAudit zuverlässig zu auditieren. Eine Lösung besteht darin, den Zugriff auf Superuser-Konten zu beschränken und die set_user-Erweiterung zu verwenden, um bei Bedarf Berechtigungen zu erhöhen.
Autoren
Die PostgreSQL-Audit-Erweiterung basiert auf dem 2ndQuadrant pgaudit-Projekt, das von Simon Riggs, Abhijit Menon-Sen und Ian Barwick verfasst und als Erweiterung an den PostgreSQL-Kern eingereicht wurde. Weitere Entwicklungsarbeit wurde von David Steele von Crunchy Data geleistet.