Skip to content

fix(kiro): route API-key connections to the Amazon Q region and auto-detect it at import - #16497

Merged
diegosouzapw merged 4 commits into
release/v3.8.52from
fix/port-pr-3185-kiro-api-key-amazon-q-region
Oct 17, 2026
Merged

diegosouzapw merged 4 commits into
release/v3.8.52from
fix/port-pr-3185-kiro-api-key-amazon-q-region

Conversation

@diegosouzapw

Copy link
Copy Markdown
Collaborator

Summary

  • Kiro API-key connections now send inference only to the regional Amazon Q host (q.<region>.amazonaws.com), us-east-1 included. Before this change, us-east-1 keys went to codewhisperer.us-east-1, which rejects API-key payloads with HTTP 400.
  • API-key import now checks the key against q.<region>/ListAvailableModels. Before, it only called ListAvailableProfiles, and AWS denies that call for every API key, so a dead or mistyped key imported "successfully". The new default region is auto: it tries us-east-1, then eu-central-1, and saves the first region that accepts the key.
  • The dashboard region field is now a select: Auto (recommended) / US East (N. Virginia) / Europe (Frankfurt).

Attribution

Thanks to @ryanngit for the original implementation.

Changes

  • open-sse/services/kiroRegion.ts: adds kiroApiKeyRuntimeHost() / resolveKiroApiKeyRegion(). The region must be us-east-1 or eu-central-1 (anything else falls back to us-east-1) because it goes into a hostname.
  • open-sse/executors/kiro.ts: api_key connections always use the single q.* URL. IdC, external IdP and social routing are unchanged (regression tests included).
  • src/lib/oauth/services/kiro.ts: validateApiKey(apiKey, "auto" | region) checks the key with ListAvailableModels (tokentype: API_KEY, 10 s timeout per region).
    • If every region returns 401/403, it throws Invalid Kiro API key … (HTTP 400).
    • If every region is unreachable or returns 5xx, it throws Kiro API key validation failed … (HTTP 500).
    • ListAvailableProfiles still runs afterwards, best-effort, to discover a profileArn (now with a timeout).
  • src/shared/validation/schemas/auth.ts: kiroApiKeyImportSchema.region only accepts auto | us-east-1 | eu-central-1 (default auto). It used to accept free text.
  • src/app/api/oauth/kiro/api-key/route.ts: defaults to auto.
  • src/lib/providers/validation/{specialtyInline,kiro}.ts: the provider test validates in the same region the executor routes to, and the runtime probe uses the q.* host.
  • src/shared/components/KiroAuthModal.tsx + 67 locale catalogs: replaces the old apiKeyRegionDescription key (it said "default: us-east-1", which is no longer true) with 4 new keys, translated in every locale (no __MISSING__ markers).
  • docs/guides/KIRO_SETUP.md: documents the new import and routing contract.
  • Existing tests updated to the new contract, with no asserts removed:
    • kiro-api-key-service, provider-validation-specialty (kiro cases): stubs now answer the ListAvailableModels proof first; call counts grow by one.
    • validation-kiro-split: the probe now targets q.us-east-1.
    • kiro-content-stall-15260, kiro-builderid-branded-gateway-profilearn-400: api_key us-east-1 now expects the q.us-east-1 URL.

Test plan

New tests, each run against the old code first and then after the change:

  • tests/unit/kiro-api-key-amazon-q-routing.test.ts
    • Old code: 3 behavioral failures (api_key us-east-1 hit codewhisperer.us-east-1, a bogus region did not fall back, 403 handling). The kiroApiKeyRuntimeHost tests did not load because the export did not exist yet.
    • After: ℹ tests 8 ℹ pass 8 ℹ fail 0.
  • tests/unit/kiro-api-key-validate-region.test.ts
    • Old code: ℹ tests 7 ℹ pass 1 ℹ fail 6.
    • After: ℹ pass 7 ℹ fail 0.
  • tests/unit/shared/components/KiroAuthModal.test.tsx (vitest UI config)
    • Old modal: Tests 1 failed | 4 passed (5).
    • After: Tests 5 passed (5).

