api_keys 0.2.1 → 0.3.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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/.simplecov +36 -0
  3. data/AGENTS.md +5 -0
  4. data/Appraisals +17 -0
  5. data/CHANGELOG.md +9 -0
  6. data/CLAUDE.md +5 -0
  7. data/README.md +767 -3
  8. data/Rakefile +9 -4
  9. data/app/controllers/api_keys/keys_controller.rb +43 -11
  10. data/app/controllers/api_keys/security_controller.rb +8 -0
  11. data/app/views/api_keys/keys/_empty_state.html.erb +9 -0
  12. data/app/views/api_keys/keys/_form.html.erb +31 -2
  13. data/app/views/api_keys/keys/_key_actions.html.erb +20 -0
  14. data/app/views/api_keys/keys/_key_badges.html.erb +17 -0
  15. data/app/views/api_keys/keys/_key_row.html.erb +21 -35
  16. data/app/views/api_keys/keys/_key_status.html.erb +10 -0
  17. data/app/views/api_keys/keys/_keys_table.html.erb +2 -7
  18. data/app/views/api_keys/keys/_publishable_keys.html.erb +40 -0
  19. data/app/views/api_keys/keys/_secret_keys.html.erb +39 -0
  20. data/app/views/api_keys/keys/_show_token.html.erb +5 -1
  21. data/app/views/api_keys/keys/_token_display.html.erb +11 -0
  22. data/app/views/api_keys/keys/index.html.erb +40 -8
  23. data/app/views/api_keys/security/best_practices.html.erb +73 -47
  24. data/app/views/layouts/api_keys/application.html.erb +113 -7
  25. data/context7.json +4 -0
  26. data/gemfiles/rails_7.2.gemfile +21 -0
  27. data/gemfiles/rails_8.0.gemfile +21 -0
  28. data/gemfiles/rails_8.1.gemfile +21 -0
  29. data/lib/api_keys/configuration.rb +77 -0
  30. data/lib/api_keys/errors.rb +73 -0
  31. data/lib/api_keys/form_builder_extensions.rb +158 -0
  32. data/lib/api_keys/helpers/expiration_options.rb +131 -0
  33. data/lib/api_keys/helpers/token_session.rb +68 -0
  34. data/lib/api_keys/helpers/view_helpers.rb +216 -0
  35. data/lib/api_keys/models/api_key.rb +229 -17
  36. data/lib/api_keys/models/concerns/has_api_keys.rb +183 -3
  37. data/lib/api_keys/services/authenticator.rb +45 -2
  38. data/lib/api_keys/services/digestor.rb +6 -2
  39. data/lib/api_keys/tenant_resolution.rb +3 -1
  40. data/lib/api_keys/version.rb +1 -1
  41. data/lib/api_keys.rb +12 -0
  42. data/lib/generators/api_keys/add_key_types_generator.rb +68 -0
  43. data/lib/generators/api_keys/templates/add_key_types_to_api_keys.rb.erb +18 -0
  44. data/lib/generators/api_keys/templates/create_api_keys_table.rb.erb +9 -0
  45. data/lib/generators/api_keys/templates/initializer.rb +242 -120
  46. metadata +24 -58
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators/base"
4
+ require "rails/generators/active_record"
5
+
6
+ module ApiKeys
7
+ module Generators
8
+ # Rails generator for adding key_type and environment columns to the api_keys table.
9
+ # This generator is for existing installations that want to enable the key types feature.
10
+ class AddKeyTypesGenerator < Rails::Generators::Base
11
+ include ActiveRecord::Generators::Migration
12
+
13
+ source_root File.expand_path("templates", __dir__)
14
+
15
+ # Implement the required interface for Rails::Generators::Migration.
16
+ def self.next_migration_number(dirname)
17
+ next_migration_number = current_migration_number(dirname) + 1
18
+ ActiveRecord::Migration.next_migration_number(next_migration_number)
19
+ end
20
+
21
+ # Creates the migration file using the template.
22
+ def create_migration_file
23
+ migration_template "add_key_types_to_api_keys.rb.erb",
24
+ File.join(db_migrate_path, "add_key_types_to_api_keys.rb")
25
+ end
26
+
27
+ # Displays helpful information to the user after installation.
28
+ def display_post_install_message
29
+ say "\nšŸ”‘ Key types migration created!", :green
30
+ say "\nNext steps:"
31
+ say " 1. Run `rails db:migrate` to add the key_type and environment columns."
32
+ say "\n 2. Configure key types in `config/initializers/api_keys.rb`:"
33
+ say " ApiKeys.configure do |config|"
34
+ say " config.key_types = {"
35
+ say " publishable: {"
36
+ say " prefix: 'pk',"
37
+ say " permissions: %w[read validate],"
38
+ say " revocable: false,"
39
+ say " limit: 1"
40
+ say " },"
41
+ say " secret: {"
42
+ say " prefix: 'sk',"
43
+ say " permissions: :all"
44
+ say " }"
45
+ say " }"
46
+ say ""
47
+ say " config.environments = {"
48
+ say " test: { prefix_segment: 'test' },"
49
+ say " live: { prefix_segment: 'live' }"
50
+ say " }"
51
+ say ""
52
+ say " config.current_environment = -> { Rails.env.production? ? :live : :test }"
53
+ say " config.strict_environment_isolation = true"
54
+ say " end"
55
+ say "\n 3. Create typed API keys:"
56
+ say " user.create_api_key!(name: 'My Key', key_type: :publishable)"
57
+ say " user.create_api_key!(name: 'Admin Key', key_type: :secret)"
58
+ say "\nSee the api_keys README for detailed usage and examples.", :cyan
59
+ end
60
+
61
+ private
62
+
63
+ def migration_version
64
+ "[#{ActiveRecord::VERSION::STRING.to_f}]"
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Migration to add key_type and environment columns to the api_keys table.
4
+ # This enables the Stripe-style publishable/secret key types feature.
5
+ #
6
+ # Run this migration if you're upgrading from a version of api_keys that
7
+ # didn't have key types support.
8
+ class AddKeyTypesToApiKeys < ActiveRecord::Migration<%= migration_version %>
9
+ def change
10
+ add_column :api_keys, :key_type, :string
11
+ add_column :api_keys, :environment, :string
12
+
13
+ add_index :api_keys, :key_type
14
+ add_index :api_keys, :environment
15
+ add_index :api_keys, [:owner_type, :owner_id, :key_type, :environment],
16
+ name: "index_api_keys_owner_type_env"
17
+ end
18
+ end
@@ -42,6 +42,12 @@ class CreateApiKeysTable < ActiveRecord::Migration<%= migration_version %>
42
42
  # Timestamp when the key was revoked (null means active)
