Skip to content

Commit 01978ef

Browse files
authored
feat: reland vault w/o pgsodium (#1452)
* Reapply "feat: vault sans pgsodium" This reverts commit 447f449. * chore: update schema snapshots * chore: print regress diffs for easier debugging * chore: remove pgsodium priv checks * fix: move it out of if else * chore: bump version * chore: bump version
1 parent 70657e2 commit 01978ef

File tree

17 files changed

+149
-271
lines changed

17 files changed

+149
-271
lines changed

Diff for: ansible/files/admin_api_scripts/pg_upgrade_scripts/complete.sh

+37
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,43 @@ EOF
152152
run_sql -c "update pg_extension set extowner = 'postgres'::regrole where extname = 'pgmq';"
153153
fi
154154

155+
# Patch to handle upgrading to pgsodium-less Vault
156+
REENCRYPT_VAULT_SECRETS_QUERY=$(cat <<EOF
157+
DO \$\$
158+
BEGIN
159+
IF EXISTS (SELECT FROM pg_available_extension_versions WHERE name = 'supabase_vault' AND version = '0.3.0')
160+
AND EXISTS (SELECT FROM pg_extension WHERE extname = 'supabase_vault')
161+
THEN
162+
IF (SELECT extversion FROM pg_extension WHERE extname = 'supabase_vault') != '0.2.8' THEN
163+
GRANT USAGE ON SCHEMA vault TO postgres WITH GRANT OPTION;
164+
GRANT SELECT, DELETE ON vault.secrets, vault.decrypted_secrets TO postgres WITH GRANT OPTION;
165+
GRANT EXECUTE ON FUNCTION vault.create_secret, vault.update_secret, vault._crypto_aead_det_decrypt TO postgres WITH GRANT OPTION;
166+
END IF;
167+
-- Do an explicit IF EXISTS check to avoid referencing pgsodium objects if the project already migrated away from using pgsodium.
168+
IF EXISTS (SELECT FROM vault.secrets WHERE key_id IS NOT NULL) THEN
169+
UPDATE vault.secrets s
170+
SET
171+
secret = encode(
172+
vault._crypto_aead_det_encrypt(
173+
message := pgsodium.crypto_aead_det_decrypt(decode(s.secret, 'base64'), convert_to(s.id || s.description || s.created_at || s.updated_at, 'utf8'), s.key_id, s.nonce),
174+
additional := convert_to(s.id::text, 'utf8'),
175+
key_id := 0,
176+
context := 'pgsodium'::bytea,
177+
nonce := s.nonce
178+
),
179+
'base64'
180+
),
181+
key_id = NULL
182+
WHERE
183+
key_id IS NOT NULL;
184+
END IF;
185+
END IF;
186+
END
187+
\$\$;
188+
EOF
189+
)
190+
run_sql -c "$REENCRYPT_VAULT_SECRETS_QUERY"
191+
155192
run_sql -c "grant pg_read_all_data, pg_signal_backend to postgres"
156193
}
157194

Diff for: ansible/files/postgresql_config/postgresql.conf.j2

+1-1
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,7 @@ default_text_search_config = 'pg_catalog.english'
688688
#local_preload_libraries = ''
689689
#session_preload_libraries = ''
690690

691-
shared_preload_libraries = 'pg_stat_statements, pgaudit, plpgsql, plpgsql_check, pg_cron, pg_net, pgsodium, timescaledb, auto_explain, pg_tle, plan_filter' # (change requires restart)
691+
shared_preload_libraries = 'pg_stat_statements, pgaudit, plpgsql, plpgsql_check, pg_cron, pg_net, pgsodium, timescaledb, auto_explain, pg_tle, plan_filter, supabase_vault' # (change requires restart)
692692
jit_provider = 'llvmjit' # JIT library to use
693693

694694
# - Other Defaults -
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
grant usage on schema vault to postgres with grant option;
2+
grant select, delete on vault.secrets, vault.decrypted_secrets to postgres with grant option;
3+
grant execute on function vault.create_secret, vault.update_secret, vault._crypto_aead_det_decrypt to postgres with grant option;

Diff for: ansible/files/sodium_extension.sql

-6
This file was deleted.

Diff for: ansible/tasks/test-image.yml

