fix(auth): Govern token rescope via restrictions, not a handler guard#904
fix(auth): Govern token rescope via restrictions, not a handler guard#904ShJ-code wants to merge 1 commit into
Conversation
The token create handler rejected any (re)authentication that carried a token restriction with `allow_rescope = false` whenever a scope was requested. That guard was redundant and too broad: `token_restriction` is only populated for `FernetToken::Restricted` auth, and the real boundary is already enforced by `SecurityContext::validate_scope_boundaries` (a restricted token is pinned to its project, since `RestrictedPayload` always carries a concrete `project_id`), while `issue_token_context` rejects the request when the user holds no role on the target scope. The guard even blocked re-scoping to the token's own bound project, which the boundary check permits. Remove the guard from `create_inner` so rescoping with regular tokens is allowed and restricted tokens remain governed by the security gate. The `AuthenticationRescopeForbidden` variant is kept (still used by the audit name and HTTP-status mappings) but is no longer produced. Move restricted-token rescope enforcement into scope boundary validation so allow_rescope=false only permits the current project, while project-pinned restrictions still reject other projects. Add a `test_api::assignment::add_project_grant` helper and an API test `test_rescope_to_newly_granted_project` that creates a project, grants a fresh user a role on it and verifies the user can rescope onto it. Add a handler unit test asserting a restricted-token rescope is no longer rejected. Closes: openstack-experimental#763 Signed-off-by: Sihao Jiang <sihao_jiang@outlook.com>
8227763 to
73554a3
Compare
| let projects = list_auth_projects(&user_sdk).await?; | ||
| assert!(projects.iter().any(|p| p.id == target.id)); | ||
|
|
||
| let mut client = TestClient::default()?; |
There was a problem hiding this comment.
please do not use TestClient - we need to get rid of it. Instead you can use https://docs.rs/openstack_sdk/latest/openstack_sdk/struct.AsyncOpenStack.html#method.authorize what your user_sdk currently is.
|
|
||
| // This is a new authentication/reauthentication. Check if that is allowed at | ||
| // all | ||
| if let Some(token_restriction) = ctx.token_restriction() |
There was a problem hiding this comment.
I am very unsure in that . The lines that the issue were referring to (iirc) were removed with 466a398 so you should not be required to change anything here
| } | ||
| } | ||
| ScopeInfo::Project { project, .. } => { | ||
| if let Some(token_restriction) = &self.token_restriction |
There was a problem hiding this comment.
this change is unnecessary (at least within this change). The test you modify is not dealing with restricted token, it only uses regular authentication tokens. Moreover I plan on removing token restrictions as a concept completely since they are now superseded by a more universal solution.
| ) | ||
| .await?; | ||
|
|
||
| let source = create_project( |
There was a problem hiding this comment.
those are not source and target, but rather project_a, project_b
|
Thanks for the comments. I will investigate those issues as well as CI checks and get back with changes ASAP. |
The token create handler rejected any (re)authentication that carried a token restriction with
allow_rescope = falsewhenever a scope was requested. That guard was redundant and too broad:token_restrictionis only populated forFernetToken::Restrictedauth, and the real boundary is already enforced bySecurityContext::validate_scope_boundaries(a restricted token is pinned to its project, sinceRestrictedPayloadalways carries a concreteproject_id), whileissue_token_contextrejects the request when the user holds no role on the target scope. The guard even blocked re-scoping to the token's own bound project, which the boundary check permits.Remove the guard from
create_innerso rescoping with regular tokens is allowed and restricted tokens remain governed by the security gate. TheAuthenticationRescopeForbiddenvariant is kept (still used by the audit name and HTTP-status mappings) but is no longer produced. Move restricted-token rescope enforcement into scope boundary validation so allow_rescope=false only permits the current project, while project-pinned restrictions still reject other projects.Add a
test_api::assignment::add_project_granthelper and an API testtest_rescope_to_newly_granted_projectthat creates a project, grants a fresh user a role on it and verifies the user can rescope onto it. Add a handler unit test asserting a restricted-token rescope is no longer rejected.Closes: #763