43
43
  t.datetime :revoked_at
44
44
 
45
+ # Key type identifier (e.g., "publishable", "secret") for Stripe-style key types
46
+ t.string :key_type
47
+
48
+ # Environment identifier (e.g., "test", "live") for environment isolation
49
+ t.string :environment
50
+
45
51
  t.timestamps
46
52
 
47
53
  # Critical index for authentication performance
@@ -58,6 +64,9 @@ class CreateApiKeysTable < ActiveRecord::Migration<%= migration_version %>
58
64
  t.index :expires_at
59
65
  t.index :revoked_at
60
66
  t.index :last_used_at
67
+ t.index :key_type
68
+ t.index :environment
69
+ t.index [:owner_type, :owner_id, :key_type, :environment], name: "index_api_keys_owner_type_env"
61
70
  end
62
71
  end
63
72
 
@@ -1,77 +1,188 @@
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
+ # The method that returns the current API key owner in your controllers.
27
+ # This should return the model instance that has_api_keys.
28
+ # Default: :current_user (works with Devise out of the box)
29
+ #
30
+ # Example for Organization-owned keys:
31
+ # config.current_owner_method = :current_organization
21
32
 
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
33
+ # The method that authenticates/requires login for the dashboard.
34
+ # This should be a before_action-style method that ensures the owner is logged in.
35
+ # Default: :authenticate_user! (works with Devise out of the box)
36
+ #
37
+ # Example for Organization-owned keys:
38
+ # config.authenticate_owner_method = :authenticate_organization!
26
39
 
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
40
+ # Dashboard environment filtering (only applies when key_types is configured).
41
+ # When false (default), dashboard only shows keys matching current_environment.
42
+ # When true, dashboard shows keys from all environments.
43
+ # Default: false
44
+ #
45
+ # config.dashboard_allow_cross_environment = false
32
46
 
