feat: Add OAuth2 PKCE browser-based auth for AWS user/root identities#2148
feat: Add OAuth2 PKCE browser-based auth for AWS user/root identities#2148
Conversation
Dependency Review✅ No vulnerabilities or license issues found.Snapshot WarningsEnsure that dependencies are being submitted on PR branches and consider enabling retry-on-snapshot-warnings. See the documentation for more information and troubleshooting advice. Scanned FilesNone |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b2480c594b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if err != nil { | ||
| // Try browser webflow as final fallback when no long-lived credentials available. | ||
| if i.isWebflowEnabled() { | ||
| webflowCreds, webflowErr := i.resolveCredentialsViaWebflow(ctx) | ||
| if webflowErr == nil { |
There was a problem hiding this comment.
Restrict webflow fallback to missing-credential errors
Authenticate now attempts browser webflow for any error from resolveLongLivedCredentials, including hard configuration errors (for example, partially specified access_key_id/secret_access_key). That means an invalid identity config can be silently bypassed by a browser login, masking misconfiguration and potentially authenticating to a different AWS principal than intended; webflow should only be used when credentials are unavailable, while validation/config errors should be returned immediately.
Useful? React with 👍 / 👎.
| if err != nil { | ||
| // Clear expired/invalid refresh token. | ||
| i.deleteRefreshCache() | ||
| return nil, fmt.Errorf("%w: %w", errUtils.ErrWebflowRefreshFailed, err) |
There was a problem hiding this comment.
Avoid deleting refresh cache on transient token errors
The refresh cache is deleted on every exchangeRefreshToken failure, but that call can fail for transient reasons (network interruption, temporary AWS signin outage, timeout) that do not invalidate the refresh token. Deleting the cache in those cases forces an unnecessary full browser re-authentication and can break unattended runs that rely on refresh-only auth; only invalidate cached tokens for definitive invalid-token responses.
Useful? React with 👍 / 👎.
pkg/auth/identities/aws/webflow.go
Outdated
| errCh := make(chan error, 1) | ||
|
|
||
| go func() { | ||
| if formErr := form.Run(); formErr != nil { |
There was a problem hiding this comment.
Replace TUI prompt in non-interactive webflow path
This branch is explicitly the non-interactive fallback (browserWebflow calls it when webflowIsInteractive() is false), but it still runs a Huh TUI form for manual code entry. In no-TTY contexts, that prompt cannot be rendered and the flow exits with a prompt error instead of accepting manual input, so the advertised non-interactive auth path is not usable.
Useful? React with 👍 / 👎.
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds a browser-based AWS OAuth2 PKCE "webflow" fallback for aws/user authentication, new webflow error sentinels, comprehensive tests, a blog post, and a roadmap update; integrates webflow as a conditional fallback when long-lived credential resolution fails. Changes
Sequence DiagramsequenceDiagram
participant User as User
participant Client as Atmos Client
participant Browser as Browser
participant Auth as AWS Auth Server
participant Callback as Local Callback Server
participant Token as AWS Token Endpoint
User->>Client: authenticate()
Client->>Client: generate PKCE verifier/challenge & state
Client->>Browser: open or display authorization URL
Browser->>Auth: request authorization (code_challenge & state)
Auth->>Browser: redirect to callback with code & state
Browser->>Callback: GET /callback?code=...&state=...
Callback->>Client: deliver code & state
Client->>Token: POST exchange (code + verifier) for tokens
Token->>Client: return access_token, refresh_token, expiry
Client->>Client: cache refresh_token, convert tokens to AWS creds
Client->>User: return AWS credentials
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
|
Warning Release Documentation RequiredThis PR is labeled
|
1 similar comment
|
Warning Release Documentation RequiredThis PR is labeled
|
Codecov Report❌ Patch coverage is
❌ Your patch check has failed because the patch coverage (66.51%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #2148 +/- ##
========================================
Coverage 77.22% 77.23%
========================================
Files 1017 1021 +4
Lines 96260 96932 +672
========================================
+ Hits 74337 74863 +526
- Misses 17729 17850 +121
- Partials 4194 4219 +25
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
|
Warning Release Documentation RequiredThis PR is labeled
|
|
Warning Release Documentation RequiredThis PR is labeled
|
2930ea2 to
84caada
Compare
|
Warning Release Documentation RequiredThis PR is labeled
|
1 similar comment
|
Warning Release Documentation RequiredThis PR is labeled
|
…date - Skip TestCacheFilePermissions on Windows (NTFS doesn't support Unix perms) - Add changelog blog post for browser-based auth feature - Update roadmap: mark browser-based auth milestone as shipped (PR #2148) - Update auth initiative progress from 85% to 92% Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
💥 This pull request now has conflicts. Could you fix it @Benbentwo? 🙏 |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (5)
pkg/auth/identities/aws/webflow_test.go (2)
637-653: Context cancellation test usestime.Sleep— consider deterministic approach.The test at line 648 uses
time.Sleep(100 * time.Millisecond)to wait for server shutdown. This can be flaky on slow CI runners.Consider polling with a timeout or using a done channel from the server shutdown.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pkg/auth/identities/aws/webflow_test.go` around lines 637 - 653, The test TestCallbackServer_ContextCancellation uses time.Sleep to wait for shutdown; replace this with a deterministic wait by either updating startCallbackServer to return a shutdown completion channel (e.g., done chan struct{}) and waiting on it after cancel(), or implement a polling loop that repeatedly attempts a connection to addr/webflowCallbackPath with a short backoff until it fails or a timeout is reached; update the test to wait on that done channel or the polling loop instead of time.Sleep so CI flakes are avoided.
1-26: MissingTestMainwith_ATMOS_TEST_EXIT_ONEgate.Per coding guidelines, test packages should include a
TestMainwith the environment gate check for cross-platform subprocess testing. If this package has subprocess tests elsewhere, add the gate; otherwise, add a minimalTestMainfor future-proofing.Add TestMain
func TestMain(m *testing.M) { if os.Getenv("_ATMOS_TEST_EXIT_ONE") == "1" { os.Exit(1) } os.Exit(m.Run()) }As per coding guidelines: "Add
TestMainwith_ATMOS_TEST_EXIT_ONEenvironment gate check for cross-platform subprocess testing."🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pkg/auth/identities/aws/webflow_test.go` around lines 1 - 26, Add a TestMain function to the aws test package (in webflow_test.go) that checks the _ATMOS_TEST_EXIT_ONE environment gate and exits 1 when it's set, otherwise runs the test suite; specifically implement func TestMain(m *testing.M) { if os.Getenv("_ATMOS_TEST_EXIT_ONE") == "1" { os.Exit(1) } os.Exit(m.Run()) } so the package-level tests (including any subprocess tests) honor the cross-platform gate—ensure you import os at the top if not already referenced.pkg/auth/identities/aws/webflow.go (3)
98-104: Global mutable variables may cause race conditions in tests.The package-level variables
defaultHTTPClient,openURLFunc,webflowIsTTYFunc, anddisplayWebflowDialogFuncare mutated during tests. This can cause data races if tests run in parallel.Consider injecting these dependencies through functional options or struct fields rather than package-level variables. Alternatively, ensure tests that mutate these use
t.Setenvpatterns with proper cleanup and avoidt.Parallel().🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pkg/auth/identities/aws/webflow.go` around lines 98 - 104, The package-level mutable variables defaultHTTPClient, openURLFunc, webflowIsTTYFunc, and displayWebflowDialogFunc can cause race conditions in parallel tests; refactor to inject them via the Webflow object (or constructor functional options) instead of globals: add fields like httpClient, openURL, isTTY, and displayDialog to the Webflow struct, update NewWebflow (or create NewWebflowWithOptions) to accept overrides, and update all uses (tokenExchange, Start/Flow methods) to reference those instance fields rather than the package globals so tests can provide isolated mocks without mutating package state.
726-731:webflowIsInteractiveis defined but never used.This function checks
viper.GetBool("force-tty")but the code useswebflowIsTTYFuncdirectly. Consider using this function or removing it.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pkg/auth/identities/aws/webflow.go` around lines 726 - 731, The function webflowIsInteractive currently duplicates logic and is unused; either replace direct uses of webflowIsTTYFunc with webflowIsInteractive so the force-tty viper override is respected (search for webflowIsTTYFunc usages and switch them to webflowIsInteractive), or delete webflowIsInteractive to remove dead code and ensure no remaining references to it exist; pick the option that preserves intended behavior (prefer using webflowIsInteractive if force-tty should take precedence).
838-847: Recursive command pattern risks unbounded stack growth.The
checkResultmethod uses recursive polling that calls itself every 100ms. While unlikely to cause issues in practice given the 5-minute timeout, this pattern accumulates stack frames. Consider using a loop-based approach ortea.Tick.Alternative using tea.Tick
func (m webflowSpinnerModel) checkResult() tea.Cmd { - return func() tea.Msg { - select { - case res := <-m.tokenCh: - return webflowSpinnerTokenResult{resp: res.resp, err: res.err} - case <-time.After(100 * time.Millisecond): - return m.checkResult()() - } - } + return tea.Tick(100*time.Millisecond, func(t time.Time) tea.Msg { + select { + case res := <-m.tokenCh: + return res + default: + return nil // Will trigger another tick via Init batch. + } + }) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pkg/auth/identities/aws/webflow.go` around lines 838 - 847, The current webflowSpinnerModel.checkResult function uses recursion to poll tokenCh and reschedules itself via m.checkResult(), which can build up stack frames; replace the recursive pattern with an iterative/tick-based command: inside checkResult use tea.Tick or a loop/ticker to wait 100ms intervals and select on m.tokenCh and the ticker (or tea.Tick's channel), then return a webflowSpinnerTokenResult when a value arrives (resp/err from tokenCh) and stop the ticker; ensure the function returns a single tea.Cmd that schedules repeated ticks rather than calling checkResult recursively.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@pkg/auth/identities/aws/webflow.go`:
- Around line 325-326: In waitForCallbackWithSpinner, the context created with
context.WithTimeout (ctx, webflowCallbackTimeout) assigns cancel but never
guaranteed to be called on the success path; add a defer cancel() immediately
after ctx, cancel := ... so the timeout context is always cleaned up (it's safe
to later pass cancel into the model/goroutine and call it there as well). This
ensures cancel is invoked if prog.Run() returns nil without relying on other
code paths.
- Around line 269-282: The Validate callback on the NewInput for "Authorization
code" currently wraps the empty-field message with the sentinel
errUtils.ErrWebflowAuthFailed; change the Validate implementation to return a
plain user-facing error (e.g., "authorization code is required") without
wrapping the sentinel, so the message is clean for UI. Keep the sentinel
wrapping at the higher-level form/error handling site that already wraps form
errors (the place that inspects the form error and wraps with
errUtils.ErrWebflowAuthFailed), leaving that wrapping logic unchanged. Ensure
you update the Validate closure that references authCode inside
huh.NewInput(...) to return an unwrapped error.
---
Nitpick comments:
In `@pkg/auth/identities/aws/webflow_test.go`:
- Around line 637-653: The test TestCallbackServer_ContextCancellation uses
time.Sleep to wait for shutdown; replace this with a deterministic wait by
either updating startCallbackServer to return a shutdown completion channel
(e.g., done chan struct{}) and waiting on it after cancel(), or implement a
polling loop that repeatedly attempts a connection to addr/webflowCallbackPath
with a short backoff until it fails or a timeout is reached; update the test to
wait on that done channel or the polling loop instead of time.Sleep so CI flakes
are avoided.
- Around line 1-26: Add a TestMain function to the aws test package (in
webflow_test.go) that checks the _ATMOS_TEST_EXIT_ONE environment gate and exits
1 when it's set, otherwise runs the test suite; specifically implement func
TestMain(m *testing.M) { if os.Getenv("_ATMOS_TEST_EXIT_ONE") == "1" {
os.Exit(1) } os.Exit(m.Run()) } so the package-level tests (including any
subprocess tests) honor the cross-platform gate—ensure you import os at the top
if not already referenced.
In `@pkg/auth/identities/aws/webflow.go`:
- Around line 98-104: The package-level mutable variables defaultHTTPClient,
openURLFunc, webflowIsTTYFunc, and displayWebflowDialogFunc can cause race
conditions in parallel tests; refactor to inject them via the Webflow object (or
constructor functional options) instead of globals: add fields like httpClient,
openURL, isTTY, and displayDialog to the Webflow struct, update NewWebflow (or
create NewWebflowWithOptions) to accept overrides, and update all uses
(tokenExchange, Start/Flow methods) to reference those instance fields rather
than the package globals so tests can provide isolated mocks without mutating
package state.
- Around line 726-731: The function webflowIsInteractive currently duplicates
logic and is unused; either replace direct uses of webflowIsTTYFunc with
webflowIsInteractive so the force-tty viper override is respected (search for
webflowIsTTYFunc usages and switch them to webflowIsInteractive), or delete
webflowIsInteractive to remove dead code and ensure no remaining references to
it exist; pick the option that preserves intended behavior (prefer using
webflowIsInteractive if force-tty should take precedence).
- Around line 838-847: The current webflowSpinnerModel.checkResult function uses
recursion to poll tokenCh and reschedules itself via m.checkResult(), which can
build up stack frames; replace the recursive pattern with an
iterative/tick-based command: inside checkResult use tea.Tick or a loop/ticker
to wait 100ms intervals and select on m.tokenCh and the ticker (or tea.Tick's
channel), then return a webflowSpinnerTokenResult when a value arrives (resp/err
from tokenCh) and stop the ticker; ensure the function returns a single tea.Cmd
that schedules repeated ticks rather than calling checkResult recursively.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 6b2a56f2-d407-4967-a76f-d7347790acae
📒 Files selected for processing (4)
pkg/auth/identities/aws/webflow.gopkg/auth/identities/aws/webflow_test.gowebsite/blog/2026-03-24-browser-based-auth-aws-user.mdxwebsite/src/data/roadmap.js
… (ATMOS-162) Implement browser-based authentication as a third-tier fallback for aws/user identity. When YAML credentials and keychain credentials are unavailable, the identity initiates an interactive OAuth2 PKCE flow via AWS signin service, providing seamless browser-based login for IAM users and root accounts. Refresh tokens enable 12-hour sessions with automatic credential refresh every 15 minutes. Non-interactive mode prompts for manual code entry. Credentials are cached in XDG directories following SSO patterns. - Add webflow_enabled config option (default: true) - Implement OAuth2 PKCE with AWS signin client arn:aws:signin:::devtools/same-device - Support interactive (browser + spinner) and non-interactive (manual code) flows - Cache refresh tokens to XDG cache for 12-hour session reuse - Add webflow entry point in Authenticate() after long-lived creds fail - Include 27 comprehensive unit tests with >80% coverage Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Add 25+ new tests covering processTokenResponse, resolveCredentialsViaWebflow refresh path, browserWebflow dispatch, waitForCallbackSimple, callTokenEndpoint error paths, spinner model methods, refresh cache edge cases, and end-to-end interactive flow. Introduce mockable function variables (openURLFunc, webflowIsTTYFunc, displayWebflowDialogFunc) following existing PromptCredentialsFunc pattern for testability. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…date - Skip TestCacheFilePermissions on Windows (NTFS doesn't support Unix perms) - Add changelog blog post for browser-based auth feature - Update roadmap: mark browser-based auth milestone as shipped (PR #2148) - Update auth initiative progress from 85% to 92% Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
31a0ecf to
82a4759
Compare
- Guard webflow fallback against invalid config errors (only trigger on missing credentials) - Add transient vs definitive error classification for refresh token cache - Replace huh TUI form with bufio.Scanner for non-interactive code entry - Add defer cancel() for context.WithTimeout in spinner - Add tests for isTransientTokenError and transient-error cache preservation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
pkg/auth/identities/aws/webflow_test.go (1)
1832-1839: Consider using mockgen instead of manual mock.The
mockHTTPClientis a manual mock. Guidelines prefer generated mocks viago.uber.org/mock/mockgenwith//go:generatedirectives for consistency across the codebase.That said, this mock is minimal and self-contained. Low priority if you'd rather keep it simple.
♻️ Suggested approach
Add a generate directive near the interface definition in
webflow.go://go:generate mockgen -destination=mock_http_client_test.go -package=aws github.com/cloudposse/atmos/pkg/auth/identities/aws HTTPClientThen remove the manual mock and use the generated one.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pkg/auth/identities/aws/webflow_test.go` around lines 1832 - 1839, The test defines a manual mock type mockHTTPClient for the HTTPClient interface in webflow tests; replace it with a generated mock to follow project conventions: add a //go:generate mockgen directive next to the HTTPClient interface in webflow.go (e.g., generating mock_http_client_test.go in package aws for github.com/cloudposse/atmos/pkg/auth/identities/aws HTTPClient), run mockgen to produce the mock, remove the manual mockHTTPClient type and its Do method from webflow_test.go, and update tests to use the generated mock (named by mockgen) instead of mockHTTPClient.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@pkg/auth/identities/aws/webflow_test.go`:
- Around line 645-654: Replace the brittle time.Sleep(100 * time.Millisecond)
after cancel() with a retry loop that polls until the server refuses connections
or a context deadline elapses; repeatedly attempt the same
http.Get(fmt.Sprintf("http://%s%s", addr, webflowCallbackPath)) (or a TCP dial
to addr) with short intervals (e.g., 10–50ms) and fail the test if the timeout
is reached, then assert that the final attempt returns an error. This change
touches the test flow around cancel(), the subsequent sleep, and the
http.Get/assert.Error lines so search for cancel(), time.Sleep, and the
http.Get(fmt.Sprintf("http://%s%s", addr, webflowCallbackPath)) call to replace
with the retry-with-timeout logic.
In `@website/blog/2026-03-24-browser-based-auth-aws-user.mdx`:
- Line 4: Replace the top-matter authors field value "authors: [atmos]" with the
actual person's name listed in website/blog/authors.yml (use the corresponding
key for the blog author), i.e., update the authors: array to include the real
author string from authors.yml instead of the organization token "atmos" so the
post credits the correct individual.
---
Nitpick comments:
In `@pkg/auth/identities/aws/webflow_test.go`:
- Around line 1832-1839: The test defines a manual mock type mockHTTPClient for
the HTTPClient interface in webflow tests; replace it with a generated mock to
follow project conventions: add a //go:generate mockgen directive next to the
HTTPClient interface in webflow.go (e.g., generating mock_http_client_test.go in
package aws for github.com/cloudposse/atmos/pkg/auth/identities/aws HTTPClient),
run mockgen to produce the mock, remove the manual mockHTTPClient type and its
Do method from webflow_test.go, and update tests to use the generated mock
(named by mockgen) instead of mockHTTPClient.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: e645c46d-8836-4ab2-93f4-0ca3d80b36a7
📒 Files selected for processing (6)
errors/errors.gopkg/auth/identities/aws/user.gopkg/auth/identities/aws/webflow.gopkg/auth/identities/aws/webflow_test.gowebsite/blog/2026-03-24-browser-based-auth-aws-user.mdxwebsite/src/data/roadmap.js
✅ Files skipped from review due to trivial changes (2)
- pkg/auth/identities/aws/user.go
- pkg/auth/identities/aws/webflow.go
🚧 Files skipped from review as they are similar to previous changes (2)
- errors/errors.go
- website/src/data/roadmap.js
- Replace time.Sleep with require.Eventually for server shutdown test - Use actual author (Benbentwo) instead of generic 'atmos' in blog post Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@website/blog/2026-03-24-browser-based-auth-aws-user.mdx`:
- Line 23: Replace the hyphenation of "signin" with "sign-in" in the phrase
"signin authorization endpoint" so it matches the earlier change on line 14;
locate the string "signin authorization endpoint" in the blog post
(website/blog/2026-03-24-browser-based-auth-aws-user.mdx) and update it to
"sign-in authorization endpoint" to keep wording consistent.
- Line 14: Update the wording for the aws/user identity description: replace the
string "signin" with "sign-in" in the sentence that reads "OAuth2 PKCE flow via
the AWS signin service" so it conforms to AWS/OAuth terminology; ensure the
phrase becomes "AWS sign-in service" wherever it appears in the 3rd-tier
authentication fallback description for the aws/user identity type.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: f9761cd5-6846-48cf-8639-ad3e71de24a8
📒 Files selected for processing (2)
pkg/auth/identities/aws/webflow_test.gowebsite/blog/2026-03-24-browser-based-auth-aws-user.mdx
🚧 Files skipped from review as they are similar to previous changes (1)
- pkg/auth/identities/aws/webflow_test.go
|
|
||
| ## What Changed | ||
|
|
||
| The `aws/user` identity type gains a new third-tier authentication fallback. When YAML credentials and keychain credentials are both unavailable, Atmos automatically initiates an OAuth2 PKCE flow via the AWS signin service. This provides the same convenient web-based authentication that SSO users already enjoy, without requiring static access keys. |
There was a problem hiding this comment.
Hyphenate "sign-in" for consistency.
The term "signin" should be hyphenated as "sign-in" per standard AWS and OAuth terminology conventions.
📝 Proposed fix
-The `aws/user` identity type gains a new third-tier authentication fallback. When YAML credentials and keychain credentials are both unavailable, Atmos automatically initiates an OAuth2 PKCE flow via the AWS signin service. This provides the same convenient web-based authentication that SSO users already enjoy, without requiring static access keys.
+The `aws/user` identity type gains a new third-tier authentication fallback. When YAML credentials and keychain credentials are both unavailable, Atmos automatically initiates an OAuth2 PKCE flow via the AWS sign-in service. This provides the same convenient web-based authentication that SSO users already enjoy, without requiring static access keys.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| The `aws/user` identity type gains a new third-tier authentication fallback. When YAML credentials and keychain credentials are both unavailable, Atmos automatically initiates an OAuth2 PKCE flow via the AWS signin service. This provides the same convenient web-based authentication that SSO users already enjoy, without requiring static access keys. | |
| The `aws/user` identity type gains a new third-tier authentication fallback. When YAML credentials and keychain credentials are both unavailable, Atmos automatically initiates an OAuth2 PKCE flow via the AWS sign-in service. This provides the same convenient web-based authentication that SSO users already enjoy, without requiring static access keys. |
🧰 Tools
🪛 LanguageTool
[grammar] ~14-~14: Ensure spelling is correct
Context: ...itiates an OAuth2 PKCE flow via the AWS signin service. This provides the same conveni...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@website/blog/2026-03-24-browser-based-auth-aws-user.mdx` at line 14, Update
the wording for the aws/user identity description: replace the string "signin"
with "sign-in" in the sentence that reads "OAuth2 PKCE flow via the AWS signin
service" so it conforms to AWS/OAuth terminology; ensure the phrase becomes "AWS
sign-in service" wherever it appears in the 3rd-tier authentication fallback
description for the aws/user identity type.
| No configuration is required. Browser authentication is enabled by default for all `aws/user` identities. When triggered, Atmos: | ||
|
|
||
| 1. Starts a local callback server on an ephemeral port | ||
| 2. Opens your browser to the AWS signin authorization endpoint |
There was a problem hiding this comment.
Same hyphenation issue here.
Consistent with line 14, use "sign-in" instead of "signin".
📝 Proposed fix
-2. Opens your browser to the AWS signin authorization endpoint
+2. Opens your browser to the AWS sign-in authorization endpoint📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| 2. Opens your browser to the AWS signin authorization endpoint | |
| 2. Opens your browser to the AWS sign-in authorization endpoint |
🧰 Tools
🪛 LanguageTool
[grammar] ~23-~23: Ensure spelling is correct
Context: ...l port 2. Opens your browser to the AWS signin authorization endpoint 3. Exchanges the...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@website/blog/2026-03-24-browser-based-auth-aws-user.mdx` at line 23, Replace
the hyphenation of "signin" with "sign-in" in the phrase "signin authorization
endpoint" so it matches the earlier change on line 14; locate the string "signin
authorization endpoint" in the blog post
(website/blog/2026-03-24-browser-based-auth-aws-user.mdx) and update it to
"sign-in authorization endpoint" to keep wording consistent.
what
aws/useridentitywhy
AWS recently introduced browser-based OAuth2 authentication for IAM users and root accounts, eliminating the need for static access keys. This implementation provides the same convenient web-based flow that SSO users already enjoy, as a fallback when YAML credentials and keychain credentials are unavailable. Refresh token support enables long-lived 12-hour sessions without requiring browser reopening.
references
docs/prd/aws-browser-auth.mdSummary by CodeRabbit
New Features
Bug Fixes
Tests
Documentation