api_keys 0.2.1 → 0.4.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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +60 -0
  3. data/README.md +851 -25
  4. data/SECURITY.md +33 -0
  5. data/app/controllers/api_keys/application_controller.rb +58 -10
  6. data/app/controllers/api_keys/keys_controller.rb +77 -23
  7. data/app/controllers/api_keys/security_controller.rb +8 -0
  8. data/app/views/api_keys/keys/_empty_state.html.erb +9 -0
  9. data/app/views/api_keys/keys/_form.html.erb +33 -4
  10. data/app/views/api_keys/keys/_key_actions.html.erb +20 -0
  11. data/app/views/api_keys/keys/_key_badges.html.erb +17 -0
  12. data/app/views/api_keys/keys/_key_row.html.erb +21 -35
  13. data/app/views/api_keys/keys/_key_status.html.erb +10 -0
  14. data/app/views/api_keys/keys/_keys_table.html.erb +3 -11
  15. data/app/views/api_keys/keys/_publishable_keys.html.erb +40 -0
  16. data/app/views/api_keys/keys/_secret_keys.html.erb +39 -0
  17. data/app/views/api_keys/keys/_show_token.html.erb +10 -47
  18. data/app/views/api_keys/keys/_token_display.html.erb +11 -0
  19. data/app/views/api_keys/keys/index.html.erb +40 -8
  20. data/app/views/api_keys/keys/show.html.erb +2 -2
  21. data/app/views/api_keys/security/best_practices.html.erb +73 -47
  22. data/app/views/layouts/api_keys/application.html.erb +267 -14
  23. data/lib/api_keys/authentication.rb +39 -11
  24. data/lib/api_keys/configuration.rb +444 -17
  25. data/lib/api_keys/engine.rb +5 -20
  26. data/lib/api_keys/errors.rb +73 -0
  27. data/lib/api_keys/form_builder_extensions.rb +168 -0
  28. data/lib/api_keys/helpers/expiration_options.rb +139 -0
  29. data/lib/api_keys/helpers/token_session.rb +203 -0
  30. data/lib/api_keys/helpers/view_helpers.rb +220 -0
  31. data/lib/api_keys/jobs/callbacks_job.rb +10 -17
  32. data/lib/api_keys/jobs/update_stats_job.rb +27 -12
  33. data/lib/api_keys/models/api_key.rb +452 -21
  34. data/lib/api_keys/models/concerns/has_api_keys.rb +269 -26
  35. data/lib/api_keys/services/authenticator.rb +300 -112
  36. data/lib/api_keys/services/digestor.rb +81 -14
  37. data/lib/api_keys/services/token_generator.rb +41 -1
  38. data/lib/api_keys/tenant_resolution.rb +4 -4
  39. data/lib/api_keys/version.rb +1 -1
  40. data/lib/api_keys.rb +12 -0
  41. data/lib/generators/api_keys/add_authentication_index_generator.rb +36 -0
  42. data/lib/generators/api_keys/add_key_types_generator.rb +68 -0
  43. data/lib/generators/api_keys/templates/add_authentication_index_to_api_keys.rb.erb +32 -0
  44. data/lib/generators/api_keys/templates/add_key_types_to_api_keys.rb.erb +18 -0
  45. data/lib/generators/api_keys/templates/create_api_keys_table.rb.erb +11 -3
  46. data/lib/generators/api_keys/templates/initializer.rb +261 -120
  47. metadata +29 -63
  48. data/Rakefile +0 -32
@@ -1,77 +1,199 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  ApiKeys.configure do |config|
4
- # === Core Authentication ===
4
+ # ============================================================================
5
+ # CORE AUTHENTICATION
6
+ # ============================================================================
5
7
 
6
8
  # The HTTP header name where the API key is expected.
7
9
  # Default: "Authorization" (expects "Bearer <token>")
8
10
  # config.header = "Authorization"
9
11
 
10
12
  # The query parameter name to check as a fallback if the header is missing.
11
- # Set to nil to disable query parameter lookup (recommended for security).
13
+ # WARNING: Query parameters appear in logs, browser history, and Referer headers.
14
+ # Only enable for development/testing. Set to nil to disable (recommended).
12
15
  # Default: nil
