ACL/permission support in chef-server


#1

Hi all,

I’m looking at implementing permission support in chef-server and would
like to run the design by the list.

While I’d like to have something that works the same way as the opscode
API, that API isn’t public and as far as I can see, there’s no way to
edit permissions except through the web UI, so my concern isn’t that
deep. That said, I think it’s important the permission models match, so
if people use both the platform and chef-server, they won’t be confused
about how features work where.

The model seems to be an additive one, ie you can add permissions, but
you can’t remove them, and a client has the union of all permissions
given to the recursive set of groups they are a member of.

My idea is to store the permissions of an object in the object itself,
so you’ll have something along the lines of:

{

“permissions”: {
“group[foo]”: [
“read”,
“update”,
“grant”
],
“client[bar]”: [
“read”,
“update”,
“delete”,
“grant”
]
},
“chef_type”: “node”
}

The chef server configuration will grow a few new configuration options,
one is default_permissions, the other is override_permissions. The
former will set permissions for objects if the permission hash is empty
or missing, the latter will always be added to objects.

In addition, permissions for creating and listing clients, nodes, data
bags, data bag items and so on will be set in the configuration.

As you can see, we need some group support for this, this is simply a
group of clients. Groups can have clients and other groups as members.
The member graph is a DAG. In addition to whatever admin-defined groups
exist, there are three more magic groups:

  • admins: contains all clients with admin: yes
  • users: contains all clients
  • self: contains the client with the same name as the object.

Searches will be handled by a filter in the chef server, solr won’t need
to know about permissions.

How does this sound to everybody? I’d particularly value input from
people with experience from the platform so I can make sure the designs
are compatible.

Best regards,

Tollef Fog Heen
UNIX is user friendly, it’s just picky about who its friends are


#2

On Tue, Dec 21, 2010 at 11:48 PM, Tollef Fog Heen tfheen@err.no wrote:

I’m looking at implementing permission support in chef-server and would
like to run the design by the list.

While I’d like to have something that works the same way as the opscode
API, that API isn’t public and as far as I can see, there’s no way to
edit permissions except through the web UI, so my concern isn’t that
deep. That said, I think it’s important the permission models match, so
if people use both the platform and chef-server, they won’t be confused
about how features work where.

The API is public, but not publicly documented, if that makes sense.
We’re in the middle of updating the internal documentation for the
service, and as soon as it’s done, we’ll get it to you. The gist is
that we break things up into Actors, Objects and Actions. So you
model things as:

Actor: Node monkeypants
Object: /nodes/monkeypants
Action: Read

And can check that against Access Control Lists made up of Access
Control Entries.

Actors can be individual objects, or they can be Groups of them.
Groups, obviously, expand - so an ACE that references a group would
expand to all the members of the group. Groups can be nested.

If you check out this book:

http://www.amazon.com/Role-Based-Access-Control-Second-Ferraiolo/dp/1596931132/ref=sr_1_1?s=books&ie=UTF8&qid=1293150427&sr=1-1

You’ll know exactly what we built.

The model seems to be an additive one, ie you can add permissions, but
you can’t remove them, and a client has the union of all permissions
given to the recursive set of groups they are a member of.

In practice, you basically never do this sort of lookup in the system
we’ve built. It’s always looking up if an Actor can perform an Action
on the Object in question.

My idea is to store the permissions of an object in the object itself,
so you’ll have something along the lines of:

{

“permissions”: {
“group[foo]”: [
“read”,
“update”,
“grant”
],
“client[bar]”: [
“read”,
“update”,
“delete”,
“grant”
]
},
“chef_type”: “node”
}

That’s a non-starter for us, since it means the underlying objects
will be incompatible with the implementation we have on the platform.
Store the ACLs and ACEs as separate objects with references to the
real ones. As a bonus, things will be much easier to maintain, less
complicated, and much faster to look up. In general, when you are
looking to extend the value of the objects we create, this is the
pattern.

The chef server configuration will grow a few new configuration options,
one is default_permissions, the other is override_permissions. The
former will set permissions for objects if the permission hash is empty
or missing, the latter will always be added to objects.

We approach this differently, which is that the default security
policy is always in place, and changes are then made against it
(possibly programatically.) I elaborate in a second.

In addition, permissions for creating and listing clients, nodes, data
bags, data bag items and so on will be set in the configuration.

With the platform, changes to the permissions are generally made
against the API directly, through endpoints that look something like
this:

/nodes/foo/_acl

Where ‘normal’ Chef REST conventions apply, about GET/PUT/POST/DELETE.

We drive the creation of initial policy through group membership, and
set defaults around which Actors are in which Groups by default.

As you can see, we need some group support for this, this is simply a
group of clients. Groups can have clients and other groups as members.
The member graph is a DAG. In addition to whatever admin-defined groups
exist, there are three more magic groups:

  • admins: contains all clients with admin: yes
  • users: contains all clients
  • self: contains the client with the same name as the object.

Searches will be handled by a filter in the chef server, solr won’t need
to know about permissions.

In our implementation, you never need to search - you just ask the
question about Actor->Object->Access. We are computing a view and
walking the DAG internally, but from the outside, not really a search.

How does this sound to everybody? I’d particularly value input from
people with experience from the platform so I can make sure the designs
are compatible.

We’re going to get you documentation of the external part of the API
(likely week after next, since most of us are out for Christmas
break).