33
- # === Storage & Verification ===
47
+ # URL for the "back" link in the dashboard UI.
48
+ # Default: "/"
49
+ # config.return_url = "/settings"
34
50
 
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
51
+ # Text for the "back" link.
52
+ # Default: "‹ Home"
53
+ # config.return_text = "‹ Back to Settings"
40
54
 
41
- # === Dashboard Configuration ===
55
+ # ============================================================================
56
+ # TOKEN PREFIXES
57
+ # ============================================================================
58
+ #
59
+ # API keys are generated with a prefix followed by random characters:
60
+ # "ak_7Hq2mJvK9pRs3xYz..."
61
+ # prefix = ak_
62
+ # random part = 7Hq2mJvK9pRs3xYz...
63
+ #
64
+ # The prefix system has two modes:
65
+ #
66
+ # 1. SIMPLE MODE (default): All keys use the same prefix from `token_prefix`
67
+ # Example: ak_7Hq2mJvK9pRs3xYz...
68
+ #
69
+ # 2. KEY TYPES MODE: Different key types get different prefixes based on
70
+ # their type and environment (Stripe-style)
71
+ # Example: pk_test_7Hq2mJvK..., sk_live_9xYz3pRs...
72
+ #
73
+ # See "KEY TYPES & ENVIRONMENTS" section below to enable key types mode.
42
74
 
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).
75
+ # ----------------------------------------------------------------------------
76
+ # Simple Prefix (when NOT using KEY TYPES)
77
+ # ----------------------------------------------------------------------------
47
78
  #
48
- # If your API keys belong to a different model (e.g., Organization),
49
- # you MUST configure these methods:
79
+ # A lambda/proc that returns the prefix for newly generated tokens.
80
+ # This is ONLY used when:
81
+ # - key_types is not configured (empty hash), OR
82
+ # - Creating a key without specifying a key_type
83
+ #
84
+ # When key_types IS configured and you specify a key_type, this setting
85
+ # is IGNORED - the prefix comes from the key type's configuration instead.
86
+ #
87
+ # WARNING: Once set, do NOT change or existing keys will fail authentication!
88
+ # Default: -> { "ak_" }
89
+ # config.token_prefix = -> { "myapp_" }
50
90
 
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
91
+ # ============================================================================
92
+ # KEY TYPES & ENVIRONMENTS (Stripe-style Publishable/Secret Keys)
93
+ # ============================================================================
94
+ #
95
+ # For applications that distribute software with embedded API keys (desktop
96
+ # apps, mobile apps, CLI tools), you can create different key types with
97
+ # different permission levels - similar to Stripe's publishable/secret pattern.
98
+ #
99
+ # When enabled:
100
+ # - Keys get type+environment prefixes: pk_test_, pk_live_, sk_test_, sk_live_
101
+ # - Each type can have different permissions, revocability, and limits
102
+ # - The `token_prefix` setting above is IGNORED for typed keys
103
+ #
104
+ # By default, this feature is DISABLED (empty hash) for backwards compatibility.
105
+ # Existing keys without key_type/environment continue to work normally.
106
+ # ============================================================================
55
107
 
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!
108
+ # Define your key types with their properties:
109
+ #
110
+ # - prefix: The token prefix for this type (e.g., "pk" becomes pk_test_)
111
+ # - permissions: Scope ceiling - array of allowed scopes, or :all for unrestricted
112
+ # - revocable: Whether keys of this type can be revoked/deleted (default: true)
113
+ # - limit: Max keys of this type per owner per environment (nil = unlimited)
114
+ # - public: If true AND revocable: false, stores plaintext token in metadata
115
+ # so it can be viewed again in the dashboard. Use ONLY for publishable
116
+ # keys designed to be embedded in distributed apps. (default: false)
117
+ # SECURITY: NEVER set public: true on secret keys!
118
+ #
119
+ # config.key_types = {
120
+ # publishable: {
121
+ # prefix: "pk", # → pk_test_, pk_live_
122
+ # permissions: %w[read validate], # Can ONLY have these scopes
123
+ # revocable: false, # Cannot be revoked - protects deployed apps!
124
+ # public: true, # Store token for later viewing in dashboard
125
+ # limit: 1 # Only 1 publishable key per environment
126
+ # },
127
+ # secret: {
128
+ # prefix: "sk", # → sk_test_, sk_live_
129
+ # permissions: :all # No scope restrictions
130
+ # # revocable: true (default)
131
+ # # public: false (default) - NEVER store secret keys!
132
+ # # limit: nil (default = unlimited)
133
+ # }
134
+ # }
135
+
136
+ # Define your environments with their prefix segments:
137
+ #
138
+ # - prefix_segment: The middle part of the prefix (e.g., "test" → pk_test_)
139
+ # Set to nil for single-environment setups (prefix becomes just "pk_")
140
+ #
141
+ # config.environments = {
142
+ # test: { prefix_segment: "test" }, # Development/staging → pk_test_, sk_test_
143
+ # live: { prefix_segment: "live" } # Production → pk_live_, sk_live_
144
+ # }
145
+ #
146
+ # Alternative naming (Stripe's newer convention):
147
+ # config.environments = {
148
+ # sandbox: { prefix_segment: "test" },
149
+ # live: { prefix_segment: "live" }
150
+ # }
151
+
152
+ # Lambda that returns the current environment.
153
+ # Used to auto-select environment when creating keys and for isolation checks.
154
+ # Default: -> { :default }
155
+ #
156
+ # config.current_environment = -> { Rails.env.production? ? :live : :test }
60
157
 
