Skip to content

fix(kiro): read the whoami identity when kiro-cli appends its Profile block - #7455

Merged
lidge-jun merged 2 commits into
lidge-jun:devfrom
martinbcg:codex/kiro-whoami-trailing-profile
Oct 21, 2026
Merged

lidge-jun merged 2 commits into
lidge-jun:devfrom
martinbcg:codex/kiro-whoami-trailing-profile

Conversation

@martinbcg

@martinbcg martinbcg commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Importing a second user of the same Kiro organization (IAM Identity Center) profile still loses one account when the users have a profile selected in kiro-cli. #6981 keys these rows by profile ARN plus the email from same-session kiro-cli whoami --format json, but that email never arrives.

Once an Identity Center profile is selected, kiro-cli 2.32.0 prints a human-readable profile block on stdout after the JSON object:

{"accountType":"IamIdentityCenter","email":"<email>","region":"us-east-1","startUrl":"https://<org>.awsapps.com/start"}

Profile:
KiroProfile-us-east-1
arn:aws:codewhisperer:us-east-1:<account>:profile/<id>

readKiroCliIdentity passes all of stdout to JSON.parse, the parse throws, and the catch returns an empty identity. Every import of such a session therefore carries only the shared ARN:

Case (kiro-cli 2.32, profile selected) Before After
Import of a second org user after the first was imported the same way overwrites the first user's account new account
Add account for a second org user overwrites the first user's account new account
Import of a second org user when the first account already has an email refused with KiroUserIdentityUnavailableError new account

On a headless hub I hit the third row: the existing account had an email, so the import of the next organization user was refused. The first two rows are what happens when the existing account was itself imported through this output and so has no email; the new regression tests pin them and fail on the current code.