13
16
  # config.query_param = "api_key"
14
17
 
15
- # === Token Generation ===
18
+ # ============================================================================
19
+ # DASHBOARD CONFIGURATION
20
+ # ============================================================================
21
+ #
22
+ # The api_keys engine provides a web UI for users to manage their API keys.
23
+ # Configure how the dashboard integrates with your application's auth system.
24
+ # ============================================================================
16
25
 
17
- # A lambda/proc that returns the prefix for newly generated tokens.
18
- # Defaults to "ak_".
19
- # Once set, do NOT change or all previously generated keys may become invalid!
20
- # config.token_prefix = -> { "ak_" }
26
+ # Controller class that the engine dashboard inherits from. Configure this in
27
+ # the initializer before engine controllers load. Accepts a Class or constant
28
+ # name string.
29
+ # Default: "::ApplicationController"
30
+ # config.parent_controller = "Admin::ApplicationController"
21
31
 
22
- # The number of random bytes to generate for the token (before encoding).
23
- # More bytes = more entropy = harder to guess.
24
- # Default: 24 (generates ~32 Base58 chars or 48 hex chars)
25
- # config.token_length = 32
32
+ # The method that returns the current API key owner in your controllers.
33
+ # This should return the model instance that has_api_keys.
34
+ # Default: :current_user (works with Devise out of the box)
35
+ #
36
+ # Example for Organization-owned keys:
37
+ # config.current_owner_method = :current_organization
26
38
 
27
- # The encoding alphabet for the random part of the token.
28
- # :base58 (recommended) - shorter, avoids ambiguous chars (0, O, I, l)
29
- # :hex - standard hexadecimal encoding
30
- # Default: :base58
31
- # config.token_alphabet = :hex
39
+ # The method that authenticates/requires login for the dashboard.
40
+ # This should be a before_action-style method that ensures the owner is logged in.
41
+ # Default: :authenticate_user! (works with Devise out of the box)
42
+ #
43
+ # Example for Organization-owned keys:
44
+ # config.authenticate_owner_method = :authenticate_organization!
32
45
 
33
- # === Storage & Verification ===
46
+ # Dashboard environment filtering (only applies when key_types is configured).
47
+ # When false (default), dashboard only shows keys matching current_environment.
48
+ # When true, dashboard shows keys from all environments.
49
+ # Default: false
50
+ #
51
+ # config.dashboard_allow_cross_environment = false
34
52
 
35
- # The hashing strategy used to store token digests in the database.
36
- # :sha256 (recommended) - fast, performant, O(1) lookups, but less secure if database is compromised (salted with prefix only)
37
- # :bcrypt - for security-critical tokens: includes salt, computationally expensive, can cause lags, 10x-50x slower than sha256
38
- # Default: :sha256
39
- # config.hash_strategy = :bcrypt
53
+ # URL for the "back" link in the dashboard UI.
54
+ # Default: "/"
55
+ # config.return_url = "/settings"
40
56
 
41
- # === Dashboard Configuration ===
57
+ # Text for the "back" link.
58
+ # Default: "‹ Home"
59
+ # config.return_text = "‹ Back to Settings"
42
60
 
43
- # IMPORTANT: Owner Context Configuration
44
- # The api_keys dashboard needs to know how to find the current owner
45
- # of API keys in your application. By default, it assumes you have
46
- # a User model with current_user/authenticate_user! methods (Devise-style).
61
+ # ============================================================================
62
+ # TOKEN PREFIXES
63
+ # ============================================================================
47
64
  #
48
- # If your API keys belong to a different model (e.g., Organization),
49
- # you MUST configure these methods:
65
+ # API keys are generated with a prefix followed by random characters:
66
+ # "ak_7Hq2mJvK9pRs3xYz..."
67
+ # prefix = ak_
68
+ # random part = 7Hq2mJvK9pRs3xYz...
69
+ #
70
+ # The prefix system has two modes:
71
+ #
72
+ # 1. SIMPLE MODE (default): All keys use the same prefix from `token_prefix`
73
+ # Example: ak_7Hq2mJvK9pRs3xYz...
74
+ #
75
+ # 2. KEY TYPES MODE: Different key types get different prefixes based on
76
+ # their type and environment (Stripe-style)
77
+ # Example: pk_test_7Hq2mJvK..., sk_live_9xYz3pRs...
78
+ #
79
+ # See "KEY TYPES & ENVIRONMENTS" section below to enable key types mode.
50
80
 
