Skip to content
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

Application passwords implementation #2578

Open
wants to merge 42 commits into
base: master
Choose a base branch
from

Conversation

scabrero
Copy link
Collaborator

This pull request replaces #2457 and follows the design document #2427.

It is just the server side for now.

Related to #41

Checklist

  • This pr contains no AI generated code
  • cargo fmt has been run
  • cargo clippy has been run
  • cargo test has been run and passes
  • book chapter included (if relevant)
  • design document included (if relevant)

@scabrero
Copy link
Collaborator Author

@Firstyear, the last test for:

Since application passwords are related to applications, on delete of an application all entries
that have a bound application password should be removed from user accounts.

fails. Any hint about how to enforce reference integrity on a "complex" attribute?

Copy link
Member

@Firstyear Firstyear left a comment

Choose a reason for hiding this comment

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

Regarding referential integrity have a look at https://github.com/kanidm/kanidm/blob/master/server/lib/src/valueset/oauth.rs#L369

It has handling for Refer as a special case, as well as Iutf8 for matching labels. You'll also notice https://github.com/kanidm/kanidm/blob/master/server/lib/src/valueset/oauth.rs#L607 which indexes the uuids of the groups related.

That way if you search an application id with PartialValue::Uuid yuo get the application itself, but PartialValue::Refer gets everything that refers to it.

That's what enables https://github.com/kanidm/kanidm/blob/master/server/lib/src/schema.rs#L771 which indicates that a reference relationship exists, and that automatically triggers https://github.com/kanidm/kanidm/blob/master/server/lib/src/plugins/refint.rs

book/src/access_control/intro.md Outdated Show resolved Hide resolved
server/lib/src/be/dbvalue.rs Show resolved Hide resolved
server/lib/src/constants/acp.rs Outdated Show resolved Hide resolved
server/lib/src/constants/acp.rs Outdated Show resolved Hide resolved
server/lib/src/constants/schema.rs Outdated Show resolved Hide resolved
server/lib/src/idm/application.rs Show resolved Hide resolved
server/lib/src/constants/schema.rs Outdated Show resolved Hide resolved
server/lib/src/idm/application.rs Outdated Show resolved Hide resolved
server/lib/src/idm/ldap.rs Outdated Show resolved Hide resolved
server/lib/src/valueset/apppwd.rs Show resolved Hide resolved
book/src/developers/designs/application_passwords.md Outdated Show resolved Hide resolved
server/lib/src/constants/acp.rs Outdated Show resolved Hide resolved
server/lib/src/credential/apppwd.rs Outdated Show resolved Hide resolved
@scabrero
Copy link
Collaborator Author

Hi @Firstyear, PR is not updated yet because I am rebasing on top of master commit by commit while addressing your comments.

@Firstyear
Copy link
Member

Hi @Firstyear, PR is not updated yet because I am rebasing on top of master commit by commit while addressing your comments.

Ahhh okay. Sorry about that :)

Want me to wait til you are ready for me to look again then?

@scabrero
Copy link
Collaborator Author

Hi @Firstyear, PR is not updated yet because I am rebasing on top of master commit by commit while addressing your comments.

Ahhh okay. Sorry about that :)

Want me to wait til you are ready for me to look again then?

Except the refint for the ApplicationPassword struct to make the last test pass, it is now ready for a second review :)

@scabrero
Copy link
Collaborator Author

Ready for review.

@scabrero scabrero marked this pull request as ready for review March 22, 2024 07:20
Copy link
Member

@Firstyear Firstyear left a comment

Choose a reason for hiding this comment

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

Haven't finished the full review but here is the first pass.

