nonnative 3.43.0 → 3.44.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/README.md +0 -3
- data/lib/nonnative/token.rb +8 -9
- data/lib/nonnative/version.rb +1 -1
- data/lib/nonnative.rb +6 -8
- metadata +1 -22
- data/lib/nonnative/ssh_token.rb +0 -69
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 86c81434b301e56014082243bce30a3ebed651adb66bdea4b8d725b040982518
|
|
4
|
+
data.tar.gz: 57c657c17907418c17392cb2a687e551d5f8830b72ce3cd4d2200eed2b4fb734
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f84551f9e069342560b321958654ebc2bf6f594e72ffc3aea9a3b5d085d3fb71e66c49c5536b76d1f1b8a289328cb9d0e9a9191b4d1a17c26c0c48c388ed785d
|
|
7
|
+
data.tar.gz: 6f955ecf1da3a0f0d374890ccca21a5414845bceab0b626e00c6d103219d80c66fc61d5d8f12c15a00acc847eaab0ba06fe8152529983409111e84e8727a36be
|
data/README.md
CHANGED
|
@@ -225,7 +225,6 @@ Supported `kind` values (all Ed25519, generation only):
|
|
|
225
225
|
|
|
226
226
|
- `jwt`: EdDSA JWT with the key id in the `kid` header. `private_key` is a PKCS#8 PEM file.
|
|
227
227
|
- `paseto`: PASETO v4.public with the key id in a `{"kid":"..."}` footer. `private_key` is a PKCS#8 PEM file. Requires system **libsodium** (via `rbnacl`); it loads lazily, so `require 'nonnative'` works without libsodium until you generate a PASETO token.
|
|
228
|
-
- `ssh`: go-service style `base64(claims).base64(signature)` with a raw Ed25519 signature over `v1` claims. `private_key` is an **OpenSSH-format** key. `issuer` and `sub` are ignored (the subject is the key id).
|
|
229
228
|
|
|
230
229
|
The audience is endpoint-scoped; build it with the helpers:
|
|
231
230
|
|
|
@@ -241,8 +240,6 @@ By default the time claims are pinned to the current time (`iat`/`nbf` at now, `
|
|
|
241
240
|
token.generate(aud: 'GET /v1/things', sub: 'user-1', not_before: Time.now + 3600)
|
|
242
241
|
```
|
|
243
242
|
|
|
244
|
-
`ssh` tokens have no `nbf` claim, so passing `not_before` for the `ssh` kind raises `ArgumentError`.
|
|
245
|
-
|
|
246
243
|
### 🔁 Lifecycle strategies (Cucumber integration)
|
|
247
244
|
|
|
248
245
|
Nonnative ships Cucumber hooks (when loaded) that support these tags/strategies:
|
data/lib/nonnative/token.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Nonnative
|
|
4
|
-
# Builds signed
|
|
4
|
+
# Builds signed JWT or PASETO tokens for authenticating against services under test.
|
|
5
5
|
#
|
|
6
6
|
# The consumer passes in the signing parameters they parsed from their own configuration; this class
|
|
7
7
|
# is not coupled to any particular service's configuration format. The generated token string is
|
|
@@ -20,7 +20,7 @@ module Nonnative
|
|
|
20
20
|
# @see Nonnative::Header.auth_bearer
|
|
21
21
|
class Token
|
|
22
22
|
# Supported token kinds mapped to their implementation.
|
|
23
|
-
KINDS = { 'jwt' => Nonnative::JwtToken, 'paseto' => Nonnative::PasetoToken
|
|
23
|
+
KINDS = { 'jwt' => Nonnative::JwtToken, 'paseto' => Nonnative::PasetoToken }.freeze
|
|
24
24
|
|
|
25
25
|
class << self
|
|
26
26
|
# Builds the audience string for an HTTP endpoint.
|
|
@@ -41,10 +41,10 @@ module Nonnative
|
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
# @param kind [String] token kind, one of `"jwt"
|
|
45
|
-
# @param issuer [String] the `iss` claim
|
|
46
|
-
# @param key [String] the key id (JWT `kid` header
|
|
47
|
-
# @param private_key [String] path to
|
|
44
|
+
# @param kind [String] token kind, one of `"jwt"` or `"paseto"`
|
|
45
|
+
# @param issuer [String] the `iss` claim
|
|
46
|
+
# @param key [String] the key id (JWT `kid` header or PASETO `kid` footer)
|
|
47
|
+
# @param private_key [String] path to a PKCS#8 Ed25519 private key PEM file
|
|
48
48
|
# @param expiration [Integer] token lifetime in seconds (drives `exp`)
|
|
49
49
|
# @raise [ArgumentError] if the kind is not supported
|
|
50
50
|
def initialize(kind:, issuer:, key:, private_key:, expiration:)
|
|
@@ -57,13 +57,12 @@ module Nonnative
|
|
|
57
57
|
# The optional time claims default to the current time (and the constructor `expiration`), so
|
|
58
58
|
# omitting them reproduces the token's normal claims. Supply them to mint tokens with specific
|
|
59
59
|
# time claims for negative auth tests, such as a not-yet-valid (future `not_before`) or
|
|
60
|
-
# clock-skewed token. Times are absolute
|
|
61
|
-
# `not_before`.
|
|
60
|
+
# clock-skewed token. Times are absolute.
|
|
62
61
|
#
|
|
63
62
|
# @param aud [String] the `aud` claim
|
|
64
63
|
# @param sub [String] the `sub` claim
|
|
65
64
|
# @param issued_at [Time, nil] overrides the `iat` claim (default: now)
|
|
66
|
-
# @param not_before [Time, nil] overrides the `nbf` claim (default: `issued_at`)
|
|
65
|
+
# @param not_before [Time, nil] overrides the `nbf` claim (default: `issued_at`)
|
|
67
66
|
# @param expires_at [Time, nil] overrides the `exp` claim (default: `issued_at` plus `expiration`)
|
|
68
67
|
# @return [String] the signed token
|
|
69
68
|
def generate(aud:, sub:, issued_at: nil, not_before: nil, expires_at: nil)
|
data/lib/nonnative/version.rb
CHANGED
data/lib/nonnative.rb
CHANGED
|
@@ -68,10 +68,9 @@ require 'rspec/wait'
|
|
|
68
68
|
require 'puma'
|
|
69
69
|
require 'puma/server'
|
|
70
70
|
|
|
71
|
-
# jwt-eddsa (with the ed25519 gem)
|
|
72
|
-
#
|
|
71
|
+
# jwt-eddsa (with the ed25519 gem) is pure Ruby and needs no system library, so it loads here.
|
|
72
|
+
# PASETO's rbnacl needs system libsodium, so Nonnative::PasetoToken requires it lazily instead.
|
|
73
73
|
require 'jwt/eddsa'
|
|
74
|
-
require 'ssh_data'
|
|
75
74
|
|
|
76
75
|
require 'nonnative/version'
|
|
77
76
|
require 'nonnative/error'
|
|
@@ -126,7 +125,6 @@ require 'nonnative/header'
|
|
|
126
125
|
require 'nonnative/ed25519_key'
|
|
127
126
|
require 'nonnative/jwt_token'
|
|
128
127
|
require 'nonnative/paseto_token'
|
|
129
|
-
require 'nonnative/ssh_token'
|
|
130
128
|
require 'nonnative/token'
|
|
131
129
|
|
|
132
130
|
# The main namespace for the gem.
|
|
@@ -218,10 +216,10 @@ module Nonnative
|
|
|
218
216
|
# The signing parameters are passed in directly; this is not coupled to any service's
|
|
219
217
|
# configuration format. The generated token string is ready for {Nonnative::Header.auth_bearer}.
|
|
220
218
|
#
|
|
221
|
-
# @param kind [String] token kind, one of `"jwt"
|
|
222
|
-
# @param issuer [String] the `iss` claim
|
|
223
|
-
# @param key [String] the key id (JWT `kid` header
|
|
224
|
-
# @param private_key [String] path to
|
|
219
|
+
# @param kind [String] token kind, one of `"jwt"` or `"paseto"`
|
|
220
|
+
# @param issuer [String] the `iss` claim
|
|
221
|
+
# @param key [String] the key id (JWT `kid` header or PASETO `kid` footer)
|
|
222
|
+
# @param private_key [String] path to a PKCS#8 Ed25519 private key PEM file
|
|
225
223
|
# @param expiration [Integer] token lifetime in seconds (drives `exp`)
|
|
226
224
|
# @return [Nonnative::Token]
|
|
227
225
|
#
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: nonnative
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.44.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alejandro Falkowski
|
|
@@ -363,26 +363,6 @@ dependencies:
|
|
|
363
363
|
- - "<"
|
|
364
364
|
- !ruby/object:Gem::Version
|
|
365
365
|
version: '5'
|
|
366
|
-
- !ruby/object:Gem::Dependency
|
|
367
|
-
name: ssh_data
|
|
368
|
-
requirement: !ruby/object:Gem::Requirement
|
|
369
|
-
requirements:
|
|
370
|
-
- - ">="
|
|
371
|
-
- !ruby/object:Gem::Version
|
|
372
|
-
version: '1'
|
|
373
|
-
- - "<"
|
|
374
|
-
- !ruby/object:Gem::Version
|
|
375
|
-
version: '3'
|
|
376
|
-
type: :runtime
|
|
377
|
-
prerelease: false
|
|
378
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
379
|
-
requirements:
|
|
380
|
-
- - ">="
|
|
381
|
-
- !ruby/object:Gem::Version
|
|
382
|
-
version: '1'
|
|
383
|
-
- - "<"
|
|
384
|
-
- !ruby/object:Gem::Version
|
|
385
|
-
version: '3'
|
|
386
366
|
description: Starts OS processes, in-process Ruby servers, and proxy-only services
|
|
387
367
|
with TCP readiness checks and fault-injection proxies.
|
|
388
368
|
email:
|
|
@@ -441,7 +421,6 @@ files:
|
|
|
441
421
|
- lib/nonnative/slicer_socket_pair.rb
|
|
442
422
|
- lib/nonnative/socket_pair.rb
|
|
443
423
|
- lib/nonnative/socket_pair_factory.rb
|
|
444
|
-
- lib/nonnative/ssh_token.rb
|
|
445
424
|
- lib/nonnative/start_error.rb
|
|
446
425
|
- lib/nonnative/startup.rb
|
|
447
426
|
- lib/nonnative/stop_error.rb
|
data/lib/nonnative/ssh_token.rb
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Nonnative
|
|
4
|
-
# Generates go-service style SSH tokens for authenticating against services under test.
|
|
5
|
-
#
|
|
6
|
-
# Despite the name this is not an SSH protocol signature: the key is loaded from an OpenSSH-format
|
|
7
|
-
# Ed25519 private key and used as a raw Ed25519 key, matching go-service's SSH token scheme. The token
|
|
8
|
-
# is `<base64(claims)>.<base64(signature)>`, where the signature is a raw Ed25519 signature over the
|
|
9
|
-
# claims JSON. Claims are ver/kid/sub/aud/iat/exp, with `sub == kid == key` and `iat`/`exp` in Unix
|
|
10
|
-
# nanoseconds. `issuer` and `sub` are accepted for a uniform interface with the other kinds but unused:
|
|
11
|
-
# SSH tokens have no issuer, and the subject is always the key id.
|
|
12
|
-
#
|
|
13
|
-
# @example
|
|
14
|
-
# ssh = Nonnative::SshToken.new(key: 'key-1', private_key: 'config/id_ed25519', expiration: 3600)
|
|
15
|
-
# ssh.generate(aud: 'GET /v1/things', sub: 'user-1')
|
|
16
|
-
#
|
|
17
|
-
# @see https://github.com/github/ssh_data ssh_data
|
|
18
|
-
class SshToken
|
|
19
|
-
# The go-service SSH token format version.
|
|
20
|
-
TOKEN_VERSION = 'v1'
|
|
21
|
-
|
|
22
|
-
# @param key [String] the key id; also used as the subject
|
|
23
|
-
# @param private_key [String] path to an OpenSSH-format Ed25519 private key file
|
|
24
|
-
# @param expiration [Integer] token lifetime in seconds (drives `exp`)
|
|
25
|
-
def initialize(key:, private_key:, expiration:, **)
|
|
26
|
-
@key = key
|
|
27
|
-
@private_key = private_key
|
|
28
|
-
@expiration = expiration
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# Generates a signed SSH token.
|
|
32
|
-
#
|
|
33
|
-
# SSH tokens carry only `iat`/`exp` (in Unix nanoseconds); there is no `nbf` claim, so
|
|
34
|
-
# `not_before` is rejected.
|
|
35
|
-
#
|
|
36
|
-
# @param aud [String] the `aud` claim (for example `"GET /v1/things"` or a gRPC full method)
|
|
37
|
-
# @param issued_at [Time, nil] overrides the `iat` claim (default: now)
|
|
38
|
-
# @param expires_at [Time, nil] overrides the `exp` claim (default: `issued_at` plus `expiration`)
|
|
39
|
-
# @raise [ArgumentError] if `not_before` is given (SSH tokens have no `nbf` claim)
|
|
40
|
-
# @return [String] the token, `"<base64(claims)>.<base64(signature)>"`
|
|
41
|
-
def generate(aud:, issued_at: nil, expires_at: nil, not_before: nil, **)
|
|
42
|
-
raise ArgumentError, "ssh tokens do not support 'not_before' (no nbf claim)" unless not_before.nil?
|
|
43
|
-
|
|
44
|
-
iat = nanoseconds(issued_at || Time.now)
|
|
45
|
-
claims = {
|
|
46
|
-
ver: TOKEN_VERSION,
|
|
47
|
-
kid: @key,
|
|
48
|
-
sub: @key,
|
|
49
|
-
aud: aud,
|
|
50
|
-
iat: iat,
|
|
51
|
-
exp: expires_at ? nanoseconds(expires_at) : iat + (@expiration * 1_000_000_000)
|
|
52
|
-
}.to_json
|
|
53
|
-
|
|
54
|
-
signature = Ed25519::SigningKey.new(seed).sign(claims)
|
|
55
|
-
|
|
56
|
-
"#{Base64.strict_encode64(claims)}.#{Base64.strict_encode64(signature)}"
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
private
|
|
60
|
-
|
|
61
|
-
def nanoseconds(time)
|
|
62
|
-
(time.to_i * 1_000_000_000) + time.nsec
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def seed
|
|
66
|
-
SSHData::PrivateKey.parse_openssh(File.read(@private_key)).first.sk[0, 32]
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
end
|