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.
- package/docs/analytics/access-and-entitlements.md +27 -34
- package/docs/analytics/overview.md +7 -6
- package/docs/analytics/reference/url-parameters.md +2 -10
- package/docs/analytics/shared-controls.md +3 -10
- package/docs/analytics/tabs/agents.md +3 -3
- package/docs/analytics/tabs/requests.md +2 -4
- package/docs/articles/connect-to-aws-alb-with-mtls.mdx +89 -13
- package/docs/articles/graphql-security.mdx +2 -1
- package/docs/articles/graphql.mdx +8 -0
- package/docs/articles/opentelemetry.mdx +7 -5
- package/docs/articles/securing-backend-mtls.mdx +92 -3
- package/docs/articles/troubleshooting-slow-responses.mdx +4 -3
- package/docs/articles/troubleshooting.md +3 -1
- package/docs/policies/_index.md +2 -0
- package/docs/policies/clerk-jwt-auth-inbound/schema.json +3 -3
- package/docs/policies/mcp-auth0-oauth-inbound/schema.json +8 -5
- package/docs/policies/mcp-clerk-oauth-inbound/schema.json +78 -0
- package/docs/policies/mcp-cognito-oauth-inbound/schema.json +78 -0
- package/docs/policies/mcp-entra-oauth-inbound/schema.json +78 -0
- package/docs/policies/mcp-google-oauth-inbound/schema.json +78 -0
- package/docs/policies/mcp-keycloak-oauth-inbound/schema.json +78 -0
- package/docs/policies/mcp-logto-oauth-inbound/schema.json +78 -0
- package/docs/policies/mcp-oauth-inbound/schema.json +8 -5
- package/docs/policies/mcp-okta-oauth-inbound/schema.json +78 -0
- package/docs/policies/mcp-onelogin-oauth-inbound/schema.json +78 -0
- package/docs/policies/mcp-ping-oauth-inbound/schema.json +78 -0
- package/docs/policies/mcp-token-exchange-inbound/doc.md +72 -4
- package/docs/policies/mcp-token-exchange-inbound/intro.md +5 -4
- package/docs/policies/mcp-token-exchange-inbound/schema.json +277 -2
- package/docs/policies/mcp-workos-oauth-inbound/schema.json +78 -0
- package/docs/policies/open-id-jwt-auth-inbound/schema.json +3 -3
- package/docs/policies/propel-auth-jwt-inbound/schema.json +3 -3
- package/docs/policies/upstream-aws-federated-auth-inbound/doc.md +78 -0
- package/docs/policies/upstream-aws-federated-auth-inbound/intro.md +20 -0
- package/docs/policies/upstream-aws-federated-auth-inbound/schema.json +98 -0
- package/docs/policies/upstream-aws-service-auth-inbound/doc.md +89 -0
- package/docs/policies/upstream-aws-service-auth-inbound/intro.md +19 -0
- package/docs/policies/upstream-aws-service-auth-inbound/schema.json +113 -0
- package/docs/policies/upstream-azure-ad-service-auth-inbound/schema.json +4 -4
- package/docs/policies/upstream-gcp-federated-auth-inbound/doc.md +2 -2
- package/docs/policies/upstream-gcp-federated-auth-inbound/schema.json +4 -4
- package/docs/policies/upstream-gcp-service-auth-inbound/doc.md +3 -3
- package/docs/policies/upstream-gcp-service-auth-inbound/schema.json +3 -3
- package/docs/policies/upstream-zuplo-jwt-auth-inbound/schema.json +19 -0
- 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
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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.",
|