Repository navigation
fix(console): serve an IAM user its own user page and access keys only - #844
Open
LeeroyHannigan wants to merge 4 commits into
Open
LeeroyHannigan wants to merge 4 commits into
LeeroyHannigan wants to merge 4 commits into
Conversation
An IAM-user console session could open every page of its own account. The account page named every user, group and role. A user page showed that user's access key IDs, inline policy names, groups and tags. A group page showed its members and inline policy names, and a role page showed its trust policy, inline policy names and tags. The handlers checked only that the account in the path was the session's own. The management API answers the same reads to the same user with HTTP 403. An IAM-user session now opens only its own user page and the forms that create and delete its own access keys. These are the access key reads and writes the management API gives the same user. The console has no form to change the password or import a key. require_user_session lets an IAM-user session through when the account ID and the user name in the path are its own. The management API applies the same rule to an IAM user's access keys. Any other user's pages redirect it to /console before the handler reads anything about that user. The account page, the group and role pages and the account list are for admins. Their handlers redirect an IAM-user session to /console before they read what the page shows. The admin-only forms under the account also redirect it to /console. Before, some of them redirected to the account page, the group page or the account list. The user's own page lists its access keys and leaves out its inline policies, groups and tags. The management API does not give the user those either. The dashboard links an IAM-user session to its own user page, and the navigation bar shows the Accounts link to admins only. The breadcrumbs of the user page and the new access key page leave out the pages the session may not open. Admin sessions get the same pages as before. The tests that read an IAM user's own account page, its dashboard link and its account list now expect the redirects.
…d keys tests/test_console_iam_user_pages.py logs in as an IAM user that holds only the self-service policy every user created with a console password gets. The account also holds two other users, a group and a role, each with an inline policy, and one user with an access key and a tag. The tests check that the account list, the account forms and every page and form under the user's account other than its own user page and access key forms redirect it to /console, and that no refused form changes the catalog. They check that no page it opens names another user, group or role of the account or links to a page that redirects it, and that the management API refuses the user the same reads. The user still reads, creates and deletes its own access keys and logs out, and an admin session still reads every page.
The getting started guide, the admin guide, the architecture guide and the security model now say that an IAM-user session opens its own user page and manages its own access keys, and that every other page under its account redirects it to the dashboard. The upgrade manual has a v0.1.15 entry for the change. The earlier v0.1.15 entry for console account scoping no longer says that the home page links an IAM user to its own account, or that the pages of the user's own account are unchanged.
account_scope_reads_tests.rs runs the account, group, role and user page handlers against a catalog store that holds no data and counts every call to it. An IAM-user session that requests the account page, a group page, a role page or another user's page gets a redirect to /console (HTTP 303). The handler makes no call to the store. An admin request and the IAM user's own user page each make one call. The integration test posts the create and delete access key forms as the IAM user. It posts each form twice, once with an empty CSRF token and once with a wrong token of the same length. Each answer is HTTP 403, and the user's access keys, as the management API lists them, do not change. The IAM user in the integration test now belongs to a second group and has a tag. The test checks that its own page leaves out that group and tag, and that the admin's view of the same page shows them.
LeeroyHannigan
requested review from
amrith,
c33howard,
eliseong,
hitesh96db,
jcshepherd,
navareamol,
pdf-amzn and
robinnsc
as code owners
November 5, 2026 02:47
| user_scope(&iam_user(), account, user).expect_err("the check let the session in"); | ||
| let (status, location, body) = answer(refused).await; | ||
|
|
||
| assert_eq!(status, StatusCode::SEE_OTHER, "{account}/{user}"); |
| let (status, location, body) = answer(refused).await; | ||
|
|
||
| assert_eq!(status, StatusCode::SEE_OTHER, "{account}/{user}"); | ||
| assert_eq!(location.as_deref(), Some("/console"), "{account}/{user}"); |
| ] { | ||
| assert!( | ||
| user_scope(&admin(), account, user).is_ok(), | ||
| "admin refused {account}/{user}" |
| .into_iter() | ||
| .filter(|link| link.starts_with("/console/accounts")) | ||
| .collect(); | ||
| assert!(to_accounts.is_empty(), "{to_accounts:?}: {body}"); |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
An IAM-user console session now reads only its own user page and its own access keys in its account. Every other page and form under
/console/accountsredirects the session to/console. Admin sessions see every page as before./console/accountsare for admin sessions only.require_user_sessioninaccount_scope.rsmakes this check. The management API uses the same rule for the access keys of an IAM user. Another user's name and a name that no user has get the same answer.GET .../users/{self}/policiesandGET .../users/{self}/tagsanswer 403, and no route lists the groups of a user./console. These are the forms that change users, groups, roles, members and policies, the delete account form and the new account form. Before, some of them sent the user to the account page, the group page or/console/accounts.Why
Closes #731.
An IAM-user console session read every page of its own account. It saw every user, group and role name. It also saw the access key IDs, inline policy names, groups and tags of every user. Group pages showed the members and policy names, and role pages showed the trust policy and policy names. The management API refuses the same reads to the same user with HTTP 403.
docs/getting-started.mdsection 8 said that IAM users view their own details and manage their own access keys.Testing done
account_scope_reads_tests.rsuses a store that counts calls. For an IAM-user session, the account page, a group page, a role page and another user's page answer 303 to/consolewith 0 store calls. The user's own page and each admin page make 1 call.tests/test_console_iam_user_pages.py(53 tests) logs in as an IAM user that holds only the self-service policy that every user with a password gets. It checks these things:/consoleand change nothing.tests/test_console_*.pyandtests/test_cross_account_isolation.py: 168 passed on a SQLite build.cargo fmt --checkandcargo clippy -p extenddb-server --all-targets -- -D warningspass.Merging with other PRs
crates/server/src/console/html.rs,nav_bar: the admin bar shows Accounts and theADMIN_LINKSof fix: serve the console metrics dashboard to admin sessions only #727. The IAM-user bar shows Dashboard, the identity label and Logout.docs/manuals/10-security-model.md: take the paragraph of this PR without its sentence "Until pull request fix: serve the console metrics dashboard to admin sessions only #727 merges, ...". Keep the "Admin-only metrics" bullet of fix: serve the console metrics dashboard to admin sessions only #727 below it.crates/server/src/console/pages/metrics_pages_tests.rs, from fix: serve the console metrics dashboard to admin sessions only #727:nav_bar_links_the_admin_only_pages_for_admins_onlyexpects the IAM-user bar to keep the Accounts link. Change that assertion to expect Dashboard followed by the spacer, and assert that the bar has no Accounts link.crates/server/src/console/pages/mod.rs. Keep both. After the merge,CountingStoreinaccount_scope_reads_tests.rsneeds aPasswordHashStoreimplementation that does not count the hash read of the session. The tests must also pass aCredentialStamptoSessionStore::create. fix(console): end console sessions when the principal is deleted or its password changes #704 reads the password hash of the session on each request. So the text "before the handler reads anything from the catalog" inaccount_scope.rsand in that test file needs new wording.Checklist
cargo test --workspace)cargo fmt --check)cargo clippy -- -W clippy::pedantic)Storagetrait, auth model, on-diskformat, or public CLI surface, an RFC has been accepted or is linked
below. Otherwise, an ADR captures the decision (link below).
ADR / RFC: n/a. The change limits what an IAM-user console session reads to what the management API already gives that user. The API, the storage and the policy evaluation do not change.
Breaking changes
In the console, an IAM user can no longer open its account page or the pages of other users. It can no longer open the group and role pages or the account list either. Its own user page no longer shows its inline policies, groups and tags. It still creates and deletes its own access keys there.
By submitting this pull request, I confirm that my contribution is made under
the terms of the Apache License 2.0 and I agree to the Developer Certificate of
Origin (DCO). See CONTRIBUTING.md for details.