atlas_rb 1.3.6 → 1.3.8
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/.version +1 -1
- data/Gemfile.lock +5 -1
- data/README.md +65 -2
- data/lib/atlas_rb/configuration.rb +23 -0
- data/lib/atlas_rb/faraday_helper.rb +116 -24
- data/lib/atlas_rb.rb +10 -2
- metadata +16 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7f2a9947778ab6d15d96514cdeb949a82ffce8023f6fe0aeee39bfce1c198ce3
|
|
4
|
+
data.tar.gz: 864fd37a55f2275417dc5f45f1c60466b41baefc3351ed6f712c7f7dfdcda28d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: afef167fa0ed86fb7ebd4d28fe693fb41fe20f2ade2e9b96ce0f1109aec7340038b4a9c9425cf53d3463bc346aa9cf4fa90fd012cf3ad2636dad42784d040fa2
|
|
7
|
+
data.tar.gz: aec3edc7ce6cb88a6d9421b449e3420521073bd20083c86afa451d74c74d903c5dc222a85f0bff2bd2a87c094f06fe3066bae7f4b814fd367a6c0640e5a6800e
|
data/.version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.3.
|
|
1
|
+
1.3.8
|
data/Gemfile.lock
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
atlas_rb (1.3.
|
|
4
|
+
atlas_rb (1.3.8)
|
|
5
5
|
faraday (~> 2.7)
|
|
6
6
|
faraday-follow_redirects (~> 0.3.0)
|
|
7
7
|
faraday-multipart (~> 1)
|
|
8
8
|
hashie (~> 5.0)
|
|
9
|
+
jwt (~> 2.7)
|
|
9
10
|
|
|
10
11
|
GEM
|
|
11
12
|
remote: https://rubygems.org/
|
|
12
13
|
specs:
|
|
14
|
+
base64 (0.3.0)
|
|
13
15
|
diff-lcs (1.6.1)
|
|
14
16
|
faraday (2.14.2)
|
|
15
17
|
faraday-net_http (>= 2.0, < 3.5)
|
|
@@ -24,6 +26,8 @@ GEM
|
|
|
24
26
|
hashie (5.1.0)
|
|
25
27
|
logger
|
|
26
28
|
json (2.19.9)
|
|
29
|
+
jwt (2.10.3)
|
|
30
|
+
base64
|
|
27
31
|
logger (1.7.0)
|
|
28
32
|
multipart-post (2.4.1)
|
|
29
33
|
net-http (0.9.1)
|
data/README.md
CHANGED
|
@@ -25,12 +25,13 @@ Then `bundle install`, or install standalone with `gem install atlas_rb`.
|
|
|
25
25
|
|
|
26
26
|
### Environment variables
|
|
27
27
|
|
|
28
|
-
Every regular-path request reads
|
|
28
|
+
Every regular-path request reads these environment variables:
|
|
29
29
|
|
|
30
30
|
| Variable | Purpose |
|
|
31
31
|
|---------------|---------------------------------------------------------------|
|
|
32
32
|
| `ATLAS_URL` | Base URL of the Atlas API (e.g. `https://atlas.example.edu`). |
|
|
33
|
-
| `ATLAS_TOKEN` |
|
|
33
|
+
| `ATLAS_TOKEN` | Cerberus-relay bearer token used in the `Authorization` header (relay mode). |
|
|
34
|
+
| `ATLAS_JWT` | *Optional.* A personal-access JWT minted by Atlas's `POST /nuid`. When set, switches to [BYO-JWT mode](#byo-jwt-mode-standalone-scripts). |
|
|
34
35
|
|
|
35
36
|
```ruby
|
|
36
37
|
ENV["ATLAS_URL"] = "https://atlas.example.edu"
|
|
@@ -76,6 +77,68 @@ AtlasRb::Work.find("w-789", nuid: "X")
|
|
|
76
77
|
If neither the call site nor the registered default supplies a value,
|
|
77
78
|
no header is sent (legacy bearer-only path preserved).
|
|
78
79
|
|
|
80
|
+
### BYO-JWT mode (standalone scripts)
|
|
81
|
+
|
|
82
|
+
The relay path above is what a Rails host (Cerberus) uses: a shared
|
|
83
|
+
`ATLAS_TOKEN` plus a `User: NUID` header naming the acting person. For
|
|
84
|
+
**standalone scripts** — a librarian automating their own workflow — Atlas
|
|
85
|
+
also accepts a *personal-access JWT*, minted by Cerberus post-SSO via
|
|
86
|
+
`POST /nuid` and handed to the user. Set it as `ATLAS_JWT` and the gem
|
|
87
|
+
switches transport modes:
|
|
88
|
+
|
|
89
|
+
```ruby
|
|
90
|
+
ENV["ATLAS_URL"] = "https://atlas.example.edu"
|
|
91
|
+
ENV["ATLAS_JWT"] = "<token minted for you by Cerberus>" # 1-week TTL
|
|
92
|
+
|
|
93
|
+
# Identity is carried by the token — no nuid plumbing needed:
|
|
94
|
+
AtlasRb::Work.find("w-789")
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
In BYO-JWT mode:
|
|
98
|
+
|
|
99
|
+
- The JWT is the bearer, **taking precedence over `ATLAS_TOKEN`**.
|
|
100
|
+
- **No `User:` header is sent** — the token already encodes the acting
|
|
101
|
+
user, and any `nuid:` kwarg or `default_nuid` is ignored on this path.
|
|
102
|
+
- **`On-Behalf-Of` is suppressed** — acting-as is a Cerberus-relay-only
|
|
103
|
+
concept; Atlas rejects it on the JWT path with a 403. Any `on_behalf_of:`
|
|
104
|
+
kwarg or `default_on_behalf_of` is dropped.
|
|
105
|
+
|
|
106
|
+
To rotate or revoke, ask Cerberus to regenerate your token (Atlas rotates
|
|
107
|
+
the user's `jti`, invalidating outstanding tokens — single-token model).
|
|
108
|
+
|
|
109
|
+
### Relay-signing mode (the `ATLAS_TOKEN` replacement)
|
|
110
|
+
|
|
111
|
+
The default relay authenticates with the shared `ATLAS_TOKEN` and *asserts* the
|
|
112
|
+
acting user via a `User: NUID` header. Relay-signing replaces that with a
|
|
113
|
+
**proven** identity: the relay **signs** a short-lived assertion with its own
|
|
114
|
+
private key (`iss=cerberus`, `aud=atlas`, `sub` = the acting nuid, ES256), which
|
|
115
|
+
Atlas verifies against the matching public key. No shared secret, no asserted
|
|
116
|
+
header.
|
|
117
|
+
|
|
118
|
+
Configure a signing key (and the `kid` Atlas indexes its public key by) — value
|
|
119
|
+
or callable, so a Rails host reads it from credentials at request time:
|
|
120
|
+
|
|
121
|
+
```ruby
|
|
122
|
+
AtlasRb.configure do |config|
|
|
123
|
+
config.assertion_signing_key = -> { Rails.application.credentials.cerberus_signing_key }
|
|
124
|
+
config.assertion_signing_kid = -> { Rails.application.credentials.cerberus_signing_kid }
|
|
125
|
+
end
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
When a signing key is configured, the regular relay (`connection` / `multipart`)
|
|
129
|
+
signs instead of sending `ATLAS_TOKEN` + `User:`. Otherwise it behaves exactly as
|
|
130
|
+
before — so signing **coexists with `ATLAS_TOKEN` during cutover** (turn it on by
|
|
131
|
+
configuring the key; roll back by clearing it).
|
|
132
|
+
|
|
133
|
+
Two carve-outs keep the boundaries safe:
|
|
134
|
+
|
|
135
|
+
- **Acting-as auto-falls-back to the `ATLAS_TOKEN` relay.** An `on_behalf_of`
|
|
136
|
+
request is *not* signed — Atlas rejects `On-Behalf-Of` on the assertion path
|
|
137
|
+
(403) until a signed `obo` claim ships, so the gem keeps acting-as on the
|
|
138
|
+
legacy relay rather than letting it 403.
|
|
139
|
+
- **`ATLAS_JWT` still wins.** A personal token (BYO-JWT) takes precedence over
|
|
140
|
+
relay-signing.
|
|
141
|
+
|
|
79
142
|
### System-path credentials
|
|
80
143
|
|
|
81
144
|
Calls under `AtlasRb::System::*` (currently just SSO user provisioning)
|
|
@@ -44,5 +44,28 @@ module AtlasRb
|
|
|
44
44
|
# @return [Proc, nil] callable returning the on-behalf-of NUID, or nil
|
|
45
45
|
# to send no `On-Behalf-Of:` header.
|
|
46
46
|
attr_accessor :default_on_behalf_of
|
|
47
|
+
|
|
48
|
+
# Relay signing (the cerberus_token replacement). When set, the regular
|
|
49
|
+
# relay path *signs* a short-lived assertion (ES256, `sub` = acting nuid)
|
|
50
|
+
# instead of sending `ATLAS_TOKEN` + a `User:` header — identity becomes
|
|
51
|
+
# proven, not asserted. Leave nil (the default) to keep the legacy relay.
|
|
52
|
+
#
|
|
53
|
+
# Accepts either a value or a callable (resolved per request, so a Rails
|
|
54
|
+
# host can read it from request-scoped state / credentials). The value may
|
|
55
|
+
# be a PEM string or an `OpenSSL::PKey`; a PEM is parsed for you.
|
|
56
|
+
#
|
|
57
|
+
# @example Rails host (initializer), reading the EC private key from credentials
|
|
58
|
+
# AtlasRb.configure do |config|
|
|
59
|
+
# config.assertion_signing_key = -> { Rails.application.credentials.cerberus_signing_key }
|
|
60
|
+
# config.assertion_signing_kid = -> { Rails.application.credentials.cerberus_signing_kid }
|
|
61
|
+
# end
|
|
62
|
+
#
|
|
63
|
+
# @return [String, OpenSSL::PKey, Proc, nil] EC private key (PEM/key/callable), or nil.
|
|
64
|
+
attr_accessor :assertion_signing_key
|
|
65
|
+
|
|
66
|
+
# @return [String, Proc, nil] the `kid` stamped in the assertion header so
|
|
67
|
+
# Atlas selects the matching public key. Value or callable. Required when
|
|
68
|
+
# {#assertion_signing_key} is set.
|
|
69
|
+
attr_accessor :assertion_signing_kid
|
|
47
70
|
end
|
|
48
71
|
end
|
|
@@ -3,22 +3,54 @@
|
|
|
3
3
|
module AtlasRb
|
|
4
4
|
# HTTP transport helpers shared by every resource class.
|
|
5
5
|
#
|
|
6
|
-
# Every Atlas request reads
|
|
6
|
+
# Every Atlas request reads these environment variables:
|
|
7
7
|
#
|
|
8
8
|
# - `ATLAS_URL` — base URL of the Atlas API (e.g. `https://atlas.example.edu`).
|
|
9
|
-
# - `ATLAS_TOKEN` — bearer token used in the `Authorization`
|
|
9
|
+
# - `ATLAS_TOKEN` — Cerberus-relay bearer token used in the `Authorization`
|
|
10
|
+
# header on the default (relay) path.
|
|
11
|
+
# - `ATLAS_JWT` — *optional* personal-access JWT (minted by Atlas's
|
|
12
|
+
# `POST /nuid`, Cerberus-delegated post-SSO). When set, it switches the
|
|
13
|
+
# transport into **bring-your-own-JWT mode** (see below).
|
|
10
14
|
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
+
# ## Two transport modes
|
|
16
|
+
#
|
|
17
|
+
# **Relay mode (default, `ATLAS_JWT` unset).** Authenticates with
|
|
18
|
+
# `ATLAS_TOKEN` and identifies the acting user via a `User: NUID <nuid>`
|
|
19
|
+
# header, optionally an `On-Behalf-Of: NUID <nuid>` header for acting-as /
|
|
20
|
+
# view-as flows. When `nuid` / `on_behalf_of` are omitted (positional arg
|
|
21
|
+
# `nil`, kwarg `nil`), the helper falls through to {AtlasRb.config}'s
|
|
15
22
|
# `default_nuid` / `default_on_behalf_of` callables — host applications wire
|
|
16
23
|
# those up to their request-scoped `Current.*` source. Caller-passed values
|
|
17
|
-
# always win over the configured defaults.
|
|
24
|
+
# always win over the configured defaults. This is the path Cerberus uses.
|
|
25
|
+
#
|
|
26
|
+
# **BYO-JWT mode (`ATLAS_JWT` set).** Authenticates with the JWT, which
|
|
27
|
+
# already encodes the acting user — so **no `User:` header is sent**, and
|
|
28
|
+
# `On-Behalf-Of` is **suppressed** (Atlas rejects acting-as on the JWT path
|
|
29
|
+
# with a 403; acting-as is a relay-only concept). `ATLAS_JWT` takes
|
|
30
|
+
# precedence over `ATLAS_TOKEN`. This is the standalone-script path: a
|
|
31
|
+
# librarian exports their minted token and runs headless against the API.
|
|
32
|
+
#
|
|
33
|
+
# **Relay-signing mode ({AtlasRb.config#assertion_signing_key} set).** The
|
|
34
|
+
# cryptographic replacement for the `ATLAS_TOKEN` relay: instead of a shared
|
|
35
|
+
# secret + an asserted `User:` header, the regular relay path **signs** a
|
|
36
|
+
# short-lived assertion (ES256, `iss=cerberus`, `aud=atlas`, `sub` = the
|
|
37
|
+
# acting nuid) with Cerberus's private key — Atlas verifies it with the
|
|
38
|
+
# public key. No `User:` header; identity is the proven `sub`. **Acting-as
|
|
39
|
+
# auto-falls-back to the legacy relay**: an `on_behalf_of` request is NOT
|
|
40
|
+
# signed (Atlas 403s `On-Behalf-Of` on the assertion path until a signed
|
|
41
|
+
# `obo` claim ships), so the boundary cannot be violated by a caller. Off
|
|
42
|
+
# unless a signing key is configured (so it coexists with `ATLAS_TOKEN`
|
|
43
|
+
# during cutover). `ATLAS_JWT`, if set, still wins over signing.
|
|
18
44
|
#
|
|
19
45
|
# The module is mixed in via `extend`, so its methods become class methods on
|
|
20
46
|
# the host (e.g. `AtlasRb::Work.connection({})`).
|
|
21
47
|
module FaradayHelper
|
|
48
|
+
# Wire contract Atlas enforces for relay-signing assertions (see Atlas
|
|
49
|
+
# ApplicationController#verify_cerberus_assertion). iss/aud are fixed; the
|
|
50
|
+
# short TTL bounds replay (Atlas allows 30s leeway on exp).
|
|
51
|
+
ASSERTION_ISSUER = "cerberus"
|
|
52
|
+
ASSERTION_AUDIENCE = "atlas"
|
|
53
|
+
ASSERTION_TTL = 30 # seconds
|
|
22
54
|
# Build a JSON-content Faraday connection to the Atlas API.
|
|
23
55
|
#
|
|
24
56
|
# @param params [Hash] query-string / body params to attach to the request.
|
|
@@ -43,15 +75,7 @@ module AtlasRb
|
|
|
43
75
|
# @example Fetching a community
|
|
44
76
|
# AtlasRb::Community.connection({}).get('/communities/abc123')
|
|
45
77
|
def connection(params, nuid=nil, on_behalf_of: nil, idempotency_key: nil)
|
|
46
|
-
nuid
|
|
47
|
-
on_behalf_of ||= AtlasRb.config.default_on_behalf_of&.call
|
|
48
|
-
|
|
49
|
-
headers = {
|
|
50
|
-
"Content-Type" => "application/json",
|
|
51
|
-
"Authorization" => "Bearer #{ENV.fetch("ATLAS_TOKEN", nil)}"
|
|
52
|
-
}
|
|
53
|
-
headers["User"] = "NUID #{nuid}" if nuid
|
|
54
|
-
headers["On-Behalf-Of"] = "NUID #{on_behalf_of}" if on_behalf_of
|
|
78
|
+
headers = auth_headers(nuid, on_behalf_of).merge("Content-Type" => "application/json")
|
|
55
79
|
headers["Idempotency-Key"] = idempotency_key if idempotency_key
|
|
56
80
|
|
|
57
81
|
Faraday.new(
|
|
@@ -91,14 +115,7 @@ module AtlasRb
|
|
|
91
115
|
# }
|
|
92
116
|
# AtlasRb::Blob.multipart.post('/files/', payload)
|
|
93
117
|
def multipart(nuid=nil, on_behalf_of: nil, idempotency_key: nil)
|
|
94
|
-
nuid
|
|
95
|
-
on_behalf_of ||= AtlasRb.config.default_on_behalf_of&.call
|
|
96
|
-
|
|
97
|
-
headers = {
|
|
98
|
-
"Authorization" => "Bearer #{ENV.fetch("ATLAS_TOKEN", nil)}"
|
|
99
|
-
}
|
|
100
|
-
headers["User"] = "NUID #{nuid}" if nuid
|
|
101
|
-
headers["On-Behalf-Of"] = "NUID #{on_behalf_of}" if on_behalf_of
|
|
118
|
+
headers = auth_headers(nuid, on_behalf_of)
|
|
102
119
|
headers["Idempotency-Key"] = idempotency_key if idempotency_key
|
|
103
120
|
|
|
104
121
|
Faraday.new(
|
|
@@ -149,5 +166,80 @@ module AtlasRb
|
|
|
149
166
|
f.adapter Faraday.default_adapter
|
|
150
167
|
end
|
|
151
168
|
end
|
|
169
|
+
|
|
170
|
+
private
|
|
171
|
+
|
|
172
|
+
# Build the auth + identity headers shared by {#connection} and {#multipart}.
|
|
173
|
+
# Precedence: ATLAS_JWT (BYO-JWT) > relay-signing > ATLAS_TOKEN relay. The
|
|
174
|
+
# acting nuid / on_behalf_of fall through to the configured `default_nuid` /
|
|
175
|
+
# `default_on_behalf_of` callables here, once, for whichever mode applies.
|
|
176
|
+
def auth_headers(nuid, on_behalf_of)
|
|
177
|
+
jwt = ENV.fetch("ATLAS_JWT", nil)
|
|
178
|
+
return { "Authorization" => "Bearer #{jwt}" } if jwt
|
|
179
|
+
|
|
180
|
+
nuid ||= AtlasRb.config.default_nuid&.call
|
|
181
|
+
on_behalf_of ||= AtlasRb.config.default_on_behalf_of&.call
|
|
182
|
+
|
|
183
|
+
signed_relay_headers(nuid, on_behalf_of) || relay_headers(nuid, on_behalf_of)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# A signed-assertion Authorization header (sub = acting nuid), or nil to
|
|
187
|
+
# defer to the legacy relay. nil when signing isn't configured, there is no
|
|
188
|
+
# acting nuid to put in `sub`, or this is an acting-as request — On-Behalf-Of
|
|
189
|
+
# stays on the cerberus_token relay (Atlas 403s it on the assertion path),
|
|
190
|
+
# so the boundary can't be violated by a caller.
|
|
191
|
+
def signed_relay_headers(nuid, on_behalf_of)
|
|
192
|
+
return nil unless nuid && on_behalf_of.nil?
|
|
193
|
+
|
|
194
|
+
key = assertion_signing_key
|
|
195
|
+
return nil unless key
|
|
196
|
+
|
|
197
|
+
{ "Authorization" => "Bearer #{signed_assertion(nuid.to_s, key)}" }
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# Legacy relay headers: ATLAS_TOKEN bearer + acting-user identity headers.
|
|
201
|
+
# `nuid` / `on_behalf_of` are already resolved by {#auth_headers}.
|
|
202
|
+
def relay_headers(nuid, on_behalf_of)
|
|
203
|
+
headers = { "Authorization" => "Bearer #{ENV.fetch("ATLAS_TOKEN", nil)}" }
|
|
204
|
+
headers["User"] = "NUID #{nuid}" if nuid
|
|
205
|
+
headers["On-Behalf-Of"] = "NUID #{on_behalf_of}" if on_behalf_of
|
|
206
|
+
headers
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# Mint a Cerberus relay assertion for `nuid`, signed ES256 with `key`. The
|
|
210
|
+
# `kid` header tells Atlas which public key to verify against; iss/aud are
|
|
211
|
+
# the fixed contract; the short TTL bounds replay; `jti` is forward-compat
|
|
212
|
+
# for an Atlas-side one-time cache.
|
|
213
|
+
def signed_assertion(nuid, key)
|
|
214
|
+
now = Time.now.to_i
|
|
215
|
+
payload = {
|
|
216
|
+
"iss" => ASSERTION_ISSUER,
|
|
217
|
+
"aud" => ASSERTION_AUDIENCE,
|
|
218
|
+
"sub" => nuid,
|
|
219
|
+
"iat" => now,
|
|
220
|
+
"exp" => now + ASSERTION_TTL,
|
|
221
|
+
"jti" => SecureRandom.uuid
|
|
222
|
+
}
|
|
223
|
+
JWT.encode(payload, key, "ES256", { kid: assertion_signing_kid })
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# Resolve the configured signing key to an OpenSSL::PKey, or nil if signing
|
|
227
|
+
# is not configured. Accepts a callable (resolved per request), a PEM
|
|
228
|
+
# string (parsed), or an already-built key.
|
|
229
|
+
def assertion_signing_key
|
|
230
|
+
raw = config_value(AtlasRb.config.assertion_signing_key)
|
|
231
|
+
return nil if raw.nil?
|
|
232
|
+
|
|
233
|
+
raw.is_a?(OpenSSL::PKey::PKey) ? raw : OpenSSL::PKey.read(raw)
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def assertion_signing_kid
|
|
237
|
+
config_value(AtlasRb.config.assertion_signing_kid)
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
# Config slots may hold a value or a callable resolved at request time.
|
|
241
|
+
def config_value(value)
|
|
242
|
+
value.respond_to?(:call) ? value.call : value
|
|
243
|
+
end
|
|
152
244
|
end
|
|
153
245
|
end
|
data/lib/atlas_rb.rb
CHANGED
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
require "faraday"
|
|
4
4
|
require "faraday/multipart"
|
|
5
5
|
require "faraday/follow_redirects"
|
|
6
|
+
require "jwt"
|
|
7
|
+
require "openssl"
|
|
8
|
+
require "securerandom"
|
|
6
9
|
require_relative "atlas_rb/version"
|
|
7
10
|
require_relative "atlas_rb/errors"
|
|
8
11
|
require_relative "atlas_rb/configuration"
|
|
@@ -32,10 +35,15 @@ require_relative "atlas_rb/audit_event"
|
|
|
32
35
|
#
|
|
33
36
|
# ## Configuration
|
|
34
37
|
#
|
|
35
|
-
#
|
|
38
|
+
# Environment variables drive every request:
|
|
36
39
|
#
|
|
37
40
|
# - `ATLAS_URL` — base URL of the Atlas API (e.g. `https://atlas.example.edu`).
|
|
38
|
-
# - `ATLAS_TOKEN` — bearer token sent in the `Authorization`
|
|
41
|
+
# - `ATLAS_TOKEN` — Cerberus-relay bearer token sent in the `Authorization`
|
|
42
|
+
# header on the default path.
|
|
43
|
+
# - `ATLAS_JWT` — optional personal-access JWT (minted by Atlas's
|
|
44
|
+
# `POST /nuid`). When set, the transport runs in bring-your-own-JWT mode:
|
|
45
|
+
# the JWT is the bearer and no `User:` / `On-Behalf-Of:` headers are sent.
|
|
46
|
+
# See {AtlasRb::FaradayHelper} for the mode semantics.
|
|
39
47
|
#
|
|
40
48
|
# {AtlasRb::Authentication} additionally accepts an NUID (Northeastern
|
|
41
49
|
# University ID) which is forwarded in a `User: NUID <nuid>` header so the
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: atlas_rb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.3.
|
|
4
|
+
version: 1.3.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Cliff
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-06-
|
|
11
|
+
date: 2026-06-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|
|
@@ -24,6 +24,20 @@ dependencies:
|
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: '2.7'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: jwt
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '2.7'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '2.7'
|
|
27
41
|
- !ruby/object:Gem::Dependency
|
|
28
42
|
name: faraday-multipart
|
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|