Related suites (characterization-oauth, executor-kiro, every kiro-*.test.ts, kiroThinking, oauth-routes-manage-scope, provider-health-inconclusive-probes, validation-kiro-split, validation-specialty-inline-split, provider-validation-specialty): ℹ tests 463 ℹ pass 461 ℹ fail 2. Both failures are not caused by this PR:

  • gemini-web validator: 200 from gemini.google.com → valid also fails with the release/v3.8.52 source files swapped back in (ℹ pass 0 ℹ fail 1).
  • One #15260 timing test failed once under load; run alone it passed 3/3 (ℹ pass 12 ℹ fail 0).

Static checks:

  • npx eslint --suppressions-location config/quality/eslint-suppressions.json <changed files> → rc=0
  • npx prettier --check <changed files> → all formatted
  • npm run typecheck:core → clean
  • check:public-creds OK · check:route-validation:t06 PASS · check:any-budget:t11 PASS · check:docs-all rc=0
  • i18n:
    • i18n:check-keys: OK, 66 locales carry all 13747 keys
    • i18n:check-ratio: OK
    • i18n:check-new-keys: PASS
    • i18n:check-ui-coverage: PASS
    • check:ui-icu: PASS
    • vi completeness / key completeness / placeholder parity / duplicate-keys tests: ℹ tests 16 ℹ pass 16
  • check-pr-test-policy (PR mode): PASS · check:test-masking: OK, no weakening

live_check (hold-vps)

This changes how a real provider is routed and has not been tested against a real key yet (Hard Rule #18). Run these on the VPS before merging:

  1. Import a real Kiro API key with region auto through the dashboard. Expected: HTTP 200, and the saved providerSpecificData.region matches the key's home region.
  2. Send a chat request with that connection pinned in us-east-1. Expected: it streams from q.us-east-1.amazonaws.com/generateAssistantResponse, and the X-Amz-Target header the executor still sends is accepted on q.*.
  3. Repeat step 2 with an eu-central-1 key, if one is available.
  4. Import a revoked or mistyped key. Expected: HTTP 400 Invalid Kiro API key ….
  5. If a us-east-1 API key that works today on codewhisperer.us-east-1 fails on q.us-east-1, add codewhisperer back as a second candidate before merging.

⚠️ base-red inherited: #15306 — unit/vitest/integration/package-artifact gates on release/v3.8.52

…detect it at import

Long-lived Kiro API keys authenticate only on the regional Amazon Q host
(q.<region>.amazonaws.com). In us-east-1 OmniRoute sent them to
codewhisperer.us-east-1, which rejects API-key payloads with HTTP 400, and the
import validated keys through ListAvailableProfiles, which AWS denies for every
API key — so a dead or mistyped key imported "successfully".

- executor: api_key connections always target q.<region>/generateAssistantResponse
  (us-east-1 included); region restricted to us-east-1 / eu-central-1, falling back
  to us-east-1. IdC, external IdP and social routing are unchanged.
- import: validateApiKey probes q.<region>/ListAvailableModels (10 s timeout per
  region). "auto" (new default) tries us-east-1 then eu-central-1 and pins the first
  region that accepts the key; rejection everywhere fails the import with HTTP 400,
  upstream outages surface as 500. Profile discovery stays best-effort.
- schema: region is an allowlist (auto | us-east-1 | eu-central-1) instead of free text.
- provider test: validates in the exact region the executor routes to; the runtime
  probe uses the q.* host.
- dashboard: region select (Auto / US East / Frankfurt) with labels in all locales.

Co-authored-by: ryanngit <ryanngit@users.noreply.github.com>
Inspired-by: decolua/9router#3185
@diegosouzapw diegosouzapw added the hold-vps PR verde, merge aguardando validação live (release-drain) label Oct 13, 2026
@github-actions

Copy link
Copy Markdown
Contributor

CI Coverage Report

  • Coverage job: skipped
  • PR test policy: success

Coverage artifact was not available for this run.

Relocate the four Kiro API-key validator tests (updated for the Amazon Q region
catalog probe) out of the frozen provider-validation-specialty.test.ts into
tests/unit/kiro-validation-region-16497.test.ts. Every assertion is kept.
@diegosouzapw
diegosouzapw merged commit 0e4d056 into release/v3.8.52 Oct 17, 2026
41 of 56 checks passed
@diegosouzapw
diegosouzapw deleted the fix/port-pr-3185-kiro-api-key-amazon-q-region branch October 18, 2026 23:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

hold-vps PR verde, merge aguardando validação live (release-drain)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant