Thanks. This makes sense. I got my group creation working using the REST api. Now here is my question about private groups and wildcard-users. I want a group that authorizes only a few select users (admin, john, and larry). Your example group public.json looks like this: { "op": [{"username": "admin", "password": "password"}], "presenter": [{}], "public": true} So first (before using the REST api) , I tried to make a private group manually in JSON files like this: { "op": [{"username": "admin", "password": "12345"}], "presenter": [{}], "description": "This is a private group to test password-based restrictions.", "displayName": "Private 3", "users":{"john":{"password":"224715","permissions":"present"},"larry":{"password":"925385","permissions":"present"}} } Being non-public, this doesn't appear in the public list of groups. Great. But, a big problem! Login [admin/12345] >>> logged in Login [admin/ anything_else ] >>> "not authorized" Login [john/224715] >>> logged in Login [john/ anything_else ] >>> "not authorized" Login [larry/925385] >>> logged in Login [larry/ anything_else ] >>> "not authorized" PROBLEM: Login [anyone_else/anything] >>> logged in It seems I can only stop anonymous logins by adding a wildcard user with obscure password: { "op": [{"username": "admin", "password": "12345"}], "presenter": [{}], "description": "This is a private group to test password-based restrictions.", "displayName": "Private Test Group", "users":{"john":{"password":"224715","permissions":"present"},"larry":{"password":"925385","permissions":"present"}}, "wildcard-user":{"password":"98579223487","permissions":"present"} } Login [admin/12345] >>> logged in Login [admin/monkey] >>> "not authorized" Login [rando/98579223487] >>> logged in Login [rando/anything_else] >>> "not authorized" What am I doing wrong or do I have the wrong mental model? -Marty On Mon, Dec 2, 2024 at 4:08 AM Juliusz Chroboczek wrote: > Hello, > > > In particular I tried to create a group using PUT method with JSON body > and it > > works fine for simple groups > > Good. > > > But if I include a "users" list or a "wildcard-user" value, it fails > with a > > "description is not sanitized" error. > > Right. That's by design. > > > Why is this "sanitized" check existing in UpdateDescription(). > > The API splits the group description into two parts: > > - the "sanitised" group description itself; > - the users' database. > > Every user, in turn, is split into two parts: > > - the user description; > - the password. > > So in order to create a group, you need to make 1 + 2n requests: > > - create the group: PUT /api/v0/.groups/groupname > - for every user > - create the user: PUT /api/v0/.groups/groupname/.users/username > - set the password: PUT > /api/v0/.groups/groupname/.users/username/.password > > You use .wildcard-user for the wildcard user. > > The main reason why I've used this organisation is that it makes > fine-grained access control possible: for example, a normal (non-admin) > user is allowed to change their own password, but they're of course not > allowed to change the rest of the group description. Conversely, an admin > is allowed to change the group description, but they're not allowed to GET > a password. > > (There are other advantages, but they're less important, so I won't bore > you with them here.) > > The main drawback, of course, is that it makes some operations > inefficient. For example, in order to display the list of users together > with their persmissions, you need to do this: > > GET /api/v0/.groups/groupname/.users/ > for every user > GET /api/v0/.groups/groupname/.users/username > > (It also makes the operation non-atomic: if a user is deleted between the > first and the subsequent GET, then you'll unexpectedly get a 404 error. > Oh, well.) > > If it becomes a problem in the future, I'll extend the API with operations > over collections, but until we gain more experience with the API, I'd > rather stick to simple operations only. > > By the way: the main user of the API right now is the galenectl program, > which you're find in the Galene sources. Feel free to copy-paste code > from there. > > I hope this helps, > > -- Juliusz Chroboczek >