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:
Stevanus Pangau
2026-06-26 11:39:33 +07:00
committed by decolua
parent 49a3ec7a72
commit a4f44e3e12
7 changed files with 554 additions and 5 deletions

View File

@@ -55,7 +55,9 @@ export async function getKiroUsage(accessToken, providerSpecificData, proxyOptio
// CodeWhisperer treats it as a long-lived API key rather than an OIDC token.
// Without this header the GetUsageLimits call is rejected (401/403).
const isApiKey = authMethod === "api_key";
const isExternalIdp = authMethod === "external_idp";
const apiKeyHeaders = isApiKey ? { tokentype: "API_KEY" } : {};
const externalIdpHeaders = isExternalIdp ? { TokenType: "EXTERNAL_IDP" } : {};
// For api-key auth, never inject the shared default placeholder profileArn —
// CodeWhisperer 403s a request whose profileArn isn't owned by the key's
@@ -84,6 +86,7 @@ export async function getKiroUsage(accessToken, providerSpecificData, proxyOptio
"x-amz-user-agent": "aws-sdk-js/1.0.0 KiroIDE",
"user-agent": "aws-sdk-js/1.0.0 KiroIDE",
...apiKeyHeaders,
...externalIdpHeaders,
},
},
proxyOptions
@@ -99,6 +102,7 @@ export async function getKiroUsage(accessToken, providerSpecificData, proxyOptio
"x-amz-target": "AmazonCodeWhispererService.GetUsageLimits",
"Accept": "application/json",
...apiKeyHeaders,
...externalIdpHeaders,
},
body: JSON.stringify({
origin: "AI_EDITOR",
@@ -121,6 +125,7 @@ export async function getKiroUsage(accessToken, providerSpecificData, proxyOptio
"Authorization": `Bearer ${accessToken}`,
"Accept": "application/json",
...apiKeyHeaders,
...externalIdpHeaders,
},
}, proxyOptions);
},