From 59e291981a22c09cd97d925e183f2e8dc2fbf936 Mon Sep 17 00:00:00 2001 From: aaron-congo Date: Mon, 19 Oct 2026 16:53:28 -0700 Subject: [PATCH 1/2] refactor: look up the HMAC key for each row in the KMS PostgreSQL trigger The PostgreSQL trigger now reads the column's HMAC key from key_storage for every row instead of keeping a per-transaction copy in a setting, which simplifies the trigger SQL. Measured on PostgreSQL 16, the lookup adds about 3 microseconds per row for multi-row transactions and no measurable cost for single-row transactions. --- CHANGELOG.md | 3 +++ .../container/kms_encryption_triggers_spec.rb | 2 -- .../sql/kms_encryption_trigger_pg.sql | 21 +++++++------------ 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 221a373d..f84406d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### :magic_wand: Added - [Federated Authentication Plugin](https://aws.github.io/aws-advanced-wrapper-docs/ruby/using-plugins/federated-auth), which authenticates with Active Directory Federation Services (AD FS), exchanges the resulting SAML assertion for temporary AWS credentials via STS, and connects to the database with an RDS IAM authentication token. Enabled with the `federated_auth` plugin code ([PR #207](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/207)). +### :crab: Changed +- Simplified the KMS Encryption Plugin's PostgreSQL trigger SQL to read the column's HMAC key from `key_storage` for every row. Re-run the trigger SQL from the [documentation](https://aws.github.io/aws-advanced-wrapper-docs/ruby/using-plugins/kms-encryption) to update existing deployments ([PR #216](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/216)). + ## [1.0.1] - 2026-10-07 ### :bug: Fixed diff --git a/spec/integration/container/kms_encryption_triggers_spec.rb b/spec/integration/container/kms_encryption_triggers_spec.rb index f00d05cd..e0c0b288 100644 --- a/spec/integration/container/kms_encryption_triggers_spec.rb +++ b/spec/integration/container/kms_encryption_triggers_spec.rb @@ -84,8 +84,6 @@ end end - # The trigger caches the column's HMAC key for the length of a transaction. A later transaction on - # the same connection must look it up again rather than reading back the expired cache entry. shared_examples 'a trigger across transactions on one connection' do it 'accepts a valid value in each of several transactions on the same connection' do 3.times do |i| diff --git a/spec/integration/host/src/test/resources/sql/kms_encryption_trigger_pg.sql b/spec/integration/host/src/test/resources/sql/kms_encryption_trigger_pg.sql index e4bf499c..bb7376b2 100644 --- a/spec/integration/host/src/test/resources/sql/kms_encryption_trigger_pg.sql +++ b/spec/integration/host/src/test/resources/sql/kms_encryption_trigger_pg.sql @@ -13,7 +13,6 @@ DECLARE col_name text := TG_ARGV[0]; col_value bytea; hmac_key bytea; - cache_key text := 'hmac_key.' || TG_TABLE_NAME || '.' || col_name; unchanged boolean; BEGIN -- An UPDATE that leaves the encrypted value as it was is not re-checked; see @@ -31,20 +30,14 @@ BEGIN RETURN NEW; END IF; - -- A setting cached by an earlier transaction reads back as '' rather than being - -- undefined, so an empty value is treated as not cached. - hmac_key := decode(NULLIF(current_setting(cache_key, true), ''), 'hex'); - IF hmac_key IS NULL THEN - SELECT ks.hmac_key INTO hmac_key - FROM encrypt.encryption_metadata em - JOIN encrypt.key_storage ks ON em.key_id = ks.id - WHERE em.table_name = TG_TABLE_NAME AND em.column_name = col_name; - - IF hmac_key IS NULL THEN - RAISE EXCEPTION 'No HMAC key is configured for %.%', TG_TABLE_NAME, col_name; - END IF; + -- Read the column's current HMAC key from key_storage. + SELECT ks.hmac_key INTO hmac_key + FROM encrypt.encryption_metadata em + JOIN encrypt.key_storage ks ON em.key_id = ks.id + WHERE em.table_name = TG_TABLE_NAME AND em.column_name = col_name; - PERFORM set_config(cache_key, encode(hmac_key, 'hex'), true); + IF hmac_key IS NULL THEN + RAISE EXCEPTION 'No HMAC key is configured for %.%', TG_TABLE_NAME, col_name; END IF; IF length(col_value) < 65 From e77640afd7ecdecd6c5fbf7d77a474d0b20abb34 Mon Sep 17 00:00:00 2001 From: aaron-congo Date: Tue, 20 Oct 2026 09:25:44 -0700 Subject: [PATCH 2/2] PR suggestion --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f84406d6..3385cf73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - [Federated Authentication Plugin](https://aws.github.io/aws-advanced-wrapper-docs/ruby/using-plugins/federated-auth), which authenticates with Active Directory Federation Services (AD FS), exchanges the resulting SAML assertion for temporary AWS credentials via STS, and connects to the database with an RDS IAM authentication token. Enabled with the `federated_auth` plugin code ([PR #207](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/207)). ### :crab: Changed -- Simplified the KMS Encryption Plugin's PostgreSQL trigger SQL to read the column's HMAC key from `key_storage` for every row. Re-run the trigger SQL from the [documentation](https://aws.github.io/aws-advanced-wrapper-docs/ruby/using-plugins/kms-encryption) to update existing deployments ([PR #216](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/216)). +- Simplified the KMS Encryption Plugin's PostgreSQL trigger SQL to read the column's HMAC key from `key_storage` for every row. Re-run the trigger SQL from the [documentation](https://aws.github.io/aws-advanced-wrapper-docs/ruby/using-plugins/kms-encryption#postgresql-1) to update existing deployments ([PR #216](https://github.com/aws/aws-advanced-ruby-driver-wrapper/pull/216)). ## [1.0.1] - 2026-10-07