Changing the default ACLs can have unforeseen consequences but can be a useful tool for managing permissions and security.
You can edit ACLs for many existing objects by using Chef Manage: https://docs.chef.io/manage.html
Or change default ACLs and the ACLs for existing objects by installing knife acl plugin: https://github.com/chef/knife-acl
Some Notes On Permissions In The Chef Server
For a brief primer on ACLs, I would start here: https://docs.chef.io/auth_authorization.html
The Chef Server uses one-time inheritance for its auth model. It has a “container” that corresponds to each object type that contains the default permissions for newly created objects. You can change the defaults for new objects by editing these containers, but keep in mind that you must update existing objects for each container type if you wish your changes to be applied retroactively to existing objects.
Regardless, I would recommend testing out any ACL changes in a new org in case you make a mistake before applying them to your existing organizations.
Restricting Client Access To Nodes
As far as your specific needs, restricting clients from reading other node objects isn’t too bad. I created a new node called testnode
and here is what the permissions look like:
{"actors"=>["testnode", "pivotal"], "groups"=>["clients", "users", "admins"]}
Now, let’s edit the nodes container to exclude the clients group in the default permissions for a node.
Here is the template for knife acl remove
:
knife acl remove MEMBER_TYPE MEMBER_NAME OBJECT_TYPE OBJECT_NAME PERMS
So let’s remove clients from the read perm for the nodes container:
$ knife acl remove group clients containers nodes read
Removing 'clients' from 'read' ACE of 'nodes'
Now, I’ll bootstrap a new node named testnode2 and see its permissions:
{"actors"=>["testnode2", "pivotal"], "groups"=>["users", "admins"]}
There you go! The only client that has read permissions on the node testnode2 is the client testnode2!
Note that my existing node, testnode, still has the clients group in its read ACL though:
{"actors"=>["testnode", "pivotal"], "groups"=>["clients", "users", "admins"]}
To fix that, you’d need to update the ACL for every existing node. You could do that with knife acl bulk
:
knife acl bulk remove group clients nodes '.*' read -y
Careful though! This will edit every node you have in the org…
Now if we look at testnode’s permissions:
{"actors"=>["testnode", "pivotal"], "groups"=>["users", "admins"]}
It is correct and now correct for all existing nodes.
Note that you can check permissions for any object with knife acl show
(I was using chef-shell
and hitting the _acl
API, but it does the same thing, output might be slightly different though).
Restricting Data Bag Access
As far as “[clients] should only have access to one data bag item in a large data bag” goes, things get a bit tricker. I’m assuming you mean each client should only have access to a single data bag item that other clients do not have access to.
Currently, data bags have ACLs, but data bag items do not; therefore, you cannot let a client access a single data bag item. You can only change a client’s access to an entire data bag. An actor either has access on all data bag items within a data bag, or none.
A possible workaround would be to remove clients from the read perms for the data container similar to what we did for the nodes container above, and then create a data bag per client and grant read on the specific data bag corresponding to client. That way, each client would have a data bag they could read from, but they couldn’t access the other data bags.
Is there a reason you want one large data bag with specific items a client can read vs separate data bags per client? If the answer is no, I can walk you through setting up what I just described.