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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +60 -0
- data/README.md +851 -25
- data/SECURITY.md +33 -0
- data/app/controllers/api_keys/application_controller.rb +58 -10
- data/app/controllers/api_keys/keys_controller.rb +77 -23
- data/app/controllers/api_keys/security_controller.rb +8 -0
- data/app/views/api_keys/keys/_empty_state.html.erb +9 -0
- data/app/views/api_keys/keys/_form.html.erb +33 -4
- data/app/views/api_keys/keys/_key_actions.html.erb +20 -0
- data/app/views/api_keys/keys/_key_badges.html.erb +17 -0
- data/app/views/api_keys/keys/_key_row.html.erb +21 -35
- data/app/views/api_keys/keys/_key_status.html.erb +10 -0
- data/app/views/api_keys/keys/_keys_table.html.erb +3 -11
- data/app/views/api_keys/keys/_publishable_keys.html.erb +40 -0
- data/app/views/api_keys/keys/_secret_keys.html.erb +39 -0
- data/app/views/api_keys/keys/_show_token.html.erb +10 -47
- data/app/views/api_keys/keys/_token_display.html.erb +11 -0
- data/app/views/api_keys/keys/index.html.erb +40 -8
- data/app/views/api_keys/keys/show.html.erb +2 -2
- data/app/views/api_keys/security/best_practices.html.erb +73 -47
- data/app/views/layouts/api_keys/application.html.erb +267 -14
- data/lib/api_keys/authentication.rb +39 -11
- data/lib/api_keys/configuration.rb +444 -17
- data/lib/api_keys/engine.rb +5 -20
- data/lib/api_keys/errors.rb +73 -0
- data/lib/api_keys/form_builder_extensions.rb +168 -0
- data/lib/api_keys/helpers/expiration_options.rb +139 -0
- data/lib/api_keys/helpers/token_session.rb +203 -0
- data/lib/api_keys/helpers/view_helpers.rb +220 -0
- data/lib/api_keys/jobs/callbacks_job.rb +10 -17
- data/lib/api_keys/jobs/update_stats_job.rb +27 -12
- data/lib/api_keys/models/api_key.rb +452 -21
- data/lib/api_keys/models/concerns/has_api_keys.rb +269 -26
- data/lib/api_keys/services/authenticator.rb +300 -112
- data/lib/api_keys/services/digestor.rb +81 -14
- data/lib/api_keys/services/token_generator.rb +41 -1
- data/lib/api_keys/tenant_resolution.rb +4 -4
- data/lib/api_keys/version.rb +1 -1
- data/lib/api_keys.rb +12 -0
- data/lib/generators/api_keys/add_authentication_index_generator.rb +36 -0
- data/lib/generators/api_keys/add_key_types_generator.rb +68 -0
- data/lib/generators/api_keys/templates/add_authentication_index_to_api_keys.rb.erb +32 -0
- data/lib/generators/api_keys/templates/add_key_types_to_api_keys.rb.erb +18 -0
- data/lib/generators/api_keys/templates/create_api_keys_table.rb.erb +11 -3
- data/lib/generators/api_keys/templates/initializer.rb +261 -120
- metadata +29 -63
- data/Rakefile +0 -32
|
@@ -1,77 +1,199 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
ApiKeys.configure do |config|
|
|
4
|
-
#
|
|
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
|
-
#
|
|
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
|
-
#
|
|
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
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
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
|
|
23
|
-
#
|
|
24
|
-
# Default:
|
|
25
|
-
#
|
|
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
|
|
28
|
-
#
|
|
29
|
-
# :
|
|
30
|
-
#
|
|
31
|
-
#
|
|
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
|
-
#
|
|
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
|
-
#
|
|
36
|
-
# :
|
|
37
|
-
#
|
|
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
|
-
#
|
|
57
|
+
# Text for the "back" link.
|
|
58
|
+
# Default: "‹ Home"
|
|
59
|
+
# config.return_text = "‹ Back to Settings"
|
|
42
60
|
|
|
43
|
-
#
|
|
44
|
-
#
|
|
45
|
-
#
|
|
46
|
-
# a User model with current_user/authenticate_user! methods (Devise-style).
|
|
61
|
+
# ============================================================================
|
|
62
|
+
# TOKEN PREFIXES
|
|
63
|
+
# ============================================================================
|
|
47
64
|
#
|
|
48
|
-
#
|
|
49
|
-
#
|
|
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
|
-
#
|
|
52
|
-
#
|
|
53
|
-
#
|
|
54
|
-
#
|
|
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
|
-
#
|
|
57
|
-
#
|
|
58
|
-
#
|
|
59
|
-
#
|
|
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
|
-
#
|
|
62
|
-
#
|
|
63
|
-
#
|
|
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
|
-
#
|
|
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
|
|
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
|
-
#
|
|
74
|
-
# Can be overridden
|
|
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
|
-
#
|
|
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
|
-
#
|
|
89
|
-
|
|
90
|
-
#
|
|
91
|
-
#
|
|
92
|
-
#
|
|
93
|
-
#
|
|
94
|
-
#
|
|
95
|
-
#
|
|
96
|
-
#
|
|
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
|
-
#
|
|
102
|
-
#
|
|
103
|
-
#
|
|
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
|
-
#
|
|
106
|
-
#
|
|
107
|
-
#
|
|
108
|
-
# config.https_strict_mode = true
|
|
226
|
+
# ============================================================================
|
|
227
|
+
# STORAGE & VERIFICATION
|
|
228
|
+
# ============================================================================
|
|
109
229
|
|
|
110
|
-
#
|
|
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
|
-
#
|
|
118
|
-
#
|
|
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
|
-
#
|
|
121
|
-
#
|
|
122
|
-
# -
|
|
123
|
-
#
|
|
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
|
-
#
|
|
126
|
-
#
|
|
127
|
-
# if you cannot use a persistent backend and performance is critical.
|
|
243
|
+
# Default: :sha256
|
|
244
|
+
# config.hash_strategy = :sha256
|
|
128
245
|
|
|
129
|
-
#
|
|
246
|
+
# ============================================================================
|
|
247
|
+
# SECURITY
|
|
248
|
+
# ============================================================================
|
|
130
249
|
|
|
131
|
-
#
|
|
132
|
-
#
|
|
133
|
-
#
|
|
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
|
-
#
|
|
136
|
-
#
|
|
137
|
-
#
|
|
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
|
-
#
|
|
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
|
-
#
|
|
142
|
-
#
|
|
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 =
|
|
275
|
+
# config.enable_async_operations = true
|
|
147
276
|
|
|
148
|
-
#
|
|
149
|
-
|
|
150
|
-
#
|
|
151
|
-
#
|
|
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 =
|
|
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
|
-
#
|
|
164
|
-
#
|
|
165
|
-
# Default:
|
|
166
|
-
# config.
|
|
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
|
-
#
|
|
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
|
-
#
|
|
171
|
-
#
|
|
172
|
-
#
|
|
173
|
-
# config.return_url = "/app/settings"
|
|
304
|
+
# ============================================================================
|
|
305
|
+
# PERFORMANCE
|
|
306
|
+
# ============================================================================
|
|
174
307
|
|
|
175
|
-
#
|
|
176
|
-
#
|
|
177
|
-
#
|
|
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
|
-
#
|
|
318
|
+
# ============================================================================
|
|
319
|
+
# DEBUGGING
|
|
320
|
+
# ============================================================================
|
|
180
321
|
|
|
181
|
-
# Enable verbose logging
|
|
322
|
+
# Enable verbose debug logging.
|
|
182
323
|
# Default: false
|
|
183
|
-
# config.debug_logging =
|
|
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.
|
|
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:
|
|
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:
|
|
82
|
-
-
|
|
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: '
|
|
89
|
-
type: :
|
|
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:
|
|
103
|
-
|
|
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: '
|
|
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
|
-
-
|
|
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.
|
|
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
|