server/lib/src/constants/acp.rs Outdated Show resolved Hide resolved
// needs to be able to assign to entry managed by
lazy_static! {
pub static ref IDM_ACP_APPLICATION_CREATE_DL6: BuiltinAcp = BuiltinAcp {
classes: vec![
Copy link
Member

Choose a reason for hiding this comment

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

Previous comment was "how do you envisage these access controls working with human roles and tasks", and I think you need to answer that because these access controls otherwise seem confused.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ok, I can think about two possibilities:

Use case 1, the IDM administrator creates the application, links the group, and sets up the members.
Use case 2, there is a person managing service X, e.g. mail. The IDM administrator creates the app, links a group,
and delegates group permission for the group to the X service manager who sets up the members.

Copy link
Member

Choose a reason for hiding this comment

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

Okay, so I actually think both possibilities are valid. We have the ability to create new applications (which we will give to an idm_application_admins group, and by default, idm_admins is a member of that, see https://github.com/kanidm/kanidm/blob/master/server/lib/src/constants/groups.rs#L203 and https://github.com/kanidm/kanidm/blob/master/server/lib/src/constants/acp.rs#L594 ) and then for group 2, we already have a delegation feature thanks to our "Entry Managed By" feature. You can see an example of this https://github.com/kanidm/kanidm/blob/master/server/lib/src/constants/acp.rs#L1047

So we'll need to support Attribute::EntryManagedBy on the LDAP application class, as well as make EntryManagedBy writable by the application_admins group, then there is a second ACP for ApplicationEntryManager which has the receiver as EntryManager and similar or constrained application rights. Does that seem reasonable?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ok, it is clearer now but I still have questions:

For case 1:
I have merged IDM_ACP_APPLICATION_{CREATE,MANAGE,DELETE}_DL7 into IDM_ACP_APPLICATION_MANAGE_DL7. The receiver is the idm_application_admins builtin group and has "full control" over the application entry.

For case 2:
I don't see the need for Attribute::EntryManagedBy in the application entry nor the need for a second ACP having EntryManager as receiver. IIUC a idm_application_admins_group member will create the application and will link a group, and then will delegate the linked group management, not the application entry. And as you said we already have IDM_ACP_GROUP_ENTRY_MANAGER_V1 to allow the delegated person to modify the linked group members. Unless you think the delegated person should be able to modify the linked group in the application entry.

Copy link
Member

Choose a reason for hiding this comment

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

But linked group is about the users who can access the application, not the group that owns and manages the application integration itself. So that's why I think there needs to be a separation.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ok, understood. I have added it.

server/lib/src/constants/schema.rs Outdated Show resolved Hide resolved
server/lib/src/credential/apppwd.rs Outdated Show resolved Hide resolved
server/lib/src/idm/account.rs Outdated Show resolved Hide resolved

#[derive(Clone)]
struct LdapApplicationsInner {
set: HashMap<String, Application>,
Copy link
Member

Choose a reason for hiding this comment

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

What's the logic of using a string to index into this Map instead of UUID?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Mainly because LdapApplicationAuthEvent carries the application name extracted from the bind DN, so we can do https://github.com/scabrero/kanidm/blob/app-passwords/server/lib/src/idm/application.rs#L178

server/lib/src/idm/application.rs Outdated Show resolved Hide resolved
@scabrero scabrero force-pushed the app-passwords branch 2 times, most recently from 244e7e0 to 9a9fd26 Compare May 24, 2024 07:38
Copy link
Member

@Firstyear Firstyear left a comment

Choose a reason for hiding this comment

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

This is looking much better, responded re the acp parts. I think next I need to just review that the tests cover all the situations we can think of, then I think we're almost there.

book/src/access_control/intro.md Outdated Show resolved Hide resolved
// needs to be able to assign to entry managed by
lazy_static! {
pub static ref IDM_ACP_APPLICATION_CREATE_DL6: BuiltinAcp = BuiltinAcp {
classes: vec![
Copy link
Member

Choose a reason for hiding this comment

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

Okay, so I actually think both possibilities are valid. We have the ability to create new applications (which we will give to an idm_application_admins group, and by default, idm_admins is a member of that, see https://github.com/kanidm/kanidm/blob/master/server/lib/src/constants/groups.rs#L203 and https://github.com/kanidm/kanidm/blob/master/server/lib/src/constants/acp.rs#L594 ) and then for group 2, we already have a delegation feature thanks to our "Entry Managed By" feature. You can see an example of this https://github.com/kanidm/kanidm/blob/master/server/lib/src/constants/acp.rs#L1047

So we'll need to support Attribute::EntryManagedBy on the LDAP application class, as well as make EntryManagedBy writable by the application_admins group, then there is a second ACP for ApplicationEntryManager which has the receiver as EntryManager and similar or constrained application rights. Does that seem reasonable?

server/lib/src/constants/schema.rs Outdated Show resolved Hide resolved
server/lib/src/constants/schema.rs Outdated Show resolved Hide resolved
server/lib/src/idm/application.rs Outdated Show resolved Hide resolved
server/lib/src/idm/server.rs Show resolved Hide resolved
server/lib/src/idm/server.rs Outdated Show resolved Hide resolved
@@ -129,6 +129,7 @@ bitflags::bitflags! {
const SYSTEM_CONFIG = 0b0001_0000;
const SYNC_AGREEMENT = 0b0010_0000;
const KEY_MATERIAL = 0b0100_0000;
const APPLICATION = 0b1000_0000;
Copy link
Member

Choose a reason for hiding this comment

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

I'm glad I left you with one more bit in the change flags 😅

Signed-off-by: Samuel Cabrero <scabrero@suse.de>
and not used

Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
TODO: How to test without client side?

Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
This is how the application passwords will be serialized and stored in
the backend.

It will be a vector of DbValueApplicationPassword, each one having its
uuid, application uuid, label and DbPasswordV1.

Signed-off-by: Samuel Cabrero <scabrero@suse.de>
This is how the data is serialized/deserialized from replication

Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: 📋 Backlog
Development

Successfully merging this pull request may close these issues.

None yet

2 participants