agentadmit 1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 71a63361a9ebd638c907411b5dcbce487f000d940c2618887d68ffe90a9bc5fa
4
+ data.tar.gz: c48534a09f1d07e05d56b34c88dfe2ecc64fcdc61564e880f2c1e948e18c9e67
5
+ SHA512:
6
+ metadata.gz: fc1d745572d89c57767e20bb6320d47816580d8d7a1a07d75333564d2b32ed562843a467483799f793d81b12d5ed185915d8afd376a206ee82029cebd5eb7d9c
7
+ data.tar.gz: 8f1f126ad0d27e99fac5e3e58fb43a6064a3078bae8b0b921ce8b3a8499caeaa16a249d7142180c84a76b8d26bc76cfcafaf073965b1e5f3591a83d4493b0889
data/LICENSE ADDED
@@ -0,0 +1,56 @@
1
+ AgentAdmit Proprietary License
2
+
3
+ Copyright (c) 2026 AgentAdmit LLC. All rights reserved.
4
+
5
+ Patent Pending — U.S. Application No. 19/660,916
6
+
7
+ TERMS OF USE
8
+
9
+ 1. GRANT OF LICENSE. AgentAdmit LLC ("Licensor") grants you a limited,
10
+ non-exclusive, non-transferable, revocable license to use this software
11
+ development kit ("SDK") solely for the purpose of integrating with the
12
+ AgentAdmit hosted service (api.agentadmit.com).
13
+
14
+ 2. RESTRICTIONS. You may not:
15
+ (a) Use this SDK with any service other than the AgentAdmit hosted service;
16
+ (b) Modify, adapt, or create derivative works of this SDK for the purpose
17
+ of building or operating a competing service;
18
+ (c) Reverse engineer, decompile, or disassemble the AgentAdmit protocol
19
+ or service architecture;
20
+ (d) Remove or alter any proprietary notices, labels, or marks;
21
+ (e) Redistribute this SDK as a standalone product or as part of a
22
+ competing authorization service.
23
+
24
+ 3. PERMITTED USES. You may:
25
+ (a) Install and use this SDK in your applications;
26
+ (b) Include this SDK as a dependency in your projects;
27
+ (c) Distribute your applications that incorporate this SDK, provided
28
+ those applications connect to the AgentAdmit hosted service.
29
+
30
+ 4. AGENTADMIT SERVICE REQUIRED. This SDK is designed exclusively for use
31
+ with the AgentAdmit hosted service. An AgentAdmit account and valid API
32
+ keys are required. Sign up at https://agentadmit.com.
33
+
34
+ 5. INTELLECTUAL PROPERTY. The AgentAdmit protocol, user-mediated token
35
+ delivery mechanism, mandatory introspection architecture, and related
36
+ inventions are protected by pending U.S. patent(s) and other intellectual
37
+ property rights. This license does not grant any rights to the underlying
38
+ patents or trade secrets.
39
+
40
+ 6. NO WARRANTY. THIS SDK IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
41
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
42
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT.
43
+
44
+ 7. LIMITATION OF LIABILITY. IN NO EVENT SHALL AGENTADMIT LLC BE LIABLE FOR
45
+ ANY INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, OR PUNITIVE DAMAGES
46
+ ARISING FROM YOUR USE OF THIS SDK.
47
+
48
+ 8. TERMINATION. This license terminates automatically if you violate any
49
+ of its terms. Upon termination, you must cease all use and destroy all
50
+ copies of this SDK in your possession.
51
+
52
+ 9. GOVERNING LAW. This license is governed by the laws of the State of
53
+ California, United States.
54
+
55
+ For licensing inquiries: legal@agentadmit.com
56
+ For developer support: https://agentadmit.com/docs
data/README.md ADDED
@@ -0,0 +1,142 @@
1
+ # AgentAdmit SDK for Ruby (Rails)
2
+
3
+ User-mediated AI agent authorization. Plug-and-play for any Rails app.
4
+
5
+ > **Get started:** Sign up at [agentadmit.com](https://agentadmit.com) → Get your test keys → Install the SDK → Build.
6
+ > Test keys are available immediately after signup. Live keys become available when you subscribe an app.
7
+
8
+ ## Quick Start
9
+
10
+ ```ruby
11
+ # Gemfile
12
+ gem 'agentadmit'
13
+ ```
14
+
15
+ ```bash
16
+ bundle install
17
+ rails generate agentadmit:install
18
+ ```
19
+
20
+ Add your credentials to `config/credentials.yml.enc` or `.env`:
21
+
22
+ ```env
23
+ AGENTADMIT_APP_ID=app_yourappid
24
+ AGENTADMIT_API_KEY=aa_test_yourkey
25
+ ```
26
+
27
+ Add scope enforcement to any controller:
28
+
29
+ ```ruby
30
+ class OrdersController < ApplicationController
31
+ before_action -> { require_scope_if_agent!('read:orders') }
32
+
33
+ def index
34
+ render json: current_user.orders
35
+ end
36
+ end
37
+ ```
38
+
39
+ Your app now supports AI agent connections with:
40
+ - Scoped access control (you define the scopes)
41
+ - User-controlled connection duration
42
+ - Token generation and exchange
43
+ - Mandatory introspection (every agent request validated through AgentAdmit)
44
+ - Revocation and audit logging
45
+ - Discovery endpoint at `/.well-known/agentadmit`
46
+
47
+ ## How It Works
48
+
49
+ 1. User clicks "AgentAdmit" in your app
50
+ 2. Selects scopes and connection duration
51
+ 3. Gets a token to give to their AI agent
52
+ 4. Agent exchanges the token for scoped API access
53
+ 5. User revokes anytime
54
+
55
+ The token goes to the human, not the agent. No automated delivery = no prompt injection surface.
56
+
57
+ ## Important
58
+
59
+ **Mandatory introspection.** All token validation goes through api.agentadmit.com. There is no self-hosted mode. No local JWT validation. No bypass. This is required for security, audit logging, and scope enforcement.
60
+
61
+ **Admin revocation.** As the app operator, you can revoke any user's agent connection via `DELETE /agentadmit/admin/connections/{connection_id}` (requires admin role or `manage:connections` scope).
62
+
63
+ **Embeddable admin panel.** Drop the `<AgentAdmitAdminPanel>` React component into your admin section to view all agent connections, usage metrics, billing status, and revoke any connection without leaving your app. See the React SDK for details.
64
+
65
+ **In-app AI scopes.** If your app has built-in AI features (analysis, plan generation, photo recognition), do not expose those as agent scopes. The user's AI agent can read the raw data and do the analysis itself. Exposing in-app AI endpoints to agents creates double cost.
66
+
67
+ ## Rate Limiting
68
+
69
+ The AgentAdmit introspection endpoint enforces rate limits. The Ruby SDK handles HTTP 429 responses **automatically** with exponential backoff and jitter — no changes needed in your middleware code.
70
+
71
+ ### Retry behavior
72
+
73
+ | Parameter | Default | Description |
74
+ |-----------|---------|-------------|
75
+ | Initial delay | 1 second | First retry wait |
76
+ | Backoff multiplier | 2× | Doubles each retry |
77
+ | Cap | 30 seconds | Maximum wait per retry |
78
+ | Jitter | 0–500 ms | Random addition to each delay |
79
+ | Max retries | **3** | Configurable |
80
+
81
+ The SDK also respects the `Retry-After` response header — if present, it overrides the computed backoff delay.
82
+
83
+ ### Configuring max retries
84
+
85
+ ```ruby
86
+ AgentAdmit.configure do |config|
87
+ config.max_retries = 5 # default: 3
88
+ end
89
+ ```
90
+
91
+ Or via environment variable:
92
+
93
+ ```env
94
+ AGENTADMIT_MAX_RETRIES=5
95
+ ```
96
+
97
+ ### Handling exhausted retries
98
+
99
+ When all retries are exhausted, `IntrospectionClient#verify` raises `AgentAdmit::RateLimitError`:
100
+
101
+ ```ruby
102
+ begin
103
+ result = client.verify(token)
104
+ rescue AgentAdmit::RateLimitError => e
105
+ render json: { error: 'rate_limited', retry_after: e.retry_after }, status: 429
106
+ end
107
+ ```
108
+
109
+ `RateLimitError` attributes:
110
+ - `retry_after` — seconds from `Retry-After` header (`nil` if absent)
111
+ - `limit` — `X-RateLimit-Limit` header value (`nil` if absent)
112
+ - `remaining` — `X-RateLimit-Remaining` header value (`nil` if absent)
113
+ - `reset` — `X-RateLimit-Reset` Unix timestamp (`nil` if absent)
114
+
115
+ ## Documentation
116
+
117
+ Full integration guide: https://agentadmit.com/docs/app-owner-guide
118
+
119
+
120
+ ## Data Collection & Privacy
121
+
122
+ The AgentAdmit Ruby SDK runs server-side and does not interact with app stores or end-user devices directly.
123
+
124
+ ### What the SDK does
125
+ - Validates AgentAdmit tokens presented by AI agents
126
+ - Enforces scope-based access control on your API routes
127
+ - Manages connection lifecycle (create, revoke, audit)
128
+
129
+ ### What the SDK does NOT do
130
+ - Does not collect end-user data
131
+ - Does not send telemetry or analytics
132
+ - Does not phone home to AgentAdmit servers (all operations use your configured keys and storage)
133
+ - Does not track users or devices
134
+
135
+ ### Privacy impact
136
+ Since this SDK runs on your server, it has no direct App Store or Play Store compliance surface. Your client-side integration (e.g., the AgentAdmit React SDK) handles privacy manifest and data safety requirements.
137
+
138
+ For complete compliance guidance, see our [compliance guide](https://agentadmit.com/docs/compliance).
139
+
140
+ ## License
141
+
142
+ All rights reserved. Patent pending.
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ # IMPORTANT: AgentAdmit uses MANDATORY hosted introspection.
4
+ # All token validation goes through api.agentadmit.com.
5
+ # There is no self-hosted mode. No local JWT validation. No bypass.
6
+ # This is required for security, audit logging, and scope enforcement.
7
+
8
+ module AgentAdmit
9
+ class Config
10
+ attr_accessor :app_id, :api_key, :verify_url, :api_url,
11
+ :token_prefix_access, :token_prefix_connection,
12
+ :max_retries
13
+
14
+ def initialize
15
+ @app_id = ENV.fetch("AGENTADMIT_APP_ID", "")
16
+ @api_key = ENV.fetch("AGENTADMIT_API_KEY", "")
17
+ @verify_url = ENV.fetch("AGENTADMIT_VERIFY_URL", "https://api.agentadmit.com/v1/verify")
18
+ @api_url = ENV.fetch("AGENTADMIT_API_URL", "https://api.agentadmit.com")
19
+ @token_prefix_access = "ag_at_"
20
+ @token_prefix_connection = "ag_ct_"
21
+ # Max retries on HTTP 429 before raising RateLimitError. Default: 3.
22
+ @max_retries = ENV.fetch("AGENTADMIT_MAX_RETRIES", "3").to_i
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,155 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "net/http"
4
+ require "json"
5
+ require "uri"
6
+
7
+ module AgentAdmit
8
+ ##
9
+ # Mandatory introspection client — validates tokens via AgentAdmit hosted service.
10
+ # No local JWT decode. Every verification call goes through AgentAdmit.
11
+ #
12
+ class IntrospectionClient
13
+ IntrospectionResult = Struct.new(:user_id, :connection_id, :scopes, :agent_label, keyword_init: true) do
14
+ def has_scope?(scope)
15
+ scopes.include?(scope)
16
+ end
17
+ end
18
+
19
+ def initialize(config = nil)
20
+ @config = config || AgentAdmit.configuration || Config.new
21
+ end
22
+
23
+ ##
24
+ # Validate an ag_at_ token via introspection.
25
+ #
26
+ # Automatically retries on HTTP 429 with exponential backoff + jitter.
27
+ # Raises {RateLimitError} when retries are exhausted.
28
+ #
29
+ # @param token [String] The full token including ag_at_ prefix
30
+ # @return [IntrospectionResult]
31
+ # @raise [InvalidTokenError] if validation fails
32
+ # @raise [IntrospectionError] if the service is unreachable
33
+ # @raise [RateLimitError] if rate-limited and retries exhausted
34
+ #
35
+ def verify(token)
36
+ unless token.start_with?(@config.token_prefix_access)
37
+ raise InvalidTokenError, "Not an AgentAdmit access token"
38
+ end
39
+
40
+ max_retries = @config.respond_to?(:max_retries) ? @config.max_retries.to_i : 3
41
+ delay_ms = 1000 # initial backoff in milliseconds
42
+
43
+ uri = URI.parse(@config.verify_url)
44
+ http = build_http(uri)
45
+
46
+ (0..max_retries).each do |attempt|
47
+ request = build_request(uri, token)
48
+
49
+ begin
50
+ response = http.request(request)
51
+ rescue StandardError => e
52
+ raise IntrospectionError, "Introspection failed: #{e.message}"
53
+ end
54
+
55
+ status = response.code.to_i
56
+
57
+ if status == 429
58
+ retry_after = parse_float_header(response, "Retry-After")
59
+ rl_limit = parse_int_header(response, "X-RateLimit-Limit")
60
+ rl_remaining = parse_int_header(response, "X-RateLimit-Remaining")
61
+ rl_reset = parse_int_header(response, "X-RateLimit-Reset")
62
+
63
+ if attempt >= max_retries
64
+ raise RateLimitError.new(
65
+ "AgentAdmit rate limit exceeded. Max retries (#{max_retries}) exhausted.",
66
+ retry_after: retry_after,
67
+ limit: rl_limit,
68
+ remaining: rl_remaining,
69
+ reset: rl_reset
70
+ )
71
+ end
72
+
73
+ # Compute wait: honor Retry-After header or use exponential backoff, cap at 30s
74
+ wait_ms = retry_after ? (retry_after * 1000).ceil : [delay_ms, 30_000].min
75
+ jitter_ms = rand(0..500)
76
+ total_ms = wait_ms + jitter_ms
77
+
78
+ warn "[AgentAdmit] Rate-limited (attempt #{attempt + 1}/#{max_retries}). " \
79
+ "Retrying in #{total_ms}ms."
80
+
81
+ sleep(total_ms / 1000.0)
82
+ delay_ms = [delay_ms * 2, 30_000].min
83
+ next
84
+ end
85
+
86
+ # Non-429 response — process normally
87
+ case status
88
+ when 200
89
+ data = JSON.parse(response.body)
90
+
91
+ # Check active flag (RFC 7662 introspection pattern).
92
+ # The verify endpoint returns {active: false} with HTTP 200 for invalid/
93
+ # expired/revoked tokens. Without this check, we'd read empty scopes.
94
+ unless data["active"]
95
+ reason = data["error"] || "invalid_token"
96
+ raise InvalidTokenError, "Token is not active: #{reason}"
97
+ end
98
+
99
+ raise InvalidTokenError, "Introspection returned no user" if data["user_id"].nil?
100
+
101
+ return IntrospectionResult.new(
102
+ user_id: data["user_id"],
103
+ connection_id: data["connection_id"],
104
+ scopes: data["scopes"] || [],
105
+ agent_label: data["agent_label"] || "Unknown Agent"
106
+ )
107
+ when 401
108
+ data = JSON.parse(response.body) rescue {}
109
+ raise InvalidTokenError, data["error_description"] || "Token validation failed"
110
+ else
111
+ raise IntrospectionError, "Verification service returned #{response.code}"
112
+ end
113
+ end
114
+
115
+ # Should never be reached
116
+ raise IntrospectionError, "Unexpected exit from retry loop"
117
+ end
118
+
119
+ private
120
+
121
+ def build_http(uri)
122
+ http = Net::HTTP.new(uri.host, uri.port)
123
+ http.use_ssl = uri.scheme == "https"
124
+ http.read_timeout = 5
125
+ http.open_timeout = 5
126
+ http
127
+ end
128
+
129
+ def build_request(uri, token)
130
+ req = Net::HTTP::Post.new(uri.path)
131
+ req["Authorization"] = "Bearer #{@config.api_key}"
132
+ req["Content-Type"] = "application/json"
133
+ req.body = JSON.generate({ token: token })
134
+ req
135
+ end
136
+
137
+ ##
138
+ # Parse a response header as Float, returning nil if absent or non-numeric.
139
+ #
140
+ def parse_float_header(response, name)
141
+ val = response[name]
142
+ return nil if val.nil? || val.empty?
143
+ Float(val) rescue nil
144
+ end
145
+
146
+ ##
147
+ # Parse a response header as Integer, returning nil if absent or non-numeric.
148
+ #
149
+ def parse_int_header(response, name)
150
+ val = response[name]
151
+ return nil if val.nil? || val.empty?
152
+ Integer(val) rescue nil
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AgentAdmit
4
+ ##
5
+ # Rack middleware that intercepts requests with ag_at_ tokens
6
+ # and validates them via introspection.
7
+ #
8
+ # Sets env variables for downstream use:
9
+ # env['agentadmit.auth_type'] — "agent" or nil
10
+ # env['agentadmit.user_id'] — validated user ID
11
+ # env['agentadmit.scopes'] — granted scopes array
12
+ # env['agentadmit.connection_id'] — connection identifier
13
+ # env['agentadmit.agent_label'] — agent display name
14
+ #
15
+ class Middleware
16
+ def initialize(app)
17
+ @app = app
18
+ @client = IntrospectionClient.new
19
+ @config = AgentAdmit.configuration || Config.new
20
+ end
21
+
22
+ def call(env)
23
+ auth = env["HTTP_AUTHORIZATION"] || ""
24
+
25
+ if auth.start_with?("Bearer #{@config.token_prefix_access}")
26
+ token = auth.sub("Bearer ", "")
27
+
28
+ begin
29
+ result = @client.verify(token)
30
+ env["agentadmit.auth_type"] = "agent"
31
+ env["agentadmit.user_id"] = result.user_id
32
+ env["agentadmit.scopes"] = result.scopes
33
+ env["agentadmit.connection_id"] = result.connection_id
34
+ env["agentadmit.agent_label"] = result.agent_label
35
+ rescue InvalidTokenError => e
36
+ return [401, { "Content-Type" => "application/json" },
37
+ [{ error: "invalid_token", error_description: e.message }.to_json]]
38
+ rescue IntrospectionError => e
39
+ return [502, { "Content-Type" => "application/json" },
40
+ [{ error: "introspection_failed", error_description: e.message }.to_json]]
41
+ end
42
+ end
43
+
44
+ @app.call(env)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AgentAdmit
4
+ class Railtie < Rails::Railtie
5
+ initializer "agentadmit.middleware" do |app|
6
+ app.middleware.use AgentAdmit::Middleware
7
+ end
8
+
9
+ initializer "agentadmit.configure" do
10
+ AgentAdmit.configure do |config|
11
+ # Config loaded from environment variables by default
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AgentAdmit
4
+ ##
5
+ # Controller concern for scope enforcement in Rails controllers.
6
+ #
7
+ # Usage:
8
+ # class OrdersController < ApplicationController
9
+ # include AgentAdmit::ScopeEnforcement
10
+ #
11
+ # before_action -> { require_scope!("read:orders") }, only: [:index, :show]
12
+ # before_action -> { require_scope_if_agent!("create:orders") }, only: [:create]
13
+ # end
14
+ #
15
+ module ScopeEnforcement
16
+ extend ActiveSupport::Concern
17
+
18
+ private
19
+
20
+ ##
21
+ # Enforce scope — agent MUST have this scope or gets 403.
22
+ #
23
+ def require_scope!(scope)
24
+ unless request.env["agentadmit.auth_type"] == "agent"
25
+ render json: { error: "invalid_token", error_description: "AgentAdmit token required" }, status: :unauthorized
26
+ return
27
+ end
28
+
29
+ scopes = request.env["agentadmit.scopes"] || []
30
+ unless scopes.include?(scope)
31
+ render json: {
32
+ error: "insufficient_scope",
33
+ required_scope: scope,
34
+ granted_scopes: scopes,
35
+ message: "This action requires '#{scope}' scope."
36
+ }, status: :forbidden
37
+ end
38
+ end
39
+
40
+ ##
41
+ # Enforce scope only for agent tokens. Regular users pass through.
42
+ #
43
+ def require_scope_if_agent!(scope)
44
+ return unless request.env["agentadmit.auth_type"] == "agent"
45
+
46
+ scopes = request.env["agentadmit.scopes"] || []
47
+ unless scopes.include?(scope)
48
+ render json: {
49
+ error: "insufficient_scope",
50
+ required_scope: scope,
51
+ granted_scopes: scopes,
52
+ message: "This action requires '#{scope}' scope."
53
+ }, status: :forbidden
54
+ end
55
+ end
56
+
57
+ ##
58
+ # Get the current agent/user context.
59
+ #
60
+ def agentadmit_context
61
+ {
62
+ auth_type: request.env["agentadmit.auth_type"],
63
+ user_id: request.env["agentadmit.user_id"],
64
+ scopes: request.env["agentadmit.scopes"],
65
+ connection_id: request.env["agentadmit.connection_id"],
66
+ agent_label: request.env["agentadmit.agent_label"],
67
+ }
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AgentAdmit
4
+ VERSION = "1.0.0"
5
+ end
data/lib/agentadmit.rb ADDED
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "agentadmit/version"
4
+ require_relative "agentadmit/config"
5
+ require_relative "agentadmit/introspection_client"
6
+ require_relative "agentadmit/middleware"
7
+ require_relative "agentadmit/scope_enforcement"
8
+ require_relative "agentadmit/railtie" if defined?(Rails)
9
+
10
+ module AgentAdmit
11
+ class Error < StandardError; end
12
+ class InvalidTokenError < Error; end
13
+ class InsufficientScopeError < Error; end
14
+ class IntrospectionError < Error; end
15
+
16
+ ##
17
+ # Raised when the AgentAdmit introspection endpoint returns HTTP 429 and
18
+ # all retry attempts (with exponential backoff + jitter) have been exhausted.
19
+ #
20
+ # @example
21
+ # begin
22
+ # client.verify(token)
23
+ # rescue AgentAdmit::RateLimitError => e
24
+ # render json: { error: 'rate_limited', retry_after: e.retry_after }, status: 429
25
+ # end
26
+ #
27
+ class RateLimitError < Error
28
+ # @return [Float, nil] Seconds to wait before retrying (Retry-After header), or nil.
29
+ attr_reader :retry_after
30
+ # @return [Integer, nil] X-RateLimit-Limit value, or nil.
31
+ attr_reader :limit
32
+ # @return [Integer, nil] X-RateLimit-Remaining value, or nil.
33
+ attr_reader :remaining
34
+ # @return [Integer, nil] X-RateLimit-Reset Unix timestamp, or nil.
35
+ attr_reader :reset
36
+
37
+ def initialize(message = "AgentAdmit rate limit exceeded. Max retries exhausted.",
38
+ retry_after: nil, limit: nil, remaining: nil, reset: nil)
39
+ super(message)
40
+ @retry_after = retry_after
41
+ @limit = limit
42
+ @remaining = remaining
43
+ @reset = reset
44
+ end
45
+ end
46
+
47
+ class << self
48
+ attr_accessor :configuration
49
+
50
+ def configure
51
+ self.configuration ||= Config.new
52
+ yield(configuration) if block_given?
53
+ end
54
+ end
55
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: agentadmit
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Christopher Emerson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-06-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: json
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: Integrate AgentAdmit into your Rails app. Mandatory introspection, scope
28
+ enforcement, and secure AI agent connections.
29
+ email:
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - LICENSE
35
+ - README.md
36
+ - lib/agentadmit.rb
37
+ - lib/agentadmit/config.rb
38
+ - lib/agentadmit/introspection_client.rb
39
+ - lib/agentadmit/middleware.rb
40
+ - lib/agentadmit/railtie.rb
41
+ - lib/agentadmit/scope_enforcement.rb
42
+ - lib/agentadmit/version.rb
43
+ homepage: https://agentadmit.com/docs
44
+ licenses:
45
+ - Nonstandard
46
+ metadata: {}
47
+ post_install_message:
48
+ rdoc_options: []
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: 3.1.0
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubygems_version: 3.0.3.1
63
+ signing_key:
64
+ specification_version: 4
65
+ summary: AgentAdmit SDK for Ruby on Rails — User-mediated AI agent authorization
66
+ test_files: []