61
- # Example for Organization-owned keys:
62
- # config.current_owner_method = :current_organization
63
- # config.authenticate_owner_method = :authenticate_organization!
158
+ # Enable strict environment isolation.
159
+ # When true, keys can ONLY authenticate in their matching environment:
160
+ # - test keys return :environment_mismatch error in production
161
+ # - live keys return :environment_mismatch error in development/test
162
+ # Default: false
163
+ #
164
+ # config.strict_environment_isolation = true
165
+
166
+ # Default key type when not specified in create_api_key!
167
+ # When set and key_types is configured, keys created without explicit
168
+ # key_type will use this default.
169
+ # Default: nil (must specify key_type explicitly when key_types is configured)
170
+ #
171
+ # config.default_key_type = :secret
64
172
 
65
- # === Optional Behaviors ===
173
+ # ============================================================================
174
+ # KEY LIMITS & BEHAVIORS
175
+ # ============================================================================
66
176
 
67
177
  # 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.
178
+ # Can be overridden per-model with `max_keys` in the `has_api_keys` block, like:
179
+ # has_api_keys max_keys: 5
69
180
  # Set to nil for no global limit.
70
181
  # Default: nil
71
182
  # config.default_max_keys_per_owner = 10
72
183
 
73
- # If true, requires a `name` when creating keys.
74
- # Can be overridden by `require_name` in the `has_api_keys` block.
184
+ # Require a name when creating keys.
185
+ # Can be overridden per-model with `require_name` in the `has_api_keys` block.
75
186
  # Default: false
76
187
  # config.require_key_name = true
77
188
 
@@ -81,104 +192,115 @@ ApiKeys.configure do |config|
81
192
  # config.expire_after = 90.days
82
193
 
83
194
  # 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.
195
+ # Can be overridden per-model with `default_scopes` in the `has_api_keys` block.
85
196
  # Default: []
86
197
  # config.default_scopes = ["read"]
87
198
 
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 ===
199
+ # ============================================================================
200
+ # TOKEN GENERATION
201
+ # ============================================================================
202
+ #
203
+ # The number of random bytes to generate for the token (before encoding).
204
+ # More bytes = more entropy = harder to guess.
205
+ # SECURITY: Minimum recommended is 16 bytes (128 bits). Default provides 192 bits.
206
+ # Default: 24 (generates ~32 Base58 chars or 48 hex chars)
207
+ # config.token_length = 24
100
208
 
