sidekiq-encrypted_args 1.1.1 → 2.0.0
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/CHANGE_LOG.md +24 -2
- data/README.md +16 -10
- data/VERSION +1 -1
- data/lib/sidekiq/encrypted_args/client_middleware.rb +16 -2
- data/lib/sidekiq/encrypted_args/server_middleware.rb +17 -13
- data/lib/sidekiq/encrypted_args/version.rb +1 -0
- data/lib/sidekiq/encrypted_args.rb +73 -43
- data/sidekiq-encrypted_args.gemspec +10 -3
- metadata +14 -16
- data/benchmark.rb +0 -38
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: aed8d03eeb0b589556b436823f85c13331ab6c1703d732d425321b4cc1b2bc71
|
|
4
|
+
data.tar.gz: 2f2a42257c669731f97ee25cfc52da48a4cbdbe18b59e0fd84bcebbe50820e89
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cbdd4e2d8144eddf2e3699ac30ab52114de6ab8e09b97e75909e2e67defc81f5c4cd71e43efb22c404ac4890213abd6c300ee45117ae7e1428cf5b2b1794595c
|
|
7
|
+
data.tar.gz: 6644bca285087c5de5b2c68aba368f4192b2061f3f5f6095125d8ca7e16888b40214e2ce7b9a3c2a2ec39b808be6ccadefc7a1c7777c0bd3edecf1ef935f7a18
|
data/CHANGE_LOG.md
CHANGED
|
@@ -4,40 +4,62 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
5
5
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## 2.0.0
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- A secret key is now required to be set. Previously the code would silently fail if no key was set. This change improves security by protecting against misconfiguration leaking data into Redis.
|
|
12
|
+
- Bumped minimum required Ruby version to 2.7 and Sidekiq to 6.3.
|
|
13
|
+
|
|
14
|
+
## 1.2.0
|
|
15
|
+
|
|
16
|
+
### Removed
|
|
17
|
+
|
|
18
|
+
- Removed deprecated method of setting encrypted args with a hash with numeric keys. This method stopped working with Sidekiq 7.1.
|
|
19
|
+
- Removed deprecated method of setting encrypted args with an array of booleans.
|
|
20
|
+
- Removed deprecated method of setting encrypted args with a mix of symbols and integers.
|
|
21
|
+
|
|
7
22
|
## 1.1.1
|
|
8
23
|
|
|
9
24
|
### Fixed
|
|
25
|
+
|
|
10
26
|
- Client middleware will no longer encrypt already encrypted arguments when a job is retried.
|
|
11
27
|
|
|
12
28
|
## 1.1.0
|
|
13
29
|
|
|
14
30
|
### Added
|
|
31
|
+
|
|
15
32
|
- Use `to_json` if it is defined when serializing encrypted args to JSON.
|
|
16
33
|
- Add client middleware to the server default configuration. This ensures that arguments will be encrypted if a worker enqueues a job with encrypted arguments.
|
|
17
34
|
- Client middleware now reads sidekiq options from the job hash instead of from the worker class so that the list of encrypted arguments is always in sync on the job payload.
|
|
18
35
|
- Added additional option to specify encrypted args with array of argument indexes.
|
|
19
36
|
|
|
20
37
|
### Changed
|
|
38
|
+
|
|
21
39
|
- Client middleware is now prepended while server middleware is appended.
|
|
22
40
|
|
|
23
41
|
### Fixed
|
|
42
|
+
|
|
24
43
|
- Don't raise error if undefined class name is passed to client middleware as a string.
|
|
25
44
|
|
|
26
45
|
### Deprecated
|
|
46
|
+
|
|
27
47
|
- Deprecated setting encrypted args as hash or array of booleans.
|
|
28
48
|
|
|
29
49
|
## 1.0.2
|
|
30
50
|
|
|
31
51
|
### Changed
|
|
52
|
+
|
|
32
53
|
- Remove overly noisy log warning when running without the secret set
|
|
33
54
|
|
|
34
55
|
## 1.0.1
|
|
35
56
|
|
|
36
|
-
### Added
|
|
37
|
-
|
|
38
57
|
### Fixed
|
|
58
|
+
|
|
39
59
|
- Added support for scheduled jobs
|
|
40
60
|
|
|
41
61
|
## 1.0.0
|
|
42
62
|
|
|
63
|
+
### Added
|
|
64
|
+
|
|
43
65
|
- Initial release
|
data/README.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# Sidekiq Encrypted Args
|
|
2
2
|
|
|
3
|
-
[](https://github.com/bdurand/sidekiq-encrypted_args/actions/workflows/continuous_integration.yml)
|
|
4
4
|
[](https://github.com/testdouble/standard)
|
|
5
|
+
[](https://badge.fury.io/rb/sidekiq-encrypted_args)
|
|
5
6
|
|
|
6
7
|
Support for encrypting arguments for [Sidekiq](https://github.com/mperham/sidekiq).
|
|
7
8
|
|
|
@@ -21,7 +22,7 @@ To use the gem, you will need to specify a secret that will be used to encrypt t
|
|
|
21
22
|
Sidekiq::EncryptedArgs.configure!(secret: "YourSecretKey")
|
|
22
23
|
```
|
|
23
24
|
|
|
24
|
-
If the secret is not set, the value of the `SIDEKIQ_ENCRYPTED_ARGS_SECRET` environment variable will be used as the secret. If
|
|
25
|
+
If the secret is not set explicitly, the value of the `SIDEKIQ_ENCRYPTED_ARGS_SECRET` environment variable will be used as the secret. If you call `configure!` without setting a secret (either explicitly or via the environment variable), an error will be raised.
|
|
25
26
|
|
|
26
27
|
The call to `Sidekiq::EncryptedArgs.configure!` will **prepend** the client encryption middleware and **append** server decryption middleware. By doing this, any other middleware you register will only receive the encrypted parameters (e.g. logging middleware will receive the encrypted parameters).
|
|
27
28
|
|
|
@@ -41,7 +42,8 @@ Sidekiq.configure_server do |config|
|
|
|
41
42
|
chain.add Sidekiq::EncryptedArgs::ServerMiddleware
|
|
42
43
|
end
|
|
43
44
|
|
|
44
|
-
#
|
|
45
|
+
# Register client middleware on the server so that starting jobs from within
|
|
46
|
+
# another also get encrypted args.
|
|
45
47
|
# https://github.com/mperham/sidekiq/wiki/Middleware#client-middleware-registered-in-both-places
|
|
46
48
|
config.client_middleware do |chain|
|
|
47
49
|
chain.prepend Sidekiq::EncryptedArgs::ClientMiddleware
|
|
@@ -57,7 +59,7 @@ Setting the option to `true` will encrypt all the arguments passed to the `perfo
|
|
|
57
59
|
|
|
58
60
|
```ruby
|
|
59
61
|
class SecretWorker
|
|
60
|
-
include Sidekiq::
|
|
62
|
+
include Sidekiq::Job
|
|
61
63
|
|
|
62
64
|
sidekiq_options encrypted_args: true
|
|
63
65
|
|
|
@@ -66,20 +68,24 @@ class SecretWorker
|
|
|
66
68
|
end
|
|
67
69
|
```
|
|
68
70
|
|
|
69
|
-
You can also choose to only encrypt specific arguments
|
|
71
|
+
You can also choose to only encrypt specific arguments by specifying either argument names (as symbols or strings) or argument positions (as integers). This is useful to preserve visibility into non-sensitive arguments for troubleshooting or other reasons. All of these examples encrypt just the second argument to the `perform` method.
|
|
70
72
|
|
|
71
73
|
```ruby
|
|
72
|
-
# Pass in a
|
|
74
|
+
# Pass in a single argument name
|
|
75
|
+
sidekiq_options encrypted_args: :arg_2
|
|
76
|
+
# or as a string
|
|
77
|
+
sidekiq_options encrypted_args: "arg_2"
|
|
78
|
+
# or as an array
|
|
73
79
|
sidekiq_options encrypted_args: [:arg_2]
|
|
74
|
-
# or
|
|
75
|
-
sidekiq_options encrypted_args: ["arg_2"]
|
|
76
80
|
|
|
77
81
|
def perform(arg_1, arg_2, arg_3)
|
|
78
82
|
end
|
|
79
83
|
```
|
|
80
84
|
|
|
81
85
|
```ruby
|
|
82
|
-
# Pass in an
|
|
86
|
+
# Pass in an integer indicating which argument position should be encrypted (0-indexed)
|
|
87
|
+
sidekiq_options encrypted_args: 1
|
|
88
|
+
# or as an array
|
|
83
89
|
sidekiq_options encrypted_args: [1]
|
|
84
90
|
|
|
85
91
|
def perform(arg_1, arg_2, arg_3)
|
|
@@ -98,7 +104,7 @@ Sidekiq::EncryptedArgs.secret = ["CurrentSecret", "OldSecret", "EvenOlderSecret"
|
|
|
98
104
|
|
|
99
105
|
The first (left most) key will be considered the current key, and is used for encrypting arguments. When decrypting, we iterate over the secrets list until we find the correct one. This allows you to switch you secret keys without breaking jobs already enqueued in Redis.
|
|
100
106
|
|
|
101
|
-
If you are using the `SIDEKIQ_ENCRYPTED_ARGS_SECRET` environment variable to specify your secret, you can
|
|
107
|
+
If you are using the `SIDEKIQ_ENCRYPTED_ARGS_SECRET` environment variable to specify your secret, you can separate multiple keys with whitespace (spaces or tabs).
|
|
102
108
|
|
|
103
109
|
You can also safely add encryption to an existing worker. Any jobs that are already enqueued will still run even without having the arguments encrypted in Redis.
|
|
104
110
|
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
2.0.0
|
|
@@ -4,8 +4,22 @@ module Sidekiq
|
|
|
4
4
|
module EncryptedArgs
|
|
5
5
|
# Sidekiq client middleware for encrypting arguments on jobs for workers
|
|
6
6
|
# with `encrypted_args` set in the `sidekiq_options`.
|
|
7
|
+
#
|
|
8
|
+
# This middleware is responsible for encrypting job arguments before they
|
|
9
|
+
# are sent to Redis. It runs on the client side when jobs are enqueued.
|
|
10
|
+
#
|
|
11
|
+
# @see ServerMiddleware
|
|
7
12
|
class ClientMiddleware
|
|
8
|
-
|
|
13
|
+
include Sidekiq::ClientMiddleware if defined?(Sidekiq::ClientMiddleware)
|
|
14
|
+
|
|
15
|
+
# Encrypt specified arguments before they're sent off to the queue.
|
|
16
|
+
#
|
|
17
|
+
# @param [String, Class] worker_class The worker class or class name
|
|
18
|
+
# @param [Hash] job The Sidekiq job hash containing arguments and metadata
|
|
19
|
+
# @param [String] queue The name of the queue
|
|
20
|
+
# @param [Object, nil] redis_pool Optional Redis connection pool (legacy parameter)
|
|
21
|
+
# @return [void]
|
|
22
|
+
# @yield Passes control to the next middleware in the chain
|
|
9
23
|
def call(worker_class, job, queue, redis_pool = nil)
|
|
10
24
|
if job.include?("encrypted_args")
|
|
11
25
|
encrypted_args = EncryptedArgs.encrypted_args_option(worker_class, job)
|
|
@@ -21,7 +35,7 @@ module Sidekiq
|
|
|
21
35
|
#
|
|
22
36
|
# Additionally, set `job["encrypted_args"]` to the canonicalized version (i.e. `Array<Integer>`)
|
|
23
37
|
#
|
|
24
|
-
# @param [Hash]
|
|
38
|
+
# @param [Hash] job The Sidekiq job hash containing arguments and metadata
|
|
25
39
|
# @param [Array<Integer>] encrypted_args array of indexes in job to encrypt
|
|
26
40
|
# @return [void]
|
|
27
41
|
def encrypt_job_arguments!(job, encrypted_args)
|
|
@@ -3,12 +3,27 @@
|
|
|
3
3
|
module Sidekiq
|
|
4
4
|
module EncryptedArgs
|
|
5
5
|
# Sidekiq server middleware for decrypting arguments on jobs that have encrypted args.
|
|
6
|
+
#
|
|
7
|
+
# This middleware is responsible for decrypting job arguments before they
|
|
8
|
+
# are passed to the worker's perform method. It runs on the server side
|
|
9
|
+
# when jobs are processed.
|
|
10
|
+
#
|
|
11
|
+
# @see ClientMiddleware
|
|
6
12
|
class ServerMiddleware
|
|
7
|
-
|
|
13
|
+
include Sidekiq::ServerMiddleware if defined?(Sidekiq::ServerMiddleware)
|
|
14
|
+
|
|
15
|
+
# Wrap the server process to decrypt incoming arguments.
|
|
16
|
+
#
|
|
17
|
+
# @param [Object] worker The worker instance that will process the job
|
|
18
|
+
# @param [Hash] job The Sidekiq job hash containing arguments and metadata
|
|
19
|
+
# @param [String] queue The name of the queue
|
|
20
|
+
# @return [void]
|
|
21
|
+
# @yield Passes control to the worker's perform method
|
|
8
22
|
def call(worker, job, queue)
|
|
9
23
|
encrypted_args = job["encrypted_args"]
|
|
24
|
+
|
|
10
25
|
if encrypted_args
|
|
11
|
-
encrypted_args =
|
|
26
|
+
encrypted_args = EncryptedArgs.encrypted_args_option(worker.class, job)
|
|
12
27
|
job_args = job["args"]
|
|
13
28
|
encrypted_args.each do |position|
|
|
14
29
|
value = job_args[position]
|
|
@@ -18,17 +33,6 @@ module Sidekiq
|
|
|
18
33
|
|
|
19
34
|
yield
|
|
20
35
|
end
|
|
21
|
-
|
|
22
|
-
private
|
|
23
|
-
|
|
24
|
-
# Ensure that the encrypted args is an array of integers. If not re-read it from the class
|
|
25
|
-
# definition since gem version 1.0.2 and earlier did not update the encrypted_args on the job.
|
|
26
|
-
def backward_compatible_encrypted_args(encrypted_args, worker_class, job)
|
|
27
|
-
unless encrypted_args.is_a?(Array) && encrypted_args.all? { |position| position.is_a?(Integer) }
|
|
28
|
-
encrypted_args = EncryptedArgs.encrypted_args_option(worker_class, job)
|
|
29
|
-
end
|
|
30
|
-
encrypted_args
|
|
31
|
-
end
|
|
32
36
|
end
|
|
33
37
|
end
|
|
34
38
|
end
|
|
@@ -5,12 +5,16 @@ require "secret_keys"
|
|
|
5
5
|
require "sidekiq"
|
|
6
6
|
|
|
7
7
|
module Sidekiq
|
|
8
|
+
# Provides middleware for encrypting sensitive arguments in Sidekiq jobs.
|
|
9
|
+
#
|
|
10
|
+
# This module allows you to specify which job arguments should be encrypted
|
|
11
|
+
# in Redis to protect sensitive information like API keys, passwords, or
|
|
12
|
+
# personally identifiable information.
|
|
8
13
|
module EncryptedArgs
|
|
14
|
+
@encryptors = nil
|
|
15
|
+
|
|
9
16
|
# Error thrown when the secret is invalid
|
|
10
17
|
class InvalidSecretError < StandardError
|
|
11
|
-
def initialize
|
|
12
|
-
super("Cannot decrypt. Invalid secret provided.")
|
|
13
|
-
end
|
|
14
18
|
end
|
|
15
19
|
|
|
16
20
|
class << self
|
|
@@ -25,10 +29,16 @@ module Sidekiq
|
|
|
25
29
|
# when decrypting the arguments when the job gets run. If you are using the
|
|
26
30
|
# environment variable, separate the keys with spaces.
|
|
27
31
|
#
|
|
28
|
-
# @
|
|
32
|
+
# @example Setting a single secret
|
|
33
|
+
# Sidekiq::EncryptedArgs.secret = "your_secret_key"
|
|
34
|
+
#
|
|
35
|
+
# @example Rolling secrets (multiple keys for backward compatibility)
|
|
36
|
+
# Sidekiq::EncryptedArgs.secret = ["new_secret", "old_secret", "older_secret"]
|
|
37
|
+
#
|
|
38
|
+
# @param [String, Array<String>] value One or more secrets to use for encrypting arguments.
|
|
29
39
|
# @return [void]
|
|
30
40
|
def secret=(value)
|
|
31
|
-
@encryptors = make_encryptors(value)
|
|
41
|
+
@encryptors = make_encryptors(value).freeze
|
|
32
42
|
end
|
|
33
43
|
|
|
34
44
|
# Add the client and server middleware to the default Sidekiq
|
|
@@ -37,9 +47,17 @@ module Sidekiq
|
|
|
37
47
|
#
|
|
38
48
|
# This method prepends client middleware and appends server middleware.
|
|
39
49
|
#
|
|
50
|
+
# @example Basic configuration
|
|
51
|
+
# Sidekiq::EncryptedArgs.configure!(secret: "your_secret_key")
|
|
52
|
+
#
|
|
53
|
+
# @example Configuration using environment variable
|
|
54
|
+
# ENV['SIDEKIQ_ENCRYPTED_ARGS_SECRET'] = "your_secret_key"
|
|
55
|
+
# Sidekiq::EncryptedArgs.configure!
|
|
56
|
+
#
|
|
40
57
|
# @param [String] secret optionally set the secret here. See {.secret=}
|
|
41
58
|
def configure!(secret: nil)
|
|
42
59
|
self.secret = secret unless secret.nil?
|
|
60
|
+
encryptors # Calling encryptors will validate that a secret is set.
|
|
43
61
|
|
|
44
62
|
Sidekiq.configure_client do |config|
|
|
45
63
|
config.client_middleware do |chain|
|
|
@@ -59,6 +77,12 @@ module Sidekiq
|
|
|
59
77
|
|
|
60
78
|
# Encrypt a value.
|
|
61
79
|
#
|
|
80
|
+
# @example Encrypting a simple value
|
|
81
|
+
# EncryptedArgs.encrypt("secret_value") #=> "encrypted_string"
|
|
82
|
+
#
|
|
83
|
+
# @example Encrypting complex data
|
|
84
|
+
# EncryptedArgs.encrypt({api_key: "secret", user_id: 123}) #=> "encrypted_string"
|
|
85
|
+
#
|
|
62
86
|
# @param [#to_json, Object] data Data to encrypt. You can pass any JSON compatible data types or structures.
|
|
63
87
|
#
|
|
64
88
|
# @return [String]
|
|
@@ -76,6 +100,12 @@ module Sidekiq
|
|
|
76
100
|
|
|
77
101
|
# Decrypt data
|
|
78
102
|
#
|
|
103
|
+
# @example Decrypting an encrypted value
|
|
104
|
+
# EncryptedArgs.decrypt("encrypted_string") #=> "original_value"
|
|
105
|
+
#
|
|
106
|
+
# @example Handling unencrypted data
|
|
107
|
+
# EncryptedArgs.decrypt("unencrypted_string") #=> "unencrypted_string"
|
|
108
|
+
#
|
|
79
109
|
# @param [String] encrypted_data Data that was previously encrypted. If the value passed in is
|
|
80
110
|
# an unencrypted string, then the string itself will be returned.
|
|
81
111
|
#
|
|
@@ -97,7 +127,10 @@ module Sidekiq
|
|
|
97
127
|
# can be `true` or an array indicating if each positional argument should be encrypted, or a hash
|
|
98
128
|
# with keys for the argument position and true as the value.
|
|
99
129
|
#
|
|
100
|
-
# @
|
|
130
|
+
# @param [String, Class] worker_class The worker class or class name
|
|
131
|
+
# @param [Hash] job The Sidekiq job hash containing arguments and metadata
|
|
132
|
+
# @return [Array<Integer>, nil] Array of argument positions to encrypt, or nil if encryption is not configured
|
|
133
|
+
# @api private
|
|
101
134
|
def encrypted_args_option(worker_class, job)
|
|
102
135
|
option = job["encrypted_args"]
|
|
103
136
|
return nil if option.nil?
|
|
@@ -107,11 +140,9 @@ module Sidekiq
|
|
|
107
140
|
if option == true
|
|
108
141
|
job["args"].size.times { |i| indexes << i }
|
|
109
142
|
elsif option.is_a?(Hash)
|
|
110
|
-
|
|
111
|
-
indexes = replace_argument_positions(worker_class, option)
|
|
143
|
+
raise ArgumentError.new("Hash-based argument encryption is no longer supported.")
|
|
112
144
|
else
|
|
113
145
|
array_type = nil
|
|
114
|
-
deprecation_message = nil
|
|
115
146
|
Array(option).each_with_index do |val, position|
|
|
116
147
|
current_type = nil
|
|
117
148
|
if val.is_a?(Integer)
|
|
@@ -123,16 +154,15 @@ module Sidekiq
|
|
|
123
154
|
indexes << position if position
|
|
124
155
|
current_type = :symbol
|
|
125
156
|
else
|
|
126
|
-
|
|
127
|
-
indexes << position if val
|
|
157
|
+
raise ArgumentError.new("Encrypted args must be specified as integers or symbols.")
|
|
128
158
|
end
|
|
129
|
-
|
|
130
|
-
|
|
159
|
+
|
|
160
|
+
if array_type && current_type != array_type
|
|
161
|
+
raise ArgumentError.new("Encrypted args cannot mix integers and symbols.")
|
|
131
162
|
else
|
|
132
163
|
array_type ||= current_type
|
|
133
164
|
end
|
|
134
165
|
end
|
|
135
|
-
deprecation_warning(deprecation_message) if deprecation_message
|
|
136
166
|
end
|
|
137
167
|
indexes
|
|
138
168
|
end
|
|
@@ -146,38 +176,47 @@ module Sidekiq
|
|
|
146
176
|
def encrypt_string(value)
|
|
147
177
|
encryptor = encryptors.first
|
|
148
178
|
return value if encryptor.nil?
|
|
179
|
+
|
|
149
180
|
encryptor.encrypt(value)
|
|
150
181
|
end
|
|
151
182
|
|
|
152
183
|
def decrypt_string(value)
|
|
153
|
-
return value if encryptors == [nil]
|
|
154
184
|
encryptors.each do |encryptor|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
# Not the right key, try the next one
|
|
159
|
-
end
|
|
185
|
+
return encryptor.decrypt(value)
|
|
186
|
+
rescue OpenSSL::Cipher::CipherError
|
|
187
|
+
# Not the right key, try the next one
|
|
160
188
|
end
|
|
161
|
-
|
|
189
|
+
|
|
190
|
+
# None of the keys worked
|
|
191
|
+
raise InvalidSecretError.new("Cannot decrypt. Invalid secret provided.")
|
|
162
192
|
end
|
|
163
193
|
|
|
164
194
|
def encryptors
|
|
165
|
-
if
|
|
166
|
-
|
|
195
|
+
if @encryptors.nil?
|
|
196
|
+
secret = ENV.fetch("SIDEKIQ_ENCRYPTED_ARGS_SECRET", "").strip
|
|
197
|
+
if secret.empty?
|
|
198
|
+
raise InvalidSecretError.new("Secret not set. Call Sidekiq::EncryptedArgs.secret= or set the SIDEKIQ_ENCRYPTED_ARGS_SECRET environment variable.")
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
@encryptors = make_encryptors(secret.split).freeze
|
|
167
202
|
end
|
|
168
203
|
@encryptors
|
|
169
204
|
end
|
|
170
205
|
|
|
206
|
+
# Create encryptors from secrets.
|
|
207
|
+
#
|
|
208
|
+
# @param [String, Array<String>] secrets One or more secrets to create encryptors from
|
|
209
|
+
# @return [Array<SecretKeys::Encryptor>, nil] Array of encryptors or nil if no secrets provided
|
|
171
210
|
def make_encryptors(secrets)
|
|
172
|
-
|
|
173
|
-
end
|
|
211
|
+
return nil if secrets.nil?
|
|
174
212
|
|
|
175
|
-
|
|
176
|
-
warn("Sidekiq::EncryptedArgs: setting encrypted_args to #{message} is deprecated; support will be removed in version 1.2.")
|
|
213
|
+
Array(secrets).map { |val| SecretKeys::Encryptor.from_password(val, SALT) }
|
|
177
214
|
end
|
|
178
215
|
|
|
179
|
-
#
|
|
180
|
-
#
|
|
216
|
+
# Convert a string class name into the actual class constant.
|
|
217
|
+
#
|
|
218
|
+
# @param [String] class_name Name of a class (e.g., "MyModule::MyClass")
|
|
219
|
+
# @return [Class] The class constant that was referenced by name
|
|
181
220
|
def constantize(class_name)
|
|
182
221
|
names = class_name.split("::")
|
|
183
222
|
# Clear leading :: for root namespace since we're already calling from object
|
|
@@ -187,20 +226,11 @@ module Sidekiq
|
|
|
187
226
|
names.inject(Object) { |constant, name| constant.const_get(name, false) }
|
|
188
227
|
end
|
|
189
228
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
position = perform_method_parameter_index(worker_class, key)
|
|
196
|
-
encrypted_indexes << position if position
|
|
197
|
-
elsif key.is_a?(Integer)
|
|
198
|
-
encrypted_indexes << key
|
|
199
|
-
end
|
|
200
|
-
end
|
|
201
|
-
encrypted_indexes
|
|
202
|
-
end
|
|
203
|
-
|
|
229
|
+
# Get the index of a parameter in the worker's perform method.
|
|
230
|
+
#
|
|
231
|
+
# @param [Class] worker_class The worker class to inspect
|
|
232
|
+
# @param [String, Symbol] parameter The parameter name to find
|
|
233
|
+
# @return [Integer, nil] The zero-based index of the parameter, or nil if not found
|
|
204
234
|
def perform_method_parameter_index(worker_class, parameter)
|
|
205
235
|
if worker_class
|
|
206
236
|
parameter = parameter.to_sym
|
|
@@ -8,6 +8,12 @@ Gem::Specification.new do |spec|
|
|
|
8
8
|
spec.homepage = "https://github.com/bdurand/sidekiq-encrypted_args"
|
|
9
9
|
spec.license = "MIT"
|
|
10
10
|
|
|
11
|
+
spec.metadata = {
|
|
12
|
+
"homepage_uri" => spec.homepage,
|
|
13
|
+
"source_code_uri" => spec.homepage,
|
|
14
|
+
"changelog_uri" => "#{spec.homepage}/blob/main/CHANGE_LOG.md"
|
|
15
|
+
}
|
|
16
|
+
|
|
11
17
|
# Specify which files should be added to the gem when it is released.
|
|
12
18
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
13
19
|
ignore_files = %w[
|
|
@@ -15,6 +21,7 @@ Gem::Specification.new do |spec|
|
|
|
15
21
|
Appraisals
|
|
16
22
|
Gemfile
|
|
17
23
|
Gemfile.lock
|
|
24
|
+
benchmark.rb
|
|
18
25
|
Rakefile
|
|
19
26
|
gemfiles/
|
|
20
27
|
spec/
|
|
@@ -27,10 +34,10 @@ Gem::Specification.new do |spec|
|
|
|
27
34
|
spec.bindir = "bin"
|
|
28
35
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
29
36
|
|
|
30
|
-
spec.required_ruby_version = ">= 2.
|
|
37
|
+
spec.required_ruby_version = ">= 2.7"
|
|
31
38
|
|
|
32
|
-
spec.add_dependency "sidekiq", ">=
|
|
39
|
+
spec.add_dependency "sidekiq", ">= 6.3"
|
|
33
40
|
spec.add_dependency "secret_keys"
|
|
34
41
|
|
|
35
|
-
spec.add_development_dependency "bundler"
|
|
42
|
+
spec.add_development_dependency "bundler"
|
|
36
43
|
end
|
metadata
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sidekiq-encrypted_args
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brian Durand
|
|
8
8
|
- Winston Durand
|
|
9
|
-
autorequire:
|
|
10
9
|
bindir: bin
|
|
11
10
|
cert_chain: []
|
|
12
|
-
date:
|
|
11
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
13
12
|
dependencies:
|
|
14
13
|
- !ruby/object:Gem::Dependency
|
|
15
14
|
name: sidekiq
|
|
@@ -17,14 +16,14 @@ dependencies:
|
|
|
17
16
|
requirements:
|
|
18
17
|
- - ">="
|
|
19
18
|
- !ruby/object:Gem::Version
|
|
20
|
-
version: '
|
|
19
|
+
version: '6.3'
|
|
21
20
|
type: :runtime
|
|
22
21
|
prerelease: false
|
|
23
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
24
23
|
requirements:
|
|
25
24
|
- - ">="
|
|
26
25
|
- !ruby/object:Gem::Version
|
|
27
|
-
version: '
|
|
26
|
+
version: '6.3'
|
|
28
27
|
- !ruby/object:Gem::Dependency
|
|
29
28
|
name: secret_keys
|
|
30
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -43,17 +42,16 @@ dependencies:
|
|
|
43
42
|
name: bundler
|
|
44
43
|
requirement: !ruby/object:Gem::Requirement
|
|
45
44
|
requirements:
|
|
46
|
-
- - "
|
|
45
|
+
- - ">="
|
|
47
46
|
- !ruby/object:Gem::Version
|
|
48
|
-
version: '
|
|
47
|
+
version: '0'
|
|
49
48
|
type: :development
|
|
50
49
|
prerelease: false
|
|
51
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
52
51
|
requirements:
|
|
53
|
-
- - "
|
|
52
|
+
- - ">="
|
|
54
53
|
- !ruby/object:Gem::Version
|
|
55
|
-
version: '
|
|
56
|
-
description:
|
|
54
|
+
version: '0'
|
|
57
55
|
email:
|
|
58
56
|
- bbdurand@gmail.com
|
|
59
57
|
- me@winstondurand.com
|
|
@@ -65,7 +63,6 @@ files:
|
|
|
65
63
|
- MIT_LICENSE.txt
|
|
66
64
|
- README.md
|
|
67
65
|
- VERSION
|
|
68
|
-
- benchmark.rb
|
|
69
66
|
- lib/sidekiq-encrypted_args.rb
|
|
70
67
|
- lib/sidekiq/encrypted_args.rb
|
|
71
68
|
- lib/sidekiq/encrypted_args/client_middleware.rb
|
|
@@ -75,8 +72,10 @@ files:
|
|
|
75
72
|
homepage: https://github.com/bdurand/sidekiq-encrypted_args
|
|
76
73
|
licenses:
|
|
77
74
|
- MIT
|
|
78
|
-
metadata:
|
|
79
|
-
|
|
75
|
+
metadata:
|
|
76
|
+
homepage_uri: https://github.com/bdurand/sidekiq-encrypted_args
|
|
77
|
+
source_code_uri: https://github.com/bdurand/sidekiq-encrypted_args
|
|
78
|
+
changelog_uri: https://github.com/bdurand/sidekiq-encrypted_args/blob/main/CHANGE_LOG.md
|
|
80
79
|
rdoc_options: []
|
|
81
80
|
require_paths:
|
|
82
81
|
- lib
|
|
@@ -84,15 +83,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
84
83
|
requirements:
|
|
85
84
|
- - ">="
|
|
86
85
|
- !ruby/object:Gem::Version
|
|
87
|
-
version: '2.
|
|
86
|
+
version: '2.7'
|
|
88
87
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
89
88
|
requirements:
|
|
90
89
|
- - ">="
|
|
91
90
|
- !ruby/object:Gem::Version
|
|
92
91
|
version: '0'
|
|
93
92
|
requirements: []
|
|
94
|
-
rubygems_version:
|
|
95
|
-
signing_key:
|
|
93
|
+
rubygems_version: 4.0.3
|
|
96
94
|
specification_version: 4
|
|
97
95
|
summary: Support for encrypting arguments that contain sensitive information in sidekiq
|
|
98
96
|
jobs.
|
data/benchmark.rb
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "bundler/setup"
|
|
4
|
-
|
|
5
|
-
require "benchmark"
|
|
6
|
-
require "sidekiq"
|
|
7
|
-
require_relative "lib/sidekiq/encrypted_args"
|
|
8
|
-
|
|
9
|
-
class WorkerWithoutEncryption
|
|
10
|
-
include Sidekiq::Worker
|
|
11
|
-
|
|
12
|
-
def perform(arg_1, arg_2, arg_3)
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
class WorkerWithEncryption
|
|
17
|
-
include Sidekiq::Worker
|
|
18
|
-
|
|
19
|
-
sidekiq_options encrypted_args: [true, true, true]
|
|
20
|
-
|
|
21
|
-
def perform(arg_1, arg_2, arg_3)
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
middleware = ->(worker_class) {
|
|
26
|
-
job = {"args" => ["foo", "bar", "baz"]}
|
|
27
|
-
Sidekiq::EncryptedArgs::ClientMiddleware.new.call(worker_class, job, "default") do
|
|
28
|
-
worker = worker_class.new
|
|
29
|
-
Sidekiq::EncryptedArgs::ServerMiddleware.new.call(worker, job, "default") do
|
|
30
|
-
worker.perform(*job["args"])
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
Benchmark.bm do |benchmark|
|
|
36
|
-
benchmark.report("No Encryption: ") { 10000.times { middleware.call(WorkerWithoutEncryption) } }
|
|
37
|
-
benchmark.report("With Encryption:") { 10000.times { middleware.call(WorkerWithEncryption) } }
|
|
38
|
-
end
|