-
Notifications
You must be signed in to change notification settings - Fork 59
[SCIM 3/4]: SCIM client token CRUD + Bearer auth #9180
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Implement the CRUD routines for the tokens that will be used to authenticate SCIM clients for SamlScim Silos. Also implement the Bearer based authentication for SCIM clients. Fill in the skeleton of CrdbScimProviderStore, which when implemented will complete the SCIM implementation in Nexus.
Instead of silo Also grant silo admin role to USER_TEST_PRIVILEGED.id() instead of OpContext::for_tests in tests.
I had a good conversation with the Codex CLI about the choice to effectively bypass the existing authn schemes setup here, treating these calls as "unauthed" from the point of view of the main authn system. The robot was pretty persuasive but I think the choice is worth pointing out and documenting in comments, probably on the https://gist.github.com/david-crespo/14d25cb770f9e10195f6d0ea45286874 |
id: Uuid::new_v4(), | ||
time_created: Utc::now(), | ||
time_deleted: None, | ||
// TODO: allow setting an expiry? have a silo default? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mind filing a follow up ticket for this and noting it in the comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
opened #9260
use nexus_db_schema::schema::scim_client_bearer_token::dsl; | ||
let maybe_token = dsl::scim_client_bearer_token | ||
.filter(dsl::bearer_token.eq(bearer_token)) | ||
.filter(dsl::time_deleted.is_null()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need filters for where we are not past the expired time here and other places?
nexus/src/app/scim.rs
Outdated
|
||
const BEARER: &str = "Bearer "; | ||
|
||
if !token.starts_with(BEARER) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't remember where we landed on this but assuming this logic is correct we are going to require operators to use Bearer xxx-xxx-xxx-xxx
on the IdP side rather than just a raw header value?
Also the logic could simply become:
let Some(token) = token.strip_prefix(BEARER) else {
return Err(Error::Unauthenticated {
internal_message: "Invalid bearer token".to_string(),
});
};
Then that could be passed to scim_idp_lookup_token_by_bearer()
directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This changed to Bearer oxide-scim-token
in 3b3b891 to fit with how other authn schemes work - we'll have to include some docs about it.
|
||
assert!(tokens.is_empty()); | ||
|
||
// Fleet admins can create SCIM client tokens |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just going off of the comment here, but can we add a test that a non fleet admin cannot create a SCIM client token?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Silo admins should be able to create SCIM tokens too. I can add a test to the follow up PR (that creates the silo admin users) to test this too.
create opctx that uses that actor create new authn scheme for "Bearer oxide-scim-... make opctx.authorize calls make more sense remove external-scim create synthetic resource ScimClientBearerTokenList for tighter permission structure: - external-auth cannot list children on ScimClientBearerTokenList for example
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still looking through, but here is a pile of comments. I am much happier with this after adding a formal authn scheme for scim.
/// might use a Silo. You usually want to use [`Context::silo_required()`] | ||
/// if you don't expect to be looking at a built-in user. | ||
/// | ||
/// Additionally, non-user Actors may also be associated with a Silo. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be good to say that by "non-user actor" you mean the SCIM arm of the match. It's obvious when you're looking at the diff but might not be so obvious later.
// XXX Ok, or an error? | ||
return Ok(()); | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it should error, that might break everything for no reason. Interestingly, the SCIM actor technically does have a role on the fleet, it just happens to be hard-coded. It probably doesn't make sense for this method to load that pseudo-assignment into roleset
, though it does make me wonder what is doing that if not this method. I will poke around — no change requested here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I misunderstood this function - it's not inserting roles for a actor, it's looking them up, so this is a short circuit because SCIM actors won't ever have roles. 493af88 removes it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be good to comment // short circuit for actors that won't ever have roles
|
||
authn::Actor::Scim { .. } => false, | ||
} | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes me feel bad, but it might just be the name is_user
, which, while it technically does divide the options the right way, doesn't feel like it names the meaning of the distinction. Or maybe the problem is that we're going to leave off is_user
by mistake and cause a bug that way. If we see this extending to service accounts, are those going to also be non-users? Should they have read perms on their own silo? Maybe this is a question for later, but it illustrates the weirdness of this concept.
silo1-proj1-collaborator ✘ ✘ ✘ ✘ ✘ ✘ ✘ ✘ | ||
silo1-proj1-viewer ✘ ✘ ✘ ✘ ✘ ✘ ✘ ✘ | ||
unauthenticated ! ! ! ! ! ! ! ! | ||
scim ✘ ✘ ✘ ✘ ✘ ✘ ✘ ✘ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so good :)
let provider = self.scim_get_provider_from_opctx(opctx).await?; | ||
|
||
let result = match provider.patch_group(&group_id, body).await { | ||
Ok(response) => response.to_http_response(StatusCode::OK), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How come some of these take StatusCode::OK
and some don't?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The scim2-rs::SingleResourceResponse
is converted to a http::Response, but the call site needs to know the proper status code cause the conversion routine does not know for what HTTP method it's being called for. POST needs to be 201, and the rest need to be 200.
@papertigers the change to have |
Implement the CRUD routines for the tokens that will be used to authenticate SCIM clients for SamlScim Silos. Also implement the Bearer based authentication for SCIM clients.
Fill in the skeleton of CrdbScimProviderStore, which when implemented will complete the SCIM implementation in Nexus.