Chef12: knife user show to non-admin users

Hello,

There is some way to give non-admins users permission to use ‘knife user
show’?

$ knife user show xxx -VV
DEBUG: Chef::HTTP calling Chef::HTTP::JSONInput#handle_request
DEBUG: Chef::HTTP calling Chef::HTTP::JSONToModelOutput#handle_request
DEBUG: Chef::HTTP calling Chef::HTTP::CookieManager#handle_request
DEBUG: Chef::HTTP calling Chef::HTTP::Decompressor#handle_request
DEBUG: Chef::HTTP calling Chef::HTTP::Authenticator#handle_request
DEBUG: Signing the request as jaum
DEBUG: Chef::HTTP calling Chef::HTTP::RemoteRequestID#handle_request
DEBUG: Chef::HTTP calling Chef::HTTP::ValidateContentLength#handle_request
DEBUG: Initiating GET to
https://chef-host/organizations/organization/users/truta
DEBUG: ---- HTTP Request Header Data: ----
DEBUG: Accept: application/json
DEBUG: Accept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3
DEBUG: X-OPS-SIGN: algorithm=sha1;version=1.0;
DEBUG: X-OPS-USERID: jaum
DEBUG: X-OPS-TIMESTAMP: 2015-01-22T19:42:02Z
DEBUG: X-OPS-CONTENT-HASH: 2jmj7l5rSw0yVb/vlWAYkK/YBwk=
DEBUG: X-OPS-AUTHORIZATION-1:
GsGVBloLX88PUr+OygGRf/JfqenGh2ZHvGS5LXEIehw/+Xu8Xgi5QYGK9lDs
DEBUG: X-OPS-AUTHORIZATION-2:
lQ6NGPt4AoiglpTuQUJnyP8rhPLEeNlMmh3hxBbGMlWHzTOqWsHvPLlbAg6e
DEBUG: X-OPS-AUTHORIZATION-3:
H7uWraSg882f26xXDkFJOhu/loBD3jZ51eCsyEJwJkkPhlOG8yVmNrgzn2cV
DEBUG: X-OPS-AUTHORIZATION-4:
sKvwKHJwAu5UUGHrNcyKeH1SPlWYHZFhL0lEMb6lwDxZA7O5nKJu9RE/nEPc
DEBUG: X-OPS-AUTHORIZATION-5:
FKYframg47s+uPYjrb9MjH5AjtAK3DBA1dZxXrTFTEeB2rtWNjrSAVNE0O5I
DEBUG: X-OPS-AUTHORIZATION-6: GlqUUlBuXa0j/Er52tIMJBl0Fav4cwGK5tNx1DniNQ==
DEBUG: HOST: chef-host:443
DEBUG: X-REMOTE-REQUEST-ID: 1fb2cc5a-25a4-483a-b4e5-adaedb01d80a
DEBUG: ---- End HTTP Request Header Data ----
DEBUG: ---- HTTP Status and Header Data: ----
DEBUG: HTTP 1.1 403 Forbidden
DEBUG: server: ngx_openresty/1.4.3.6
DEBUG: date: Thu, 22 Jan 2015 19:42:01 GMT
DEBUG: content-length: 37
DEBUG: connection: close
DEBUG: x-ops-api-info: flavor=cs;version=12.0.0;oc_erchef=0.29.4
DEBUG: ---- End HTTP Status/Header Data ----
DEBUG: Chef::HTTP calling Chef::HTTP::ValidateContentLength#handle_response
DEBUG: Content-Length validated correctly.
DEBUG: Chef::HTTP calling Chef::HTTP::RemoteRequestID#handle_response
DEBUG: Chef::HTTP calling Chef::HTTP::Authenticator#handle_response
DEBUG: Chef::HTTP calling Chef::HTTP::Decompressor#handle_response
DEBUG: Chef::HTTP calling Chef::HTTP::CookieManager#handle_response
DEBUG: Chef::HTTP calling Chef::HTTP::JSONToModelOutput#handle_response
DEBUG: Expected JSON response, but got content-type '‘
DEBUG: Chef::HTTP calling Chef::HTTP::JSONInput#handle_response
INFO: HTTP Request Returned 403 Forbidden: error
/opt/chefdk/embedded/lib/ruby/2.1.0/net/http/response.rb:119:in error!': 403 "Forbidden" (Net::HTTPServerException) from /opt/chefdk/embedded/apps/chef/lib/chef/http.rb:145:inrequest’
from /opt/chefdk/embedded/apps/chef/lib/chef/rest.rb:115:in get' from /opt/chefdk/embedded/apps/chef/lib/chef/user.rb:164:inload’
from /opt/chefdk/embedded/apps/chef/lib/chef/knife/user_show.rb:43:in run' from /opt/chefdk/embedded/apps/chef/lib/chef/knife.rb:493:inrun_with_pretty_exceptions’
from /opt/chefdk/embedded/apps/chef/lib/chef/knife.rb:174:in run' from /opt/chefdk/embedded/apps/chef/lib/chef/application/knife.rb:139:inrun’
from /opt/chefdk/embedded/apps/chef/bin/knife:25:in <top (required)>' from /usr/bin/knife:33:inload’
from /usr/bin/knife:33:in `’

Thanks!!

– Tiago Cruz

I tried to

$ knife acl add groups users read group vault-admins

And put my users on 'vault-admins' group, but does not work :frowning:

The problem is: knife-vault needs to get public key of the users to
generate the hash.

If the guy is a non-admin, he only can generate for his own, and I can't
see the key:

$ knife vault show reliability portability-credentials
ERROR: ChefVault::Exceptions::SecretDecryption:
reliability/portability-credentials is not encrypted with your public key.
Contact an administrator of the vault item to encrypt for you!

And the guy who did, can't generate to me because the can't see my private
key using 'knife user show tiago_cruz'

So, how can I give him access to my private_key?

Thanks a lot!

On Thu, Jan 22, 2015 at 5:51 PM, Tiago Cruz tiago.tuxkiller@gmail.com
wrote:

Hello,

There is some way to give non-admins users permission to use 'knife user
show'?

$ knife user show xxx -VV
DEBUG: Chef::HTTP calling Chef::HTTP::JSONInput#handle_request
DEBUG: Chef::HTTP calling Chef::HTTP::JSONToModelOutput#handle_request
DEBUG: Chef::HTTP calling Chef::HTTP::CookieManager#handle_request
DEBUG: Chef::HTTP calling Chef::HTTP::Decompressor#handle_request
DEBUG: Chef::HTTP calling Chef::HTTP::Authenticator#handle_request
DEBUG: Signing the request as jaum
DEBUG: Chef::HTTP calling Chef::HTTP::RemoteRequestID#handle_request
DEBUG: Chef::HTTP calling Chef::HTTP::ValidateContentLength#handle_request
DEBUG: Initiating GET to
https://chef-host/organizations/organization/users/truta
DEBUG: ---- HTTP Request Header Data: ----
DEBUG: Accept: application/json
DEBUG: Accept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3
DEBUG: X-OPS-SIGN: algorithm=sha1;version=1.0;
DEBUG: X-OPS-USERID: jaum
DEBUG: X-OPS-TIMESTAMP: 2015-01-22T19:42:02Z
DEBUG: X-OPS-CONTENT-HASH: 2jmj7l5rSw0yVb/vlWAYkK/YBwk=
DEBUG: X-OPS-AUTHORIZATION-1:
GsGVBloLX88PUr+OygGRf/JfqenGh2ZHvGS5LXEIehw/+Xu8Xgi5QYGK9lDs
DEBUG: X-OPS-AUTHORIZATION-2:
lQ6NGPt4AoiglpTuQUJnyP8rhPLEeNlMmh3hxBbGMlWHzTOqWsHvPLlbAg6e
DEBUG: X-OPS-AUTHORIZATION-3:
H7uWraSg882f26xXDkFJOhu/loBD3jZ51eCsyEJwJkkPhlOG8yVmNrgzn2cV
DEBUG: X-OPS-AUTHORIZATION-4:
sKvwKHJwAu5UUGHrNcyKeH1SPlWYHZFhL0lEMb6lwDxZA7O5nKJu9RE/nEPc
DEBUG: X-OPS-AUTHORIZATION-5:
FKYframg47s+uPYjrb9MjH5AjtAK3DBA1dZxXrTFTEeB2rtWNjrSAVNE0O5I
DEBUG: X-OPS-AUTHORIZATION-6: GlqUUlBuXa0j/Er52tIMJBl0Fav4cwGK5tNx1DniNQ==
DEBUG: HOST: chef-host:443
DEBUG: X-REMOTE-REQUEST-ID: 1fb2cc5a-25a4-483a-b4e5-adaedb01d80a
DEBUG: ---- End HTTP Request Header Data ----
DEBUG: ---- HTTP Status and Header Data: ----
DEBUG: HTTP 1.1 403 Forbidden
DEBUG: server: ngx_openresty/1.4.3.6
DEBUG: date: Thu, 22 Jan 2015 19:42:01 GMT
DEBUG: content-length: 37
DEBUG: connection: close
DEBUG: x-ops-api-info: flavor=cs;version=12.0.0;oc_erchef=0.29.4
DEBUG: ---- End HTTP Status/Header Data ----
DEBUG: Chef::HTTP calling Chef::HTTP::ValidateContentLength#handle_response
DEBUG: Content-Length validated correctly.
DEBUG: Chef::HTTP calling Chef::HTTP::RemoteRequestID#handle_response
DEBUG: Chef::HTTP calling Chef::HTTP::Authenticator#handle_response
DEBUG: Chef::HTTP calling Chef::HTTP::Decompressor#handle_response
DEBUG: Chef::HTTP calling Chef::HTTP::CookieManager#handle_response
DEBUG: Chef::HTTP calling Chef::HTTP::JSONToModelOutput#handle_response
DEBUG: Expected JSON response, but got content-type ''
DEBUG: Chef::HTTP calling Chef::HTTP::JSONInput#handle_response
INFO: HTTP Request Returned 403 Forbidden: error
/opt/chefdk/embedded/lib/ruby/2.1.0/net/http/response.rb:119:in error!': 403 "Forbidden" (Net::HTTPServerException) from /opt/chefdk/embedded/apps/chef/lib/chef/http.rb:145:in request'
from /opt/chefdk/embedded/apps/chef/lib/chef/rest.rb:115:in get' from /opt/chefdk/embedded/apps/chef/lib/chef/user.rb:164:in load'
from /opt/chefdk/embedded/apps/chef/lib/chef/knife/user_show.rb:43:in run' from /opt/chefdk/embedded/apps/chef/lib/chef/knife.rb:493:in run_with_pretty_exceptions'
from /opt/chefdk/embedded/apps/chef/lib/chef/knife.rb:174:in run' from /opt/chefdk/embedded/apps/chef/lib/chef/application/knife.rb:139:in run'
from /opt/chefdk/embedded/apps/chef/bin/knife:25:in <top (required)>' from /usr/bin/knife:33:in load'
from /usr/bin/knife:33:in `'

Thanks!!

-- Tiago Cruz

--
-- Tiago Cruz

Hi Tiago,

The short story is that this may be impossible without talking
directly to the internal SQL database and/or the bifrost (internal
authorization system) API. I’ve explained a bit below. The
explanation may be a bit terse for those on the list who haven’t used
the RBAC system much.

To read a user’s private key, you need to have the read permission on
the user itself either by being directly in the read ACE for that user
object or in a group that is in the read ACE. Adding your
vault-admins group to the read ACE of the users group won’t provide
the permissions you need since it doesn’t give you any permission on
the members of that group, simply on the group object itself.

The read ACE for a user Mary in the organization acme looks like this:

mary > knife raw -s 'https://api.opscode.piab/' 'users/mary/_acl' | jq .read
{
  "actors": [
    "pivotal",
    "mary"
  ],
  "groups": [
    "acme_global_admins"
  ]
}

When Mary is associated to an organization, a special group is added
to the READ ace of the user. The group is in the form of
ORGNAME_global_admin and contains the admin group of the organization.
When she is disassociated from the org, that group is removed from her
read ACE. Since the admin users are in the admin group, the admin
group is in the acme_global_admins group, and the acme_global_admins
is in the read ACE of the user, an admin user can read Mary’s user
object.

Now, knowing this, to give your users access to read each others’ keys
you might try:

  1. Adding the users group to the acme_global_admins group
  2. Adding a given user to the “actors” section of the user’s read ace
  3. Adding some arbitrary other group that contains the users to the
    groups section of the users read ace

