mirror of
https://github.com/Nezumi-2711/9router.git
synced 2026-09-22 13:38:31 +00:00
feat(kiro): add external_idp CLIProxyAPI import for Microsoft SSO
Import Kiro accounts authenticated via Microsoft Entra/365 SSO using CLIProxyAPI JSON. Adds external_idp refresh path (form-encoded OAuth2, Microsoft login host allowlist), TokenType: EXTERNAL_IDP header for runtime and usage/quota requests, dashboard import UI, and unit tests. Scoped to authMethod === "external_idp"; existing Kiro auth unchanged. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
committed by
decolua
co-authored by
Cursor
parent
49a3ec7a72
commit
a4f44e3e12
@@ -26,7 +26,11 @@ export class KiroExecutor extends BaseExecutor {
|
||||
// exactly like an OAuth access token, but with an extra `tokentype: API_KEY`
|
||||
// header so CodeWhisperer treats it as a long-lived API key rather than an
|
||||
// OIDC/social access token. Mirrors the Kiro IDE headless-auth behavior.
|
||||
const isApiKey = credentials?.providerSpecificData?.authMethod === "api_key";
|
||||
// Enterprise / Microsoft Entra (external_idp) tokens are OAuth access tokens,
|
||||
// but CodeWhisperer requires TokenType=EXTERNAL_IDP to bind them to profiles.
|
||||
const authMethod = credentials?.providerSpecificData?.authMethod;
|
||||
const isApiKey = authMethod === "api_key";
|
||||
const isExternalIdp = authMethod === "external_idp";
|
||||
|
||||
const apiKey = credentials?.apiKey || (isApiKey ? credentials?.accessToken : null);
|
||||
if (isApiKey && apiKey) {
|
||||
@@ -34,6 +38,9 @@ export class KiroExecutor extends BaseExecutor {
|
||||
headers["tokentype"] = "API_KEY";
|
||||
} else if (credentials.accessToken) {
|
||||
headers["Authorization"] = `Bearer ${credentials.accessToken}`;
|
||||
if (isExternalIdp) {
|
||||
headers["TokenType"] = "EXTERNAL_IDP";
|
||||
}
|
||||
}
|
||||
|
||||
return headers;
|
||||
@@ -49,13 +56,16 @@ export class KiroExecutor extends BaseExecutor {
|
||||
* BaseExecutor.execute() returns immediately (only 429 / network errors fall
|
||||
* through to the next host). So for api-key auth we must try the *.amazonaws.com
|
||||
* CodeWhisperer hosts FIRST, mirroring the Kiro-Go reference fork which never
|
||||
* routes api-key traffic through kiro.dev. OAuth keeps the default order
|
||||
* (kiro.dev first) since its token is what that gateway accepts.
|
||||
* routes api-key traffic through kiro.dev. External IdP enterprise tokens also
|
||||
* use the CodeWhisperer surface, with the `TokenType: EXTERNAL_IDP` header.
|
||||
* Other OAuth methods keep the default order (kiro.dev first) since their
|
||||
* tokens are what that gateway accepts.
|
||||
*/
|
||||
getOrderedBaseUrls(credentials) {
|
||||
const baseUrls = this.getBaseUrls();
|
||||
const isApiKey = credentials?.providerSpecificData?.authMethod === "api_key";
|
||||
if (!isApiKey) return baseUrls;
|
||||
const authMethod = credentials?.providerSpecificData?.authMethod;
|
||||
const isCodeWhispererSurface = authMethod === "api_key" || authMethod === "external_idp";
|
||||
if (!isCodeWhispererSurface) return baseUrls;
|
||||
const amazon = baseUrls.filter((u) => u.includes("amazonaws.com"));
|
||||
const others = baseUrls.filter((u) => !u.includes("amazonaws.com"));
|
||||
return amazon.length > 0 ? [...amazon, ...others] : baseUrls;
|
||||
|
||||
Reference in New Issue
Block a user