api_keys 0.7.0 → 0.8.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 +6 -0
- data/README.md +11 -1
- data/lib/api_keys/configuration.rb +9 -2
- data/lib/api_keys/services/authenticator.rb +10 -3
- data/lib/api_keys/version.rb +1 -1
- data/lib/generators/api_keys/templates/initializer.rb +5 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 465a7a5c57c770d52195e2c8a182b00d60ea19dc8cc879ebfdb83b3e16d810f2
|
|
4
|
+
data.tar.gz: daa04e5c07e2dbfe8200c9a43189a2249b680e00737f6c201646a1495847fb06
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a4b8b2a0f2386cbbe52505afc68e6ca972aaf4106efa27d72aaa09441805760eea8772666133734c288c39cd8542db096a712bc17ad514a1be8331875faf741d
|
|
7
|
+
data.tar.gz: 3bd195acb458ff535ed41ceb699d3bf6972ace5cc7d46e80a58ac743849ef3549baaaf29baacf836c5ede49587cd93c1a2532ea002f9d5667802d6c830712de6
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
## [0.8.0] - 2026-10-25
|
|
2
|
+
|
|
3
|
+
### Added
|
|
4
|
+
|
|
5
|
+
- `config.require_bearer_scheme`. When true, the authentication header is accepted only as `Bearer <token>` (any case, spaces or tabs after the scheme); a bare token, another scheme such as `Basic`, or a lone `Bearer` gets the ordinary 401 `invalid_token`, is never looked up, and never falls back to `config.query_param`. It applies to whichever header `config.header` names. The default, false, keeps accepting a bare token as every earlier version did. Asked for by ReplyBrain, whose public API should parse one credential shape only.
|
|
6
|
+
|
|
1
7
|
## [0.7.0] - 2026-10-24
|
|
2
8
|
|
|
3
9
|
Four features that an invoicing app on the fleet runs in production today, moved into the gem with their tests so that apps on the fleet can delete their own copies. Each one is opt-in: an app that does not use it sees no change.
|
data/README.md
CHANGED
|
@@ -1298,9 +1298,19 @@ See the [Key Types](#key-types-stripe-style-publishable--secret-keys) section be
|
|
|
1298
1298
|
|
|
1299
1299
|
Some highlights:
|
|
1300
1300
|
|
|
1301
|
+
### Require the `Bearer` scheme
|
|
1302
|
+
|
|
1303
|
+
Clients send `Authorization: Bearer ak_123abc...`. For compatibility, a bare `Authorization: ak_123abc...` is accepted too. A public API should accept one shape only, so turn the bare token off:
|
|
1304
|
+
|
|
1305
|
+
```ruby
|
|
1306
|
+
config.require_bearer_scheme = true
|
|
1307
|
+
```
|
|
1308
|
+
|
|
1309
|
+
Now a header without the scheme (a bare token, `Basic …`, `Token …`) gets the same 401 `invalid_token` as any wrong key, and is never looked up. It applies to whichever header you configured in `config.header`, and a refused header never falls back to the query parameter.
|
|
1310
|
+
|
|
1301
1311
|
### Accept API keys via query params instead of Authentication HTTP headers
|
|
1302
1312
|
|
|
1303
|
-
By default, the `api_key` gem expects API keys to come *exclusively*
|
|
1313
|
+
By default, the `api_key` gem expects API keys to come *exclusively* in the `Authorization` header, for security purposes. But you can allow users to make requests to your endpoints with the API key token passed as a URL query param too, like this:
|
|
1304
1314
|
|
|
1305
1315
|
```
|
|
1306
1316
|
https://example.com/api/endpoint?api_key=ak_123abc...
|
|
@@ -16,7 +16,13 @@ module ApiKeys
|
|
|
16
16
|
# == Accessors ==
|
|
17
17
|
|
|
18
18
|
# Core Authentication
|
|
19
|
-
|
|
19
|
+
#
|
|
20
|
+
# @!attribute [rw] require_bearer_scheme
|
|
21
|
+
# @return [Boolean] Accept the header only as "Bearer <token>". A value
|
|
22
|
+
# without the scheme is refused like any invalid token (401
|
|
23
|
+
# `invalid_token`). false (the default) also accepts the bare token,
|
|
24
|
+
# as every earlier version did.
|
|
25
|
+
attr_reader :header, :query_param, :require_bearer_scheme
|
|
20
26
|
|
|
21
27
|
# Token Generation
|
|
22
28
|
attr_reader :token_prefix, :token_length, :token_alphabet
|
|
@@ -192,7 +198,7 @@ module ApiKeys
|
|
|
192
198
|
BOOLEAN_SETTINGS = %i[
|
|
193
199
|
require_key_name track_requests_count https_only_production https_strict_mode
|
|
194
200
|
enable_async_operations debug_logging strict_environment_isolation
|
|
195
|
-
dashboard_allow_cross_environment
|
|
201
|
+
dashboard_allow_cross_environment require_bearer_scheme
|
|
196
202
|
].freeze
|
|
197
203
|
|
|
198
204
|
def header=(value)
|
|
@@ -633,6 +639,7 @@ module ApiKeys
|
|
|
633
639
|
# Core Authentication
|
|
634
640
|
@header = "Authorization" # Expects "Bearer <token>"
|
|
635
641
|
@query_param = nil # No query param lookup by default
|
|
642
|
+
@require_bearer_scheme = false # Also accept a bare token in the header
|
|
636
643
|
|
|
637
644
|
# Token Generation
|
|
638
645
|
@token_prefix = -> { "ak_" }
|
|
@@ -18,8 +18,9 @@ module ApiKeys
|
|
|
18
18
|
# The longest authentication header that can still carry a valid token:
|
|
19
19
|
# the token plus the "Bearer" scheme and generous separator whitespace.
|
|
20
20
|
MAX_CREDENTIAL_HEADER_BYTESIZE = MAX_TOKEN_BYTESIZE + 64
|
|
21
|
-
# Stands in for a
|
|
22
|
-
#
|
|
21
|
+
# Stands in for a refused header: malformed, or without the Bearer
|
|
22
|
+
# scheme the app requires. It is not a String, so it can never match a
|
|
23
|
+
# key and always yields :invalid_token.
|
|
23
24
|
MALFORMED_CREDENTIAL = Object.new.freeze
|
|
24
25
|
MAX_BCRYPT_CANDIDATES = 32
|
|
25
26
|
MAX_KNOWN_PREFIXES = 1_024
|
|
@@ -146,7 +147,13 @@ module ApiKeys
|
|
|
146
147
|
log_debug "[ApiKeys Auth] Extracted token from Bearer scheme."
|
|
147
148
|
return match[1]
|
|
148
149
|
end
|
|
149
|
-
#
|
|
150
|
+
# A bare token is accepted unless the app requires the scheme.
|
|
151
|
+
# Refused, it is an invalid token: the header was present, so it
|
|
152
|
+
# never falls through to the query parameter.
|
|
153
|
+
if config.require_bearer_scheme
|
|
154
|
+
log_debug "[ApiKeys Auth] Refused a header without the Bearer scheme."
|
|
155
|
+
return MALFORMED_CREDENTIAL
|
|
156
|
+
end
|
|
150
157
|
log_debug "[ApiKeys Auth] No Bearer scheme, using raw header value as token."
|
|
151
158
|
return header_value
|
|
152
159
|
end
|
data/lib/api_keys/version.rb
CHANGED
|
@@ -9,6 +9,11 @@ ApiKeys.configure do |config|
|
|
|
9
9
|
# Default: "Authorization" (expects "Bearer <token>")
|
|
10
10
|
# config.header = "Authorization"
|
|
11
11
|
|
|
12
|
+
# Accept the header only as "Bearer <token>", refusing a bare token with
|
|
13
|
+
# 401 invalid_token. Recommended for public APIs.
|
|
14
|
+
# Default: false (a bare token is accepted too)
|
|
15
|
+
# config.require_bearer_scheme = true
|
|
16
|
+
|
|
12
17
|
# The query parameter name to check as a fallback if the header is missing.
|
|
13
18
|
# WARNING: Query parameters appear in logs, browser history, and Referer headers.
|
|
14
19
|
# Only enable for development/testing. Set to nil to disable (recommended).
|