The secondary part of this conversation is that we’re having some very
brass-tacks conversations about whether or not we will just open
source our implementation, from the back-end services forward. I
expect we’ll have a decision on this front early in the first of the
year, and if we do, I imagine your time will be better spent helping
us get it out the door.

Best,
Adam


Opscode, Inc.
Adam Jacob, CTO
T: (206) 508-7449 E: adam@opscode.com


#3

]] Adam Jacob

Hi Adam,

| On Tue, Dec 21, 2010 at 11:48 PM, Tollef Fog Heen tfheen@err.no wrote:
| > I’m looking at implementing permission support in chef-server and would
| > like to run the design by the list.
| >
| > While I’d like to have something that works the same way as the opscode
| > API, that API isn’t public and as far as I can see, there’s no way to
| > edit permissions except through the web UI, so my concern isn’t that
| > deep. That said, I think it’s important the permission models match, so
| > if people use both the platform and chef-server, they won’t be confused
| > about how features work where.
|
| The API is public, but not publicly documented, if that makes
| sense. We’re in the middle of updating the internal documentation for
| the service, and as soon as it’s done, we’ll get it to you.

Sounds good. Do you have any idea how long this will take?

| The gist is that we break things up into Actors, Objects and Actions.
| So you model things as:
|
| Actor: Node monkeypants
| Object: /nodes/monkeypants
| Action: Read
|
| And can check that against Access Control Lists made up of Access
| Control Entries.
|
| Actors can be individual objects, or they can be Groups of them.
| Groups, obviously, expand - so an ACE that references a group would
| expand to all the members of the group. Groups can be nested.

Given you want the ACEs stored as separate objects,

| If you check out this book:
|
| http://www.amazon.com/Role-Based-Access-Control-Second-Ferraiolo/dp/1596931132/ref=sr_1_1?s=books&ie=UTF8&qid=1293150427&sr=1-1
|
| You’ll know exactly what we built.

I haven’t read it, but I know a little bit about RBAC, so I assume I can
fill in most of the holes myself.

| > The model seems to be an additive one, ie you can add permissions, but
| > you can’t remove them, and a client has the union of all permissions
| > given to the recursive set of groups they are a member of.
|
| In practice, you basically never do this sort of lookup in the system
| we’ve built. It’s always looking up if an Actor can perform an Action
| on the Object in question.

How do you know what actor to use when doing the lookup? Are you using
the client, the groups the client is a member of, or how are you doing
that expansion.

| > My idea is to store the permissions of an object in the object itself,
| > so you’ll have something along the lines of:
| >
| > {
| > …
| > “permissions”: {
| > “group[foo]”: [
| > “read”,
| > “update”,
| > “grant”
| > ],
| > “client[bar]”: [
| > “read”,
| > “update”,
| > “delete”,
| > “grant”
| > ]
| > },
| > “chef_type”: “node”
| > }
|
| That’s a non-starter for us, since it means the underlying objects
| will be incompatible with the implementation we have on the platform.

Well, that’d just be a one-time conversion so I don’t really think
that’s such a big issue, as long as the semantic are the same. I’m
willing to be convinced that your approach is better, though, as long as
it actually is.

| Store the ACLs and ACEs as separate objects with references to the
| real ones. As a bonus, things will be much easier to maintain, less
| complicated, and much faster to look up. In general, when you are
| looking to extend the value of the objects we create, this is the
| pattern.

To me, it looks more complex, since you need to keep ACEs in sync with
the objects themselves.

| > The chef server configuration will grow a few new configuration options,
| > one is default_permissions, the other is override_permissions. The
| > former will set permissions for objects if the permission hash is empty
| > or missing, the latter will always be added to objects.
|
| We approach this differently, which is that the default security
| policy is always in place, and changes are then made against it
| (possibly programatically.) I elaborate in a second.
|
| > In addition, permissions for creating and listing clients, nodes, data
| > bags, data bag items and so on will be set in the configuration.
|
| With the platform, changes to the permissions are generally made
| against the API directly, through endpoints that look something like
| this:
|
| /nodes/foo/_acl
|
| Where ‘normal’ Chef REST conventions apply, about GET/PUT/POST/DELETE.
|
| We drive the creation of initial policy through group membership, and
| set defaults around which Actors are in which Groups by default.

Fair enough, this is reasonably easy to do.

[…]

| > Searches will be handled by a filter in the chef server, solr won’t need
| > to know about permissions.
|
| In our implementation, you never need to search - you just ask the
| question about Actor->Object->Access. We are computing a view and
| walking the DAG internally, but from the outside, not really a search.

I was thinking about searches as in API searches, not searches for
ACLs. You want to make sure that somebody doing «knife search node
:’» doesn’t see nodes that client isn’t authorised to.

| > How does this sound to everybody? I’d particularly value input from
| > people with experience from the platform so I can make sure the designs
| > are compatible.
|
| We’re going to get you documentation of the external part of the API
| (likely week after next, since most of us are out for Christmas
| break).

Sounds good.

| The secondary part of this conversation is that we’re having some very
| brass-tacks conversations about whether or not we will just open
| source our implementation, from the back-end services forward. I
| expect we’ll have a decision on this front early in the first of the
| year, and if we do, I imagine your time will be better spent helping
| us get it out the door.

That’d be even better, of course. :slight_smile:

Regards,

Tollef Fog Heen
UNIX is user friendly, it’s just picky about who its friends are