Unfortunately,

a) It appears Chef 12 has a bug such that you can’t update a user’s
acl without removing the ORGNAME_global_admin group from the ACL.
This would break the access that org admins have by default and would
put you in a situation that isn’t likely well tested. [0]

b) You can’t add actors or groups to the ORGNAME_global_admin group
because that group doesn’t exist inside an organization and thus
simply isn’t reachable via an API endpoint.

Option (1) above is likely doable with a script that directly
manipulates some of the backend services [1].

I hope this help.

Cheers,

Steven

[0] Updating user ACLs worked in 11.2.x so I’ll likely be following up
internally and filing a bug.
[1] By likely doable, I mean completely doable:

You can use it like this from your Chef Server:

./danger_add_users_to_global_admins_group acme

HOWEVER, please note that (1) this is messing with internal
implemntation details and it will probably break, (2) I haven’t
audited what other permissions those users will get, and (3) I haven’t
audited edge cases of users being associated and disassociated from
orgs. Basically I ran it once and it worked.

Hello Steven, thanks again!

Just to clarify: The group 'acme_global_admins' has the same privileges
than the 'admin' default group?

Because if I just put the user in admin group, the 'knife user show' works,
and so he is able to use 'knife vault' using the option:

knife[:vault_admins] = [ 'user_a', 'user_b', 'user_c' ]