+20-3
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,34 @@
1111
# cmd: sed -i.bak -e "s/pg_net,\ pgsodium,\ timescaledb/pg_net,\ timescaledb/g" -e "s/pgsodium.getkey_script=/#pgsodium.getkey_script=/g" /etc/postgresql/postgresql.conf
1212
# when: debpkg_mode or stage2_nix
1313

14-
- name: Temporarily disable PG Sodium references in config
14+
- name: Temporarily disable PG Sodium and Supabase Vault references in config
1515
become: yes
1616
become_user: postgres
1717
shell:
1818
cmd: >
19-
sed -i.bak
20-
-e 's/\(shared_preload_libraries = '\''.*\)pgsodium,\(.*'\''\)/\1\2/'
19+
sed -i.bak
20+
-e 's/\(shared_preload_libraries = '\''.*\)pgsodium,\(.*'\''\)/\1\2/'
21+
-e 's/\(shared_preload_libraries = '\''.*\)supabase_vault,\(.*'\''\)/\1\2/'
22+
-e 's/\(shared_preload_libraries = '\''.*\), *supabase_vault'\''/\1'\''/'
2123
-e 's/pgsodium.getkey_script=/#pgsodium.getkey_script=/'
2224
/etc/postgresql/postgresql.conf
2325
when: debpkg_mode or stage2_nix
2426

27+
- name: Verify pgsodium and vault removal from config
28+
become: yes
29+
become_user: postgres
30+
shell:
31+
cmd: |
32+
FOUND=$(grep -E "shared_preload_libraries.*pgsodium|shared_preload_libraries.*supabase_vault|^pgsodium\.getkey_script" /etc/postgresql/postgresql.conf)
33+
if [ ! -z "$FOUND" ]; then
34+
echo "Found unremoved references:"
35+
echo "$FOUND"
36+
exit 1
37+
fi
38+
register: verify_result
39+
failed_when: verify_result.rc != 0
40+
when: debpkg_mode or stage2_nix
41+
2542
- name: Start Postgres Database to load all extensions.
2643
become: yes
2744
become_user: postgres

Diff for: ansible/vars.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ postgres_major:
88

99
# Full version strings for each major version
1010
postgres_release:
11-
postgresorioledb-17: "17.0.1.049-orioledb"
12-
postgres15: "15.8.1.056"
11+
postgresorioledb-17: "17.0.1.050-orioledb"
12+
postgres15: "15.8.1.057"
1313

1414
# Non Postgres Extensions
1515
pgbouncer_release: "1.19.0"

Diff for: ebssurrogate/files/unit-tests/unit-test-01.sql

