Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 2 additions & 12 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ jobs:

services:
mysql:
image: mysql:5.7
image: mysql:8.0
env:
MYSQL_DATABASE: ${{ env.MYSQL_DATABASE }}
MYSQL_ROOT_PASSWORD: ${{ env.MYSQL_PASSWORD }}
Expand All @@ -145,18 +145,8 @@ jobs:
run: |
bundle exec rake download

- name: Initialize RDBMS metastore
run: |
mysql -h ${{ env.MYSQL_HOSTNAME }} -P${{ job.services.mysql.ports[3306] }} -u ${{ env.MYSQL_USERNAME }} -p${{ env.MYSQL_PASSWORD }} -e "CREATE TABLE ${{ env.MYSQL_DATABASE }}.encryption_key (
id VARCHAR(255) NOT NULL,
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
key_record TEXT NOT NULL,
PRIMARY KEY (id, created),
INDEX (created)
);"

- name: Set up Go
uses: actions/setup-go@v6.2.0
uses: actions/setup-go@v6.3.0
with:
go-version: 1.24

Expand Down
3 changes: 3 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ Style/Documentation:
Style/DocumentationMethod:
Enabled: false # YARD comments are optional

Style/EmptyClassDefinition:
Enabled: false

# Additional cops for code quality
Lint/UnusedMethodArgument:
Enabled: true
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
## [Unreleased]

## [0.8.0] - 2026-03-04

- Upgrade to use asherah-cobhan v0.5.0
- Expose disable_zero_copy config option to disable zero-copy FFI input buffers

## [0.7.0] - 2025-08-15

- Fix memory leak risks in buffer management
Expand Down
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,22 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run

For tests requiring secrets (AWS KMS, database credentials), copy `.env.secrets.example` to `.env.secrets` and fill in the required values. The `.env.secrets` file is already in `.gitignore` to prevent accidental commits.

### Cross-Language Tests

Cross-language tests verify that data encrypted with the Go implementation can be decrypted with the Ruby implementation and vice versa.

**Prerequisites:**
- MySQL running locally
- Go 1.24+ installed

**Running the tests:**

```bash
TEST_DB_PASSWORD=pass bin/cross-language-test.sh
```

See `bin/cross-language-test.sh` for available environment variables and their defaults.

To install this gem onto your local machine, run `rake install`.

To release a new version, update the version number in `version.rb`, create and push a version tag:
Expand Down
42 changes: 39 additions & 3 deletions bin/cross-language-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,43 @@ ROOT_DIR=$(pwd)
ASHERAH_GO_DIR=$(pwd)/tmp/asherah
ASHERAH_GO_TEST_DIR=$(pwd)/tmp/asherah/tests/cross-language/go

# Set database environment variables
export TEST_DB_NAME=${TEST_DB_NAME:-testdb}
export TEST_DB_USER=${TEST_DB_USER:-root}
export TEST_DB_PASSWORD=${TEST_DB_PASSWORD:-}
export TEST_DB_HOSTNAME=${TEST_DB_HOSTNAME:-localhost}
export TEST_DB_PORT=${TEST_DB_PORT:-3306}

# Set Asherah environment variables
export ASHERAH_SERVICE_NAME=${ASHERAH_SERVICE_NAME:-service}
export ASHERAH_PRODUCT_NAME=${ASHERAH_PRODUCT_NAME:-product}
export ASHERAH_KMS_MODE=${ASHERAH_KMS_MODE:-static}

# Initialize database and table
echo "Initializing database..."
MYSQL_CMD="mysql -h $TEST_DB_HOSTNAME -P$TEST_DB_PORT -u $TEST_DB_USER"
if [ -n "$TEST_DB_PASSWORD" ]; then
MYSQL_CMD="$MYSQL_CMD -p$TEST_DB_PASSWORD"
fi

# Create database if it doesn't exist
$MYSQL_CMD -e "CREATE DATABASE IF NOT EXISTS $TEST_DB_NAME;" 2>/dev/null || {
echo "Warning: Could not create database. It may already exist or you may not have permissions."
}

# Create encryption_key table if it doesn't exist
$MYSQL_CMD $TEST_DB_NAME <<'SQL' 2>/dev/null || echo "Warning: Could not create table. It may already exist or you may not have permissions."
CREATE TABLE IF NOT EXISTS encryption_key (
id VARCHAR(255) NOT NULL,
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
key_record TEXT NOT NULL,
PRIMARY KEY (id, created),
INDEX (created)
);
SQL

echo "Database initialization complete."

# Clean tmp dir
rm -rf $ASHERAH_GO_DIR

Expand All @@ -19,11 +56,10 @@ cd $ASHERAH_GO_TEST_DIR
go build ./...
go mod edit -replace github.com/godaddy/asherah/go/appencryption=../../../go/appencryption
go mod tidy
go install github.com/cucumber/godog/cmd/godog@latest

# Encrypt with Go
cd $ASHERAH_GO_TEST_DIR
godog run "$ROOT_DIR/features/encrypt.feature"
go run github.com/cucumber/godog/cmd/godog@latest run "$ROOT_DIR/features/encrypt.feature"

# Encrypt with Ruby
cd $ROOT_DIR
Expand All @@ -35,4 +71,4 @@ bundle exec cucumber "$ROOT_DIR/features/decrypt.feature"

# Decrypt all with Go
cd $ASHERAH_GO_TEST_DIR
godog run "$ROOT_DIR/features/decrypt.feature"
go run github.com/cucumber/godog/cmd/godog@latest run "$ROOT_DIR/features/decrypt.feature"
10 changes: 5 additions & 5 deletions ext/asherah/checksums.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
version: v0.4.35
libasherah-arm64.so: fad23a38e68e126374075adf197f0f431720aea9852deebe5f62d9240c935a66
libasherah-x64.so: 8c52fc000df2c02fb2d1430afc3cd68e997f47f04b60d61481f8c4b201958ef8
libasherah-arm64.dylib: 315bc41c85177a2b0c97f32e0af8e2694f393928678cbe648fdd8c16b8fe062a
libasherah-x64.dylib: 848d3635713373e0482223087f454ff8464e36e7695e0ed19f830737288adaa9
version: v0.5.0
libasherah-arm64.so: 8271298c357808d7e6daa4ca81ded8f39c1947a55043abe3b32359e0f5840a6c
libasherah-x64.so: 645c0da7d1330db511c6724f08154cfae3959610bd709d60eded1c1420d2fce8
libasherah-arm64.dylib: 909097bf62207e6927a0184e41859ccf42a62afd711cdadf69b8c5672939468b
libasherah-x64.dylib: e53ee66b7dd16ce587d5062e9eed8835f272653b6a91b4b5c5c1efd2ca97483e
2 changes: 1 addition & 1 deletion features/support/env.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
DB_USER = ENV.fetch('TEST_DB_USER')
DB_PASS = ENV.fetch('TEST_DB_PASSWORD')
DB_PORT = ENV.fetch('TEST_DB_PORT')
DB_HOST = 'localhost'
DB_HOST = ENV.fetch('TEST_DB_HOSTNAME', 'localhost')
CONNECTION_STRING = "#{DB_USER}:#{DB_PASS}@tcp(#{DB_HOST}:#{DB_PORT})/#{DB_NAME}?tls=skip-verify"
TMP_DIR = '/tmp/'
FILE_NAME = 'ruby_encrypted'
Expand Down
2 changes: 2 additions & 0 deletions lib/asherah/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ module Asherah
# @attr [Integer] expire_after, The amount of time in seconds a key is considered valid
# @attr [Integer] check_interval, The amount of time in seconds before cached keys are considered stale
# @attr [Boolean] enable_session_caching, Enable shared session caching
# @attr [Boolean] disable_zero_copy, Disable zero-copy FFI input buffers to prevent use-after-free from caller runtime
# @attr [Boolean] verbose, Enable verbose logging output
class Config
MAPPING = {
Expand All @@ -40,6 +41,7 @@ class Config
session_cache_max_size: :SessionCacheMaxSize,
session_cache_duration: :SessionCacheDuration,
enable_session_caching: :EnableSessionCaching,
disable_zero_copy: :DisableZeroCopy,
expire_after: :ExpireAfter,
check_interval: :CheckInterval,
verbose: :Verbose
Expand Down
2 changes: 1 addition & 1 deletion lib/asherah/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module Asherah
VERSION = '0.7.0'
VERSION = '0.8.0'
end
90 changes: 90 additions & 0 deletions spec/config_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -163,4 +163,94 @@
end
end
end

describe '#disable_zero_copy' do
it 'accepts disable_zero_copy as true' do
expect {
Asherah.configure do |config|
base_config.call(config)
config.disable_zero_copy = true
end
}.not_to raise_error
Asherah.shutdown
end

it 'accepts disable_zero_copy as false' do
expect {
Asherah.configure do |config|
base_config.call(config)
config.disable_zero_copy = false
end
}.not_to raise_error
Asherah.shutdown
end
end

describe '#to_json' do
it 'correctly maps all configuration options to Go JSON format' do
config = Asherah::Config.new
config.service_name = 'test-service'
config.product_id = 'test-product'
config.kms = 'aws'
config.metastore = 'dynamodb'
config.connection_string = 'mysql://localhost:3306/test'
config.replica_read_consistency = 'eventual'
config.sql_metastore_db_type = 'postgres'
config.dynamo_db_endpoint = 'http://localhost:8000'
config.dynamo_db_region = 'us-west-2'
config.dynamo_db_table_name = 'test-table'
config.enable_region_suffix = true
config.region_map = { 'us-west-2' => 'arn' }
config.preferred_region = 'us-west-2'
config.session_cache_max_size = 500
config.session_cache_duration = 3600
config.enable_session_caching = true
config.disable_zero_copy = true
config.expire_after = 7200
config.check_interval = 1800
config.verbose = true

json_output = JSON.parse(config.to_json)

expect(json_output).to eq(
'ServiceName' => 'test-service',
'ProductID' => 'test-product',
'KMS' => 'aws',
'Metastore' => 'dynamodb',
'ConnectionString' => 'mysql://localhost:3306/test',
'ReplicaReadConsistency' => 'eventual',
'SQLMetastoreDBType' => 'postgres',
'DynamoDBEndpoint' => 'http://localhost:8000',
'DynamoDBRegion' => 'us-west-2',
'DynamoDBTableName' => 'test-table',
'EnableRegionSuffix' => true,
'RegionMap' => { 'us-west-2' => 'arn' },
'PreferredRegion' => 'us-west-2',
'SessionCacheMaxSize' => 500,
'SessionCacheDuration' => 3600,
'EnableSessionCaching' => true,
'DisableZeroCopy' => true,
'ExpireAfter' => 7200,
'CheckInterval' => 1800,
'Verbose' => true
)
end

it 'excludes nil values from JSON output' do
config = Asherah::Config.new
config.service_name = 'test-service'
config.product_id = 'test-product'
config.kms = 'test-debug-static'
config.metastore = 'test-debug-memory'

json_output = JSON.parse(config.to_json)

expect(json_output).to eq(
'ServiceName' => 'test-service',
'ProductID' => 'test-product',
'KMS' => 'test-debug-static',
'Metastore' => 'test-debug-memory'
)
end
end
end