51
- # The method that returns the current API key owner in your controllers.
52
- # This should return the object that has_api_keys (e.g., current_organization).
53
- # Default: :current_user
54
- # config.current_owner_method = :current_organization
81
+ # ----------------------------------------------------------------------------
82
+ # Simple Prefix (when NOT using KEY TYPES)
83
+ # ----------------------------------------------------------------------------
84
+ #
85
+ # A lambda/proc that returns the prefix for newly generated tokens.
86
+ # This is ONLY used when:
87
+ # - key_types is not configured (empty hash), OR
88
+ # - Creating a key without specifying a key_type
89
+ #
90
+ # When key_types IS configured and you specify a key_type, this setting
91
+ # is IGNORED - the prefix comes from the key type's configuration instead.
92
+ #
93
+ # Changing this later is SAFE for existing keys: every key stores its own
94
+ # prefix, so authentication keeps finding keys minted under retired
95
+ # prefixes (sha256 looks up by pure token digest; bcrypt uses a bounded
96
+ # stored-prefix lookup with an indexed last-four fallback for deployments
97
+ # with many retired prefixes). Only NEW keys wear the new prefix.
98
+ # Default: -> { "ak_" }
99
+ # config.token_prefix = -> { "myapp_" }
100
+
101
+ # ============================================================================
102
+ # KEY TYPES & ENVIRONMENTS (Stripe-style Publishable/Secret Keys)
103
+ # ============================================================================
104
+ #
105
+ # For applications that distribute software with embedded API keys (desktop
106
+ # apps, mobile apps, CLI tools), you can create different key types with
107
+ # different permission levels - similar to Stripe's publishable/secret pattern.
108
+ #
109
+ # When enabled:
110
+ # - Keys get type+environment prefixes: pk_test_, pk_live_, sk_test_, sk_live_
111
+ # - Each type can have different permissions, revocability, and limits
112
+ # - The `token_prefix` setting above is IGNORED for typed keys
113
+ #
114
+ # By default, this feature is DISABLED (empty hash) for backwards compatibility.
115
+ # Existing keys without key_type/environment continue to work normally.
116
+ # ============================================================================
55
117
 
56
- # The method that authenticates/requires login for the dashboard.
57
- # This should ensure the owner is logged in before accessing the dashboard.
58
- # Default: :authenticate_user!
59
- # config.authenticate_owner_method = :authenticate_organization!
118
+ # Define your key types with their properties:
119
+ #
120
+ # - prefix: The token prefix for this type (e.g., "pk" becomes pk_test_)
121
+ # - permissions: Scope ceiling - array of allowed scopes, or :all for unrestricted
122
+ # - revocable: Whether keys of this type can be revoked/deleted (default: true)
123
+ # - limit: Max keys of this type per owner per environment (nil = unlimited)
124
+ # - public: If true AND revocable: false, stores plaintext token in metadata
125
+ # so it can be viewed again in the dashboard. Use ONLY for publishable
126
+ # keys designed to be embedded in distributed apps. Public types must
127
+ # use a finite, non-empty permissions array (never :all). (default: false)
128
+ # SECURITY: NEVER set public: true on secret keys!
129
+ #
130
+ # config.key_types = {
131
+ # publishable: {
132
+ # prefix: "pk", # → pk_test_, pk_live_
133
+ # permissions: %w[read validate], # Can ONLY have these scopes
134
+ # revocable: false, # Cannot be revoked - protects deployed apps!
135
+ # public: true, # Store token for later viewing in dashboard
136
+ # limit: 1 # Only 1 publishable key per environment
137
+ # },
138
+ # secret: {
139
+ # prefix: "sk", # → sk_test_, sk_live_
140
+ # permissions: :all # No scope restrictions
141
+ # # revocable: true (default)
142
+ # # public: false (default) - NEVER store secret keys!
143
+ # # limit: nil (default = unlimited)
144
+ # }
145
+ # }
146
+
147
+ # Define your environments with their prefix segments:
148
+ #
149
+ # - prefix_segment: The middle part of the prefix (e.g., "test" → pk_test_)
150
+ # Set to nil for single-environment setups (prefix becomes just "pk_")
151
+ #
152
+ # config.environments = {
153
+ # test: { prefix_segment: "test" }, # Development/staging → pk_test_, sk_test_
154
+ # live: { prefix_segment: "live" } # Production → pk_live_, sk_live_
155
+ # }
156
+ #
157
+ # Alternative naming (Stripe's newer convention):
158
+ # config.environments = {
159
+ # sandbox: { prefix_segment: "test" },
160
+ # live: { prefix_segment: "live" }
161
+ # }
162
+
163
+ # Lambda that returns the current environment.
164
+ # Used to auto-select environment when creating keys and for isolation checks.
165
+ # Default: -> { :default }
166
+ #
167
+ # config.current_environment = -> { Rails.env.production? ? :live : :test }
60
168
 