The fix reads only the leading top-level JSON object of the whoami output. The object has to start the output and end its line, so text on later lines is ignored. A second value on the same line still leaves the identity unread rather than picking one. Everything after parsing is unchanged: the narrow email/profile ARN fields, the session-switch revalidation (#993), and the identity rules from #6641. The profile ARN printed in the text block is deliberately not read. The SQLite profile state already supplies it, and parsing human-readable output for an ARN would contradict the narrow-shape rule from #993.

structure/providers-and-adapters.md records the parsing contract in the src/oauth/ row. This touches Kiro OAuth identity, which is an authentication surface, so it needs maintainer sponsorship per CONTRIBUTING.

Verification

  • Live check, kiro-cli 2.32.0 on Linux with an Identity Center profile selected: whoami --format json stdout has the shape above, and JSON.parse of it throws. The import of a second user of that profile is refused. With a temporary wrapper that kept only the first line of that output, ocx login kiro imported two more users of the profile as separate accounts, each with its email, and ocx account refresh kiro reported quota for all three.
  • bun test tests/providers/kiro/kiro-oauth.test.ts tests/providers/kiro/kiro-org-user-identity.test.ts: 82 pass, 0 fail. With src/oauth/kiro.ts reverted, the three new trailer tests fail (79 pass, 3 fail). The new same-line test passes both ways because it pins a boundary the fix must keep.
  • bun run typecheck: pass. After the docstring-only commit 33f6baf (it documents readKiroCliIdentity, the production function the docstring check flagged), the two Kiro test files were rerun (82 pass, 0 fail) and bun run typecheck passed again.
  • bun run structure:check: pass.
  • bun run privacy:scan: pass.
  • bun run test:changed with Bun 1.4.3 (OCX_TEST_RUNNER_BUN): 33020 pass, 40 skip, 0 fail across 1466 files.
  • bun run test with Bun 1.4.3 on macOS arm64: 51134 pass, 152 skip, 2 fail. Both failures also occur on upstream/dev without this change on the same machine. tests/claude-integration/claude-desktop-remote-hub.test.ts ("connected Desktop uses hub IDs across a cold restart (stored profile=false)") fails on both. tests/clients/link-ssh-argv-discovery.test.ts ("remote sh reports missing when all candidates are absent or fail --version") hits its 5 s timeout on both, and passes 12/12 when rerun on this branch.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed. The public docs already describe whoami email identity; this restores that documented behavior, so only the structure contract changed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults. Fixtures use synthetic identities and ARNs; parsing stays fail-closed.

Review readiness checklist

This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:

  • Required local validation passed; commands, results, and any full-suite exception are documented.

  • I pushed my PR to a recent dev commit (at most 10 behind; a maintainer may still ask for the exact tip before merge).

  • I resolved all correct Codex and CodeRabbit findings.

  • My PR is ready for review.

Summary by CodeRabbit

  • Bug Fixes

    • Improved Kiro CLI identity detection when JSON output is followed by human-readable profile information.
    • Preserves profile and email details from valid identity responses.
    • Rejects malformed or concatenated same-line JSON to avoid using incomplete identity data.
    • Maintains separate account identities during imports and account setup.
  • Documentation

    • Clarified how Kiro CLI identity output is interpreted.
  • Tests

    • Added coverage for profile blocks, malformed output, and account import flows.

… block

kiro-cli 2.32 prints a human-readable "Profile:" block on stdout after the
`whoami --format json` object once an IAM Identity Center profile is
selected. readKiroCliIdentity parsed the whole stream with JSON.parse, so
the parse failed and the user email was silently dropped. Without that
email, users of one organization profile collapse onto the same ARN
identity (lidge-jun#6641): an import of a second user overwrote the first user's
account, or, once that account had an email, was refused.

Read only the leading top-level JSON object, which must end its line.
Text on later lines is ignored; a second value on the same line still
leaves the identity unread.
@github-actions github-actions Bot added the intake: hygiene-blocked Deterministic PR hygiene checks failed label Oct 20, 2026
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Deterministic hygiene checks failed.

  • unsponsored_surface — This changes an authentication, workflow, release-automation, or dependency surface. MAINTAINERS.md requires security review for these; ask a maintainer to apply maintainer-sponsored once they have reviewed it. Paths: src/oauth/kiro.ts.

@github-actions github-actions Bot added the bug Something isn't working label Oct 20, 2026
@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

✅ READY

  • all PR quality gates passed; the review readiness checklist is complete.

Review readiness checklist

  • ✅ Required local validation passed; commands, results, and any full-suite exception are documented.
  • ✅ I pushed my PR to a recent dev commit (at most 10 behind; a maintainer may still ask for the exact tip before merge).
  • ✅ I resolved all correct Codex and CodeRabbit findings.
  • ✅ My PR is ready for review.

✅ 4/4 boxes ticked.

This pull request is already Ready for Review.
The review-ready label marks this PR as ready; review automation runs independently.
Maintainers: @lidge-jun @Ingwannu

@github-actions
github-actions Bot marked this pull request as draft October 20, 2026 20:49
@coderabbitai

coderabbitai Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: lidge-jun/opencodex/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: d82f95bd-d23a-4141-93b8-24bb96f1d6d9
📥 Commits

Reviewing files that changed from the base of the PR and between a5bd748 and 33f6baf.

📒 Files selected for processing: 1
  • src/oauth/kiro.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

📝 Walkthrough

Kiro identity parsing now reads a leading top-level JSON object from kiro-cli whoami output when it ends at a line boundary or end of input. Tests cover trailing profile text, concatenated JSON values, and account import flows.

Changes: Kiro identity parsing

Layer / File(s) Summary
Parse leading identity JSON and validate flows
src/oauth/kiro.ts, tests/providers/kiro/kiro-oauth.test.ts, tests/providers/kiro/kiro-org-user-identity.test.ts, structure/providers-and-adapters.md
readKiroCliIdentity now parses a leading top-level JSON object when it ends at a line boundary or end of input. Tests cover trailing profile text, concatenated JSON values, and separate account identities in re-import and add-account flows. The documentation describes the parsing rule.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 33f6b

The Kiro identity parsing change is ready to merge.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 3 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the primary change: fixing Kiro identity parsing when kiro-cli appends a Profile block to whoami output.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches: 💡 1
🛠️ Fix failing CI checks: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Ingwannu Ingwannu left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Manual authentication-boundary review at 33f6bafb235223b544df41414016fd0994d38f6f:

The new parser consumes only a leading JSON object, respects quoted/escaped delimiters, requires a line boundary, and leaves malformed/nonzero/throwing CLI output on the existing unread-identity path. It does not parse the human-readable profile ARN, mint identity from trailer text, change credential destinations, or alter account selection/persistence rules. Email normalization, narrow ARN validation and the existing same-session/session-switch fences remain in their original owner after parsing.

Independently ran bun test tests/providers/kiro/kiro-oauth.test.ts tests/providers/kiro/kiro-org-user-identity.test.ts on Linux/Bun 1.4.3 under fresh homes and hard resource limits: 82 passed, 0 failed. These include org-user isolation, add/import identity, invalid output and the new Profile trailer cases; no real Kiro login or account was touched. I am applying maintainer-sponsored on this reviewed scope. This records a completed manual boundary review, not a CI waiver, whole-branch approval, live acceptance or merge decision. Functional CI execution was separately approved and must actually finish.

@Ingwannu Ingwannu added the maintainer-sponsored Maintainer sponsors this change to an auth, workflow, release, or dependency surface label Oct 21, 2026
@github-actions github-actions Bot added review-ready and removed intake: hygiene-blocked Deterministic PR hygiene checks failed labels Oct 21, 2026
@github-actions
github-actions Bot marked this pull request as ready for review October 21, 2026 06:00

@Ingwannu Ingwannu left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved exact head 33f6bafb235223b544df41414016fd0994d38f6f against current dev 12025981e5a3, following the explicit authentication-boundary review already recorded on this head. Independent capped/fresh-home OAuth and organization-identity suites passed 82 tests, 0 failures. Actual Cross-platform CI, Catalog contracts and React Doctor now completed successfully, and the author-owned readiness gate has moved this unchanged head out of Draft with no unresolved review threads or outstanding change request. The bounded leading JSON object is parsed with string/escape awareness; trailing human Profile output is not treated as identity authority, invalid/nonzero/throwing results retain the existing unread-identity path, and validation/account-selection/persistence/destination boundaries remain intact. No live Kiro account or Codex Security scan was used. This approval is not a merge/release.

@lidge-jun
lidge-jun merged commit b8a9013 into lidge-jun:dev Oct 21, 2026
42 of 47 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working maintainer-sponsored Maintainer sponsors this change to an auth, workflow, release, or dependency surface review-ready

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants