zuplo 6.72.3 → 6.72.7

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 (45) hide show
  1. package/docs/analytics/access-and-entitlements.md +27 -34
  2. package/docs/analytics/overview.md +7 -6
  3. package/docs/analytics/reference/url-parameters.md +2 -10
  4. package/docs/analytics/shared-controls.md +3 -10
  5. package/docs/analytics/tabs/agents.md +3 -3
  6. package/docs/analytics/tabs/requests.md +2 -4
  7. package/docs/articles/connect-to-aws-alb-with-mtls.mdx +89 -13
  8. package/docs/articles/graphql-security.mdx +2 -1
  9. package/docs/articles/graphql.mdx +8 -0
  10. package/docs/articles/opentelemetry.mdx +7 -5
  11. package/docs/articles/securing-backend-mtls.mdx +92 -3
  12. package/docs/articles/troubleshooting-slow-responses.mdx +4 -3
  13. package/docs/articles/troubleshooting.md +3 -1
  14. package/docs/policies/_index.md +2 -0
  15. package/docs/policies/clerk-jwt-auth-inbound/schema.json +3 -3
  16. package/docs/policies/mcp-auth0-oauth-inbound/schema.json +8 -5
  17. package/docs/policies/mcp-clerk-oauth-inbound/schema.json +78 -0
  18. package/docs/policies/mcp-cognito-oauth-inbound/schema.json +78 -0
  19. package/docs/policies/mcp-entra-oauth-inbound/schema.json +78 -0
  20. package/docs/policies/mcp-google-oauth-inbound/schema.json +78 -0
  21. package/docs/policies/mcp-keycloak-oauth-inbound/schema.json +78 -0
  22. package/docs/policies/mcp-logto-oauth-inbound/schema.json +78 -0
  23. package/docs/policies/mcp-oauth-inbound/schema.json +8 -5
  24. package/docs/policies/mcp-okta-oauth-inbound/schema.json +78 -0
  25. package/docs/policies/mcp-onelogin-oauth-inbound/schema.json +78 -0
  26. package/docs/policies/mcp-ping-oauth-inbound/schema.json +78 -0
  27. package/docs/policies/mcp-token-exchange-inbound/doc.md +72 -4
  28. package/docs/policies/mcp-token-exchange-inbound/intro.md +5 -4
  29. package/docs/policies/mcp-token-exchange-inbound/schema.json +277 -2
  30. package/docs/policies/mcp-workos-oauth-inbound/schema.json +78 -0
  31. package/docs/policies/open-id-jwt-auth-inbound/schema.json +3 -3
  32. package/docs/policies/propel-auth-jwt-inbound/schema.json +3 -3
  33. package/docs/policies/upstream-aws-federated-auth-inbound/doc.md +78 -0
  34. package/docs/policies/upstream-aws-federated-auth-inbound/intro.md +20 -0
  35. package/docs/policies/upstream-aws-federated-auth-inbound/schema.json +98 -0
  36. package/docs/policies/upstream-aws-service-auth-inbound/doc.md +89 -0
  37. package/docs/policies/upstream-aws-service-auth-inbound/intro.md +19 -0
  38. package/docs/policies/upstream-aws-service-auth-inbound/schema.json +113 -0
  39. package/docs/policies/upstream-azure-ad-service-auth-inbound/schema.json +4 -4
  40. package/docs/policies/upstream-gcp-federated-auth-inbound/doc.md +2 -2
  41. package/docs/policies/upstream-gcp-federated-auth-inbound/schema.json +4 -4
  42. package/docs/policies/upstream-gcp-service-auth-inbound/doc.md +3 -3
  43. package/docs/policies/upstream-gcp-service-auth-inbound/schema.json +3 -3
  44. package/docs/policies/upstream-zuplo-jwt-auth-inbound/schema.json +19 -0
  45. package/package.json +4 -4
@@ -79,6 +79,84 @@
79
79
  }
80
80
  }
81
81
  },
82
+ "idJag": {
83
+ "description": "Optional Identity Assertion JWT Authorization Grant (ID-JAG / XAA) support for the gateway token endpoint.",
84
+ "oneOf": [
85
+ {
86
+ "type": "object",
87
+ "additionalProperties": false,
88
+ "required": ["enabled"],
89
+ "properties": {
90
+ "enabled": {
91
+ "const": false,
92
+ "description": "Disable ID-JAG support."
93
+ }
94
+ }
95
+ },
96
+ {
97
+ "type": "object",
98
+ "additionalProperties": false,
99
+ "required": ["enabled"],
100
+ "properties": {
101
+ "enabled": {
102
+ "const": true,
103
+ "description": "Enable ID-JAG support."
104
+ },
105
+ "trustedIssuers": {
106
+ "type": "array",
107
+ "minItems": 1,
108
+ "description": "Trusted ID-JAG issuers. These values are never published in OAuth metadata. Omit to trust this policy's browser-login IdP.",
109
+ "items": {
110
+ "type": "object",
111
+ "additionalProperties": false,
112
+ "dependentRequired": {
113
+ "issuer": ["jwksUrl"],
114
+ "jwksUrl": ["issuer"]
115
+ },
116
+ "properties": {
117
+ "issuer": {
118
+ "type": "string",
119
+ "format": "uri",
120
+ "description": "Exact issuer URL expected in the ID-JAG iss claim. Provide together with jwksUrl, or omit both to default to this policy's browser-login IdP."
121
+ },
122
+ "jwksUrl": {
123
+ "type": "string",
124
+ "format": "uri",
125
+ "description": "JWKS URL used to verify ID-JAG signatures from this issuer. Provide together with issuer, or omit both to default to this policy's browser-login IdP."
126
+ },
127
+ "expectedClientIds": {
128
+ "type": "array",
129
+ "items": {
130
+ "type": "string",
131
+ "minLength": 1
132
+ },
133
+ "description": "Optional allow-list of client IDs accepted from this issuer. The ID-JAG client_id must still match the authenticated token-endpoint client."
134
+ },
135
+ "subjectMapping": {
136
+ "type": "string",
137
+ "enum": [
138
+ "iss_prefix",
139
+ "iss_tenant_prefix",
140
+ "sub_id_only"
141
+ ],
142
+ "default": "iss_prefix",
143
+ "description": "How the ID-JAG subject is mapped into the gateway subject ID."
144
+ }
145
+ }
146
+ }
147
+ },
148
+ "authorizationDetailsTypesAllowed": {
149
+ "type": "array",
150
+ "items": {
151
+ "type": "string",
152
+ "minLength": 1
153
+ },
154
+ "description": "Optional allow-list of RFC 9396 authorization_details type values accepted from ID-JAGs."
155
+ }
156
+ }
157
+ }
158
+ ]
159
+ },
82
160
  "browserLoginOverrides": {
83
161
  "type": "object",
84
162
  "description": "Optional overrides for the derived browser-login settings.",
@@ -97,6 +97,84 @@
97
97
  }
98
98
  }
99
99
  },
100
+ "idJag": {
101
+ "description": "Optional Identity Assertion JWT Authorization Grant (ID-JAG / XAA) support for the gateway token endpoint.",
102
+ "oneOf": [
103
+ {
104
+ "type": "object",
105
+ "additionalProperties": false,
106
+ "required": ["enabled"],
107
+ "properties": {
108
+ "enabled": {
109
+ "const": false,
110
+ "description": "Disable ID-JAG support."
111
+ }
112
+ }
113
+ },
114
+ {
115
+ "type": "object",
116
+ "additionalProperties": false,
117
+ "required": ["enabled"],
118
+ "properties": {
119
+ "enabled": {
120
+ "const": true,
121
+ "description": "Enable ID-JAG support."
122
+ },
123
+ "trustedIssuers": {
124
+ "type": "array",
125
+ "minItems": 1,
126
+ "description": "Trusted ID-JAG issuers. These values are never published in OAuth metadata. Omit to trust this policy's browser-login IdP.",
127
+ "items": {
128
+ "type": "object",
129
+ "additionalProperties": false,
130
+ "dependentRequired": {
131
+ "issuer": ["jwksUrl"],
132
+ "jwksUrl": ["issuer"]
133
+ },
134
+ "properties": {
135
+ "issuer": {
136
+ "type": "string",
137
+ "format": "uri",
138
+ "description": "Exact issuer URL expected in the ID-JAG iss claim. Provide together with jwksUrl, or omit both to default to this policy's browser-login IdP."
139
+ },
140
+ "jwksUrl": {
141
+ "type": "string",
142
+ "format": "uri",
143
+ "description": "JWKS URL used to verify ID-JAG signatures from this issuer. Provide together with issuer, or omit both to default to this policy's browser-login IdP."
144
+ },
145
+ "expectedClientIds": {
146
+ "type": "array",
147
+ "items": {
148
+ "type": "string",
149
+ "minLength": 1
150
+ },
151
+ "description": "Optional allow-list of client IDs accepted from this issuer. The ID-JAG client_id must still match the authenticated token-endpoint client."
152
+ },
153
+ "subjectMapping": {
154
+ "type": "string",
155
+ "enum": [
156
+ "iss_prefix",
157
+ "iss_tenant_prefix",
158
+ "sub_id_only"
159
+ ],
160
+ "default": "iss_prefix",
161
+ "description": "How the ID-JAG subject is mapped into the gateway subject ID."
162
+ }
163
+ }
164
+ }
165
+ },
166
+ "authorizationDetailsTypesAllowed": {
167
+ "type": "array",
168
+ "items": {
169
+ "type": "string",
170
+ "minLength": 1
171
+ },
172
+ "description": "Optional allow-list of RFC 9396 authorization_details type values accepted from ID-JAGs."
173
+ }
174
+ }
175
+ }
176
+ ]
177
+ },
100
178
  "browserLoginOverrides": {
101
179
  "type": "object",
102
180
  "description": "Optional overrides for the derived browser-login settings.",
@@ -4,10 +4,11 @@ The `mcp-token-exchange-inbound` policy resolves gateway-managed upstream MCP
4
4
  credentials and applies them to the request before the normal Zuplo route
5
5
  handler forwards it.
6
6
 
7
- Use this policy only when Zuplo manages upstream OAuth credentials, such as
8
- per-user OAuth or shared OAuth. If the upstream is public, uses an API key
9
- header, or only needs static routing/context headers, omit this policy and
10
- compose the existing Zuplo header/auth policies instead.
7
+ Use this policy only when Zuplo manages upstream credentials: per-user OAuth
8
+ (`user-oauth`), a gateway-wide shared OAuth grant (`shared-oauth`), or ID-JAG
9
+ token exchange (`id-jag`). If the upstream is public, uses an API key header, or
10
+ only needs static routing/context headers, omit this policy and compose the
11
+ existing Zuplo header/auth policies instead.
11
12
 
12
13
  Zuplo is only the gateway. It discovers the upstream MCP server, sends users
13
14
  through the upstream OAuth flow, stores the resulting upstream connection, and
@@ -107,6 +108,73 @@ as Entra tenant admin consent. If connections start requiring frequent
107
108
  reauthorization after setting `prompt: false`, remove the option so the consent
108
109
  grant is requested again.
109
110
 
111
+ ## ID-JAG Token Exchange (Cross-App Access)
112
+
113
+ Set `authMode` to `id-jag` when the upstream is protected by an Identity
114
+ Assertion JWT Authorization Grant (ID-JAG) Resource Authorization Server, the
115
+ pattern also known as Cross-App Access (XAA). Instead of sending users through
116
+ the upstream's browser OAuth flow, the gateway obtains the upstream credential
117
+ in two server-to-server steps:
118
+
119
+ 1. **IdP token exchange**: the gateway exchanges the caller's identity assertion
120
+ at the configured identity provider's token endpoint for an ID-JAG, sending
121
+ the configured `audience` (the Resource Authorization Server) and `resource`
122
+ (the upstream MCP server).
123
+ 2. **Resource AS redemption**: the gateway redeems the ID-JAG at the upstream
124
+ Resource Authorization Server's token endpoint using the `jwt-bearer` grant
125
+ and receives the upstream access token it attaches to the forwarded request.
126
+
127
+ Use this mode in enterprise deployments where the gateway and the upstream
128
+ trust the same identity provider (for example, Okta Cross-App Access), so
129
+ upstream access follows the caller's identity without a per-user upstream
130
+ consent flow. The `user-oauth`/`shared-oauth` options — `scopes`,
131
+ `scopeDelimiter`, `prompt`, and `clientRegistration` — do not apply; the
132
+ `id-jag` mode is configured entirely through the `idJag` option.
133
+
134
+ ```json
135
+ {
136
+ "name": "mcp-token-exchange-acme",
137
+ "policyType": "mcp-token-exchange-inbound",
138
+ "handler": {
139
+ "module": "$import(@zuplo/runtime/mcp-gateway)",
140
+ "export": "McpTokenExchangeInboundPolicy",
141
+ "options": {
142
+ "displayName": "Acme",
143
+ "authMode": "id-jag",
144
+ "idJag": {
145
+ "scopes": ["mcp:tools"],
146
+ "idp": {
147
+ "tokenUrl": "https://idp.example.com/oauth2/token",
148
+ "clientAuth": {
149
+ "method": "client_secret_post",
150
+ "clientId": "gateway-client",
151
+ "clientSecret": "$env(IDP_CLIENT_SECRET)"
152
+ }
153
+ },
154
+ "resourceAs": {
155
+ "tokenUrl": "https://auth.acme-mcp.example.com/oauth2/token",
156
+ "audience": "https://auth.acme-mcp.example.com",
157
+ "resource": "https://mcp.acme.example.com/mcp",
158
+ "clientAuth": {
159
+ "method": "client_secret_post",
160
+ "clientId": "gateway-resource-client",
161
+ "clientSecret": "$env(RESOURCE_AS_CLIENT_SECRET)"
162
+ }
163
+ }
164
+ }
165
+ }
166
+ }
167
+ }
168
+ ```
169
+
170
+ Both `clientAuth` blocks also accept `client_secret_basic` and
171
+ `private_key_jwt`. Use `private_key_jwt` for providers such as Okta that
172
+ require a signed client assertion for token exchange; it takes `privateKeyPem`,
173
+ an optional `keyId`, and an `algorithm` (default `RS256`). Source secrets and
174
+ private keys from environment variables with `$env(VAR_NAME)`. When `resource`
175
+ is omitted, the gateway defaults it to the upstream MCP server URL from the
176
+ route handler's `rewritePattern`.
177
+
110
178
  ## Route Shape
111
179
 
112
180
  Publish both MCP transport methods as one Zuplo multi-method operation using
@@ -1,6 +1,7 @@
1
1
  Resolve gateway-managed upstream MCP credentials and apply them to the request.
2
2
 
3
- Use this after gateway auth when the upstream requires Zuplo-managed OAuth. Omit
4
- it for public upstreams or upstreams handled by ordinary Zuplo header/API-key
5
- policies. The route should use `McpProxyHandler` with the upstream URL
6
- configured on the handler.
3
+ Use this after gateway auth when the upstream requires Zuplo-managed
4
+ credentials: per-user OAuth, shared OAuth, or ID-JAG (Cross-App Access) token
5
+ exchange. Omit it for public upstreams or upstreams handled by ordinary Zuplo
6
+ header/API-key policies. The route should use `McpProxyHandler` with the
7
+ upstream URL configured on the handler.
@@ -34,6 +34,38 @@
34
34
  "description": "The options for this policy.",
35
35
  "additionalProperties": false,
36
36
  "required": ["displayName", "authMode"],
37
+ "if": {
38
+ "properties": {
39
+ "authMode": {
40
+ "const": "id-jag"
41
+ }
42
+ },
43
+ "required": ["authMode"]
44
+ },
45
+ "then": {
46
+ "required": ["idJag"],
47
+ "not": {
48
+ "anyOf": [
49
+ {
50
+ "required": ["scopes"]
51
+ },
52
+ {
53
+ "required": ["scopeDelimiter"]
54
+ },
55
+ {
56
+ "required": ["prompt"]
57
+ },
58
+ {
59
+ "required": ["clientRegistration"]
60
+ }
61
+ ]
62
+ }
63
+ },
64
+ "else": {
65
+ "not": {
66
+ "required": ["idJag"]
67
+ }
68
+ },
37
69
  "properties": {
38
70
  "id": {
39
71
  "type": "string",
@@ -57,8 +89,8 @@
57
89
  },
58
90
  "authMode": {
59
91
  "type": "string",
60
- "enum": ["user-oauth", "shared-oauth"],
61
- "description": "Authentication mode. `user-oauth` performs per-user OAuth federation; `shared-oauth` uses a gateway-wide OAuth grant."
92
+ "enum": ["user-oauth", "shared-oauth", "id-jag"],
93
+ "description": "Authentication mode. `user-oauth` performs per-user OAuth federation; `shared-oauth` uses a gateway-wide OAuth grant; `id-jag` exchanges the caller's identity assertion at the configured IdP for an ID-JAG (Identity Assertion JWT Authorization Grant, also known as Cross-App Access / XAA), then redeems it at the upstream Resource Authorization Server for an upstream access token."
62
94
  },
63
95
  "scopes": {
64
96
  "type": "array",
@@ -126,6 +158,243 @@
126
158
  }
127
159
  }
128
160
  ]
161
+ },
162
+ "idJag": {
163
+ "type": "object",
164
+ "additionalProperties": false,
165
+ "required": ["idp", "resourceAs"],
166
+ "description": "ID-JAG (Cross-App Access / XAA) token-exchange configuration. Required when `authMode` is `id-jag`; not used by the OAuth modes.",
167
+ "properties": {
168
+ "scopes": {
169
+ "type": "array",
170
+ "default": [],
171
+ "description": "Scopes to request on the ID-JAG token exchange at the IdP.",
172
+ "items": {
173
+ "type": "string"
174
+ }
175
+ },
176
+ "scopeDelimiter": {
177
+ "type": "string",
178
+ "default": " ",
179
+ "description": "Delimiter used to join scopes in the token-exchange request. Defaults to a single space."
180
+ },
181
+ "idp": {
182
+ "type": "object",
183
+ "additionalProperties": false,
184
+ "required": ["tokenUrl", "clientAuth"],
185
+ "description": "The identity provider that exchanges the caller's identity assertion for an ID-JAG.",
186
+ "properties": {
187
+ "tokenUrl": {
188
+ "type": "string",
189
+ "format": "uri",
190
+ "description": "The IdP token endpoint used for the ID-JAG token exchange."
191
+ },
192
+ "clientAuth": {
193
+ "description": "Client authentication used at the token endpoint.",
194
+ "oneOf": [
195
+ {
196
+ "type": "object",
197
+ "additionalProperties": false,
198
+ "required": ["method", "clientId", "clientSecret"],
199
+ "properties": {
200
+ "method": {
201
+ "type": "string",
202
+ "const": "client_secret_post"
203
+ },
204
+ "clientId": {
205
+ "type": "string"
206
+ },
207
+ "clientSecret": {
208
+ "type": "string",
209
+ "examples": ["$env(IDP_CLIENT_SECRET)"],
210
+ "description": "OAuth client secret. Use `$env(VAR_NAME)` to source from an environment variable."
211
+ }
212
+ }
213
+ },
214
+ {
215
+ "type": "object",
216
+ "additionalProperties": false,
217
+ "required": ["method", "clientId", "clientSecret"],
218
+ "properties": {
219
+ "method": {
220
+ "type": "string",
221
+ "const": "client_secret_basic"
222
+ },
223
+ "clientId": {
224
+ "type": "string"
225
+ },
226
+ "clientSecret": {
227
+ "type": "string",
228
+ "examples": ["$env(IDP_CLIENT_SECRET)"],
229
+ "description": "OAuth client secret. Use `$env(VAR_NAME)` to source from an environment variable."
230
+ }
231
+ }
232
+ },
233
+ {
234
+ "type": "object",
235
+ "additionalProperties": false,
236
+ "required": ["method", "clientId", "privateKeyPem"],
237
+ "properties": {
238
+ "method": {
239
+ "type": "string",
240
+ "const": "private_key_jwt"
241
+ },
242
+ "clientId": {
243
+ "type": "string"
244
+ },
245
+ "privateKeyPem": {
246
+ "type": "string",
247
+ "examples": ["$env(IDP_PRIVATE_KEY_PEM)"],
248
+ "description": "PEM-encoded private key used to sign the client assertion. Use `$env(VAR_NAME)` to source from an environment variable."
249
+ },
250
+ "algorithm": {
251
+ "type": "string",
252
+ "enum": [
253
+ "RS256",
254
+ "RS384",
255
+ "RS512",
256
+ "ES256",
257
+ "ES384",
258
+ "ES512"
259
+ ],
260
+ "default": "RS256",
261
+ "description": "JWS algorithm used to sign the client assertion."
262
+ },
263
+ "keyId": {
264
+ "type": "string",
265
+ "description": "Optional `kid` header set on the client assertion, for providers that select the verification key by key id."
266
+ },
267
+ "audience": {
268
+ "type": "string",
269
+ "format": "uri",
270
+ "description": "Optional override for the client assertion `aud` claim. Defaults to the token endpoint URL."
271
+ },
272
+ "expiresInSeconds": {
273
+ "type": "integer",
274
+ "default": 300,
275
+ "minimum": 1,
276
+ "maximum": 3600,
277
+ "description": "Client assertion lifetime in seconds."
278
+ }
279
+ }
280
+ }
281
+ ]
282
+ }
283
+ }
284
+ },
285
+ "resourceAs": {
286
+ "type": "object",
287
+ "additionalProperties": false,
288
+ "required": ["tokenUrl", "audience", "clientAuth"],
289
+ "description": "The upstream Resource Authorization Server that redeems the ID-JAG for an upstream access token.",
290
+ "properties": {
291
+ "tokenUrl": {
292
+ "type": "string",
293
+ "format": "uri",
294
+ "description": "The Resource Authorization Server token endpoint where the gateway redeems the ID-JAG via the jwt-bearer grant."
295
+ },
296
+ "audience": {
297
+ "type": "string",
298
+ "description": "The `audience` value sent on the ID-JAG token exchange, identifying the Resource Authorization Server (typically its issuer)."
299
+ },
300
+ "resource": {
301
+ "type": "string",
302
+ "description": "Optional `resource` indicator sent on the token exchange, identifying the upstream MCP resource. Defaults to the upstream MCP server URL from the route handler's rewritePattern."
303
+ },
304
+ "clientAuth": {
305
+ "description": "Client authentication used at the token endpoint.",
306
+ "oneOf": [
307
+ {
308
+ "type": "object",
309
+ "additionalProperties": false,
310
+ "required": ["method", "clientId", "clientSecret"],
311
+ "properties": {
312
+ "method": {
313
+ "type": "string",
314
+ "const": "client_secret_post"
315
+ },
316
+ "clientId": {
317
+ "type": "string"
318
+ },
319
+ "clientSecret": {
320
+ "type": "string",
321
+ "examples": ["$env(IDP_CLIENT_SECRET)"],
322
+ "description": "OAuth client secret. Use `$env(VAR_NAME)` to source from an environment variable."
323
+ }
324
+ }
325
+ },
326
+ {
327
+ "type": "object",
328
+ "additionalProperties": false,
329
+ "required": ["method", "clientId", "clientSecret"],
330
+ "properties": {
331
+ "method": {
332
+ "type": "string",
333
+ "const": "client_secret_basic"
334
+ },
335
+ "clientId": {
336
+ "type": "string"
337
+ },
338
+ "clientSecret": {
339
+ "type": "string",
340
+ "examples": ["$env(IDP_CLIENT_SECRET)"],
341
+ "description": "OAuth client secret. Use `$env(VAR_NAME)` to source from an environment variable."
342
+ }
343
+ }
344
+ },
345
+ {
346
+ "type": "object",
347
+ "additionalProperties": false,
348
+ "required": ["method", "clientId", "privateKeyPem"],
349
+ "properties": {
350
+ "method": {
351
+ "type": "string",
352
+ "const": "private_key_jwt"
353
+ },
354
+ "clientId": {
355
+ "type": "string"
356
+ },
357
+ "privateKeyPem": {
358
+ "type": "string",
359
+ "examples": ["$env(IDP_PRIVATE_KEY_PEM)"],
360
+ "description": "PEM-encoded private key used to sign the client assertion. Use `$env(VAR_NAME)` to source from an environment variable."
361
+ },
362
+ "algorithm": {
363
+ "type": "string",
364
+ "enum": [
365
+ "RS256",
366
+ "RS384",
367
+ "RS512",
368
+ "ES256",
369
+ "ES384",
370
+ "ES512"
371
+ ],
372
+ "default": "RS256",
373
+ "description": "JWS algorithm used to sign the client assertion."
374
+ },
375
+ "keyId": {
376
+ "type": "string",
377
+ "description": "Optional `kid` header set on the client assertion, for providers that select the verification key by key id."
378
+ },
379
+ "audience": {
380
+ "type": "string",
381
+ "format": "uri",
382
+ "description": "Optional override for the client assertion `aud` claim. Defaults to the token endpoint URL."
383
+ },
384
+ "expiresInSeconds": {
385
+ "type": "integer",
386
+ "default": 300,
387
+ "minimum": 1,
388
+ "maximum": 3600,
389
+ "description": "Client assertion lifetime in seconds."
390
+ }
391
+ }
392
+ }
393
+ ]
394
+ }
395
+ }
396
+ }
397
+ }
129
398
  }
