rb_snowflake_client 1.5.0 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -0
- data/Gemfile +1 -1
- data/README.md +3 -0
- data/lib/ruby_snowflake/client/key_pair_jwt_auth_manager.rb +4 -4
- data/lib/ruby_snowflake/client.rb +3 -2
- data/lib/ruby_snowflake/version.rb +1 -1
- data/rb_snowflake_client.gemspec +16 -1
- metadata +2 -3
- data/Gemfile.lock +0 -84
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 57d979564fce1cdc8fb8b92043e89b631f4f1ca35db2cc2d4601a1739506e89a
|
|
4
|
+
data.tar.gz: ecfd25eb94ae8e5767e49c7b3b5dd33f02905e09c839ba0bd59be81f629f1390
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 906470b3b67d6a102bbe25bc02e42c2178a4a9fc7a1eb6785398a1bfc45d6e47e9b5dc392aebc4dc35dbd0c6a2263c30c39c3ce522396a6584629f8d8e7ad43e
|
|
7
|
+
data.tar.gz: d767e9956def03c80dd8eb66d24649c54c987f37dc07870a319a55ac9455821b330e4d5a59e89246282899f40d76222c6a07b90dc6882a5e89ba3c410a6c1f95
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## Unreleased
|
|
9
9
|
|
|
10
|
+
## [1.6.1] - 2026-08-18
|
|
11
|
+
### Security
|
|
12
|
+
- Bumped `json` to patch a format-string injection CVE (#169)
|
|
13
|
+
- Bumped `concurrent-ruby` and `jwt` to patch CVEs (#182)
|
|
14
|
+
### Changed
|
|
15
|
+
- `Gemfile.lock` is no longer shipped inside the published gem. It has no function in a
|
|
16
|
+
consumer's dependency resolution, but image scanners read it as a manifest and reported our
|
|
17
|
+
development pins as CRITICAL findings against every consumer (#186)
|
|
18
|
+
|
|
19
|
+
## [1.6.0] - 2026-04-13
|
|
20
|
+
### Added
|
|
21
|
+
- Support for passing a passphrase when using an encrypted private key for JWT authentication (#166)
|
|
22
|
+
### Security
|
|
23
|
+
- Bumped `activesupport` to patch CVEs (#167)
|
|
24
|
+
|
|
10
25
|
## [1.5.0] - 2025-10-14
|
|
11
26
|
### Added
|
|
12
27
|
- Instrumentation feature added for Active Support users
|
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -48,6 +48,8 @@ Available ENV variables (see below in the config section for details)
|
|
|
48
48
|
- `SNOWFLAKE_URI`
|
|
49
49
|
- `SNOWFLAKE_PRIVATE_KEY_PATH` or `SNOWFLAKE_PRIVATE_KEY`
|
|
50
50
|
- Use either the key or the path. Key takes precedence if both are provided.
|
|
51
|
+
- `SNOWFLAKE_PRIVATE_KEY_PASSPHRASE`
|
|
52
|
+
- Optional, if you are using an encrypted private key
|
|
51
53
|
- `SNOWFLAKE_ORGANIZATION`
|
|
52
54
|
- Optional, if you leave it off, the library will authenticate with an account name of only SNOWFLAKE_ACCOUNT
|
|
53
55
|
- `SNOWFLAKE_ACCOUNT`
|
|
@@ -265,6 +267,7 @@ or alternatively, use the client to verify:
|
|
|
265
267
|
client = RubySnowflake::Client.new(
|
|
266
268
|
"https://yourinstance.region.snowflakecomputing.com", # insert your URL here
|
|
267
269
|
File.read("secrets/my_key.pem"), # path to your private key
|
|
270
|
+
"private-key-passphrase", # your private key passphrase, if it has one (defaults to nil)
|
|
268
271
|
"snowflake-organization", # your account name (doesn't match your URL), using nil may be required depending on your snowflake account
|
|
269
272
|
"snowflake-account", # typically your subdomain
|
|
270
273
|
"snowflake-user", # Your snowflake user
|
|
@@ -8,12 +8,13 @@ module RubySnowflake
|
|
|
8
8
|
class Client
|
|
9
9
|
class KeyPairJwtAuthManager
|
|
10
10
|
# requires text of a PEM formatted RSA private key
|
|
11
|
-
def initialize(organization, account, user, private_key, jwt_token_ttl)
|
|
11
|
+
def initialize(organization, account, user, private_key, jwt_token_ttl, private_key_passphrase = nil)
|
|
12
12
|
@organization = organization
|
|
13
13
|
@account = account
|
|
14
14
|
@user = user
|
|
15
15
|
@private_key_pem = private_key
|
|
16
16
|
@jwt_token_ttl = jwt_token_ttl
|
|
17
|
+
@private_key_passphrase = private_key_passphrase
|
|
17
18
|
|
|
18
19
|
# start with an expired value to force creation
|
|
19
20
|
@token_expires_at = Time.now.to_i - 1
|
|
@@ -26,8 +27,7 @@ module RubySnowflake
|
|
|
26
27
|
@token_semaphore.acquire do
|
|
27
28
|
now = Time.now.to_i
|
|
28
29
|
@token_expires_at = now + @jwt_token_ttl
|
|
29
|
-
|
|
30
|
-
private_key = OpenSSL::PKey.read(@private_key_pem)
|
|
30
|
+
private_key = OpenSSL::PKey.read(@private_key_pem, @private_key_passphrase)
|
|
31
31
|
|
|
32
32
|
payload = {
|
|
33
33
|
:iss => "#{account_name}.#{@user.upcase}.#{public_key_fingerprint}",
|
|
@@ -56,7 +56,7 @@ module RubySnowflake
|
|
|
56
56
|
def public_key_fingerprint
|
|
57
57
|
return @public_key_fingerprint unless @public_key_fingerprint.nil?
|
|
58
58
|
|
|
59
|
-
public_key_der = OpenSSL::PKey::RSA.new(@private_key_pem).public_key.to_der
|
|
59
|
+
public_key_der = OpenSSL::PKey::RSA.new(@private_key_pem, @private_key_passphrase).public_key.to_der
|
|
60
60
|
digest = OpenSSL::Digest::SHA256.new.digest(public_key_der)
|
|
61
61
|
fingerprint = Base64.strict_encode64(digest)
|
|
62
62
|
|
|
@@ -97,6 +97,7 @@ module RubySnowflake
|
|
|
97
97
|
new(
|
|
98
98
|
ENV.fetch("SNOWFLAKE_URI"),
|
|
99
99
|
private_key,
|
|
100
|
+
ENV["SNOWFLAKE_PRIVATE_KEY_PASSPHRASE"],
|
|
100
101
|
ENV.fetch("SNOWFLAKE_ORGANIZATION"),
|
|
101
102
|
ENV.fetch("SNOWFLAKE_ACCOUNT"),
|
|
102
103
|
ENV.fetch("SNOWFLAKE_USER"),
|
|
@@ -116,7 +117,7 @@ module RubySnowflake
|
|
|
116
117
|
end
|
|
117
118
|
|
|
118
119
|
def initialize(
|
|
119
|
-
uri, private_key, organization, account, user, default_warehouse, default_database,
|
|
120
|
+
uri, private_key, private_key_passphrase = nil, organization, account, user, default_warehouse, default_database,
|
|
120
121
|
default_role: nil,
|
|
121
122
|
logger: DEFAULT_LOGGER,
|
|
122
123
|
log_level: DEFAULT_LOG_LEVEL,
|
|
@@ -130,7 +131,7 @@ module RubySnowflake
|
|
|
130
131
|
)
|
|
131
132
|
@base_uri = uri
|
|
132
133
|
@key_pair_jwt_auth_manager =
|
|
133
|
-
KeyPairJwtAuthManager.new(organization, account, user, private_key, jwt_token_ttl)
|
|
134
|
+
KeyPairJwtAuthManager.new(organization, account, user, private_key, jwt_token_ttl, private_key_passphrase)
|
|
134
135
|
@default_warehouse = default_warehouse
|
|
135
136
|
@default_database = default_database
|
|
136
137
|
@default_role = default_role
|
data/rb_snowflake_client.gemspec
CHANGED
|
@@ -14,8 +14,23 @@ Gem::Specification.new do |s|
|
|
|
14
14
|
s.homepage = "https://github.com/rinsed-org/rb-snowflake-client"
|
|
15
15
|
s.license = "MIT"
|
|
16
16
|
|
|
17
|
+
# Gemfile.lock is excluded deliberately, and it is a security fix rather than tidiness.
|
|
18
|
+
#
|
|
19
|
+
# A lockfile has no function inside a published gem -- Bundler resolves a consumer's tree from the
|
|
20
|
+
# dependency constraints below, never from a lockfile shipped in a dependency -- but container image
|
|
21
|
+
# scanners read any Gemfile.lock they find on disk as a manifest of what is installed. So our
|
|
22
|
+
# DEVELOPMENT lock became a vulnerability report against every consumer: an image that installs this
|
|
23
|
+
# gem gets .../gems/rb_snowflake_client-1.6.0/Gemfile.lock scanned, and the pinned
|
|
24
|
+
# concurrent-ruby 1.3.6, jwt 3.1.2 and json 2.15.1 are reported as CRITICAL findings on the consumer.
|
|
25
|
+
#
|
|
26
|
+
# That is all three CRITICAL findings on the DataExtract Lambda image, and they are unfixable there:
|
|
27
|
+
# the versions are ours, in our published artifact, and no bump on the consumer's side can move them.
|
|
28
|
+
# The runtime constraints (concurrent-ruby >= 1.2, json >= 2.1.0, jwt >= 2.7) are open-ended, so
|
|
29
|
+
# consumers already resolve their own versions and lose nothing by not receiving this file.
|
|
17
30
|
s.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
18
|
-
`git ls-files -z`.split("\x0").reject
|
|
31
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
|
32
|
+
f.match(%r{\A(?:test|spec|features|vendor)/}) || f == "Gemfile.lock"
|
|
33
|
+
end
|
|
19
34
|
end
|
|
20
35
|
|
|
21
36
|
s.require_paths = ["lib"]
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rb_snowflake_client
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.6.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Rinsed
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-08-18 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bigdecimal
|
|
@@ -127,7 +127,6 @@ files:
|
|
|
127
127
|
- CHANGELOG.md
|
|
128
128
|
- CODE_OF_CONDUCT.md
|
|
129
129
|
- Gemfile
|
|
130
|
-
- Gemfile.lock
|
|
131
130
|
- LICENSE.txt
|
|
132
131
|
- README.md
|
|
133
132
|
- Rakefile
|
data/Gemfile.lock
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
PATH
|
|
2
|
-
remote: .
|
|
3
|
-
specs:
|
|
4
|
-
rb_snowflake_client (1.5.0)
|
|
5
|
-
bigdecimal (>= 3.0)
|
|
6
|
-
concurrent-ruby (>= 1.2)
|
|
7
|
-
connection_pool (>= 2.4)
|
|
8
|
-
dotenv (>= 2.8)
|
|
9
|
-
json (>= 2.1.0)
|
|
10
|
-
jwt (>= 2.7)
|
|
11
|
-
retryable (>= 3.0)
|
|
12
|
-
|
|
13
|
-
GEM
|
|
14
|
-
remote: https://rubygems.org/
|
|
15
|
-
specs:
|
|
16
|
-
activesupport (8.0.3)
|
|
17
|
-
base64
|
|
18
|
-
benchmark (>= 0.3)
|
|
19
|
-
bigdecimal
|
|
20
|
-
concurrent-ruby (~> 1.0, >= 1.3.1)
|
|
21
|
-
connection_pool (>= 2.2.5)
|
|
22
|
-
drb
|
|
23
|
-
i18n (>= 1.6, < 2)
|
|
24
|
-
logger (>= 1.4.2)
|
|
25
|
-
minitest (>= 5.1)
|
|
26
|
-
securerandom (>= 0.3)
|
|
27
|
-
tzinfo (~> 2.0, >= 2.0.5)
|
|
28
|
-
uri (>= 0.13.1)
|
|
29
|
-
base64 (0.3.0)
|
|
30
|
-
benchmark (0.4.1)
|
|
31
|
-
bigdecimal (3.3.1)
|
|
32
|
-
coderay (1.1.3)
|
|
33
|
-
concurrent-ruby (1.3.5)
|
|
34
|
-
connection_pool (2.5.4)
|
|
35
|
-
diff-lcs (1.6.2)
|
|
36
|
-
dotenv (3.1.8)
|
|
37
|
-
drb (2.2.3)
|
|
38
|
-
i18n (1.14.7)
|
|
39
|
-
concurrent-ruby (~> 1.0)
|
|
40
|
-
json (2.15.1)
|
|
41
|
-
jwt (3.1.2)
|
|
42
|
-
base64
|
|
43
|
-
logger (1.7.0)
|
|
44
|
-
method_source (1.1.0)
|
|
45
|
-
minitest (5.26.0)
|
|
46
|
-
parallel (1.27.0)
|
|
47
|
-
pry (0.15.2)
|
|
48
|
-
coderay (~> 1.1)
|
|
49
|
-
method_source (~> 1.0)
|
|
50
|
-
rake (13.3.0)
|
|
51
|
-
retryable (3.0.5)
|
|
52
|
-
rspec (3.13.1)
|
|
53
|
-
rspec-core (~> 3.13.0)
|
|
54
|
-
rspec-expectations (~> 3.13.0)
|
|
55
|
-
rspec-mocks (~> 3.13.0)
|
|
56
|
-
rspec-core (3.13.5)
|
|
57
|
-
rspec-support (~> 3.13.0)
|
|
58
|
-
rspec-expectations (3.13.5)
|
|
59
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
|
60
|
-
rspec-support (~> 3.13.0)
|
|
61
|
-
rspec-mocks (3.13.5)
|
|
62
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
|
63
|
-
rspec-support (~> 3.13.0)
|
|
64
|
-
rspec-support (3.13.6)
|
|
65
|
-
securerandom (0.4.1)
|
|
66
|
-
tzinfo (2.0.6)
|
|
67
|
-
concurrent-ruby (~> 1.0)
|
|
68
|
-
uri (1.0.4)
|
|
69
|
-
|
|
70
|
-
PLATFORMS
|
|
71
|
-
arm64-darwin-22
|
|
72
|
-
ruby
|
|
73
|
-
|
|
74
|
-
DEPENDENCIES
|
|
75
|
-
activesupport
|
|
76
|
-
bundler
|
|
77
|
-
parallel
|
|
78
|
-
pry
|
|
79
|
-
rake
|
|
80
|
-
rb_snowflake_client!
|
|
81
|
-
rspec
|
|
82
|
-
|
|
83
|
-
BUNDLED WITH
|
|
84
|
-
2.5.10
|