So the key will be manageable to more than one person (this is good for us!)

Thanks a lot!

On Fri, Jan 23, 2015 at 11:21 PM, Steven Danna steve@chef.io wrote:

Hi Tiago,

The short story is that this may be impossible without talking
directly to the internal SQL database and/or the bifrost (internal
authorization system) API. I've explained a bit below. The
explanation may be a bit terse for those on the list who haven't used
the RBAC system much.

To read a user's private key, you need to have the read permission on
the user itself either by being directly in the read ACE for that user
object or in a group that is in the read ACE. Adding your
vault-admins group to the read ACE of the users group won't provide
the permissions you need since it doesn't give you any permission on
the members of that group, simply on the group object itself.

The read ACE for a user Mary in the organization acme looks like this:

mary > knife raw -s 'https://api.opscode.piab/' 'users/mary/_acl' |

jq .read
{
"actors": [
"pivotal",
"mary"
],
"groups": [
"acme_global_admins"
]
}

When Mary is associated to an organization, a special group is added
to the READ ace of the user. The group is in the form of
ORGNAME_global_admin and contains the admin group of the organization.
When she is disassociated from the org, that group is removed from her
read ACE. Since the admin users are in the admin group, the admin
group is in the acme_global_admins group, and the acme_global_admins
is in the read ACE of the user, an admin user can read Mary's user
object.

Now, knowing this, to give your users access to read each others' keys
you might try:

  1. Adding the users group to the acme_global_admins group
  2. Adding a given user to the "actors" section of the user's read ace
  3. Adding some arbitrary other group that contains the users to the
    groups section of the users read ace

Unfortunately,

a) It appears Chef 12 has a bug such that you can't update a user's
acl without removing the ORGNAME_global_admin group from the ACL.
This would break the access that org admins have by default and would
put you in a situation that isn't likely well tested. [0]

b) You can't add actors or groups to the ORGNAME_global_admin group
because that group doesn't exist inside an organization and thus
simply isn't reachable via an API endpoint.

Option (1) above is likely doable with a script that directly
manipulates some of the backend services [1].

I hope this help.

Cheers,

Steven

[0] Updating user ACLs worked in 11.2.x so I'll likely be following up
internally and filing a bug.
[1] By likely doable, I mean completely doable:
danger_add_users_to_global_admins_group · GitHub

You can use it like this from your Chef Server:

./danger_add_users_to_global_admins_group acme

HOWEVER, please note that (1) this is messing with internal
implemntation details and it will probably break, (2) I haven't
audited what other permissions those users will get, and (3) I haven't
audited edge cases of users being associated and disassociated from
orgs. Basically I ran it once and it worked.

--
-- Tiago Cruz

Ohai again!

On Fri, Jan 23, 2015 at 11:21 PM, Steven Danna steve@chef.io wrote:

To read a user's private key, you need to have the read permission on
the user itself either by being directly in the read ACE for that user
object or in a group that is in the read ACE.

And to read the user's public key, do we have some easier and way? :slight_smile:

Sounds like chef-vault just need access to the public key to encrypt:

"Gem that allows you to encrypt a Chef Data Bag Item using the public keys
of a list of chef nodes. This allows only those chef nodes to decrypt the
encrypted values."

Many thanks!!

https://github.com/Nordstrom/chef-vault#installation

Hi,

Just to clarify: The group 'acme_global_admins' has the same privileges than
the 'admin' default group?

No, apologies if this was unclear. The ORGNAME_global_admins group,
as far as I know, only appears in the ACL of user's who have been
associated to ORGNAME. It does not, by default, grant members any
other permissions. The admins group is a member of the
ORGNAME_global_admins group specifically for the purpose of getting
permission on the global user objects for members of the org. Perhaps
this will help:

ORGNAME_global_admins group --has--> Permission on user objects

admin --has--> permission on many local organization objects
--is a member of --> ORGNAME_global_admins group

Because if I just put the user in admin group, the 'knife user show' works,
and so he is able to use 'knife vault' using the option:

Correct, if you put a user in the admin group, they will be able to
see the keys of all other users in that org by virtue of the fact that
the admin group in ORGNAME is a member of the special
ORGNAME_global_admins group. Of course, any user in the admin group
gets the permissions associated with the admin group.

And to read the user's public key, do we have some easier and way? :slight_smile:

Not that I know of.

Cheers,

Steven