The client-channel human-interaction flow (/v1/ops/client-channel/*) is currently used for
toolset sign-in. It must also support external-service sign-in — JSON-RPC method
external-service/signin with params.url = applications/{app_id}/external_services/{id}.
The transport is already scope-agnostic: core does not inspect the JSON-RPC method or params,
so such a message already flows end-to-end. What is missing is admission control and a
reliable trigger for the interaction.
Required
- Handle sign-in requests per JSON-RPC method instead of relaying them blindly. Toolset
sign-in keeps its current behaviour.
- Authorize
external-service/signin: require a per-request key and verify that the app id in
the requested scope matches the calling deployment. Otherwise an application can prompt a
user to sign in to another application's external service. The equivalent check already
exists on the credential retrieval path.
- Validate the requested scope (parses correctly, external service exists, has auth settings)
and reject with JSON-RPC -32602 instead of showing a prompt the user cannot satisfy.
- Return
success immediately when credentials for the scope already exist (USER, then
APPLICATION/GLOBAL), without prompting the user.
- Return a machine-readable
sign_in_required signal from
POST /v1/ops/external-service/credentials when no credential is stored. It is currently a
plain 404, indistinguishable from an unknown scope, so an application has no reliable way to
decide to start an interactive sign-in.
- Define the response semantics:
success means credentials were stored and the application
should retry retrieval; denied means the user refused and the application should not
re-prompt within the same request.
Out of scope
External-service OAuth supports pre-registered static clients only (no PKCE, no dynamic client
registration). Providers that mandate PKCE will not be able to complete interactive sign-in;
supporting them is separate work.
The client-channel human-interaction flow (
/v1/ops/client-channel/*) is currently used fortoolset sign-in. It must also support external-service sign-in — JSON-RPC method
external-service/signinwithparams.url = applications/{app_id}/external_services/{id}.The transport is already scope-agnostic: core does not inspect the JSON-RPC method or params,
so such a message already flows end-to-end. What is missing is admission control and a
reliable trigger for the interaction.
Required
sign-in keeps its current behaviour.
external-service/signin: require a per-request key and verify that the app id inthe requested scope matches the calling deployment. Otherwise an application can prompt a
user to sign in to another application's external service. The equivalent check already
exists on the credential retrieval path.
and reject with JSON-RPC
-32602instead of showing a prompt the user cannot satisfy.successimmediately when credentials for the scope already exist (USER, thenAPPLICATION/GLOBAL), without prompting the user.
sign_in_requiredsignal fromPOST /v1/ops/external-service/credentialswhen no credential is stored. It is currently aplain 404, indistinguishable from an unknown scope, so an application has no reliable way to
decide to start an interactive sign-in.
successmeans credentials were stored and the applicationshould retry retrieval;
deniedmeans the user refused and the application should notre-prompt within the same request.
Out of scope
External-service OAuth supports pre-registered static clients only (no PKCE, no dynamic client
registration). Providers that mandate PKCE will not be able to complete interactive sign-in;
supporting them is separate work.