Skip to content

Show AWS profile in EKS auth error hints - #1725

Merged
nadaverell merged 2 commits into
skyhook-io:mainfrom
feiming:eks-auth-profile-hint
Sep 11, 2026
Merged

nadaverell merged 2 commits into
skyhook-io:mainfrom
feiming:eks-auth-profile-hint

Conversation

@feiming

@feiming feiming commented Sep 11, 2026 •

Copy link
Copy Markdown
Contributor

When Radar cannot connect to an EKS cluster due to credential failure, the suggested aws sso login command now includes --profile <name> when the kubeconfig exec block pins a profile via the AWS_PROFILE env var or a --profile argument.

aws eks update-kubeconfig always injects the profile as AWS_PROFILE in the exec env block, so this covers the common real-world case.

Description

Brief description of the changes in this PR.

Type of change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

How has this been tested?

Describe the tests you ran to verify your changes.

  • Tested locally with minikube/kind
  • Tested against a remote cluster
  • Added/updated unit tests

Checklist

  • My code follows the project's coding standards
  • I have performed a self-review of my code
  • I have added comments where necessary
  • My changes generate no new warnings
  • Any dependent changes have been merged

Related issues

Fixes #(issue number)


Note

Low Risk
User-facing hint text and read-only kubeconfig parsing; shell interpolation is gated by an allowlist with tests for hostile profiles.

Overview
EKS connection errors now suggest AWS CLI commands with the same profile the kubeconfig exec block uses, instead of assuming the terminal’s default profile.

The backend adds awsProfile on each context by parsing aws / aws-iam-authenticator exec auth (--profile or AWS_PROFILE). For the active context it prefers the snapshotted kubeconfig used at client creation so the hint matches live credentials. The UI waits for contexts to load, then threads awsProfile into EKS auth, auth-rejected, and timeout hints (aws sso login, aws eks update-kubeconfig, STS/describe diagnostics).

New isShellSafeAWSProfile / awsProfileFlag allow slash-separated SSO profile names but omit --profile when the value looks hostile, matching existing context-name safety for terminal-run commands.

Reviewed by Cursor Bugbot for commit 713af24. Bugbot is set up for automated code reviews on this repo. Configure here.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Include AWS profiles in EKS authentication recovery hints

âœĻ Enhancement 🧊 Tests 🕐 20-40 Minutes

Grey Divider

AI Description

â€Ē Extract pinned AWS profiles from EKS kubeconfig exec plugins and expose them with contexts.
â€Ē Include safe profile flags in EKS SSO recovery commands across connection failures.
â€Ē Cover AWS profile precedence, plugin filtering, and shell-safe profile validation.
Diagram

graph TD
  K["Kubeconfig Exec"] --> E["Profile Extractor"] --> C["Context API"] --> T["UI Context Type"] --> H["Error Hint Selector"] --> A["AWS SSO Command"]
Loading
High-Level Assessment

Backend extraction is the best approach because the Go layer already owns parsed kubeconfig data, while the UI only needs explicit context metadata. Client-side kubeconfig parsing would duplicate sensitive configuration logic, and generic shell validation would incorrectly reject valid slash-separated AWS profiles; the dedicated validator appropriately limits interpolation risk.

Files changed (6) +196 / -19

Enhancement (4) +77 / -18
client.goExpose AWS exec-plugin profiles in context metadata +48/-5

Expose AWS exec-plugin profiles in context metadata

â€Ē Adds AWS profile extraction for 'aws' and 'aws-iam-authenticator' exec plugins, preferring '--profile' over 'AWS_PROFILE'. Populates the optional profile for contexts loaded through both isolated registries and single-file kubeconfigs.

internal/k8s/client.go

core.tsAdd AWS profile to shared context type +3/-0

Add AWS profile to shared context type

â€Ē Extends 'ContextInfo' with the optional 'awsProfile' metadata returned for EKS contexts that pin a profile.

packages/k8s-ui/src/types/core.ts

ConnectionErrorView.tsxAdd AWS profiles to EKS SSO recovery commands +17/-13

Add AWS profiles to EKS SSO recovery commands

â€Ē Passes matched context profile metadata into connection-hint selection. Authentication, rejected-authentication, and timeout guidance now appends a validated '--profile' flag to 'aws sso login'.

web/src/components/ConnectionErrorView.tsx

shell-safe.tsValidate AWS profiles for safe command interpolation +9/-0

Validate AWS profiles for safe command interpolation

â€Ē Adds a dedicated AWS profile validator that permits slash-separated SSO profile paths while excluding unsafe shell syntax and option-like leading dashes.

