zuplo 6.72.3 → 6.72.8

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 (96) 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/ddos-protection.mdx +2 -2
  9. package/docs/articles/graphql-security.mdx +2 -1
  10. package/docs/articles/graphql.mdx +8 -0
  11. package/docs/articles/limits.mdx +12 -0
  12. package/docs/articles/local-development-troubleshooting.mdx +12 -3
  13. package/docs/articles/opentelemetry.mdx +7 -5
  14. package/docs/articles/securing-backend-mtls.mdx +92 -3
  15. package/docs/articles/troubleshooting-slow-responses.mdx +4 -3
  16. package/docs/articles/troubleshooting.md +3 -1
  17. package/docs/articles/waf-ddos.mdx +1 -24
  18. package/docs/policies/_index.md +2 -0
  19. package/docs/policies/akamai-ai-firewall/schema.json +1 -0
  20. package/docs/policies/akamai-firewall-for-ai-inbound/schema.json +2 -0
  21. package/docs/policies/akamai-firewall-for-ai-outbound/schema.json +2 -0
  22. package/docs/policies/amberflo-metering-inbound/schema.json +5 -2
  23. package/docs/policies/api-key-inbound/schema.json +11 -5
  24. package/docs/policies/audit-log-inbound/schema.json +2 -0
  25. package/docs/policies/auth0-jwt-auth-inbound/schema.json +7 -5
  26. package/docs/policies/authzen-inbound/schema.json +7 -5
  27. package/docs/policies/axiomatics-authz-inbound/schema.json +14 -6
  28. package/docs/policies/basic-auth-inbound/schema.json +2 -1
  29. package/docs/policies/caching-inbound/schema.json +20 -16
  30. package/docs/policies/clerk-jwt-auth-inbound/schema.json +8 -6
  31. package/docs/policies/cognito-jwt-auth-inbound/schema.json +7 -5
  32. package/docs/policies/comet-opik-tracing-inbound/schema.json +1 -0
  33. package/docs/policies/complex-rate-limit-inbound/schema.json +4 -0
  34. package/docs/policies/curity-phantom-token-inbound/schema.json +1 -0
  35. package/docs/policies/data-loss-prevention-inbound/schema.json +15 -12
  36. package/docs/policies/data-loss-prevention-outbound/schema.json +15 -12
  37. package/docs/policies/firebase-jwt-inbound/schema.json +7 -5
  38. package/docs/policies/formdata-to-json-inbound/schema.json +1 -0
  39. package/docs/policies/galileo-tracing-inbound/schema.json +1 -0
  40. package/docs/policies/geo-filter-inbound/schema.json +1 -0
  41. package/docs/policies/graphql-analytics-outbound/schema.json +1 -0
  42. package/docs/policies/mcp-auth0-oauth-inbound/schema.json +11 -5
  43. package/docs/policies/mcp-clerk-oauth-inbound/schema.json +81 -0
  44. package/docs/policies/mcp-cognito-oauth-inbound/schema.json +81 -0
  45. package/docs/policies/mcp-entra-oauth-inbound/schema.json +81 -0
  46. package/docs/policies/mcp-google-oauth-inbound/schema.json +81 -0
  47. package/docs/policies/mcp-keycloak-oauth-inbound/schema.json +81 -0
  48. package/docs/policies/mcp-logto-oauth-inbound/schema.json +81 -0
  49. package/docs/policies/mcp-oauth-inbound/schema.json +10 -5
  50. package/docs/policies/mcp-okta-oauth-inbound/schema.json +81 -0
  51. package/docs/policies/mcp-onelogin-oauth-inbound/schema.json +81 -0
  52. package/docs/policies/mcp-ping-oauth-inbound/schema.json +81 -0
  53. package/docs/policies/mcp-token-exchange-inbound/doc.md +72 -4
  54. package/docs/policies/mcp-token-exchange-inbound/intro.md +5 -4
  55. package/docs/policies/mcp-token-exchange-inbound/schema.json +287 -7
  56. package/docs/policies/mcp-workos-oauth-inbound/schema.json +81 -0
  57. package/docs/policies/monetization-inbound/schema.json +25 -23
  58. package/docs/policies/mtls-auth-inbound/schema.json +6 -5
  59. package/docs/policies/okta-fga-authz-inbound/schema.json +7 -6
  60. package/docs/policies/okta-jwt-auth-inbound/schema.json +7 -5
  61. package/docs/policies/open-id-jwt-auth-inbound/schema.json +14 -9
  62. package/docs/policies/openfga-authz-inbound/schema.json +7 -6
  63. package/docs/policies/openmeter-inbound/schema.json +23 -19
  64. package/docs/policies/prompt-injection-outbound/schema.json +6 -5
  65. package/docs/policies/propel-auth-jwt-inbound/schema.json +10 -8
  66. package/docs/policies/query-param-to-header-inbound/schema.json +1 -0
  67. package/docs/policies/quota-inbound/schema.json +9 -6
  68. package/docs/policies/rate-limit-inbound/schema.json +4 -0
  69. package/docs/policies/readme-metrics-inbound/schema.json +9 -5
  70. package/docs/policies/request-size-limit-inbound/schema.json +1 -0
  71. package/docs/policies/request-validation-inbound/schema.json +8 -6
  72. package/docs/policies/require-origin-inbound/schema.json +1 -0
  73. package/docs/policies/semantic-cache-inbound/schema.json +9 -5
  74. package/docs/policies/set-status-outbound/schema.json +1 -0
  75. package/docs/policies/set-upstream-api-key-inbound/schema.json +7 -5
  76. package/docs/policies/stripe-webhook-verification-inbound/schema.json +2 -1
  77. package/docs/policies/supabase-jwt-auth-inbound/schema.json +7 -5
  78. package/docs/policies/traffic-splitting-inbound/schema.json +1 -0
  79. package/docs/policies/upstream-aws-federated-auth-inbound/doc.md +78 -0
  80. package/docs/policies/upstream-aws-federated-auth-inbound/intro.md +20 -0
  81. package/docs/policies/upstream-aws-federated-auth-inbound/schema.json +104 -0
  82. package/docs/policies/upstream-aws-service-auth-inbound/doc.md +89 -0
  83. package/docs/policies/upstream-aws-service-auth-inbound/intro.md +19 -0
  84. package/docs/policies/upstream-aws-service-auth-inbound/schema.json +121 -0
  85. package/docs/policies/upstream-azure-ad-service-auth-inbound/schema.json +7 -5
  86. package/docs/policies/upstream-firebase-admin-auth-inbound/schema.json +2 -0
  87. package/docs/policies/upstream-firebase-user-auth-inbound/schema.json +8 -5
  88. package/docs/policies/upstream-gcp-federated-auth-inbound/doc.md +2 -2
  89. package/docs/policies/upstream-gcp-federated-auth-inbound/schema.json +8 -4
  90. package/docs/policies/upstream-gcp-service-auth-inbound/doc.md +3 -3
  91. package/docs/policies/upstream-gcp-service-auth-inbound/schema.json +8 -3
  92. package/docs/policies/upstream-zuplo-jwt-auth-inbound/schema.json +39 -15
  93. package/docs/policies/web-bot-auth-inbound/schema.json +2 -0
  94. package/docs/policies/xml-to-json-outbound/schema.json +9 -5
  95. package/package.json +4 -4
  96. package/docs/articles/zuplo-waf.mdx +0 -156
@@ -57,6 +57,7 @@
57
57
  },
58
58
  "gateway": {
59
59
  "type": "object",
60
+ "x-advanced": true,
60
61
  "description": "Gateway-side OAuth token settings. The gateway issuer and advertised URLs are derived from the incoming request origin.",
61
62
  "additionalProperties": false,
62
63
  "properties": {
@@ -79,8 +80,88 @@
79
80
  }
80
81
  }
81
82
  },
83
+ "idJag": {
84
+ "x-advanced": true,
85
+ "description": "Optional Identity Assertion JWT Authorization Grant (ID-JAG / XAA) support for the gateway token endpoint.",
86
+ "oneOf": [
87
+ {
88
+ "type": "object",
89
+ "additionalProperties": false,
90
+ "required": ["enabled"],
91
+ "properties": {
92
+ "enabled": {
93
+ "const": false,
94
+ "description": "Disable ID-JAG support."
95
+ }
96
+ }
97
+ },
98
+ {
99
+ "type": "object",
100
+ "additionalProperties": false,
101
+ "required": ["enabled"],
102
+ "properties": {
103
+ "enabled": {
104
+ "const": true,
105
+ "description": "Enable ID-JAG support."
106
+ },
107
+ "trustedIssuers": {
108
+ "type": "array",
109
+ "minItems": 1,
110
+ "description": "Trusted ID-JAG issuers. These values are never published in OAuth metadata. Omit to trust this policy's browser-login IdP.",
111
+ "items": {
112
+ "type": "object",
113
+ "additionalProperties": false,
114
+ "dependentRequired": {
115
+ "issuer": ["jwksUrl"],
116
+ "jwksUrl": ["issuer"]
117
+ },
118
+ "properties": {
119
+ "issuer": {
120
+ "type": "string",
121
+ "format": "uri",
122
+ "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."
123
+ },
124
+ "jwksUrl": {
125
+ "type": "string",
126
+ "format": "uri",
127
+ "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."
128
+ },
129
+ "expectedClientIds": {
130
+ "type": "array",
131
+ "items": {
132
+ "type": "string",
133
+ "minLength": 1
134
+ },
135
+ "description": "Optional allow-list of client IDs accepted from this issuer. The ID-JAG client_id must still match the authenticated token-endpoint client."
136
+ },
137
+ "subjectMapping": {
138
+ "type": "string",
139
+ "enum": [
140
+ "iss_prefix",
141
+ "iss_tenant_prefix",
142
+ "sub_id_only"
143
+ ],
144
+ "default": "iss_prefix",
145
+ "description": "How the ID-JAG subject is mapped into the gateway subject ID."
146
+ }
147
+ }
148
+ }
149
+ },
150
+ "authorizationDetailsTypesAllowed": {
151
+ "type": "array",
152
+ "items": {
153
+ "type": "string",
154
+ "minLength": 1
155
+ },
156
+ "description": "Optional allow-list of RFC 9396 authorization_details type values accepted from ID-JAGs."
157
+ }
158
+ }
159
+ }
160
+ ]
161
+ },
82
162
  "browserLoginOverrides": {
83
163
  "type": "object",
164
+ "x-advanced": true,
84
165
  "description": "Optional overrides for the derived browser-login settings.",
85
166
  "additionalProperties": false,
86
167
  "properties": {
@@ -126,6 +126,7 @@
126
126
  },
127
127
  "gateway": {
128
128
  "type": "object",
129
+ "x-advanced": true,
129
130
  "description": "Gateway-side OAuth token settings. The gateway issuer and advertised URLs are derived from the incoming request origin.",
130
131
  "additionalProperties": false,
131
132
  "properties": {
@@ -149,6 +150,7 @@
149
150
  }
150
151
  },
151
152
  "idJag": {
153
+ "x-advanced": true,
152
154
  "description": "Optional Identity Assertion JWT Authorization Grant (ID-JAG / XAA) support for the gateway token endpoint.",
153
155
  "oneOf": [
154
156
  {
@@ -165,7 +167,7 @@
165
167
  {
166
168
  "type": "object",
167
169
  "additionalProperties": false,
168
- "required": ["enabled", "trustedIssuers"],
170
+ "required": ["enabled"],
169
171
  "properties": {
170
172
  "enabled": {
171
173
  "const": true,
@@ -174,21 +176,24 @@
174
176
  "trustedIssuers": {
175
177
  "type": "array",
176
178
  "minItems": 1,
177
- "description": "Trusted ID-JAG issuers. These values are never published in OAuth metadata.",
179
+ "description": "Trusted ID-JAG issuers. These values are never published in OAuth metadata. Omit to trust this policy's browser-login IdP.",
178
180
  "items": {
179
181
  "type": "object",
180
182
  "additionalProperties": false,
181
- "required": ["issuer", "jwksUrl"],
183
+ "dependentRequired": {
184
+ "issuer": ["jwksUrl"],
185
+ "jwksUrl": ["issuer"]
186
+ },
182
187
  "properties": {
183
188
  "issuer": {
184
189
  "type": "string",
185
190
  "format": "uri",
186
- "description": "Exact issuer URL expected in the ID-JAG iss claim."
191
+ "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."
187
192
  },
188
193
  "jwksUrl": {
189
194
  "type": "string",
190
195
  "format": "uri",
191
- "description": "JWKS URL used to verify ID-JAG signatures from this issuer."
196
+ "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."
192
197
  },
193
198
  "expectedClientIds": {
194
199
  "type": "array",
@@ -62,6 +62,7 @@
62
62
  },
63
63
  "gateway": {
64
64
  "type": "object",
65
+ "x-advanced": true,
65
66
  "description": "Gateway-side OAuth token settings. The gateway issuer and advertised URLs are derived from the incoming request origin.",
66
67
  "additionalProperties": false,
67
68
  "properties": {
@@ -84,8 +85,88 @@
84
85
  }
85
86
  }
86
87
  },
88
+ "idJag": {
89
+ "x-advanced": true,
90
+ "description": "Optional Identity Assertion JWT Authorization Grant (ID-JAG / XAA) support for the gateway token endpoint.",
91
+ "oneOf": [
92
+ {
93
+ "type": "object",
94
+ "additionalProperties": false,
95
+ "required": ["enabled"],
96
+ "properties": {
97
+ "enabled": {
98
+ "const": false,
99
+ "description": "Disable ID-JAG support."
100
+ }
101
+ }
102
+ },
103
+ {
104
+ "type": "object",
105
+ "additionalProperties": false,
106
+ "required": ["enabled"],
107
+ "properties": {
108
+ "enabled": {
109
+ "const": true,
110
+ "description": "Enable ID-JAG support."
111
+ },
112
+ "trustedIssuers": {
113
+ "type": "array",
114
+ "minItems": 1,
115
+ "description": "Trusted ID-JAG issuers. These values are never published in OAuth metadata. Omit to trust this policy's browser-login IdP.",
116
+ "items": {
117
+ "type": "object",
118
+ "additionalProperties": false,
119
+ "dependentRequired": {
120
+ "issuer": ["jwksUrl"],
121
+ "jwksUrl": ["issuer"]
122
+ },
123
+ "properties": {
124
+ "issuer": {
125
+ "type": "string",
126
+ "format": "uri",
127
+ "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."
128
+ },
129
+ "jwksUrl": {
130
+ "type": "string",
131
+ "format": "uri",
132
+ "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."
133
+ },
134
+ "expectedClientIds": {
135
+ "type": "array",
136
+ "items": {
137
+ "type": "string",
138
+ "minLength": 1
139
+ },
140
+ "description": "Optional allow-list of client IDs accepted from this issuer. The ID-JAG client_id must still match the authenticated token-endpoint client."
141
+ },
142
+ "subjectMapping": {
143
+ "type": "string",
144
+ "enum": [
145
+ "iss_prefix",
146
+ "iss_tenant_prefix",
147
+ "sub_id_only"
148
+ ],
149
+ "default": "iss_prefix",
150
+ "description": "How the ID-JAG subject is mapped into the gateway subject ID."
151
+ }
152
+ }
153
+ }
154
+ },
155
+ "authorizationDetailsTypesAllowed": {
156
+ "type": "array",
157
+ "items": {
158
+ "type": "string",
159
+ "minLength": 1
160
+ },
161
+ "description": "Optional allow-list of RFC 9396 authorization_details type values accepted from ID-JAGs."
162
+ }
163
+ }
164
+ }
165
+ ]
166
+ },
87
167
  "browserLoginOverrides": {
88
168
  "type": "object",
169
+ "x-advanced": true,
89
170
  "description": "Optional overrides for the derived browser-login settings.",
90
171
  "additionalProperties": false,
91
172
  "properties": {
@@ -57,6 +57,7 @@
57
57
  },
58
58
  "gateway": {
59
59
  "type": "object",
60
+ "x-advanced": true,
60
61
  "description": "Gateway-side OAuth token settings. The gateway issuer and advertised URLs are derived from the incoming request origin.",
61
62
  "additionalProperties": false,
62
63
  "properties": {
@@ -79,8 +80,88 @@
79
80
  }
80
81
  }
81
82
  },
83
+ "idJag": {
84
+ "x-advanced": true,
85
+ "description": "Optional Identity Assertion JWT Authorization Grant (ID-JAG / XAA) support for the gateway token endpoint.",
86
+ "oneOf": [
87
+ {
88
+ "type": "object",
89
+ "additionalProperties": false,
90
+ "required": ["enabled"],
91
+ "properties": {
92
+ "enabled": {
93
+ "const": false,
94
+ "description": "Disable ID-JAG support."
95
+ }
96
+ }
97
+ },
98
+ {
99
+ "type": "object",
100
+ "additionalProperties": false,
101
+ "required": ["enabled"],
102
+ "properties": {
103
+ "enabled": {
104
+ "const": true,
105
+ "description": "Enable ID-JAG support."
106
+ },
107
+ "trustedIssuers": {
108
+ "type": "array",
109
+ "minItems": 1,
110
+ "description": "Trusted ID-JAG issuers. These values are never published in OAuth metadata. Omit to trust this policy's browser-login IdP.",
111
+ "items": {
112
+ "type": "object",
113
+ "additionalProperties": false,
114
+ "dependentRequired": {
115
+ "issuer": ["jwksUrl"],
116
+ "jwksUrl": ["issuer"]
117
+ },
118
+ "properties": {
119
+ "issuer": {
120
+ "type": "string",
121
+ "format": "uri",
122
+ "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."
123
+ },
124
+ "jwksUrl": {
125
+ "type": "string",
126
+ "format": "uri",
127
+ "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."
128
+ },
129
+ "expectedClientIds": {
130
+ "type": "array",
131
+ "items": {
132
+ "type": "string",
133
+ "minLength": 1
134
+ },
135
+ "description": "Optional allow-list of client IDs accepted from this issuer. The ID-JAG client_id must still match the authenticated token-endpoint client."
136
+ },
137
+ "subjectMapping": {
138
+ "type": "string",
139
+ "enum": [
140
+ "iss_prefix",
141
+ "iss_tenant_prefix",
142
+ "sub_id_only"
143
+ ],
144
+ "default": "iss_prefix",
145
+ "description": "How the ID-JAG subject is mapped into the gateway subject ID."
146
+ }
147
+ }
148
+ }
149
+ },
150
+ "authorizationDetailsTypesAllowed": {
151
+ "type": "array",
152
+ "items": {
153
+ "type": "string",
154
+ "minLength": 1
155
+ },
156
+ "description": "Optional allow-list of RFC 9396 authorization_details type values accepted from ID-JAGs."
157
+ }
158
+ }
159
+ }
160
+ ]
161
+ },
82
162
  "browserLoginOverrides": {
83
163
  "type": "object",
164
+ "x-advanced": true,
84
165
  "description": "Optional overrides for the derived browser-login settings.",
85
166
  "additionalProperties": false,
86
167
  "properties": {
@@ -75,6 +75,7 @@
75
75
  },
76
76
  "gateway": {
77
77
  "type": "object",
78
+ "x-advanced": true,
78
79
  "description": "Gateway-side OAuth token settings. The gateway issuer and advertised URLs are derived from the incoming request origin.",
79
80
  "additionalProperties": false,
80
81
  "properties": {
@@ -97,8 +98,88 @@
97
98
  }
98
99
  }
99
100
  },
101
+ "idJag": {
102
+ "x-advanced": true,
103
+ "description": "Optional Identity Assertion JWT Authorization Grant (ID-JAG / XAA) support for the gateway token endpoint.",
104
+ "oneOf": [
105
+ {
106
+ "type": "object",
107
+ "additionalProperties": false,
108
+ "required": ["enabled"],
109
+ "properties": {
110
+ "enabled": {
111
+ "const": false,
112
+ "description": "Disable ID-JAG support."
113
+ }
114
+ }
115
+ },
116
+ {
117
+ "type": "object",
118
+ "additionalProperties": false,
119
+ "required": ["enabled"],
120
+ "properties": {
121
+ "enabled": {
122
+ "const": true,
123
+ "description": "Enable ID-JAG support."
124
+ },
125
+ "trustedIssuers": {
126
+ "type": "array",
127
+ "minItems": 1,
128
+ "description": "Trusted ID-JAG issuers. These values are never published in OAuth metadata. Omit to trust this policy's browser-login IdP.",
129
+ "items": {
130
+ "type": "object",
131
+ "additionalProperties": false,
132
+ "dependentRequired": {
133
+ "issuer": ["jwksUrl"],
134
+ "jwksUrl": ["issuer"]
135
+ },
136
+ "properties": {
137
+ "issuer": {
138
+ "type": "string",
139
+ "format": "uri",
140
+ "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."
141
+ },
142
+ "jwksUrl": {
143
+ "type": "string",
144
+ "format": "uri",
145
+ "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."
146
+ },
147
+ "expectedClientIds": {
148
+ "type": "array",
149
+ "items": {
150
+ "type": "string",
151
+ "minLength": 1
152
+ },
153
+ "description": "Optional allow-list of client IDs accepted from this issuer. The ID-JAG client_id must still match the authenticated token-endpoint client."
154
+ },
155
+ "subjectMapping": {
156
+ "type": "string",
157
+ "enum": [
158
+ "iss_prefix",
159
+ "iss_tenant_prefix",
160
+ "sub_id_only"
161
+ ],
162
+ "default": "iss_prefix",
163
+ "description": "How the ID-JAG subject is mapped into the gateway subject ID."
164
+ }
165
+ }
166
+ }
167
+ },
168
+ "authorizationDetailsTypesAllowed": {
169
+ "type": "array",
170
+ "items": {
171
+ "type": "string",
172
+ "minLength": 1
173
+ },
174
+ "description": "Optional allow-list of RFC 9396 authorization_details type values accepted from ID-JAGs."
175
+ }
176
+ }
177
+ }
178
+ ]
179
+ },
100
180
  "browserLoginOverrides": {
101
181
  "type": "object",
182
+ "x-advanced": true,
102
183
  "description": "Optional overrides for the derived browser-login settings.",
103
184
  "additionalProperties": false,
104
185
  "properties": {
@@ -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.