+2-8
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ BEGIN
1717
extension_array := ARRAY[
1818
'plpgsql',
1919
'pg_stat_statements',
20-
'pgsodium',
2120
'pgtap',
2221
'pg_graphql',
2322
'pgcrypto',
@@ -30,7 +29,6 @@ BEGIN
3029
extension_array := ARRAY[
3130
'plpgsql',
3231
'pg_stat_statements',
33-
'pgsodium',
3432
'pgtap',
3533
'pg_graphql',
3634
'pgcrypto',
@@ -44,7 +42,7 @@ BEGIN
4442
PERFORM set_config('myapp.extensions', array_to_string(extension_array, ','), false);
4543
END $$;
4644

47-
SELECT plan(8);
45+
SELECT no_plan();
4846

4947
SELECT extensions_are(
5048
string_to_array(current_setting('myapp.extensions'), ',')::text[]
@@ -56,9 +54,5 @@ SELECT has_schema('pg_catalog');
5654
SELECT has_schema('information_schema');
5755
SELECT has_schema('public');
5856

59-
SELECT function_privs_are('pgsodium', 'crypto_aead_det_decrypt', array['bytea', 'bytea', 'uuid', 'bytea'], 'service_role', array['EXECUTE']);
60-
SELECT function_privs_are('pgsodium', 'crypto_aead_det_encrypt', array['bytea', 'bytea', 'uuid', 'bytea'], 'service_role', array['EXECUTE']);
61-
SELECT function_privs_are('pgsodium', 'crypto_aead_det_keygen', array[]::text[], 'service_role', array['EXECUTE']);
62-
6357
SELECT * FROM finish();
64-
ROLLBACK;
58+
ROLLBACK;

Diff for: flake.nix

+44-34
Original file line numberDiff line numberDiff line change
@@ -606,42 +606,49 @@
606606
sqlTests = ./nix/tests/smoke;
607607
pg_prove = pkgs.perlPackages.TAPParserSourceHandlerpgTAP;
608608
pg_regress = basePackages.pg_regress;
609-
getkey-script = pkgs.writeScriptBin "pgsodium-getkey" ''
610-
#!${pkgs.bash}/bin/bash
611-
set -euo pipefail
612-
613-
TMPDIR_BASE=$(mktemp -d)
614-
615-
if [[ "$(uname)" == "Darwin" ]]; then
616-
KEY_DIR="/private/tmp/pgsodium"
617-
else
618-
KEY_DIR="''${PGSODIUM_KEY_DIR:-$TMPDIR_BASE/pgsodium}"
619-
fi
620-
KEY_FILE="$KEY_DIR/pgsodium.key"
621-
622-
if ! mkdir -p "$KEY_DIR" 2>/dev/null; then
623-
echo "Error: Could not create key directory $KEY_DIR" >&2
624-
exit 1
625-
fi
626-
chmod 1777 "$KEY_DIR"
627-
628-
if [[ ! -f "$KEY_FILE" ]]; then
629-
if ! (dd if=/dev/urandom bs=32 count=1 2>/dev/null | od -A n -t x1 | tr -d ' \n' > "$KEY_FILE"); then
630-
if ! (openssl rand -hex 32 > "$KEY_FILE"); then
631-
echo "00000000000000000000000000000000" > "$KEY_FILE"
632-
echo "Warning: Using fallback key" >&2
609+
getkey-script = pkgs.stdenv.mkDerivation {
610+
name = "pgsodium-getkey";
611+
buildCommand = ''
612+
mkdir -p $out/bin
613+
cat > $out/bin/pgsodium-getkey << 'EOF'
614+
#!${pkgs.bash}/bin/bash
615+
set -euo pipefail
616+
617+
TMPDIR_BASE=$(mktemp -d)
618+
619+
if [[ "$(uname)" == "Darwin" ]]; then
620+
KEY_DIR="/private/tmp/pgsodium"
621+
else
622+
KEY_DIR="''${PGSODIUM_KEY_DIR:-$TMPDIR_BASE/pgsodium}"
623+
fi
624+
KEY_FILE="$KEY_DIR/pgsodium.key"
625+
626+
if ! mkdir -p "$KEY_DIR" 2>/dev/null; then
627+
echo "Error: Could not create key directory $KEY_DIR" >&2
628+
exit 1
629+
fi
630+
chmod 1777 "$KEY_DIR"
631+
632+
if [[ ! -f "$KEY_FILE" ]]; then
633+
if ! (dd if=/dev/urandom bs=32 count=1 2>/dev/null | od -A n -t x1 | tr -d ' \n' > "$KEY_FILE"); then
634+
if ! (openssl rand -hex 32 > "$KEY_FILE"); then
635+
echo "00000000000000000000000000000000" > "$KEY_FILE"
636+
echo "Warning: Using fallback key" >&2
637+
fi
633638
fi
639+
chmod 644 "$KEY_FILE"
634640
fi
635-
chmod 644 "$KEY_FILE"
636-
fi
637-
638-
if [[ -f "$KEY_FILE" && -r "$KEY_FILE" ]]; then
639-
cat "$KEY_FILE"
640-
else
641-
echo "Error: Cannot read key file $KEY_FILE" >&2
642-
exit 1
643-
fi
644-
'';
641+
642+
if [[ -f "$KEY_FILE" && -r "$KEY_FILE" ]]; then
643+
cat "$KEY_FILE"
644+
else
645+
echo "Error: Cannot read key file $KEY_FILE" >&2
646+
exit 1
647+
fi
648+
EOF
649+
chmod +x $out/bin/pgsodium-getkey
650+
'';
651+
};
645652

646653
# Use the shared setup but with a test-specific name
647654
start-postgres-server-bin = makePostgresDevSetup {
@@ -710,6 +717,8 @@
710717
echo "listen_addresses = '*'" >> "$PGTAP_CLUSTER"/postgresql.conf
711718
echo "port = 5435" >> "$PGTAP_CLUSTER"/postgresql.conf
712719
echo "host all all 127.0.0.1/32 trust" >> $PGTAP_CLUSTER/pg_hba.conf
720+
echo "Checking shared_preload_libraries setting:"
721+
grep -rn "shared_preload_libraries" "$PGTAP_CLUSTER"/postgresql.conf
713722
# Remove timescaledb if running orioledb-17 check
714723
echo "I AM ${pgpkg.version}===================================================="
715724
if [[ "${pgpkg.version}" == *"17"* ]]; then
@@ -808,6 +817,7 @@
808817
--user=supabase_admin \
809818
${builtins.concatStringsSep " " sortedTestList}; then
810819
echo "pg_regress tests failed"
820+
cat $out/regression_output/regression.diffs
811821
exit 1
812822
fi
813823

Diff for: migrations/schema-15.sql

-67
Original file line numberDiff line numberDiff line change
@@ -44,27 +44,6 @@ CREATE SCHEMA graphql_public;
4444
CREATE SCHEMA pgbouncer;
4545

4646

47-
--
48-
-- Name: pgsodium; Type: SCHEMA; Schema: -; Owner: -
49-
--
50-
51-
CREATE SCHEMA pgsodium;
52-
53-
54-
--
55-
-- Name: pgsodium; Type: EXTENSION; Schema: -; Owner: -
56-
--
57-
58-
CREATE EXTENSION IF NOT EXISTS pgsodium WITH SCHEMA pgsodium;
59-
60-
61-
--
62-
-- Name: EXTENSION pgsodium; Type: COMMENT; Schema: -; Owner: -
63-
--
64-
65-
COMMENT ON EXTENSION pgsodium IS 'Pgsodium is a modern cryptography library for Postgres.';
66-
67-
6847
--
6948
-- Name: realtime; Type: SCHEMA; Schema: -; Owner: -
7049
--
@@ -582,28 +561,6 @@ END
582561
$$;
583562

584563

585-
--
586-
-- Name: secrets_encrypt_secret_secret(); Type: FUNCTION; Schema: vault; Owner: -
587-
--
588-
589-
CREATE FUNCTION vault.secrets_encrypt_secret_secret() RETURNS trigger
590-
LANGUAGE plpgsql
591-
AS $$
592-
BEGIN
593-
new.secret = CASE WHEN new.secret IS NULL THEN NULL ELSE
594-
CASE WHEN new.key_id IS NULL THEN NULL ELSE pg_catalog.encode(
595-
pgsodium.crypto_aead_det_encrypt(
596-
pg_catalog.convert_to(new.secret, 'utf8'),
597-
pg_catalog.convert_to((new.id::text || new.description::text || new.created_at::text || new.updated_at::text)::text, 'utf8'),
598-
new.key_id::uuid,
599-
new.nonce
600-
),
601-
'base64') END END;
602-
RETURN new;
603-
END;
604-
$$;
605-
606-
607564
SET default_tablespace = '';
608565

609566
SET default_table_access_method = heap;
@@ -790,30 +747,6 @@ CREATE TABLE storage.objects (
790747
);
791748

792749

793-
--
794-
-- Name: decrypted_secrets; Type: VIEW; Schema: vault; Owner: -
795-
--
796-
797-
CREATE VIEW vault.decrypted_secrets AS
798-
SELECT secrets.id,
799-
secrets.name,
800-
secrets.description,
801-
secrets.secret,
802-
CASE
803-
WHEN (secrets.secret IS NULL) THEN NULL::text
804-
ELSE
805-
CASE
806-
WHEN (secrets.key_id IS NULL) THEN NULL::text
807-
ELSE convert_from(pgsodium.crypto_aead_det_decrypt(decode(secrets.secret, 'base64'::text), convert_to(((((secrets.id)::text || secrets.description) || (secrets.created_at)::text) || (secrets.updated_at)::text), 'utf8'::name), secrets.key_id, secrets.nonce), 'utf8'::name)
808-
END
809-
END AS decrypted_secret,
810-
secrets.key_id,
811-
secrets.nonce,
812-
secrets.created_at,
813-
secrets.updated_at
814-
FROM vault.secrets;
815-
816-
817750
--
818751
-- Name: refresh_tokens id; Type: DEFAULT; Schema: auth; Owner: -
819752
--

0 commit comments

Comments
 (0)