11BEGIN ;
22
3- -- Create api_keys table with bcrypt hashing for api_key_hash
3+ -- Create api_keys table with encryption for api_key_encrypted (following secrets pattern)
44CREATE TABLE IF NOT EXISTS api_keys (
55 api_key_id UUID NOT NULL ,
66 developer_id UUID NOT NULL ,
7- api_key_hash TEXT NOT NULL ,
7+ api_key_encrypted BYTEA NOT NULL ,
88 name TEXT NOT NULL ,
99 created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP ,
1010 updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP ,
@@ -38,22 +38,33 @@ CREATE INDEX IF NOT EXISTS idx_api_keys_name ON api_keys(name);
3838CREATE INDEX IF NOT EXISTS idx_api_keys_metadata ON api_keys USING gin(metadata);
3939CREATE INDEX IF NOT EXISTS idx_api_keys_deleted_at ON api_keys(deleted_at) WHERE deleted_at IS NULL ;
4040
41- -- Helper functions for bcrypt hashing and verification
42- CREATE OR REPLACE FUNCTION hash_api_key (api_key TEXT )
43- RETURNS TEXT AS $$
41+ -- Helper functions for encryption/decryption (following secrets pattern)
42+ CREATE OR REPLACE FUNCTION encrypt_api_key (
43+ p_value TEXT ,
44+ p_key TEXT
45+ ) RETURNS BYTEA AS $$
4446BEGIN
45- RETURN crypt(api_key, gen_salt(' bf' , 12 ));
47+ RETURN pgp_sym_encrypt(
48+ p_value,
49+ p_key,
50+ ' cipher-algo=aes256'
51+ );
4652END;
4753$$ LANGUAGE plpgsql SECURITY DEFINER;
4854
49- CREATE OR REPLACE FUNCTION verify_api_key (api_key TEXT , hash TEXT )
50- RETURNS BOOLEAN AS $$
55+ CREATE OR REPLACE FUNCTION decrypt_api_key (
56+ p_encrypted_value BYTEA ,
57+ p_key TEXT
58+ ) RETURNS TEXT AS $$
5159BEGIN
52- RETURN crypt(api_key, hash) = hash;
60+ RETURN pgp_sym_decrypt(
61+ p_encrypted_value,
62+ p_key
63+ );
5364END;
5465$$ LANGUAGE plpgsql SECURITY DEFINER;
5566
5667-- Add comment to table
57- COMMENT ON TABLE api_keys IS ' Stores API keys with bcrypt hashing for developers' ;
68+ COMMENT ON TABLE api_keys IS ' Stores API keys with encryption for developers' ;
5869
5970COMMIT ;
0 commit comments