web/src/utils/shell-safe.ts

Tests (2) +119 / -1
client_test.goTest AWS profile extraction behavior +94/-0

Test AWS profile extraction behavior

â€Ē Adds table-driven coverage for nil configuration, unsupported plugins, environment profiles, both argument forms, precedence, missing values, authenticator support, and absolute command paths.

internal/k8s/client_test.go

shell-safe.test.tsTest shell-safe AWS profile validation +25/-1

Test shell-safe AWS profile validation

â€Ē Verifies acceptance of common and slash-separated AWS profile names while rejecting metacharacters, whitespace, leading dashes, and absent values.

web/src/utils/shell-safe.test.ts

@qodo-code-review

qodo-code-review Bot commented Sep 11, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Two profile comments repeat the code ✓ Resolved 📘 Rule violation ⚙ Maintainability
Description
The doc comment above extractAWSProfile restates that the function reads --profile or
AWS_PROFILE, while the inline comment restates the immediately following plugin-name check. Both
comments describe behavior already evident from the function name and conditions, so they add no
rationale or hidden constraint for later changes.
Code

internal/k8s/client.go[R1470-1471]

+// extractAWSProfile returns the AWS profile from an exec block's --profile
+// argument or AWS_PROFILE environment variable, or empty string if not set.
Relevance

●●● Strong

Explicit repository rule rejects comments that merely restate obvious code behavior.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Compliance rule 3036542 prohibits newly added explanatory comments that only restate obvious code
behavior. The function declaration and its argument/environment checks directly express the behavior
summarized at lines 1470-1471, while line 1477 directly narrates the command-name condition below
it.

Rule 3036542: Avoid explanatory comments that restate obvious code behavior
internal/k8s/client.go[1470-1477]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Two comments in `extractAWSProfile` merely translate the function name and immediately following conditions into prose without documenting intent, rationale, or a hidden constraint.

## Fix Focus Areas
- internal/k8s/client.go[1470-1477]

## Recommended Fix
Remove the function-level behavior summary and the `Only inspect known AWS exec plugins` comment. Preserve the separate precedence comment because it explains compatibility with AWS CLI behavior.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Login hints omit profiles while loading 🐞 Bug ≡ Correctness
Description
ConnectionErrorView destructures only data from useContexts, so matchedContext?.awsProfile
becomes undefined and the command is rendered without the profile before the query resolves or after
it fails. On an initial connection failure or contexts-endpoint error, users can copy or run the
ambient-profile command even though the kubeconfig pins another account.
Code

web/src/components/ConnectionErrorView.tsx[R350-353]

  const { data: contexts } = useContexts()
-  const originalContext = contexts?.find((context) => context.name === connection.context)?.originalName
-  const commandInfo = selectConnectionHints(connection.errorType, connection.context || '', originalContext)
+  const matchedContext = contexts?.find((context) => context.name === connection.context)
+  const originalContext = matchedContext?.originalName
+  const commandInfo = selectConnectionHints(connection.errorType, connection.context || '', originalContext, matchedContext?.awsProfile)
Relevance

●●● Strong

Matches accepted precedent where unresolved API data produced an unsafe fallback terminal command.

PR-#881

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The contexts hook is asynchronous and may return undefined data, but command generation immediately
treats the missing profile as an instruction to omit --profile; the resulting command remains
runnable and copyable. Past PR #881 demonstrates the same failure pattern of treating an unresolved
API response as a valid fallback while constructing a terminal command.

web/src/components/ConnectionErrorView.tsx[350-353]
web/src/api/client.ts[6093-6099]
web/src/components/ConnectionErrorView.tsx[369-381]
PR-#881

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Profile-aware AWS commands silently fall back to the terminal's ambient profile while the contexts query is unresolved or has failed.

## Fix Focus Areas
- web/src/components/ConnectionErrorView.tsx[344-353]
- web/src/components/ConnectionErrorView.tsx[369-381]
- web/src/api/client.ts[6093-6099]

## Recommended Fix
Consume the contexts query's loading and error states and do not expose an unqualified EKS login command until profile metadata has resolved successfully. If the query fails, show that the profile could not be determined rather than silently presenting a command that may target the wrong account.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Login hints use a profile not in use ✓ Resolved 🐞 Bug ≡ Correctness
Description
GetAvailableContexts extracts AWSProfile from the newly refreshed per-file config, while the
active REST client keeps the exec configuration captured in activeSourceConfig. When an active
kubeconfig file is rewritten with a different profile before an authentication failure, the UI
suggests logging into the new profile even though retries still invoke the old one.
Code

