From ebc5526149c4d195356d4705f09ae5b1c80b78b5 Mon Sep 17 00:00:00 2001 From: Paul Reilly Date: Thu, 5 Nov 2026 14:29:13 -0500 Subject: [PATCH 1/3] feat: guide human-gated clearing on Okta and other customer IdPs Gateways now bind human-gated clears on the claim that identifies the same person in both tokens, detected from the issuer host: Entra ID and Okta are recognised, and SESSION_SUBJECT_PROVIDER in `gateway.advanced` covers an Okta custom domain or a sovereign-cloud Entra ID issuer. The gateway-config skill now tells users how to set up the clearing app on Okta (Native app, Okta-generated client ID, in the authorization server's access policy), which redirect URI to register, that intent clears need intent capture, and when to set the provider. The vendored schema reference picks up the matching `session_control.client_id` guidance; the digest is regenerated and its pinned hash bumped. Only that rationale string changed, so no safe-default seed moved. Bumps the plugin to 1.3.5. --- dtwo/.claude-plugin/plugin.json | 2 +- dtwo/.codex-plugin/plugin.json | 2 +- dtwo/.cursor-plugin/plugin.json | 2 +- dtwo/skills/dtwo-gateway-config/SKILL.md | 15 +++++++++++++-- .../dtwo-gateway-config/schema-reference.json | 2 +- skill-harness/src/schemaArtifact.ts | 2 +- 6 files changed, 18 insertions(+), 7 deletions(-) diff --git a/dtwo/.claude-plugin/plugin.json b/dtwo/.claude-plugin/plugin.json index 7d32bab..ded6de7 100644 --- a/dtwo/.claude-plugin/plugin.json +++ b/dtwo/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "dtwo", - "version": "1.3.4", + "version": "1.3.5", "description": "Manage Dtwo gateways, policies, and Rego with the Dtwo MCP server.", "author": { "name": "Dtwo", diff --git a/dtwo/.codex-plugin/plugin.json b/dtwo/.codex-plugin/plugin.json index 97ea777..120c9d9 100644 --- a/dtwo/.codex-plugin/plugin.json +++ b/dtwo/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "dtwo", - "version": "1.3.4", + "version": "1.3.5", "description": "Manage Dtwo gateways, policies, and Rego with the Dtwo MCP server.", "author": { "name": "Dtwo", diff --git a/dtwo/.cursor-plugin/plugin.json b/dtwo/.cursor-plugin/plugin.json index 34ef67a..8f9b37d 100644 --- a/dtwo/.cursor-plugin/plugin.json +++ b/dtwo/.cursor-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "dtwo", - "version": "1.3.4", + "version": "1.3.5", "description": "Manage Dtwo gateways, policies, and Rego with the Dtwo MCP server.", "author": { "name": "Dtwo", diff --git a/dtwo/skills/dtwo-gateway-config/SKILL.md b/dtwo/skills/dtwo-gateway-config/SKILL.md index cbf59bb..689aa1c 100644 --- a/dtwo/skills/dtwo-gateway-config/SKILL.md +++ b/dtwo/skills/dtwo-gateway-config/SKILL.md @@ -283,7 +283,7 @@ Human-gated session clearing (session-control) registration: the IdP app the bro | Field | Required | Type | Default | Target | Guidance (from artifact) | |---|---|---|---|---|---| -| `client_id` | no | string | `not declared` | `SESSION_CONTROL_CLIENT_ID` | Leave unset on a gateway using Dtwo authentication. Set it only when the gateway trusts your own IdP: the ceremony app must live in the IdP that issues the gateway's inbound tokens, so register a dedicated public client there (authorization-code + PKCE, no refresh grant) and paste its client id here. Do not reuse the gateway API client. | +| `client_id` | no | string | `not declared` | `SESSION_CONTROL_CLIENT_ID` | Leave unset on a gateway using Dtwo authentication. Set it only when the gateway trusts your own IdP: the ceremony app must live in the IdP that issues the gateway's inbound tokens, so register a dedicated public client there (authorization-code + PKCE, no refresh grant) and paste its client id here. Do not reuse the gateway API client. On Okta that is a Native app with an Okta-generated client ID, included in the custom authorization server's access policy. The gateway picks the identity claim it binds on from the issuer host (Entra, Okta or other); for an Okta org on a custom domain or a sovereign-cloud Entra issuer, also add `SESSION_SUBJECT_PROVIDER=okta` (or `entra`) to `gateway.advanced`, or every clear fails `subject_mismatch`. | | `redirect_uri` | no | string | `not declared` | `SESSION_CONTROL_REDIRECT_URI` | Leave unset in almost all cases — the gateway derives `/session-control/clear/callback` and the platform registers that. Set it when a reverse proxy or split-horizon DNS puts the browser on a different origin than the audience: give the URL the browser can actually reach, at the root path (`/mcp/*` routes to the streamable-HTTP handler, which rejects browser GETs). It is required when the first `jwt_audience` is not an absolute URL — e.g. an Entra ID v2.0 gateway, whose audience is the gateway app's client ID (a GUID) — since there is no origin to derive from, and the deploy rejects an armed gateway that leaves it unset. | **Cross-field constraints** (verbatim from artifact): @@ -398,7 +398,7 @@ Every field marked `secret: true` in the artifact. Put a Vault reference there ( - **`targetKind: platform`** — value is applied as a platform-side control at the named `platform.*` path rather than written to the gateway env file. - **`targetKind: sotwPath`** — value is written into the SOTW YAML at the named dotted path (e.g. `sotw.url`, `sotw.oauth_config.client_secret`). Read the `Target` column per field; do not infer a field's target from its section. - + @@ -409,6 +409,17 @@ Controls authentication, SSRF protection, `log_level`, `advanced` flags, DCR / d - **Authentication** defaults to enabled when omitted. Every field in `gateway.authentication` — including the token-validation flags (`jwt_issuer_verification`, `jwt_audience_verification`, `require_jti`, `require_token_expiration`, `mcp_oauth_resource_metadata_enabled`) — is listed in the Schema Digest above with its target, its default, and the schema's own guidance on when to set it. Read the table there rather than guessing from this summary; most of those flags carry a gateway-applied default (their Default column reads `` `true` (gateway) ``), and where the artifact declares none (`mcp_oauth_resource_metadata_enabled` reads `not declared`) the Guidance column states the effective value. - **Gateway-side `jwks_info` is independent of any `mcp_servers[].authentication` block.** When the prompt supplies an IdP tenant and audience (e.g. Auth0), populate `gateway.authentication.jwks_info` (`jwt_algorithm`, `jwt_jwks_uri`, `jwt_issuer`, `jwt_audience`) — even when the upstream MCP server uses OAuth/DCR, and even when the prompt says the upstream server "only supports OAuth" or "does not accept bearer tokens." Those statements describe the outbound leg to the MCP server, not the inbound leg from clients to the gateway. - **SSRF** defaults to strict (block localhost, block private networks, fail-closed DNS) when omitted. Set `allow_private_networks: true` to permit access to `host.docker.internal` and other private addresses. +- **Human-gated clearing on your own IdP** (a gateway whose `jwks_info` points at Okta, Entra ID or another IdP rather than Dtwo authentication) needs a `session_control.client_id` for a dedicated public client in that same IdP. The digest's `client_id` guidance covers the general rule. Things users get wrong: + - **Okta:** create a **Native** OIDC app (authorization code with PKCE, no client secret, no refresh token) and choose **Okta-generated client ID**, not a Client ID Metadata Document. Add it, and every app the MCP clients sign in with, to the custom authorization server's **access policy**, or Okta refuses the sign-in before the gateway sees it. + - **Sign-in redirect URI:** register `/session-control/clear/callback` on the clearing app, or whatever `session_control.redirect_uri` names. It is required when the first `jwt_audience` is not a URL (Entra ID v2.0), and when the browser reaches the gateway at a different origin than its audience. + - **Intent clears need intent capture:** set `gateway.intent.enabled: true`, or `set_intent` succeeds but nothing is stored and a clear finds nothing to clear. + - **Identity claim:** the gateway detects Entra ID (`login.microsoftonline.com`, `sts.windows.net`) and Okta (`*.okta.com`, `*.oktapreview.com`, `*.okta-emea.com`, `*.okta-gov.com`) from the `jwt_issuer` host, and binds clears on the claim that identifies the same person in both tokens. For an **Okta org on a custom domain** or a **sovereign-cloud Entra ID** issuer, add the provider to `gateway.advanced` as a list entry, or every clear fails `subject_mismatch`. The accepted values are `auto` (the default), `oidc`, `entra` and `okta`; anything else fails the deploy. + + ```yaml + gateway: + advanced: + - SESSION_SUBJECT_PROVIDER=okta + ``` ### MCP Servers Section diff --git a/dtwo/skills/dtwo-gateway-config/schema-reference.json b/dtwo/skills/dtwo-gateway-config/schema-reference.json index 1940fb8..9985151 100644 --- a/dtwo/skills/dtwo-gateway-config/schema-reference.json +++ b/dtwo/skills/dtwo-gateway-config/schema-reference.json @@ -717,7 +717,7 @@ "deployDefault": null, "target": "SESSION_CONTROL_CLIENT_ID", "description": "Public client id of the dedicated session-control OAuth app (native, PKCE, no client secret). Optional on a gateway authenticating against Dtwo's Auth0: the platform provisions one per organization and renders it at deploy. An explicit value always wins.", - "rationale": "Leave unset on a gateway using Dtwo authentication. Set it only when the gateway trusts your own IdP: the ceremony app must live in the IdP that issues the gateway's inbound tokens, so register a dedicated public client there (authorization-code + PKCE, no refresh grant) and paste its client id here. Do not reuse the gateway API client.", + "rationale": "Leave unset on a gateway using Dtwo authentication. Set it only when the gateway trusts your own IdP: the ceremony app must live in the IdP that issues the gateway's inbound tokens, so register a dedicated public client there (authorization-code + PKCE, no refresh grant) and paste its client id here. Do not reuse the gateway API client. On Okta that is a Native app with an Okta-generated client ID, included in the custom authorization server's access policy. The gateway picks the identity claim it binds on from the issuer host (Entra, Okta or other); for an Okta org on a custom domain or a sovereign-cloud Entra issuer, also add `SESSION_SUBJECT_PROVIDER=okta` (or `entra`) to `gateway.advanced`, or every clear fails `subject_mismatch`.", "targetKind": "envVar" }, { diff --git a/skill-harness/src/schemaArtifact.ts b/skill-harness/src/schemaArtifact.ts index d4643ed..602b4fc 100644 --- a/skill-harness/src/schemaArtifact.ts +++ b/skill-harness/src/schemaArtifact.ts @@ -45,7 +45,7 @@ export const SCHEMA_ARTIFACT_VERSION = '1.1.0'; * in reviewed source. It cannot stop a PR that bumps both the artifact and * this constant — judging that change is still review's job. */ -export const EXPECTED_SCHEMA_ARTIFACT_SHA256 = '4dc79f71108e6c02642bd5fc8463e310924d0c3c453e634cd5afc60d9b46af16'; +export const EXPECTED_SCHEMA_ARTIFACT_SHA256 = 'cc6509d801ba1c84067dde97e5787498da70571c0d207711c34872d714219555'; /** * `platform` is emitted by the currently vendored artifact (every From b9876aa38f420c4f6e0a4a662cc63b15a700180a Mon Sep 17 00:00:00 2001 From: Paul Reilly Date: Thu, 5 Nov 2026 14:59:40 -0500 Subject: [PATCH 2/3] chore: re-vendor the validator bundle with the schema it was built with The schema reference was re-copied for the session_control.client_id guidance; the validator bundle is built from the same schema, so it is re-vendored from the same source revision and its pinned hash bumped. Only that rationale string differs. --- skill-harness/src/validatorBundle.ts | 2 +- skill-harness/vendor/config-validator.bundle.mjs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/skill-harness/src/validatorBundle.ts b/skill-harness/src/validatorBundle.ts index ab137e3..e071cc7 100644 --- a/skill-harness/src/validatorBundle.ts +++ b/skill-harness/src/validatorBundle.ts @@ -39,7 +39,7 @@ export const EXPECTED_VALIDATOR_BUNDLE_VERSION = '4.0.0'; * `__tests__/schemaDigest.test.ts`, not at module load. Bump this together * with `EXPECTED_VALIDATOR_BUNDLE_VERSION` when the bundle is re-vendored. */ -export const EXPECTED_VALIDATOR_BUNDLE_SHA256 = '9dba8b63ab3b7ef486aa3e448048ebe8eea04fac3e26598cc75f57e112d1474f'; +export const EXPECTED_VALIDATOR_BUNDLE_SHA256 = '5c280f5a00d8ced46bcc12e41af1ec72940abc8ace1ed00d66047594ea95d6d9'; const HERE = dirname(fileURLToPath(import.meta.url)); diff --git a/skill-harness/vendor/config-validator.bundle.mjs b/skill-harness/vendor/config-validator.bundle.mjs index c8d2e57..2ccafac 100644 --- a/skill-harness/vendor/config-validator.bundle.mjs +++ b/skill-harness/vendor/config-validator.bundle.mjs @@ -23447,7 +23447,7 @@ var SessionControlSchema = external_exports.object({ description: "Public client id of the dedicated session-control OAuth app (native, PKCE, no client secret). Optional on a gateway authenticating against Dtwo's Auth0: the platform provisions one per organization and renders it at deploy. An explicit value always wins.", target: "SESSION_CONTROL_CLIENT_ID", audience: "user", - rationale: "Leave unset on a gateway using Dtwo authentication. Set it only when the gateway trusts your own IdP: the ceremony app must live in the IdP that issues the gateway's inbound tokens, so register a dedicated public client there (authorization-code + PKCE, no refresh grant) and paste its client id here. Do not reuse the gateway API client." + rationale: "Leave unset on a gateway using Dtwo authentication. Set it only when the gateway trusts your own IdP: the ceremony app must live in the IdP that issues the gateway's inbound tokens, so register a dedicated public client there (authorization-code + PKCE, no refresh grant) and paste its client id here. Do not reuse the gateway API client. On Okta that is a Native app with an Okta-generated client ID, included in the custom authorization server's access policy. The gateway picks the identity claim it binds on from the issuer host (Entra, Okta or other); for an Okta org on a custom domain or a sovereign-cloud Entra issuer, also add `SESSION_SUBJECT_PROVIDER=okta` (or `entra`) to `gateway.advanced`, or every clear fails `subject_mismatch`." }) ), redirect_uri: external_exports.string().min(1).refine(isRenderableRedirectUri, { @@ -23462,8 +23462,8 @@ var SessionControlSchema = external_exports.object({ ), // There is deliberately NO `issuer` field. The ceremony's issuer is always // `gateway.authentication.jwks_info.jwt_issuer` — the callback binds the - // inbound and browser-login identities as raw `iss|` (`sub`, or `oid` - // on an Entra issuer), so any other value + // inbound and browser-login identities as raw `iss|` (`sub`, `oid` + // on an Entra issuer, `uid` against the ID token's `sub` on Okta), so any other value // makes every ceremony deterministically fail subject_mismatch. A field // whose only legal value is a copy of another field is pure misconfiguration // surface, so the deploy derives SESSION_CONTROL_ISSUER from jwt_issuer From 416d8743bd17a79be167ad323eb7647b7901c5cc Mon Sep 17 00:00:00 2001 From: Paul Reilly Date: Thu, 5 Nov 2026 15:35:52 -0500 Subject: [PATCH 3/3] docs: make clear most gateways never set SESSION_SUBJECT_PROVIDER The identity-claim note and the vendored client_id guidance now lead with the default: Entra ID and Okta are detected and every other issuer, Auth0 included, is standard OIDC. The setting is only for an Okta custom domain or a sovereign-cloud Entra ID issuer. Schema and validator bundle are re-vendored from the same source revision and their pins bumped. --- dtwo/skills/dtwo-gateway-config/SKILL.md | 6 +++--- dtwo/skills/dtwo-gateway-config/schema-reference.json | 2 +- skill-harness/src/schemaArtifact.ts | 2 +- skill-harness/src/validatorBundle.ts | 2 +- skill-harness/vendor/config-validator.bundle.mjs | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dtwo/skills/dtwo-gateway-config/SKILL.md b/dtwo/skills/dtwo-gateway-config/SKILL.md index 689aa1c..1e80f1d 100644 --- a/dtwo/skills/dtwo-gateway-config/SKILL.md +++ b/dtwo/skills/dtwo-gateway-config/SKILL.md @@ -283,7 +283,7 @@ Human-gated session clearing (session-control) registration: the IdP app the bro | Field | Required | Type | Default | Target | Guidance (from artifact) | |---|---|---|---|---|---| -| `client_id` | no | string | `not declared` | `SESSION_CONTROL_CLIENT_ID` | Leave unset on a gateway using Dtwo authentication. Set it only when the gateway trusts your own IdP: the ceremony app must live in the IdP that issues the gateway's inbound tokens, so register a dedicated public client there (authorization-code + PKCE, no refresh grant) and paste its client id here. Do not reuse the gateway API client. On Okta that is a Native app with an Okta-generated client ID, included in the custom authorization server's access policy. The gateway picks the identity claim it binds on from the issuer host (Entra, Okta or other); for an Okta org on a custom domain or a sovereign-cloud Entra issuer, also add `SESSION_SUBJECT_PROVIDER=okta` (or `entra`) to `gateway.advanced`, or every clear fails `subject_mismatch`. | +| `client_id` | no | string | `not declared` | `SESSION_CONTROL_CLIENT_ID` | Leave unset on a gateway using Dtwo authentication. Set it only when the gateway trusts your own IdP: the ceremony app must live in the IdP that issues the gateway's inbound tokens, so register a dedicated public client there (authorization-code + PKCE, no refresh grant) and paste its client id here. Do not reuse the gateway API client. On Okta that is a Native app with an Okta-generated client ID, included in the custom authorization server's access policy. The gateway picks the identity claim it binds on from the issuer host (Entra, Okta or other); most gateways need nothing more. For an Okta org on a custom domain or a sovereign-cloud Entra issuer — and only then — add `SESSION_SUBJECT_PROVIDER=okta` (or `entra`) to `gateway.advanced`, or every clear fails `subject_mismatch`. | | `redirect_uri` | no | string | `not declared` | `SESSION_CONTROL_REDIRECT_URI` | Leave unset in almost all cases — the gateway derives `/session-control/clear/callback` and the platform registers that. Set it when a reverse proxy or split-horizon DNS puts the browser on a different origin than the audience: give the URL the browser can actually reach, at the root path (`/mcp/*` routes to the streamable-HTTP handler, which rejects browser GETs). It is required when the first `jwt_audience` is not an absolute URL — e.g. an Entra ID v2.0 gateway, whose audience is the gateway app's client ID (a GUID) — since there is no origin to derive from, and the deploy rejects an armed gateway that leaves it unset. | **Cross-field constraints** (verbatim from artifact): @@ -398,7 +398,7 @@ Every field marked `secret: true` in the artifact. Put a Vault reference there ( - **`targetKind: platform`** — value is applied as a platform-side control at the named `platform.*` path rather than written to the gateway env file. - **`targetKind: sotwPath`** — value is written into the SOTW YAML at the named dotted path (e.g. `sotw.url`, `sotw.oauth_config.client_secret`). Read the `Target` column per field; do not infer a field's target from its section. - + @@ -413,7 +413,7 @@ Controls authentication, SSRF protection, `log_level`, `advanced` flags, DCR / d - **Okta:** create a **Native** OIDC app (authorization code with PKCE, no client secret, no refresh token) and choose **Okta-generated client ID**, not a Client ID Metadata Document. Add it, and every app the MCP clients sign in with, to the custom authorization server's **access policy**, or Okta refuses the sign-in before the gateway sees it. - **Sign-in redirect URI:** register `/session-control/clear/callback` on the clearing app, or whatever `session_control.redirect_uri` names. It is required when the first `jwt_audience` is not a URL (Entra ID v2.0), and when the browser reaches the gateway at a different origin than its audience. - **Intent clears need intent capture:** set `gateway.intent.enabled: true`, or `set_intent` succeeds but nothing is stored and a clear finds nothing to clear. - - **Identity claim:** the gateway detects Entra ID (`login.microsoftonline.com`, `sts.windows.net`) and Okta (`*.okta.com`, `*.oktapreview.com`, `*.okta-emea.com`, `*.okta-gov.com`) from the `jwt_issuer` host, and binds clears on the claim that identifies the same person in both tokens. For an **Okta org on a custom domain** or a **sovereign-cloud Entra ID** issuer, add the provider to `gateway.advanced` as a list entry, or every clear fails `subject_mismatch`. The accepted values are `auto` (the default), `oidc`, `entra` and `okta`; anything else fails the deploy. + - **Identity claim — most gateways set nothing.** The gateway detects Entra ID (`login.microsoftonline.com`, `sts.windows.net`) and Okta (`*.okta.com`, `*.oktapreview.com`, `*.okta-emea.com`, `*.okta-gov.com`) from the `jwt_issuer` host, treats every other issuer (Auth0 included) as standard OIDC, and binds clears on the claim that identifies the same person in both tokens. Do not add `SESSION_SUBJECT_PROVIDER` unless the issuer is an **Okta org on a custom domain** or a **sovereign-cloud Entra ID** host; for those two only, add the provider to `gateway.advanced` as a list entry, or every clear fails `subject_mismatch`. The accepted values are `auto` (the default), `oidc`, `entra` and `okta`; anything else fails the deploy. ```yaml gateway: diff --git a/dtwo/skills/dtwo-gateway-config/schema-reference.json b/dtwo/skills/dtwo-gateway-config/schema-reference.json index 9985151..a4e4094 100644 --- a/dtwo/skills/dtwo-gateway-config/schema-reference.json +++ b/dtwo/skills/dtwo-gateway-config/schema-reference.json @@ -717,7 +717,7 @@ "deployDefault": null, "target": "SESSION_CONTROL_CLIENT_ID", "description": "Public client id of the dedicated session-control OAuth app (native, PKCE, no client secret). Optional on a gateway authenticating against Dtwo's Auth0: the platform provisions one per organization and renders it at deploy. An explicit value always wins.", - "rationale": "Leave unset on a gateway using Dtwo authentication. Set it only when the gateway trusts your own IdP: the ceremony app must live in the IdP that issues the gateway's inbound tokens, so register a dedicated public client there (authorization-code + PKCE, no refresh grant) and paste its client id here. Do not reuse the gateway API client. On Okta that is a Native app with an Okta-generated client ID, included in the custom authorization server's access policy. The gateway picks the identity claim it binds on from the issuer host (Entra, Okta or other); for an Okta org on a custom domain or a sovereign-cloud Entra issuer, also add `SESSION_SUBJECT_PROVIDER=okta` (or `entra`) to `gateway.advanced`, or every clear fails `subject_mismatch`.", + "rationale": "Leave unset on a gateway using Dtwo authentication. Set it only when the gateway trusts your own IdP: the ceremony app must live in the IdP that issues the gateway's inbound tokens, so register a dedicated public client there (authorization-code + PKCE, no refresh grant) and paste its client id here. Do not reuse the gateway API client. On Okta that is a Native app with an Okta-generated client ID, included in the custom authorization server's access policy. The gateway picks the identity claim it binds on from the issuer host (Entra, Okta or other); most gateways need nothing more. For an Okta org on a custom domain or a sovereign-cloud Entra issuer — and only then — add `SESSION_SUBJECT_PROVIDER=okta` (or `entra`) to `gateway.advanced`, or every clear fails `subject_mismatch`.", "targetKind": "envVar" }, { diff --git a/skill-harness/src/schemaArtifact.ts b/skill-harness/src/schemaArtifact.ts index 602b4fc..3217af9 100644 --- a/skill-harness/src/schemaArtifact.ts +++ b/skill-harness/src/schemaArtifact.ts @@ -45,7 +45,7 @@ export const SCHEMA_ARTIFACT_VERSION = '1.1.0'; * in reviewed source. It cannot stop a PR that bumps both the artifact and * this constant — judging that change is still review's job. */ -export const EXPECTED_SCHEMA_ARTIFACT_SHA256 = 'cc6509d801ba1c84067dde97e5787498da70571c0d207711c34872d714219555'; +export const EXPECTED_SCHEMA_ARTIFACT_SHA256 = '9133ce3ac2650844dc11ad453ed36ae929f11ab7b3df4d4842c1504292075313'; /** * `platform` is emitted by the currently vendored artifact (every diff --git a/skill-harness/src/validatorBundle.ts b/skill-harness/src/validatorBundle.ts index e071cc7..6e9e0aa 100644 --- a/skill-harness/src/validatorBundle.ts +++ b/skill-harness/src/validatorBundle.ts @@ -39,7 +39,7 @@ export const EXPECTED_VALIDATOR_BUNDLE_VERSION = '4.0.0'; * `__tests__/schemaDigest.test.ts`, not at module load. Bump this together * with `EXPECTED_VALIDATOR_BUNDLE_VERSION` when the bundle is re-vendored. */ -export const EXPECTED_VALIDATOR_BUNDLE_SHA256 = '5c280f5a00d8ced46bcc12e41af1ec72940abc8ace1ed00d66047594ea95d6d9'; +export const EXPECTED_VALIDATOR_BUNDLE_SHA256 = '27c46ab1263fe0b75f71e60a8a37f4f401c5699651542565859cd0843ff9868c'; const HERE = dirname(fileURLToPath(import.meta.url)); diff --git a/skill-harness/vendor/config-validator.bundle.mjs b/skill-harness/vendor/config-validator.bundle.mjs index 2ccafac..7a8bf5b 100644 --- a/skill-harness/vendor/config-validator.bundle.mjs +++ b/skill-harness/vendor/config-validator.bundle.mjs @@ -23447,7 +23447,7 @@ var SessionControlSchema = external_exports.object({ description: "Public client id of the dedicated session-control OAuth app (native, PKCE, no client secret). Optional on a gateway authenticating against Dtwo's Auth0: the platform provisions one per organization and renders it at deploy. An explicit value always wins.", target: "SESSION_CONTROL_CLIENT_ID", audience: "user", - rationale: "Leave unset on a gateway using Dtwo authentication. Set it only when the gateway trusts your own IdP: the ceremony app must live in the IdP that issues the gateway's inbound tokens, so register a dedicated public client there (authorization-code + PKCE, no refresh grant) and paste its client id here. Do not reuse the gateway API client. On Okta that is a Native app with an Okta-generated client ID, included in the custom authorization server's access policy. The gateway picks the identity claim it binds on from the issuer host (Entra, Okta or other); for an Okta org on a custom domain or a sovereign-cloud Entra issuer, also add `SESSION_SUBJECT_PROVIDER=okta` (or `entra`) to `gateway.advanced`, or every clear fails `subject_mismatch`." + rationale: "Leave unset on a gateway using Dtwo authentication. Set it only when the gateway trusts your own IdP: the ceremony app must live in the IdP that issues the gateway's inbound tokens, so register a dedicated public client there (authorization-code + PKCE, no refresh grant) and paste its client id here. Do not reuse the gateway API client. On Okta that is a Native app with an Okta-generated client ID, included in the custom authorization server's access policy. The gateway picks the identity claim it binds on from the issuer host (Entra, Okta or other); most gateways need nothing more. For an Okta org on a custom domain or a sovereign-cloud Entra issuer \u2014 and only then \u2014 add `SESSION_SUBJECT_PROVIDER=okta` (or `entra`) to `gateway.advanced`, or every clear fails `subject_mismatch`." }) ), redirect_uri: external_exports.string().min(1).refine(isRenderableRedirectUri, {