Skip to content

fix(auth): Govern token rescope via restrictions, not a handler guard#904

Open
ShJ-code wants to merge 1 commit into
openstack-experimental:mainfrom
ShJ-code:fix-763-test-rescope
Open

fix(auth): Govern token rescope via restrictions, not a handler guard#904
ShJ-code wants to merge 1 commit into
openstack-experimental:mainfrom
ShJ-code:fix-763-test-rescope

Conversation

@ShJ-code

@ShJ-code ShJ-code commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

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: #763

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>
@ShJ-code ShJ-code force-pushed the fix-763-test-rescope branch from 8227763 to 73554a3 Compare July 3, 2026 14:25
@ShJ-code ShJ-code self-assigned this Jul 3, 2026
let projects = list_auth_projects(&user_sdk).await?;
assert!(projects.iter().any(|p| p.id == target.id));

let mut client = TestClient::default()?;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

those are not source and target, but rather project_a, project_b

@ShJ-code

ShJ-code commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks for the comments. I will investigate those issues as well as CI checks and get back with changes ASAP.

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.

Improve API test test_rescope_project_scope

2 participants