101
- # If true, logs a warning if the gem is used over HTTP in production.
102
- # Default: true
103
- # config.https_only_production = true
209
+ # The encoding alphabet for the random part of the token.
210
+ # :base58 - shorter tokens, avoids ambiguous chars (0, O, I, l) - RECOMMENDED
211
+ # :hex - standard hexadecimal encoding, longer tokens
212
+ # Default: :base58
213
+ # config.token_alphabet = :base58
104
214
 
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
215
+ # ============================================================================
216
+ # STORAGE & VERIFICATION
217
+ # ============================================================================
109
218
 
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`)
219
+ # The hashing strategy used to store token digests in the database.
116
220
  #
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). ***
221
+ # :sha256 (RECOMMENDED for API keys)
222
+ # - Fast, performant, O(1) database lookups
223
+ # - Secure for high-entropy tokens (192+ bits from SecureRandom)
224
+ # - Industry standard for API keys (used by Stripe, GitHub, AWS)
119
225
  #
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.
226
+ # :bcrypt (for extra security at cost of performance)
227
+ # - Includes salt, computationally expensive by design
228
+ # - 10x-50x slower than SHA256 - impacts every API request
229
+ # - Better for low-entropy secrets (passwords), overkill for random API keys
124
230
  #
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.
231
+ # Default: :sha256
232
+ # config.hash_strategy = :sha256
128
233
 
129
- # === Background Job Queues ===
234
+ # ============================================================================
235
+ # SECURITY
236
+ # ============================================================================
130
237
 
131
- # Configure the ActiveJob queue name for processing API key usage statistics.
132
- # Default: :default
133
- # config.stats_job_queue = :api_keys_stats
238
+ # Log a warning if API authentication is attempted over HTTP in production.
239
+ # API keys should always be transmitted over HTTPS.
240
+ # Default: true
241
+ # config.https_only_production = true
134
242
 
135
- # Configure the ActiveJob queue name for processing asynchronous callbacks.
136
- # Default: :default
137
- # config.callbacks_job_queue = :api_keys_callbacks
243
+ # Raise an error (instead of just warning) for HTTP in production.
244
+ # Only applies when https_only_production is true.
245
+ # Default: false
246
+ # config.https_strict_mode = false
138
247
 
139
- # === Global Async Toggle ===
248
+ # ============================================================================
249
+ # BACKGROUND JOBS & CALLBACKS
250
+ # ============================================================================
251
+ #
252
+ # The gem can update usage statistics and execute callbacks asynchronously
253
+ # using ActiveJob. For reliable operation, configure a persistent job backend
254
+ # (Sidekiq, GoodJob, SolidQueue, etc.).
255
+ #
256
+ # WARNING: The default :async adapter may lose jobs on app restart.
257
+ # The :inline adapter runs synchronously, impacting request performance.
258
+ # ============================================================================
140
259
 
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.
260
+ # Master toggle for all background job operations.
261
+ # When false, last_used_at, requests_count, and callbacks are NOT processed.
145
262
  # Default: true
146
- # config.enable_async_operations = false
147
-
148
- # === Usage Statistics ===
263
+ # config.enable_async_operations = true
149
264
 
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.
265
+ # Track request counts (increments requests_count on each authentication).
266
+ # Note: High-frequency counter updates can impact database performance.
153
267
  # Default: false
154
- # config.track_requests_count = true
268
+ # config.track_requests_count = false
155
269
 
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}" }
162
-
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) }
270
+ # Queue names for background jobs.
271
+ # Default: :default
272
+ # config.stats_job_queue = :default
273
+ # config.callbacks_job_queue = :default
167
274
 
168
- # === Engine UI Configuration ===
275
+ # Callbacks executed on authentication attempts.
276
+ # before_authentication: receives the request object
277
+ # after_authentication: receives the Result object (success/failure info)
278
+ #
279
+ # Default: empty procs (no-op)
280
+ # config.before_authentication = ->(request) { Rails.logger.info "Auth: #{request.uuid}" }
281
+ # config.after_authentication = ->(result) { Analytics.track(result) }
169
282
 
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"
283
+ # ============================================================================
284
+ # PERFORMANCE
285
+ # ============================================================================
174
286
 
175
- # The text displayed for the return link.
176
- # Default: "‹ Home"
177
- # config.return_text = "‹ Back to Settings"
287
+ # Time-to-live (TTL) for caching API key lookups in Rails.cache.
288
+ #
289
+ # Higher values = better performance (fewer DB queries)
290
+ # Lower values = faster propagation of revocations/changes
291
+ #
292
+ # Trade-off: A revoked key may still work for up to `cache_ttl` seconds
293
+ # until the cache expires.
294
+ #
295
+ # Set to 0 or nil to disable caching entirely.
296
+ # Default: 5.seconds
297
+ # config.cache_ttl = 5.seconds
178
298
 
179
- # === Debugging ===
299
+ # ============================================================================
300
+ # DEBUGGING
301
+ # ============================================================================
180
302
 
181
- # Enable verbose logging for debugging purposes.
303
+ # Enable verbose debug logging.
182
304
  # Default: false
183
- # config.debug_logging = true
305
+ # config.debug_logging = false
184
306
  end