lex-identity-kubernetes 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 64532b0d40a6355aae79ca7e617fe31c4eeac3ab314cc19e332ae08a82c1a81a
4
+ data.tar.gz: 87bbcc620b450a6164831b4c12b3fd1c244d3ebae039444cd369ad91e3b35f23
5
+ SHA512:
6
+ metadata.gz: 16d652cd69c68996700401b73979b2624d44a4d24a3ba6215f7a9a266e36710443c8a962db595580fd1b0cf19d0497bbdb8578a595d6be152c4bc3d24690175b
7
+ data.tar.gz: c79c166fa01b11844c6c91507eab494b03abc4c831eb41908adc82920f515cbc777d564d8bd4b3fb8fa922cb9bc199b984661726c8a64e8510d732988b36e483
@@ -0,0 +1,7 @@
1
+ # Auto-generated from team-config.yml
2
+ # Team: extensions
3
+ #
4
+ # To apply: scripts/apply-codeowners.sh lex-identity-kubernetes
5
+
6
+ * @LegionIO/maintainers
7
+ * @LegionIO/extensions
@@ -0,0 +1,18 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: bundler
4
+ directory: /
5
+ schedule:
6
+ interval: weekly
7
+ day: monday
8
+ open-pull-requests-limit: 5
9
+ labels:
10
+ - "type:dependencies"
11
+ - package-ecosystem: github-actions
12
+ directory: /
13
+ schedule:
14
+ interval: weekly
15
+ day: monday
16
+ open-pull-requests-limit: 5
17
+ labels:
18
+ - "type:dependencies"
@@ -0,0 +1,34 @@
1
+ name: CI
2
+ on:
3
+ push:
4
+ branches: [main]
5
+ pull_request:
6
+ schedule:
7
+ - cron: '0 9 * * 1'
8
+
9
+ jobs:
10
+ ci:
11
+ uses: LegionIO/.github/.github/workflows/ci.yml@main
12
+
13
+ excluded-files:
14
+ uses: LegionIO/.github/.github/workflows/excluded-files.yml@main
15
+
16
+ security:
17
+ uses: LegionIO/.github/.github/workflows/security-scan.yml@main
18
+
19
+ version-changelog:
20
+ uses: LegionIO/.github/.github/workflows/version-changelog.yml@main
21
+
22
+ dependency-review:
23
+ uses: LegionIO/.github/.github/workflows/dependency-review.yml@main
24
+
25
+ stale:
26
+ if: github.event_name == 'schedule'
27
+ uses: LegionIO/.github/.github/workflows/stale.yml@main
28
+
29
+ release:
30
+ needs: [ci, excluded-files]
31
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
32
+ uses: LegionIO/.github/.github/workflows/release.yml@main
33
+ secrets:
34
+ rubygems-api-key: ${{ secrets.RUBYGEMS_API_KEY }}
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ .rspec_status
10
+ Gemfile.lock
data/.rubocop.yml ADDED
@@ -0,0 +1,2 @@
1
+ inherit_gem:
2
+ rubocop-legion: config/lex.yml
data/CHANGELOG.md ADDED
@@ -0,0 +1,18 @@
1
+ # Changelog
2
+
3
+ ## [0.1.0] - 2026-04-07
4
+
5
+ ### Added
6
+
7
+ - Initial release
8
+ - `Identity` module implementing the LegionIO identity provider contract
9
+ - `provider_type: :auth`, `facing: :machine`, `priority: 95`, `trust_weight: 100`
10
+ - `capabilities: [:authenticate, :vault_auth]`
11
+ - `resolve` reads projected SA token from `/var/run/secrets/kubernetes.io/serviceaccount/token`
12
+ - Vault-verified path: when `Legion::Crypt::LeaseManager` is available, validates token via `auth/kubernetes/login` and populates groups from Vault policies
13
+ - Unverified JWT fallback: decodes JWT payload without signature verification; `groups` always `[]` on this path (RBAC safety); logs warning
14
+ - `provide_token` returns a `Legion::Identity::Lease` with `renewable: true` (projected tokens auto-rotate)
15
+ - `vault_auth` delegates to `LeaseManager#vault_logical` for namespace-aware Vault calls
16
+ - `canonical_name` derived from `namespace-sa_name` (dots and special chars replaced with hyphens)
17
+ - `Settings` module with configurable `token_path`, `namespace_path`, `vault_role`, `vault_auth_path`
18
+ - `normalize` strips non-alphanumeric characters, collapses consecutive hyphens, trims leading/trailing hyphens
data/CLAUDE.md ADDED
@@ -0,0 +1,78 @@
1
+ # lex-identity-kubernetes: Kubernetes Service Account Identity Provider
2
+
3
+ **Repository Level 3 Documentation**
4
+ - **Parent (Level 2)**: `/Users/miverso2/rubymine/legion/extensions/CLAUDE.md`
5
+ - **Parent (Level 1)**: `/Users/miverso2/rubymine/legion/CLAUDE.md`
6
+
7
+ ## Purpose
8
+
9
+ Kubernetes service account identity provider for LegionIO. Reads projected SA tokens from the standard K8s mount path and validates them via Vault Kubernetes auth (preferred) or falls back to unverified JWT decode.
10
+
11
+ **GitHub**: https://github.com/LegionIO/lex-identity-kubernetes
12
+ **License**: MIT
13
+ **Version**: 0.1.0
14
+
15
+ ## Architecture
16
+
17
+ ```
18
+ Legion::Extensions::Identity::Kubernetes
19
+ ├── Identity # provider contract: resolve, provide_token, vault_auth, normalize, ...
20
+ └── Settings # default settings (token_path, namespace_path, vault_role, vault_auth_path)
21
+ ```
22
+
23
+ No runners, no actors, no transport. Identity-only gem.
24
+
25
+ ## File Map
26
+
27
+ | File | Purpose |
28
+ |------|---------|
29
+ | `lib/legion/extensions/identity/kubernetes.rb` | Entry point — requires version/settings/identity, declares `identity_provider?`, `remote_invocable?`, top-level delegation methods |
30
+ | `lib/legion/extensions/identity/kubernetes/identity.rb` | Provider contract: `resolve`, `provide_token`, `vault_auth`, `normalize`, private helpers |
31
+ | `lib/legion/extensions/identity/kubernetes/settings.rb` | Default settings, `Settings.get` merges with `Legion::Settings` |
32
+ | `lib/legion/extensions/identity/kubernetes/version.rb` | `VERSION = '0.1.0'` |
33
+
34
+ ## Provider Contract
35
+
36
+ | Method | Return |
37
+ |--------|--------|
38
+ | `provider_name` | `:kubernetes` |
39
+ | `provider_type` | `:auth` |
40
+ | `facing` | `:machine` |
41
+ | `priority` | `95` |
42
+ | `trust_weight` | `100` |
43
+ | `capabilities` | `[:authenticate, :vault_auth]` |
44
+ | `resolve` | identity hash or `nil` |
45
+ | `provide_token` | `Legion::Identity::Lease` or `nil` |
46
+ | `vault_auth(token:)` | Vault response or `nil` |
47
+ | `normalize(val)` | String |
48
+
49
+ ## Key Design Rules
50
+
51
+ - `groups: []` on unverified path — NEVER populate groups from unverified JWT for RBAC safety
52
+ - Log warning when using unverified path: `"K8s identity resolved without cryptographic verification — groups empty"`
53
+ - `groups` from Vault-verified path only — populated from `response.auth.policies`
54
+ - `provide_token` re-reads SA token from file each call — projected tokens auto-rotate
55
+ - `renewable: true` — signals `LeaseRenewer` to call `provide_token` periodically
56
+ - `canonical_name` = `normalize("#{namespace}-#{sa_name}")` — dots replaced with hyphens
57
+ - `private_class_method` explicit method names for all private helpers
58
+ - `vault_logical` via `LeaseManager.instance.vault_logical` (NOT raw `::Vault.logical`)
59
+ - `Legion::JSON.load` returns SYMBOL keys — use `:sub`, `:exp`, `:groups`, NOT string keys
60
+
61
+ ## Dependencies
62
+
63
+ | Gem | Purpose |
64
+ |-----|---------|
65
+ | `legion-json` | JSON serialization (`symbolize_names: true` — SYMBOL keys) |
66
+ | `legion-settings` | Configuration management |
67
+
68
+ ## Testing
69
+
70
+ ```bash
71
+ bundle install
72
+ bundle exec rspec
73
+ bundle exec rubocop
74
+ ```
75
+
76
+ ---
77
+
78
+ **Maintained By**: Matthew Iverson (@Esity)
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+ gemspec
5
+
6
+ group :development, :test do
7
+ gem 'rspec', '~> 3.13'
8
+ gem 'rubocop', '~> 1.75'
9
+ gem 'rubocop-legion', '~> 0.1'
10
+ gem 'simplecov', '~> 0.22'
11
+ end
data/README.md ADDED
@@ -0,0 +1,77 @@
1
+ # lex-identity-kubernetes
2
+
3
+ Kubernetes service account identity provider for LegionIO. Reads projected SA tokens from the standard mount path and optionally validates them via Vault Kubernetes auth.
4
+
5
+ **Gem**: `lex-identity-kubernetes`
6
+ **Version**: 0.1.0
7
+ **License**: MIT
8
+
9
+ ## Overview
10
+
11
+ When running inside a Kubernetes pod, LegionIO can establish machine identity from the pod's service account. This provider:
12
+
13
+ 1. Reads the projected SA token from `/var/run/secrets/kubernetes.io/serviceaccount/token`
14
+ 2. If Vault is connected: validates the token via `auth/kubernetes/login` and derives groups from Vault policies (verified path)
15
+ 3. If Vault is not connected: decodes the JWT payload without signature verification (unverified fallback) — groups are always empty on this path for RBAC safety
16
+
17
+ ## Identity Shape
18
+
19
+ ```ruby
20
+ {
21
+ canonical_name: 'legionio-legion-worker', # namespace-sa_name
22
+ kind: :machine,
23
+ source: :kubernetes,
24
+ persistent: true,
25
+ groups: ['default', 'legionio'], # from Vault policies (verified only)
26
+ metadata: {
27
+ namespace: 'legionio',
28
+ service_account: 'legion-worker',
29
+ verified: true # false on unverified path
30
+ }
31
+ }
32
+ ```
33
+
34
+ ## Configuration
35
+
36
+ Settings at `Legion::Settings[:identity][:kubernetes]`:
37
+
38
+ | Key | Default | Description |
39
+ |-----|---------|-------------|
40
+ | `token_path` | `/var/run/secrets/kubernetes.io/serviceaccount/token` | SA token file path |
41
+ | `namespace_path` | `/var/run/secrets/kubernetes.io/serviceaccount/namespace` | Namespace file path |
42
+ | `vault_role` | `legionio` | Vault Kubernetes auth role |
43
+ | `vault_auth_path` | `kubernetes` | Vault auth mount path |
44
+
45
+ ## Provider Contract
46
+
47
+ | Method | Return |
48
+ |--------|--------|
49
+ | `provider_name` | `:kubernetes` |
50
+ | `provider_type` | `:auth` |
51
+ | `facing` | `:machine` |
52
+ | `priority` | `95` |
53
+ | `trust_weight` | `100` |
54
+ | `capabilities` | `[:authenticate, :vault_auth]` |
55
+
56
+ ## Vault Setup
57
+
58
+ ```bash
59
+ vault auth enable kubernetes
60
+ vault write auth/kubernetes/config \
61
+ token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
62
+ kubernetes_host="https://kubernetes.default.svc"
63
+
64
+ vault write auth/kubernetes/role/legionio \
65
+ bound_service_account_names=legion-worker \
66
+ bound_service_account_namespaces=legionio \
67
+ policies=default,legionio \
68
+ ttl=1h
69
+ ```
70
+
71
+ ## Development
72
+
73
+ ```bash
74
+ bundle install
75
+ bundle exec rspec
76
+ bundle exec rubocop
77
+ ```
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/legion/extensions/identity/kubernetes/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'lex-identity-kubernetes'
7
+ spec.version = Legion::Extensions::Identity::Kubernetes::VERSION
8
+ spec.authors = ['Esity']
9
+ spec.email = ['matthewdiverson@gmail.com']
10
+
11
+ spec.summary = 'LEX Identity Kubernetes'
12
+ spec.description = 'LegionIO Kubernetes service account identity provider — reads projected SA tokens and optionally validates via Vault Kubernetes auth'
13
+ spec.homepage = 'https://github.com/LegionIO/lex-identity-kubernetes'
14
+ spec.license = 'MIT'
15
+ spec.required_ruby_version = '>= 3.4'
16
+
17
+ spec.metadata['homepage_uri'] = spec.homepage
18
+ spec.metadata['source_code_uri'] = 'https://github.com/LegionIO/lex-identity-kubernetes'
19
+ spec.metadata['documentation_uri'] = 'https://github.com/LegionIO/lex-identity-kubernetes'
20
+ spec.metadata['changelog_uri'] = 'https://github.com/LegionIO/lex-identity-kubernetes'
21
+ spec.metadata['bug_tracker_uri'] = 'https://github.com/LegionIO/lex-identity-kubernetes/issues'
22
+ spec.metadata['rubygems_mfa_required'] = 'true'
23
+
24
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
25
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
+ end
27
+ spec.require_paths = ['lib']
28
+
29
+ spec.add_dependency 'base64', '>= 0.2'
30
+ spec.add_dependency 'legion-json', '>= 1.2.1'
31
+ spec.add_dependency 'legion-settings', '>= 1.3.14'
32
+ end
@@ -0,0 +1,173 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'base64'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Identity
8
+ module Kubernetes
9
+ module Identity
10
+ SA_TOKEN_PATH = '/var/run/secrets/kubernetes.io/serviceaccount/token'
11
+ SA_NAMESPACE_PATH = '/var/run/secrets/kubernetes.io/serviceaccount/namespace'
12
+
13
+ def self.provider_name
14
+ :kubernetes
15
+ end
16
+
17
+ def self.provider_type
18
+ :auth
19
+ end
20
+
21
+ def self.facing
22
+ :machine
23
+ end
24
+
25
+ def self.priority
26
+ 95
27
+ end
28
+
29
+ def self.trust_weight
30
+ 100
31
+ end
32
+
33
+ def self.capabilities
34
+ %i[authenticate vault_auth]
35
+ end
36
+
37
+ def self.resolve(canonical_name: nil) # rubocop:disable Lint/UnusedMethodArgument
38
+ token = read_sa_token
39
+ return nil unless token
40
+
41
+ if vault_available?
42
+ vault_resolve(token)
43
+ else
44
+ unverified_resolve(token)
45
+ end
46
+ end
47
+
48
+ def self.provide_token
49
+ token = read_sa_token
50
+ return nil unless token
51
+
52
+ claims = decode_jwt_claims(token)
53
+ expires_at = claims && claims[:exp] ? Time.at(claims[:exp]) : nil
54
+
55
+ Legion::Identity::Lease.new(
56
+ provider: :kubernetes,
57
+ credential: token,
58
+ expires_at: expires_at,
59
+ renewable: true,
60
+ issued_at: Time.now,
61
+ metadata: { namespace: read_namespace }
62
+ )
63
+ end
64
+
65
+ def self.vault_auth(token: nil)
66
+ token ||= read_sa_token
67
+ return nil unless token
68
+
69
+ logical = if defined?(Legion::Crypt::LeaseManager)
70
+ Legion::Crypt::LeaseManager.instance.vault_logical
71
+ elsif defined?(::Vault)
72
+ ::Vault.logical
73
+ end
74
+ return nil unless logical
75
+
76
+ logical.write(
77
+ "auth/#{settings[:vault_auth_path] || 'kubernetes'}/login",
78
+ role: settings[:vault_role] || 'legionio',
79
+ jwt: token
80
+ )
81
+ rescue StandardError => e
82
+ Legion::Logging.warn("K8s Vault auth failed: #{e.message}") if defined?(Legion::Logging) # rubocop:disable Legion/HelperMigration/DirectLogging,Legion/HelperMigration/LoggingGuard
83
+ nil
84
+ end
85
+
86
+ def self.normalize(val)
87
+ val.to_s.downcase.strip.gsub(/[^a-z0-9_-]/, '-').gsub(/-{2,}/, '-').gsub(/^-|-$/, '')
88
+ end
89
+
90
+ def self.settings
91
+ Kubernetes::Settings.get
92
+ end
93
+ private_class_method :settings
94
+
95
+ def self.vault_available?
96
+ defined?(Legion::Crypt::LeaseManager) &&
97
+ Legion::Crypt::LeaseManager.instance.respond_to?(:vault_logical)
98
+ end
99
+ private_class_method :vault_available?
100
+
101
+ def self.vault_resolve(token)
102
+ response = vault_auth(token: token)
103
+ return unverified_resolve(token) unless response
104
+
105
+ policies = response.auth&.policies || []
106
+ metadata = response.auth&.metadata || {}
107
+ namespace = metadata[:kubernetes_namespace] || read_namespace
108
+ sa_name = metadata[:kubernetes_service_account] || 'unknown'
109
+
110
+ {
111
+ canonical_name: normalize("#{namespace}-#{sa_name}"),
112
+ kind: :machine,
113
+ source: :kubernetes,
114
+ persistent: true,
115
+ groups: policies,
116
+ metadata: { namespace: namespace, service_account: sa_name, verified: true }
117
+ }
118
+ end
119
+ private_class_method :vault_resolve
120
+
121
+ def self.unverified_resolve(token)
122
+ claims = decode_jwt_claims(token)
123
+ return nil unless claims
124
+
125
+ Legion::Logging.warn('K8s identity resolved without cryptographic verification — groups empty') if defined?(Legion::Logging) # rubocop:disable Legion/HelperMigration/DirectLogging,Legion/HelperMigration/LoggingGuard
126
+
127
+ parts = claims[:sub].to_s.split(':')
128
+ namespace = parts[2] || read_namespace
129
+ sa_name = parts[3] || 'unknown'
130
+
131
+ {
132
+ canonical_name: normalize("#{namespace}-#{sa_name}"),
133
+ kind: :machine,
134
+ source: :kubernetes,
135
+ persistent: true,
136
+ groups: [],
137
+ metadata: { namespace: namespace, service_account: sa_name, verified: false }
138
+ }
139
+ end
140
+ private_class_method :unverified_resolve
141
+
142
+ def self.read_sa_token
143
+ path = settings[:token_path] || SA_TOKEN_PATH
144
+ return nil unless File.exist?(path)
145
+
146
+ File.read(path).strip
147
+ end
148
+ private_class_method :read_sa_token
149
+
150
+ def self.read_namespace
151
+ path = settings[:namespace_path] || SA_NAMESPACE_PATH
152
+ return nil unless File.exist?(path)
153
+
154
+ File.read(path).strip
155
+ end
156
+ private_class_method :read_namespace
157
+
158
+ def self.decode_jwt_claims(token)
159
+ payload = token.split('.')[1]
160
+ return nil unless payload
161
+
162
+ padded = payload + ('=' * ((4 - (payload.length % 4)) % 4))
163
+ Legion::JSON.load(Base64.urlsafe_decode64(padded)) # rubocop:disable Legion/HelperMigration/DirectJson
164
+ rescue StandardError => e
165
+ Legion::Logging.debug("K8s JWT decode failed: #{e.message}") if defined?(Legion::Logging) # rubocop:disable Legion/HelperMigration/DirectLogging,Legion/HelperMigration/LoggingGuard
166
+ nil
167
+ end
168
+ private_class_method :decode_jwt_claims
169
+ end
170
+ end
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Identity
6
+ module Kubernetes
7
+ module Settings
8
+ DEFAULTS = {
9
+ token_path: '/var/run/secrets/kubernetes.io/serviceaccount/token',
10
+ namespace_path: '/var/run/secrets/kubernetes.io/serviceaccount/namespace',
11
+ vault_role: 'legionio',
12
+ vault_auth_path: 'kubernetes'
13
+ }.freeze
14
+
15
+ def self.load
16
+ return unless defined?(Legion::Settings)
17
+
18
+ Legion::Settings.merge_settings(:kubernetes, DEFAULTS)
19
+ end
20
+
21
+ def self.get
22
+ return DEFAULTS unless defined?(Legion::Settings)
23
+
24
+ settings = Legion::Settings.dig(:identity, :kubernetes)
25
+ return DEFAULTS if settings.nil?
26
+
27
+ DEFAULTS.merge(settings)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Identity
6
+ module Kubernetes
7
+ VERSION = '0.1.0'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/identity/kubernetes/version'
4
+ require 'legion/extensions/identity/kubernetes/settings'
5
+ require 'legion/extensions/identity/kubernetes/identity'
6
+
7
+ module Legion
8
+ module Extensions
9
+ module Identity
10
+ module Kubernetes
11
+ extend Legion::Extensions::Core if Legion::Extensions.const_defined?(:Core, false)
12
+
13
+ def self.identity_provider?
14
+ true
15
+ end
16
+
17
+ def self.remote_invocable?
18
+ false
19
+ end
20
+
21
+ def self.provider_name
22
+ Identity.provider_name
23
+ end
24
+
25
+ def self.provider_type
26
+ Identity.provider_type
27
+ end
28
+
29
+ def self.facing
30
+ Identity.facing
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lex-identity-kubernetes
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Esity
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: base64
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0.2'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0.2'
26
+ - !ruby/object:Gem::Dependency
27
+ name: legion-json
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.2.1
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: 1.2.1
40
+ - !ruby/object:Gem::Dependency
41
+ name: legion-settings
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 1.3.14
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 1.3.14
54
+ description: LegionIO Kubernetes service account identity provider — reads projected
55
+ SA tokens and optionally validates via Vault Kubernetes auth
56
+ email:
57
+ - matthewdiverson@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".github/CODEOWNERS"
63
+ - ".github/dependabot.yml"
64
+ - ".github/workflows/ci.yml"
65
+ - ".gitignore"
66
+ - ".rubocop.yml"
67
+ - CHANGELOG.md
68
+ - CLAUDE.md
69
+ - Gemfile
70
+ - README.md
71
+ - lex-identity-kubernetes.gemspec
72
+ - lib/legion/extensions/identity/kubernetes.rb
73
+ - lib/legion/extensions/identity/kubernetes/identity.rb
74
+ - lib/legion/extensions/identity/kubernetes/settings.rb
75
+ - lib/legion/extensions/identity/kubernetes/version.rb
76
+ homepage: https://github.com/LegionIO/lex-identity-kubernetes
77
+ licenses:
78
+ - MIT
79
+ metadata:
80
+ homepage_uri: https://github.com/LegionIO/lex-identity-kubernetes
81
+ source_code_uri: https://github.com/LegionIO/lex-identity-kubernetes
82
+ documentation_uri: https://github.com/LegionIO/lex-identity-kubernetes
83
+ changelog_uri: https://github.com/LegionIO/lex-identity-kubernetes
84
+ bug_tracker_uri: https://github.com/LegionIO/lex-identity-kubernetes/issues
85
+ rubygems_mfa_required: 'true'
86
+ rdoc_options: []
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '3.4'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ requirements: []
100
+ rubygems_version: 3.6.9
101
+ specification_version: 4
102
+ summary: LEX Identity Kubernetes
103
+ test_files: []