130
399
  }
131
400
  }
@@ -137,6 +406,12 @@
137
406
  "options": {
138
407
  "displayName": "Linear",
139
408
  "id": "linear",
409
+ "idJag": {
410
+ "idp": {},
411
+ "resourceAs": {},
412
+ "scopeDelimiter": " ",
413
+ "scopes": []
414
+ },
140
415
  "scopes": [],
141
416
  "summary": "Native Linear remote MCP server."
142
417
  }
@@ -74,6 +74,84 @@
74
74
  }
75
75
  }
76
76
  },
77
+ "idJag": {
78
+ "description": "Optional Identity Assertion JWT Authorization Grant (ID-JAG / XAA) support for the gateway token endpoint.",
79
+ "oneOf": [
80
+ {
81
+ "type": "object",
82
+ "additionalProperties": false,
83
+ "required": ["enabled"],
84
+ "properties": {
85
+ "enabled": {
86
+ "const": false,
87
+ "description": "Disable ID-JAG support."
88
+ }
89
+ }
90
+ },
91
+ {
92
+ "type": "object",
93
+ "additionalProperties": false,
94
+ "required": ["enabled"],
95
+ "properties": {
96
+ "enabled": {
97
+ "const": true,
98
+ "description": "Enable ID-JAG support."
99
+ },
100
+ "trustedIssuers": {
101
+ "type": "array",
102
+ "minItems": 1,
103
+ "description": "Trusted ID-JAG issuers. These values are never published in OAuth metadata. Omit to trust this policy's browser-login IdP.",
104
+ "items": {
105
+ "type": "object",
106
+ "additionalProperties": false,
107
+ "dependentRequired": {
108
+ "issuer": ["jwksUrl"],
109
+ "jwksUrl": ["issuer"]
110
+ },
111
+ "properties": {
112
+ "issuer": {
113
+ "type": "string",
114
+ "format": "uri",
115
+ "description": "Exact issuer URL expected in the ID-JAG iss claim. Provide together with jwksUrl, or omit both to default to this policy's browser-login IdP."
116
+ },
117
+ "jwksUrl": {
118
+ "type": "string",
119
+ "format": "uri",
120
+ "description": "JWKS URL used to verify ID-JAG signatures from this issuer. Provide together with issuer, or omit both to default to this policy's browser-login IdP."
121
+ },
122
+ "expectedClientIds": {
123
+ "type": "array",
124
+ "items": {
125
+ "type": "string",
126
+ "minLength": 1
127
+ },
128
+ "description": "Optional allow-list of client IDs accepted from this issuer. The ID-JAG client_id must still match the authenticated token-endpoint client."
129
+ },
130
+ "subjectMapping": {
131
+ "type": "string",
132
+ "enum": [
133
+ "iss_prefix",
134
+ "iss_tenant_prefix",
135
+ "sub_id_only"
136
+ ],
137
+ "default": "iss_prefix",
138
+ "description": "How the ID-JAG subject is mapped into the gateway subject ID."
139
+ }
140
+ }
141
+ }
142
+ },
143
+ "authorizationDetailsTypesAllowed": {
144
+ "type": "array",
145
+ "items": {
146
+ "type": "string",
147
+ "minLength": 1
148
+ },
149
+ "description": "Optional allow-list of RFC 9396 authorization_details type values accepted from ID-JAGs."
150
+ }
151
+ }
152
+ }
153
+ ]
154
+ },
77
155
  "browserLoginOverrides": {
78
156
  "type": "object",
79
157
  "description": "Optional overrides for the derived browser-login settings.",