@o3co/create-auth-policy-verifier 0.8.1 → 0.9.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.
- package/package.json +1 -1
- package/templates/standalone/README.ja.md +3 -1
- package/templates/standalone/README.md +3 -1
- package/templates/standalone/config/application.conf +24 -0
- package/templates/standalone/package.json +1 -1
- package/templates/standalone/src/__tests__/loadConfig.test.mts +17 -17
- package/templates/versions.json +3 -3
package/package.json
CHANGED
|
@@ -43,7 +43,9 @@ OAUTH_JWT_SECRET=$(openssl rand -hex 32) \
|
|
|
43
43
|
| `OAUTH_JWT_JWKS_TIMEOUT_MS` | `5000` | JWKS 取得をこの時間で打ち切る |
|
|
44
44
|
| `OAUTH_JWT_JWKS_COOLDOWN_MS` | `30000` | JWKS 再取得の最小間隔 |
|
|
45
45
|
| `OAUTH_JWT_JWKS_CACHE_MAX_AGE_MS` | `600000` | 取得した JWKS をキャッシュから返す期間 |
|
|
46
|
-
| `OAUTH_JWT_TOKEN_TYPE` | `at+jwt` | 受け入れる `typ` ヘッダ。同じ鍵で署名された id/refresh/logout token
|
|
46
|
+
| `OAUTH_JWT_TOKEN_TYPE` | `at+jwt` | 受け入れる `typ` ヘッダ。同じ鍵で署名された id/refresh/logout token を拒否する。`*` で pin しない(その場合 `audience` を OIDC client id にしてはいけない) |
|
|
47
|
+
| `OAUTH_JWT_AUDIENCE_CLAIM` | `aud` | audience を読む claim。`azp`(Clerk)、`client_id`(Cognito)。`aud` 以外を指定すると `aud` は一切見ない |
|
|
48
|
+
| `OAUTH_AUTHENTICATOR` | `jwt` | subject を確立する token authenticator。他の名前は `main.mts` で module が登録したもの |
|
|
47
49
|
| `OAUTH_JWT_MODE` | `verify` | `verify` はトークンを完全検証。明示的な `insecure-decode`(テスト専用)は署名検証なしでデコードする — `exp`/`nbf` は引き続き強制される |
|
|
48
50
|
| `RULE_ON_EMPTY_RULE_SET` | `deny` | ルールが 1 つも集まらなかったときの決定(`deny` \| `allow`) |
|
|
49
51
|
| `VERIFY_MAX_BATCH_SIZE` | `50` | `POST /verify/batch` の件数上限 |
|
|
@@ -43,7 +43,9 @@ Individual values can also be overridden with environment variables.
|
|
|
43
43
|
| `OAUTH_JWT_JWKS_TIMEOUT_MS` | `5000` | Abort a JWKS fetch after this long |
|
|
44
44
|
| `OAUTH_JWT_JWKS_COOLDOWN_MS` | `30000` | Minimum spacing between JWKS fetches |
|
|
45
45
|
| `OAUTH_JWT_JWKS_CACHE_MAX_AGE_MS` | `600000` | How long a fetched JWKS is served from cache |
|
|
46
|
-
| `OAUTH_JWT_TOKEN_TYPE` | `at+jwt` | Accepted `typ` header; rejects id/refresh/logout tokens signed with the same key |
|
|
46
|
+
| `OAUTH_JWT_TOKEN_TYPE` | `at+jwt` | Accepted `typ` header; rejects id/refresh/logout tokens signed with the same key. `*` pins nothing (then `audience` must not be an OIDC client id) |
|
|
47
|
+
| `OAUTH_JWT_AUDIENCE_CLAIM` | `aud` | Claim the audience is read from: `azp` (Clerk), `client_id` (Cognito). Anything but `aud` means `aud` is not consulted at all |
|
|
48
|
+
| `OAUTH_AUTHENTICATOR` | `jwt` | Which token authenticator establishes the subject; another name must be registered by a module in `main.mts` |
|
|
47
49
|
| `OAUTH_JWT_MODE` | `verify` | `verify` fully verifies tokens; the explicit `insecure-decode` (test-only) decodes without signature verification — `exp`/`nbf` are still enforced |
|
|
48
50
|
| `RULE_ON_EMPTY_RULE_SET` | `deny` | Decision when no rule is collected (`deny` \| `allow`) |
|
|
49
51
|
| `VERIFY_MAX_BATCH_SIZE` | `50` | Cap on `POST /verify/batch` entries |
|
|
@@ -35,6 +35,15 @@ http {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
oauth {
|
|
38
|
+
# Which token authenticator establishes the subject of a decision. "jwt"
|
|
39
|
+
# (the default) is the built-in bearer-JWT path the block below configures.
|
|
40
|
+
# A deployment whose IdP issues opaque tokens, or whose gateway already
|
|
41
|
+
# authenticated the caller, registers its own authenticator in main.mts and
|
|
42
|
+
# names it here — see docs/extending.md, "Writing a token authenticator".
|
|
43
|
+
# With another name the `jwt` block must be omitted — that authenticator's
|
|
44
|
+
# keys go under its own sub-block (oauth.<name> { … }).
|
|
45
|
+
authenticator = "jwt"
|
|
46
|
+
authenticator = ${?OAUTH_AUTHENTICATOR}
|
|
38
47
|
jwt {
|
|
39
48
|
algorithm = "HS256"
|
|
40
49
|
algorithm = ${?OAUTH_JWT_ALGORITHM}
|
|
@@ -120,6 +129,19 @@ oauth {
|
|
|
120
129
|
# rejects id_tokens, refresh tokens and logout tokens signed with the same key.
|
|
121
130
|
tokenType = "at+jwt"
|
|
122
131
|
tokenType = ${?OAUTH_JWT_TOKEN_TYPE}
|
|
132
|
+
# `tokenType = "*"` (exactly that) pins nothing — any typ, or none. For
|
|
133
|
+
# issuers whose tokens carry no typ header (Cognito). The audience is then
|
|
134
|
+
# the only thing telling an access token from an id_token signed with the
|
|
135
|
+
# same key, so `audience` must NOT be an OIDC client id under "*": use an
|
|
136
|
+
# API identifier, or an audienceClaim id_tokens lack (Cognito: client_id).
|
|
137
|
+
# The claim the audience is read from. "aud" (the default) is RFC 9068;
|
|
138
|
+
# "azp" binds a Clerk session token, "client_id" a Cognito access token.
|
|
139
|
+
# The check moves, it never goes away — `audience` above stays required.
|
|
140
|
+
# With anything but "aud" here, `aud` is NOT consulted at all: use it only
|
|
141
|
+
# for issuers that emit no aud, and never name a claim the user can write
|
|
142
|
+
# (Clerk unsafe_metadata, Auth0 user_metadata).
|
|
143
|
+
audienceClaim = "aud"
|
|
144
|
+
audienceClaim = ${?OAUTH_JWT_AUDIENCE_CLAIM}
|
|
123
145
|
|
|
124
146
|
# Bounds on a presented token's own lifetime. Both apply in EVERY mode,
|
|
125
147
|
# insecure-decode included. `exp` itself is required and has no setting:
|
|
@@ -176,6 +198,8 @@ attribute {
|
|
|
176
198
|
# can never pass — see the note in the rule block.
|
|
177
199
|
collectors = [
|
|
178
200
|
# The token's `scope` claim, split into the list the scope rule reads.
|
|
201
|
+
# `claim = "scp"` reads Okta's scope array instead; pair it with the same
|
|
202
|
+
# `claim` on ResourceActionScopeRuleCollector below (#219).
|
|
179
203
|
{ collector = "PayloadScopeCollector" }
|
|
180
204
|
# The token's `sub`, which becomes the `subject` on the decision response
|
|
181
205
|
# and the `sub` field on the audit log line.
|
|
@@ -89,12 +89,12 @@ describe("loadAppConfig", () => {
|
|
|
89
89
|
pathPrefix: "",
|
|
90
90
|
callerAuth: { header: "x-caller-token" },
|
|
91
91
|
});
|
|
92
|
-
expect(config.oauth.jwt
|
|
93
|
-
expect(config.oauth.jwt
|
|
94
|
-
expect(config.oauth.jwt
|
|
95
|
-
expect(config.oauth.jwt
|
|
96
|
-
expect(config.oauth.jwt
|
|
97
|
-
expect(config.oauth.jwt
|
|
92
|
+
expect(config.oauth.jwt?.algorithm).toBe("HS256");
|
|
93
|
+
expect(config.oauth.jwt?.secret).toBe(TEST_SECRET);
|
|
94
|
+
expect(config.oauth.jwt?.mode).toBe("verify");
|
|
95
|
+
expect(config.oauth.jwt?.issuer).toBe("https://issuer.test");
|
|
96
|
+
expect(config.oauth.jwt?.audience).toBe("https://api.test");
|
|
97
|
+
expect(config.oauth.jwt?.tokenType).toBe("at+jwt");
|
|
98
98
|
expect(config.verify.maxBatchSize).toBe(50);
|
|
99
99
|
},
|
|
100
100
|
);
|
|
@@ -170,7 +170,7 @@ describe("loadAppConfig", () => {
|
|
|
170
170
|
|
|
171
171
|
const config = loadAppConfig(configDirPath, "development");
|
|
172
172
|
|
|
173
|
-
expect(config.oauth.jwt
|
|
173
|
+
expect(config.oauth.jwt?.mode).toBe("insecure-decode");
|
|
174
174
|
});
|
|
175
175
|
|
|
176
176
|
it("rejects a boolean-ish OAUTH_JWT_MODE left over from the removed OAUTH_JWT_VALIDATE", () => {
|
|
@@ -237,11 +237,11 @@ describe("loadAppConfig — numeric knobs through the real 3-tier resolution (#1
|
|
|
237
237
|
const config = loadAppConfig(configDirPath, "development");
|
|
238
238
|
|
|
239
239
|
expect(config.http.port).toBe(3000);
|
|
240
|
-
expect(config.oauth.jwt
|
|
241
|
-
expect(config.oauth.jwt
|
|
242
|
-
expect(config.oauth.jwt
|
|
243
|
-
expect(config.oauth.jwt
|
|
244
|
-
expect(config.oauth.jwt
|
|
240
|
+
expect(config.oauth.jwt?.jwksTimeoutMs).toBe(5000);
|
|
241
|
+
expect(config.oauth.jwt?.jwksCooldownMs).toBe(30_000);
|
|
242
|
+
expect(config.oauth.jwt?.jwksCacheMaxAgeMs).toBe(600_000);
|
|
243
|
+
expect(config.oauth.jwt?.maxTokenAgeSeconds).toBe(86_400);
|
|
244
|
+
expect(config.oauth.jwt?.clockToleranceSeconds).toBe(0);
|
|
245
245
|
expect(config.verify.maxBatchSize).toBe(50);
|
|
246
246
|
// The request limits (#118) travel the same path.
|
|
247
247
|
expect(config.verify.maxBodyBytes).toBe(65_536);
|
|
@@ -272,11 +272,11 @@ describe("loadAppConfig — numeric knobs through the real 3-tier resolution (#1
|
|
|
272
272
|
const config = loadAppConfig(configDirPath, "development");
|
|
273
273
|
|
|
274
274
|
expect(config.http.port).toBe(8080);
|
|
275
|
-
expect(config.oauth.jwt
|
|
276
|
-
expect(config.oauth.jwt
|
|
277
|
-
expect(config.oauth.jwt
|
|
278
|
-
expect(config.oauth.jwt
|
|
279
|
-
expect(config.oauth.jwt
|
|
275
|
+
expect(config.oauth.jwt?.jwksTimeoutMs).toBe(2500);
|
|
276
|
+
expect(config.oauth.jwt?.jwksCooldownMs).toBe(0);
|
|
277
|
+
expect(config.oauth.jwt?.jwksCacheMaxAgeMs).toBe(120_000);
|
|
278
|
+
expect(config.oauth.jwt?.maxTokenAgeSeconds).toBe(600);
|
|
279
|
+
expect(config.oauth.jwt?.clockToleranceSeconds).toBe(60);
|
|
280
280
|
expect(config.verify.maxBatchSize).toBe(25);
|
|
281
281
|
expect(config.verify.maxBodyBytes).toBe(16_384);
|
|
282
282
|
expect(config.verify.maxResourceLength).toBe(128);
|
package/templates/versions.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"@o3co/auth.policy-verifier.core": "0.
|
|
3
|
-
"@o3co/auth.policy-verifier.builtins": "0.
|
|
4
|
-
"@o3co/auth.policy-verifier.server": "0.
|
|
2
|
+
"@o3co/auth.policy-verifier.core": "0.9.0",
|
|
3
|
+
"@o3co/auth.policy-verifier.builtins": "0.9.0",
|
|
4
|
+
"@o3co/auth.policy-verifier.server": "0.9.0"
|
|
5
5
|
}
|