61
- # Example for Organization-owned keys:
62
- # config.current_owner_method = :current_organization
63
- # config.authenticate_owner_method = :authenticate_organization!
169
+ # Enable strict environment isolation.
170
+ # When true, keys can ONLY authenticate in their matching environment:
171
+ # - test keys return :environment_mismatch error in production
172
+ # - live keys return :environment_mismatch error in development/test
173
+ # Default: false
174
+ #
175
+ # config.strict_environment_isolation = true
64
176
 
65
- # === Optional Behaviors ===
177
+ # Default key type when not specified in create_api_key!
178
+ # When set and key_types is configured, keys created without explicit
179
+ # key_type will use this default.
180
+ # Default: nil (must specify key_type explicitly when key_types is configured)
181
+ #
182
+ # config.default_key_type = :secret
183
+
184
+ # ============================================================================
185
+ # KEY LIMITS & BEHAVIORS
186
+ # ============================================================================
66
187
 
67
188
  # Global limit on the number of *active* keys an owner can have.
68
- # Can be overridden by `max_keys` in the `has_api_keys` block.
189
+ # Can be overridden per-model with `max_keys` in the `has_api_keys` block, like:
190
+ # has_api_keys max_keys: 5
69
191
  # Set to nil for no global limit.
70
192
  # Default: nil
71
193
  # config.default_max_keys_per_owner = 10
72
194
 
73
- # If true, requires a `name` when creating keys.
74
- # Can be overridden by `require_name` in the `has_api_keys` block.
195
+ # Require a name when creating keys.
196
+ # Can be overridden per-model with `require_name` in the `has_api_keys` block.
75
197
  # Default: false
76
198
  # config.require_key_name = true
77
199
 
@@ -81,104 +203,123 @@ ApiKeys.configure do |config|
81
203
  # config.expire_after = 90.days
82
204
 
83
205
  # Default scopes to assign to newly created keys if none are specified.
84
- # Applies globally unless overridden by `has_api_keys` in the owner model.
206
+ # Can be overridden per-model with `default_scopes` in the `has_api_keys` block.
85
207
  # Default: []
86
208
  # config.default_scopes = ["read"]
87
209
 
88
- # === Performance ===
89
-
90
- # Time-to-live (TTL) for caching ApiKey lookups.
91
- # Higher values improve performance by reducing database lookups and
92
- # expensive comparisons (like bcrypt), but increase the delay for changes
93
- # (like revocation or expiration) to take effect for already cached keys.
94
- # Set to 0 or nil to disable caching.
95
- # Uses Rails.cache.
96
- # Default: 5.seconds
97
- # config.cache_ttl = 30.seconds # Higher TTL = higher risk of "revoked-but-still-valid" edge cases
98
-
99
- # === Security ===
210
+ # ============================================================================
211
+ # TOKEN GENERATION
212
+ # ============================================================================
213
+ #
214
+ # The number of random bytes to generate for the token (before encoding).
215
+ # More bytes = more entropy = harder to guess.
216
+ # SECURITY: Minimum recommended is 16 bytes (128 bits). Default provides 192 bits.
217
+ # Default: 24 (generates ~32 Base58 chars or 48 hex chars)
218
+ # config.token_length = 24
100
219
 
101
- # If true, logs a warning if the gem is used over HTTP in production.
102
- # Default: true
103
- # config.https_only_production = true
220
+ # The encoding alphabet for the random part of the token.
221
+ # :base58 - shorter tokens, avoids ambiguous chars (0, O, I, l) - RECOMMENDED
222
+ # :hex - standard hexadecimal encoding, longer tokens
223
+ # Default: :base58
224
+ # config.token_alphabet = :base58
104
225
 
105
- # If true (and https_only_production is true), raises an error instead of
106
- # just logging a warning when used over HTTP in production.
107
- # Default: false
108
- # config.https_strict_mode = true
226
+ # ============================================================================
227
+ # STORAGE & VERIFICATION
228
+ # ============================================================================
109
229
 
110
- # IMPORTANT: Usage Statistics & Background Jobs
111
- # ---------------------------------------------
112
- # The api_keys gem executes callbacks and updates the `last_used_at` timestamp on every successful authentication
113
- # and optionally increments `requests_count` if `track_requests_count` is true.
114
- # To avoid blocking the request cycle, these calls and updates are performed asynchronously
115
- # using ActiveJob (`ApiKeys::Jobs::UpdateStatsJob` and `ApiKeys::Jobs::CallbacksJob`)
230
+ # The hashing strategy used to store token digests in the database.
116
231
  #
117
- # *** For callbacks to be executed, and for reliable and performant usage statistics, you MUST configure a persistent
118
- # ActiveJob backend adapter in your Rails app! (e.g., Sidekiq, GoodJob, SolidQueue, Resque, Delayed::Job). ***
232
+ # :sha256 (RECOMMENDED for API keys)
233
+ # - Fast, performant, O(1) database lookups
234
+ # - Secure for high-entropy tokens (192+ bits from SecureRandom)
235
+ # - Industry standard for API keys (used by Stripe, GitHub, AWS)
119
236
  #
120
- # - Using the default :async adapter is NOT recommended for production as updates
121
- # run in-process and may be lost if the application restarts unexpectedly.
122
- # - Using the :inline adapter will perform updates synchronously within the request,
123
- # negating the performance benefits and potentially slowing down responses.
237
+ # :bcrypt (for extra security at cost of performance)
238
+ # - Includes salt, computationally expensive by design
239
+ # - 10x-50x slower than SHA256 - impacts every API request
240
+ # - Better for low-entropy secrets (passwords), overkill for random API keys
241
+ # - Prefix + encoded random token must fit bcrypt's 72-byte input limit
124
242
  #
125
- # If you do not have a persistent background job system configured, callbacks won't fire and stats updates
126
- # might be unreliable or impact performance. Consider disabling `track_requests_count` and avoid using callbacks
127
- # if you cannot use a persistent backend and performance is critical.
243
+ # Default: :sha256
244
+ # config.hash_strategy = :sha256
128
245
 
129
- # === Background Job Queues ===
246
+ # ============================================================================
247
+ # SECURITY
248
+ # ============================================================================
130
249
 
131
- # Configure the ActiveJob queue name for processing API key usage statistics.
132
- # Default: :default
133
- # config.stats_job_queue = :api_keys_stats
250
+ # Log a warning if API authentication is attempted over HTTP in production.
251
+ # API keys should always be transmitted over HTTPS.
252
+ # Default: true
253
+ # config.https_only_production = true
134
254
 
135
- # Configure the ActiveJob queue name for processing asynchronous callbacks.
136
- # Default: :default
137
- # config.callbacks_job_queue = :api_keys_callbacks
255
+ # Reject authentication (instead of just warning) over HTTP in production.
256
+ # Only applies when https_only_production is true.
257
+ # Default: true
258
+ # config.https_strict_mode = true
138
259
 
139
- # === Global Async Toggle ===
260
+ # ============================================================================
261
+ # BACKGROUND JOBS & CALLBACKS
262
+ # ============================================================================
263
+ #
264
+ # The gem can update usage statistics and execute callbacks asynchronously
265
+ # using ActiveJob. For reliable operation, configure a persistent job backend
266
+ # (Sidekiq, GoodJob, SolidQueue, etc.).
267
+ #
268
+ # WARNING: The default :async adapter may lose jobs on app restart.
269
+ # The :inline adapter runs synchronously, impacting request performance.
270
+ # ============================================================================
140
271
 
141
- # Set to false to completely disable all background job enqueueing performed
142
- # by this gem (stats updates and callbacks). If false, `last_used_at`,
143
- # `requests_count`, and configured callbacks will NOT be processed.
144
- # Useful if you handle these concerns externally or cannot use ActiveJob.
272
+ # Master toggle for all background job operations.
273
+ # When false, last_used_at, requests_count, and callbacks are NOT processed.
145
274
  # Default: true
146
- # config.enable_async_operations = false
275
+ # config.enable_async_operations = true
147
276
 
148
- # === Usage Statistics ===
149
-
150
- # If true, automatically update `last_used_at` and increment `requests_count`
151
- # on the ApiKey record upon successful authentication.
152
- # Note: Incrementing counters frequently can impact DB performance.
277
+ # Track request counts (increments requests_count on each authentication).
278
+ # Exact counting bypasses last-used debouncing and therefore enqueues one stats
279
+ # job per successful request. High-frequency updates can impact queue/database
280
+ # performance.
153
281
  # Default: false
154
- # config.track_requests_count = true
155
-
156
- # === Callbacks ===
157
-
158
- # A lambda/proc to run *before* token extraction and verification.
159
- # Receives the request object.
160
- # Default: ->(request) { }
161
- # config.before_authentication = ->(request) { Rails.logger.info "Authenticating request: #{request.uuid}" }
282
+ # config.track_requests_count = false
162
283
 
163
- # A lambda/proc to run *after* authentication attempt (success or failure).
164
- # Receives the ApiKeys::Services::Authenticator::Result object.
165
- # Default: ->(result) { }
166
- # config.after_authentication = ->(result) { MyAnalytics.track_auth(result) }
284
+ # Minimum interval between last_used_at jobs when exact request counting is
285
+ # disabled. Set to 0 or nil to update on every successful authentication.
286
+ # Default: 1.minute
287
+ # config.stats_update_interval = 1.minute
167
288
 
168
- # === Engine UI Configuration ===
289
+ # Queue names for background jobs.
290
+ # Default: :default
291
+ # config.stats_job_queue = :default
292
+ # config.callbacks_job_queue = :default
293
+
294
+ # Callbacks enqueued on authentication attempts. Contexts are serializable
295
+ # hashes and never contain the token, request, result, or ApiKey object.
296
+ # before_authentication: { request_uuid: String }
297
+ # after_authentication: { success:, error_code:, api_key_id:,
298
+ # required_scope_check: (optional) }
299
+ #
300
+ # Default: empty procs (no-op)
301
+ # config.before_authentication = ->(context) { Rails.logger.info "Auth request: #{context[:request_uuid]}" }
302
+ # config.after_authentication = ->(context) { Analytics.track_auth(context) }
169
303
 
170
- # The URL or path helper method (as a string) to link back to from the engine's UI.
171
- # Useful when embedding the engine within a larger application context.
172
- # Default: "/" (Root path)
173
- # config.return_url = "/app/settings"
304
+ # ============================================================================
305
+ # PERFORMANCE
306
+ # ============================================================================
174
307
 
175
- # The text displayed for the return link.
176
- # Default: "‹ Home"
177
- # config.return_text = "‹ Back to Settings"
308
+ # Time-to-live (TTL) for caching API key ID lookup hints in Rails.cache.
309
+ #
310
+ # Cache entries are never authorization authority. Every hit reloads the
311
+ # current database row and cryptographically re-verifies the token, so
312
+ # revocation, expiration, and permission changes remain immediate.
313
+ #
314
+ # Set to 0 or nil to disable caching entirely.
315
+ # Default: 5.seconds
316
+ # config.cache_ttl = 5.seconds
178
317
 