internal/k8s/client.go[R1595-1597]

+			var awsProfile string
+			if ai := cfg.AuthInfos[ctx.AuthInfo]; ai != nil {
+				awsProfile = extractAWSProfile(ai)
Relevance

●● Moderate

Plausible stale-profile correctness issue, but no closely matching historical precedent confirms
expected source selection.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Registry refresh publishes newly loaded file configurations, and the added extraction reads directly
from those configurations. The active client and its source snapshot are only replaced during
initialization or an explicit context switch, while the UI uses the refreshed contexts response for
its command.

internal/k8s/client.go[1536-1554]
internal/k8s/client.go[1591-1607]
internal/k8s/client.go[1794-1805]
web/src/components/ConnectionErrorView.tsx[350-353]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Context enumeration reads the profile from refreshed kubeconfig metadata even when the active Kubernetes client still uses an older exec configuration.

## Fix Focus Areas
- internal/k8s/client.go[1536-1567]
- internal/k8s/client.go[1591-1607]
- internal/k8s/client.go[1631-1644]

## Recommended Fix
For the current context, derive `AWSProfile` from the immutable configuration used to create the active client, such as a safely snapshotted `activeSourceConfig`, rather than the refreshed registry entry. Continue using refreshed per-file metadata for inactive contexts, or rebuild the active client whenever its source file changes so both sources remain synchronized.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
✅ Compliance rules (platform): 44 rules
✅ Cross-repo context — repo relationships
  Explored: repo: skyhook-dev/radar-hub-web (sha: d58deff3)
Review mode: ⚖ïļ Balanced: This is a behavior-changing cross-layer feature spanning backend kubeconfig parsing, frontend command construction, and shell-safety validation, so it warrants a complete single-pass review.

Grey Divider

Tip of the day
ðŸ’Ą Did you know, you can switch off images and animations for a plain-text comment

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread internal/k8s/client.go Outdated
Comment thread internal/k8s/client.go
Comment on lines +350 to +353
const { data: contexts } = useContexts()
const originalContext = contexts?.find((context) => context.name === connection.context)?.originalName
const commandInfo = selectConnectionHints(connection.errorType, connection.context || '', originalContext)
const matchedContext = contexts?.find((context) => context.name === connection.context)
const originalContext = matchedContext?.originalName
const commandInfo = selectConnectionHints(connection.errorType, connection.context || '', originalContext, matchedContext?.awsProfile)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

2. Login hints omit profiles while loading 🐞 Bug ≡ Correctness

ConnectionErrorView destructures only data from useContexts, so matchedContext?.awsProfile
becomes undefined and the command is rendered without the profile before the query resolves or after
it fails. On an initial connection failure or contexts-endpoint error, users can copy or run the
ambient-profile command even though the kubeconfig pins another account.
Agent Prompt
## Issue description
Profile-aware AWS commands silently fall back to the terminal's ambient profile while the contexts query is unresolved or has failed.

## Fix Focus Areas
- web/src/components/ConnectionErrorView.tsx[344-353]
- web/src/components/ConnectionErrorView.tsx[369-381]
- web/src/api/client.ts[6093-6099]

## Recommended Fix
Consume the contexts query's loading and error states and do not expose an unqualified EKS login command until profile metadata has resolved successfully. If the query fails, show that the profile could not be determined rather than silently presenting a command that may target the wrong account.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@feiming
feiming force-pushed the eks-auth-profile-hint branch 2 times, most recently from 947328a to 961d11c Compare September 11, 2026 10:58
When Radar cannot connect to an EKS cluster due to credential failure,
the suggested `aws sso login` command now includes `--profile <name>`
when the kubeconfig exec block pins a profile via the AWS_PROFILE env
var or a --profile argument.

`aws eks update-kubeconfig` always injects the profile as AWS_PROFILE
in the exec env block, so this covers the common real-world case.
@feiming
feiming force-pushed the eks-auth-profile-hint branch from 961d11c to deb6575 Compare September 11, 2026 11:03
`aws eks update-kubeconfig` overwrites the user entry and only writes the
AWS_PROFILE env when invoked with --profile, so the profile-blind fallback
would strip the pin the login hint had just surfaced. The auth-rejected
diagnostic likewise inspected the terminal's ambient profile while the
login command next to it targeted the pinned one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fh426ozpfnu7Hq2sHeyt9n

@nadaverell nadaverell left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the PR!
looks good

@nadaverell
nadaverell merged commit eb2f39b into skyhook-io:main Sep 11, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants