legion-crypt 1.4.0 → 1.4.2
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 +14 -0
- data/CLAUDE.md +45 -1
- data/README.md +19 -0
- data/legion-crypt.gemspec +1 -0
- data/lib/legion/crypt/attestation.rb +39 -0
- data/lib/legion/crypt/ed25519.rb +63 -0
- data/lib/legion/crypt/erasure.rb +43 -0
- data/lib/legion/crypt/mock_vault.rb +40 -0
- data/lib/legion/crypt/partition_keys.rb +43 -0
- data/lib/legion/crypt/version.rb +1 -1
- metadata +20 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 171a3a22eeb730be2a47dccb7f96ec1b4ffcf4df03792eae594f63b61106224a
|
|
4
|
+
data.tar.gz: 597ca3ea73e5864a572621312cf7ff0efea424c4e3e05c22e16f0044deb97753
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fb76b8b671a10380aaccb82eb62f611f9998112bd95ec8a5b184679b1694204d3b7adb14b3c7f141ae072254671728bf2b8b1701c94291f0b285ccb335d0e15e
|
|
7
|
+
data.tar.gz: 8d0d58cb2c9d4fc543fc7d3be4628142405c388e1436211df59d1d26614c18d49f6e158ab25e440b643401c8c527de1160470a0623536a4f79040fb2f475a6fc
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [1.4.2] - 2026-03-16
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- `Legion::Crypt::Ed25519`: Ed25519 key generation, signing, verification, Vault key storage
|
|
9
|
+
- `Legion::Crypt::PartitionKeys`: HKDF-based per-tenant key derivation with AES-256-GCM encrypt/decrypt
|
|
10
|
+
- `Legion::Crypt::Erasure`: cryptographic erasure via Vault master key deletion with event emission
|
|
11
|
+
- `Legion::Crypt::Attestation`: signed identity claims with Ed25519 signatures and freshness checking
|
|
12
|
+
- Dependency: `ed25519` gem ~> 1.3
|
|
13
|
+
|
|
14
|
+
## [1.4.1] - 2026-03-16
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
- `Legion::Crypt::MockVault` in-memory Vault mock for local development mode
|
|
18
|
+
|
|
5
19
|
## [1.4.0] - 2026-03-16
|
|
6
20
|
|
|
7
21
|
### Added
|
data/CLAUDE.md
CHANGED
|
@@ -34,8 +34,14 @@ Legion::Crypt (singleton module)
|
|
|
34
34
|
├── JWT # JSON Web Token operations
|
|
35
35
|
│ ├── .issue # Create signed JWT (HS256 or RS256)
|
|
36
36
|
│ ├── .verify # Verify and decode JWT
|
|
37
|
+
│ ├── .verify_with_jwks # Verify RS256 token via external JWKS endpoint (Entra ID, etc.)
|
|
37
38
|
│ └── .decode # Decode without verification (inspection)
|
|
38
39
|
│
|
|
40
|
+
├── JwksClient # External JWKS endpoint integration (thread-safe)
|
|
41
|
+
│ ├── .fetch_keys # Fetch and parse JWKS from a URL
|
|
42
|
+
│ ├── .find_key # Lookup key by kid (cache-first, re-fetch on miss)
|
|
43
|
+
│ └── .clear_cache # Clear the key cache
|
|
44
|
+
│
|
|
39
45
|
├── ClusterSecret # Cluster-wide shared secret management
|
|
40
46
|
│ └── .cs # Generate/distribute cluster secret
|
|
41
47
|
│
|
|
@@ -45,7 +51,12 @@ Legion::Crypt (singleton module)
|
|
|
45
51
|
│ └── .worker_login # Issue a Legion JWT and authenticate to Vault in one step
|
|
46
52
|
│
|
|
47
53
|
├── VaultRenewer # Background Vault token renewal thread
|
|
54
|
+
├── Ed25519 # Ed25519 key generation, signing, verification, Vault storage
|
|
55
|
+
├── PartitionKeys # HKDF per-tenant key derivation, AES-256-GCM encrypt/decrypt
|
|
56
|
+
├── Erasure # Cryptographic erasure via Vault master key deletion
|
|
57
|
+
├── Attestation # Signed identity claims with Ed25519, freshness checking
|
|
48
58
|
├── LeaseManager # Dynamic Vault lease lifecycle: fetch, cache, renew, rotate, push-back
|
|
59
|
+
├── MockVault # In-memory Vault mock for local development mode
|
|
49
60
|
├── Settings # Default crypt config
|
|
50
61
|
└── Version
|
|
51
62
|
```
|
|
@@ -57,6 +68,7 @@ Legion::Crypt (singleton module)
|
|
|
57
68
|
- **Vault Conditional**: Vault module is only included if the `vault` gem is available
|
|
58
69
|
- **Token Lifecycle**: VaultRenewer runs background thread for automatic token renewal
|
|
59
70
|
- **JWT Dual Algorithm**: HS256 (symmetric, cluster secret) for intra-cluster tokens; RS256 (asymmetric, RSA keypair) for tokens verifiable without sharing the signing key
|
|
71
|
+
- **JWKS External Validation**: `JwksClient` fetches public keys from external identity provider JWKS endpoints (Entra ID, Bot Framework). Keys cached for 1 hour (CACHE_TTL=3600s), thread-safe via Mutex, automatic re-fetch on cache miss handles key rotation
|
|
60
72
|
|
|
61
73
|
## Default Settings
|
|
62
74
|
|
|
@@ -83,6 +95,7 @@ Legion::Crypt (singleton module)
|
|
|
83
95
|
|
|
84
96
|
| Gem | Purpose |
|
|
85
97
|
|-----|---------|
|
|
98
|
+
| `ed25519` (~> 1.3) | Ed25519 key operations (pure Ruby) |
|
|
86
99
|
| `jwt` (>= 2.7) | JSON Web Token encoding/decoding |
|
|
87
100
|
| `vault` (>= 0.17) | HashiCorp Vault Ruby client |
|
|
88
101
|
|
|
@@ -94,13 +107,18 @@ Dev dependencies: `legion-logging`, `legion-settings`
|
|
|
94
107
|
|------|---------|
|
|
95
108
|
| `lib/legion/crypt.rb` | Module entry, start/shutdown lifecycle |
|
|
96
109
|
| `lib/legion/crypt/cipher.rb` | AES-256-CBC encrypt/decrypt, RSA key generation |
|
|
97
|
-
| `lib/legion/crypt/jwt.rb` | JWT issue/verify/decode operations |
|
|
110
|
+
| `lib/legion/crypt/jwt.rb` | JWT issue/verify/decode/verify_with_jwks operations |
|
|
111
|
+
| `lib/legion/crypt/jwks_client.rb` | JWKS endpoint fetch, parse, cache (thread-safe, 1hr TTL) |
|
|
98
112
|
| `lib/legion/crypt/vault.rb` | Vault read/write/connect/renew operations |
|
|
99
113
|
| `lib/legion/crypt/cluster_secret.rb` | Cluster-wide shared secret management |
|
|
100
114
|
| `lib/legion/crypt/vault_jwt_auth.rb` | Vault JWT auth backend: `.login`, `.login!`, `.worker_login`; raises `AuthError` on failure |
|
|
101
115
|
| `lib/legion/crypt/vault_renewer.rb` | Background Vault token renewal |
|
|
102
116
|
| `lib/legion/crypt/lease_manager.rb` | Dynamic Vault lease lifecycle management |
|
|
103
117
|
| `lib/legion/crypt/settings.rb` | Default configuration |
|
|
118
|
+
| `lib/legion/crypt/ed25519.rb` | Ed25519 key generation, signing, verification, Vault storage |
|
|
119
|
+
| `lib/legion/crypt/partition_keys.rb` | HKDF per-tenant key derivation with AES-256-GCM |
|
|
120
|
+
| `lib/legion/crypt/erasure.rb` | Cryptographic erasure via Vault master key deletion |
|
|
121
|
+
| `lib/legion/crypt/attestation.rb` | Signed identity claims with Ed25519 signatures |
|
|
104
122
|
| `lib/legion/crypt/version.rb` | VERSION constant |
|
|
105
123
|
|
|
106
124
|
## Role in LegionIO
|
|
@@ -110,6 +128,7 @@ First service-level module initialized during `Legion::Service` startup (before
|
|
|
110
128
|
2. Message encryption for `legion-transport` (optional `transport.messages.encrypt`)
|
|
111
129
|
3. Cluster secret for inter-node encrypted communication
|
|
112
130
|
4. JWT tokens for node authentication and task authorization
|
|
131
|
+
5. External token verification for identity providers (Entra ID OIDC via JWKS)
|
|
113
132
|
|
|
114
133
|
### Vault JWT Auth Usage
|
|
115
134
|
|
|
@@ -144,6 +163,31 @@ decoded = Legion::Crypt::JWT.decode(token) # no verification, inspection only
|
|
|
144
163
|
- `HS256` (default): Uses cluster secret. All cluster nodes can issue and verify.
|
|
145
164
|
- `RS256`: Uses RSA keypair. Only the issuing node can sign; anyone with the public key can verify.
|
|
146
165
|
|
|
166
|
+
### External Token Verification (JWKS)
|
|
167
|
+
|
|
168
|
+
Verify tokens from external identity providers using their public JWKS endpoints:
|
|
169
|
+
|
|
170
|
+
```ruby
|
|
171
|
+
# Convenience method
|
|
172
|
+
claims = Legion::Crypt.verify_external_token(
|
|
173
|
+
token,
|
|
174
|
+
jwks_url: 'https://login.microsoftonline.com/TENANT/discovery/v2.0/keys',
|
|
175
|
+
issuers: ['https://login.microsoftonline.com/TENANT/v2.0'],
|
|
176
|
+
audience: 'app-client-id'
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
# Direct module usage
|
|
180
|
+
claims = Legion::Crypt::JWT.verify_with_jwks(token, jwks_url: jwks_url)
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**Flow:** decode JWT header (unverified) to extract `kid` -> `JwksClient.find_key` fetches the matching public key from cache or JWKS endpoint -> verify JWT signature with the public key.
|
|
184
|
+
|
|
185
|
+
**Options:** `issuers:` (array, multi-issuer support), `audience:` (string), `verify_expiration:` (bool, default true).
|
|
186
|
+
|
|
187
|
+
**Error hierarchy:** `ExpiredTokenError`, `InvalidTokenError` (bad signature, wrong issuer, wrong audience), `DecodeError` (malformed token) — all inherit from `Legion::Crypt::JWT::Error`.
|
|
188
|
+
|
|
189
|
+
**Used by:** `lex-identity` Entra runner for Digital Worker OIDC token validation.
|
|
190
|
+
|
|
147
191
|
---
|
|
148
192
|
|
|
149
193
|
**Maintained By**: Matthew Iverson (@Esity)
|
data/README.md
CHANGED
|
@@ -41,6 +41,25 @@ claims = Legion::Crypt.verify_token(token, algorithm: 'RS256')
|
|
|
41
41
|
decoded = Legion::Crypt::JWT.decode(token)
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
+
### External Token Verification (JWKS)
|
|
45
|
+
|
|
46
|
+
Verify tokens from external identity providers (Entra ID, Bot Framework) using their public JWKS endpoints:
|
|
47
|
+
|
|
48
|
+
```ruby
|
|
49
|
+
# Verify an Entra ID OIDC token
|
|
50
|
+
claims = Legion::Crypt.verify_external_token(
|
|
51
|
+
token,
|
|
52
|
+
jwks_url: 'https://login.microsoftonline.com/TENANT/discovery/v2.0/keys',
|
|
53
|
+
issuers: ['https://login.microsoftonline.com/TENANT/v2.0'],
|
|
54
|
+
audience: 'app-client-id'
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
# Or use the JWT module directly
|
|
58
|
+
claims = Legion::Crypt::JWT.verify_with_jwks(token, jwks_url: jwks_url)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Public keys are cached for 1 hour and automatically re-fetched on cache miss (handles key rotation).
|
|
62
|
+
|
|
44
63
|
## Configuration
|
|
45
64
|
|
|
46
65
|
```json
|
data/legion-crypt.gemspec
CHANGED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'securerandom'
|
|
4
|
+
|
|
5
|
+
module Legion
|
|
6
|
+
module Crypt
|
|
7
|
+
module Attestation
|
|
8
|
+
class << self
|
|
9
|
+
def create(agent_id:, capabilities:, state:, private_key:)
|
|
10
|
+
claim = {
|
|
11
|
+
agent_id: agent_id,
|
|
12
|
+
capabilities: Array(capabilities),
|
|
13
|
+
state: state.to_s,
|
|
14
|
+
timestamp: Time.now.utc.iso8601,
|
|
15
|
+
nonce: SecureRandom.hex(16)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
payload = Legion::JSON.dump(claim)
|
|
19
|
+
signature = Legion::Crypt::Ed25519.sign(payload, private_key)
|
|
20
|
+
|
|
21
|
+
{ claim: claim, signature: signature.unpack1('H*'), payload: payload }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def verify(claim_hash:, signature_hex:, public_key:)
|
|
25
|
+
payload = Legion::JSON.dump(claim_hash)
|
|
26
|
+
signature = [signature_hex].pack('H*')
|
|
27
|
+
Legion::Crypt::Ed25519.verify(payload, signature, public_key)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def fresh?(claim_hash, max_age_seconds: 300)
|
|
31
|
+
timestamp = Time.parse(claim_hash[:timestamp])
|
|
32
|
+
Time.now.utc - timestamp < max_age_seconds
|
|
33
|
+
rescue StandardError
|
|
34
|
+
false
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'ed25519'
|
|
4
|
+
|
|
5
|
+
module Legion
|
|
6
|
+
module Crypt
|
|
7
|
+
module Ed25519
|
|
8
|
+
class << self
|
|
9
|
+
def generate_keypair
|
|
10
|
+
signing_key = ::Ed25519::SigningKey.generate
|
|
11
|
+
{
|
|
12
|
+
private_key: signing_key.to_bytes,
|
|
13
|
+
public_key: signing_key.verify_key.to_bytes,
|
|
14
|
+
public_key_hex: signing_key.verify_key.to_bytes.unpack1('H*')
|
|
15
|
+
}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def sign(message, private_key_bytes)
|
|
19
|
+
signing_key = ::Ed25519::SigningKey.new(private_key_bytes)
|
|
20
|
+
signing_key.sign(message)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def verify(message, signature, public_key_bytes)
|
|
24
|
+
verify_key = ::Ed25519::VerifyKey.new(public_key_bytes)
|
|
25
|
+
verify_key.verify(signature, message)
|
|
26
|
+
true
|
|
27
|
+
rescue ::Ed25519::VerifyError
|
|
28
|
+
false
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def store_keypair(agent_id:, keypair: nil)
|
|
32
|
+
keypair ||= generate_keypair
|
|
33
|
+
vault_path = "#{key_prefix}/#{agent_id}"
|
|
34
|
+
if defined?(Legion::Crypt::Vault)
|
|
35
|
+
Legion::Crypt::Vault.write(vault_path, {
|
|
36
|
+
private_key: keypair[:private_key].unpack1('H*'),
|
|
37
|
+
public_key: keypair[:public_key_hex]
|
|
38
|
+
})
|
|
39
|
+
end
|
|
40
|
+
keypair
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def load_private_key(agent_id:)
|
|
44
|
+
vault_path = "#{key_prefix}/#{agent_id}"
|
|
45
|
+
data = Legion::Crypt::Vault.read(vault_path)
|
|
46
|
+
[data[:private_key]].pack('H*') if data&.dig(:private_key)
|
|
47
|
+
rescue StandardError
|
|
48
|
+
nil
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def key_prefix
|
|
54
|
+
begin
|
|
55
|
+
Legion::Settings[:crypt][:ed25519][:vault_key_prefix]
|
|
56
|
+
rescue StandardError
|
|
57
|
+
nil
|
|
58
|
+
end || 'secret/data/legion/keys'
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Crypt
|
|
5
|
+
module Erasure
|
|
6
|
+
class << self
|
|
7
|
+
def erase_tenant(tenant_id:)
|
|
8
|
+
key_path = "#{tenant_prefix}/#{tenant_id}/master_key"
|
|
9
|
+
|
|
10
|
+
delete_vault_key(key_path) if defined?(Legion::Crypt::Vault)
|
|
11
|
+
Legion::Events.emit('crypt.tenant_erased', { tenant_id: tenant_id, erased_at: Time.now.utc }) if defined?(Legion::Events)
|
|
12
|
+
Legion::Logging.warn "[crypt] Tenant #{tenant_id} cryptographically erased" if defined?(Legion::Logging)
|
|
13
|
+
|
|
14
|
+
{ erased: true, tenant_id: tenant_id, path: key_path }
|
|
15
|
+
rescue StandardError => e
|
|
16
|
+
{ erased: false, tenant_id: tenant_id, error: e.message }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def verify_erasure(tenant_id:)
|
|
20
|
+
key_path = "#{tenant_prefix}/#{tenant_id}/master_key"
|
|
21
|
+
data = Legion::Crypt::Vault.read(key_path)
|
|
22
|
+
{ erased: data.nil?, tenant_id: tenant_id }
|
|
23
|
+
rescue StandardError
|
|
24
|
+
{ erased: true, tenant_id: tenant_id }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def delete_vault_key(path)
|
|
30
|
+
::Vault.logical.delete(path)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def tenant_prefix
|
|
34
|
+
begin
|
|
35
|
+
Legion::Settings[:crypt][:partition_keys][:vault_tenant_prefix]
|
|
36
|
+
rescue StandardError
|
|
37
|
+
nil
|
|
38
|
+
end || 'secret/data/legion/tenants'
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Crypt
|
|
5
|
+
module MockVault
|
|
6
|
+
@store = {}
|
|
7
|
+
@mutex = Mutex.new
|
|
8
|
+
|
|
9
|
+
class << self
|
|
10
|
+
def read(path)
|
|
11
|
+
@mutex.synchronize { @store[path]&.dup }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def write(path, data)
|
|
15
|
+
@mutex.synchronize { @store[path] = data.dup }
|
|
16
|
+
true
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def delete(path)
|
|
20
|
+
@mutex.synchronize { @store.delete(path) }
|
|
21
|
+
true
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def list(prefix)
|
|
25
|
+
@mutex.synchronize do
|
|
26
|
+
@store.keys.select { |k| k.start_with?(prefix) }
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def reset!
|
|
31
|
+
@mutex.synchronize { @store.clear }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def connected?
|
|
35
|
+
true
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'openssl'
|
|
4
|
+
|
|
5
|
+
module Legion
|
|
6
|
+
module Crypt
|
|
7
|
+
module PartitionKeys
|
|
8
|
+
class << self
|
|
9
|
+
def derive_key(master_key:, tenant_id:, context: nil)
|
|
10
|
+
context ||= begin
|
|
11
|
+
Legion::Settings[:crypt][:partition_keys][:derivation_context]
|
|
12
|
+
rescue StandardError
|
|
13
|
+
nil
|
|
14
|
+
end || 'legion-partition'
|
|
15
|
+
salt = OpenSSL::Digest::SHA256.digest(tenant_id.to_s)
|
|
16
|
+
OpenSSL::KDF.hkdf(master_key, salt: salt, info: context, length: 32, hash: 'SHA256')
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def encrypt_for_tenant(plaintext:, tenant_id:, master_key:)
|
|
20
|
+
key = derive_key(master_key: master_key, tenant_id: tenant_id)
|
|
21
|
+
cipher = OpenSSL::Cipher.new('aes-256-gcm')
|
|
22
|
+
cipher.encrypt
|
|
23
|
+
cipher.key = key
|
|
24
|
+
iv = cipher.random_iv
|
|
25
|
+
ciphertext = cipher.update(plaintext) + cipher.final
|
|
26
|
+
auth_tag = cipher.auth_tag
|
|
27
|
+
|
|
28
|
+
{ ciphertext: ciphertext, iv: iv, auth_tag: auth_tag }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def decrypt_for_tenant(ciphertext:, init_vector:, auth_tag:, tenant_id:, master_key:)
|
|
32
|
+
key = derive_key(master_key: master_key, tenant_id: tenant_id)
|
|
33
|
+
decipher = OpenSSL::Cipher.new('aes-256-gcm')
|
|
34
|
+
decipher.decrypt
|
|
35
|
+
decipher.key = key
|
|
36
|
+
decipher.iv = init_vector
|
|
37
|
+
decipher.auth_tag = auth_tag
|
|
38
|
+
decipher.update(ciphertext) + decipher.final
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
data/lib/legion/crypt/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: legion-crypt
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.4.
|
|
4
|
+
version: 1.4.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Esity
|
|
@@ -9,6 +9,20 @@ bindir: bin
|
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: ed25519
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '1.3'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '1.3'
|
|
12
26
|
- !ruby/object:Gem::Dependency
|
|
13
27
|
name: jwt
|
|
14
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -57,11 +71,16 @@ files:
|
|
|
57
71
|
- README.md
|
|
58
72
|
- legion-crypt.gemspec
|
|
59
73
|
- lib/legion/crypt.rb
|
|
74
|
+
- lib/legion/crypt/attestation.rb
|
|
60
75
|
- lib/legion/crypt/cipher.rb
|
|
61
76
|
- lib/legion/crypt/cluster_secret.rb
|
|
77
|
+
- lib/legion/crypt/ed25519.rb
|
|
78
|
+
- lib/legion/crypt/erasure.rb
|
|
62
79
|
- lib/legion/crypt/jwks_client.rb
|
|
63
80
|
- lib/legion/crypt/jwt.rb
|
|
64
81
|
- lib/legion/crypt/lease_manager.rb
|
|
82
|
+
- lib/legion/crypt/mock_vault.rb
|
|
83
|
+
- lib/legion/crypt/partition_keys.rb
|
|
65
84
|
- lib/legion/crypt/settings.rb
|
|
66
85
|
- lib/legion/crypt/vault.rb
|
|
67
86
|
- lib/legion/crypt/vault_jwt_auth.rb
|