179
- # === Debugging ===
318
+ # ============================================================================
319
+ # DEBUGGING
320
+ # ============================================================================
180
321
 
181
- # Enable verbose logging for debugging purposes.
322
+ # Enable verbose debug logging.
182
323
  # Default: false
183
- # config.debug_logging = true
324
+ # config.debug_logging = false
184
325
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: api_keys
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - rameerez
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-08-04 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rails
@@ -23,34 +23,6 @@ dependencies:
23
23
  - - ">="
24
24
  - !ruby/object:Gem::Version
25
25
  version: '6.1'
26
- - !ruby/object:Gem::Dependency
27
- name: activerecord
28
- requirement: !ruby/object:Gem::Requirement
29
- requirements:
30
- - - ">="
31
- - !ruby/object:Gem::Version
32
- version: '6.0'
33
- type: :runtime
34
- prerelease: false
35
- version_requirements: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - ">="
38
- - !ruby/object:Gem::Version
39
- version: '6.0'
40
- - !ruby/object:Gem::Dependency
41
- name: activesupport
42
- requirement: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - ">="
45
- - !ruby/object:Gem::Version
46
- version: '6.0'
47
- type: :runtime
48
- prerelease: false
49
- version_requirements: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - ">="
52
- - !ruby/object:Gem::Version
53
- version: '6.0'
54
26
  - !ruby/object:Gem::Dependency
55
27
  name: base58
56
28
  requirement: !ruby/object:Gem::Requirement
@@ -69,44 +41,22 @@ dependencies:
69
41
  name: bcrypt
70
42
  requirement: !ruby/object:Gem::Requirement
71
43
  requirements:
72
- - - "~>"
73
- - !ruby/object:Gem::Version
74
- version: '3.1'
75
- type: :runtime
76
- prerelease: false
77
- version_requirements: !ruby/object:Gem::Requirement
78
- requirements:
79
- - - "~>"
44
+ - - ">="
80
45
  - !ruby/object:Gem::Version
81
- version: '3.1'
82
- - !ruby/object:Gem::Dependency
83
- name: bundler
84
- requirement: !ruby/object:Gem::Requirement
85
- requirements:
86
- - - "~>"
46
+ version: 3.1.22
47
+ - - "<"
87
48
  - !ruby/object:Gem::Version
88
- version: '2.0'
89
- type: :development
49
+ version: '4'
50
+ type: :runtime
90
51
  prerelease: false
91
52
  version_requirements: !ruby/object:Gem::Requirement
92
53
  requirements:
93
- - - "~>"
94
- - !ruby/object:Gem::Version
95
- version: '2.0'
96
- - !ruby/object:Gem::Dependency
97
- name: rake
98
- requirement: !ruby/object:Gem::Requirement
99
- requirements:
100
- - - "~>"
54
+ - - ">="
101
55
  - !ruby/object:Gem::Version
102
- version: '13.0'
103
- type: :development
104
- prerelease: false
105
- version_requirements: !ruby/object:Gem::Requirement
106
- requirements:
107
- - - "~>"
56
+ version: 3.1.22
57
+ - - "<"
108
58
  - !ruby/object:Gem::Version
109
- version: '13.0'
59
+ version: '4'
110
60
  description: Add secure, production-ready API key authentication to your Rails app
111
61
  in minutes. Handles key generation, hashing, expiration, revocation, per-key scopes;
112
62
  plus a drop-in dashboard for your users to self-issue and manage their own API keys.
@@ -119,17 +69,24 @@ files:
119
69
  - CHANGELOG.md
120
70
  - LICENSE.txt
121
71
  - README.md
122
- - Rakefile
72
+ - SECURITY.md
123
73
  - api_keys_dashboard.webp
124
74
  - api_keys_permissions.webp
125
75
  - api_keys_token.webp
126
76
  - app/controllers/api_keys/application_controller.rb
127
77
  - app/controllers/api_keys/keys_controller.rb
128
78
  - app/controllers/api_keys/security_controller.rb
79
+ - app/views/api_keys/keys/_empty_state.html.erb
129
80
  - app/views/api_keys/keys/_form.html.erb
81
+ - app/views/api_keys/keys/_key_actions.html.erb
82
+ - app/views/api_keys/keys/_key_badges.html.erb
130
83
  - app/views/api_keys/keys/_key_row.html.erb
84
+ - app/views/api_keys/keys/_key_status.html.erb
131
85
  - app/views/api_keys/keys/_keys_table.html.erb
86
+ - app/views/api_keys/keys/_publishable_keys.html.erb
87
+ - app/views/api_keys/keys/_secret_keys.html.erb
132
88
  - app/views/api_keys/keys/_show_token.html.erb
89
+ - app/views/api_keys/keys/_token_display.html.erb
133
90
  - app/views/api_keys/keys/edit.html.erb
134
91
  - app/views/api_keys/keys/index.html.erb
135
92
  - app/views/api_keys/keys/new.html.erb
@@ -142,6 +99,11 @@ files:
142
99
  - lib/api_keys/configuration.rb
143
100
  - lib/api_keys/controller.rb
144
101
  - lib/api_keys/engine.rb
102
+ - lib/api_keys/errors.rb
103
+ - lib/api_keys/form_builder_extensions.rb
104
+ - lib/api_keys/helpers/expiration_options.rb
105
+ - lib/api_keys/helpers/token_session.rb
106
+ - lib/api_keys/helpers/view_helpers.rb
145
107
  - lib/api_keys/jobs/callbacks_job.rb
146
108
  - lib/api_keys/jobs/update_stats_job.rb
147
109
  - lib/api_keys/logging.rb
@@ -152,7 +114,11 @@ files:
152
114
  - lib/api_keys/services/token_generator.rb
153
115
  - lib/api_keys/tenant_resolution.rb
154
116
  - lib/api_keys/version.rb
117
+ - lib/generators/api_keys/add_authentication_index_generator.rb
118
+ - lib/generators/api_keys/add_key_types_generator.rb
155
119
  - lib/generators/api_keys/install_generator.rb
120
+ - lib/generators/api_keys/templates/add_authentication_index_to_api_keys.rb.erb
121
+ - lib/generators/api_keys/templates/add_key_types_to_api_keys.rb.erb
156
122
  - lib/generators/api_keys/templates/create_api_keys_table.rb.erb
157
123
  - lib/generators/api_keys/templates/initializer.rb
158
124
  homepage: https://github.com/rameerez/api_keys
@@ -178,7 +144,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
178
144
  - !ruby/object:Gem::Version
179
145
  version: '0'
180
146
  requirements: []
181
- rubygems_version: 3.6.2
147
+ rubygems_version: 3.6.9
182
148
  specification_version: 4
183
149
  summary: Gate your Rails API with secure, self-serve API keys in minutes
184
150
  test_files: []
data/Rakefile DELETED
@@ -1,32 +0,0 @@
1
- begin
2
- require "bundler/setup"
3
- rescue LoadError
4
- puts "You must `gem install bundler` and `bundle install` to run rake tasks"
5
- end
6
-
7
- require "bundler/gem_tasks"
8
-
9
- require "rdoc/task"
10
-
11
- RDoc::Task.new(:rdoc) do |rdoc|
12
- rdoc.rdoc_dir = "rdoc"
13
- rdoc.title = "Pay"
14
- rdoc.options << "--line-numbers"
15
- rdoc.rdoc_files.include("README.md")
16
- rdoc.rdoc_files.include("lib/**/*.rb")
17
- end
18
-
19
- APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
20
- load "rails/tasks/engine.rake"
21
-
22
- load "rails/tasks/statistics.rake"
23
-
24
- require "rake/testtask"
25
-
26
- Rake::TestTask.new(:test) do |t|
27
- t.libs << "test"
28
- t.pattern = "test/**/*_test.rb"
29
- t.verbose = false
30
- end
31
-
32
- task default: :test