hashicorp / vault

A tool for secrets management, encryption as a service, and privileged access management
https://www.vaultproject.io/
Other
31.05k stars 4.2k forks source link

Feature Request: Valid_Principals to be additive lists instead of strings #7150

Open DamianBis opened 5 years ago

DamianBis commented 5 years ago

Is your feature request related to a problem? Please describe.

The business problem this is trying to solve is that i wish to have my users not care about what principals they have access to. When they request a cert i'm wanting to sign it with all the valid principals they have.

I have locked down our vault pretty securely so for signing certificates I have multiple policies

Policy 1:

path "ssh-client-signer/*" {
    capabilities = ["create", "read", "update", "delete", "list"]
    allowed_parameters = {
    "valid_principals" = ["server1"]
    "*" = []
  }
}

Policy 2:

path "ssh-client-signer/*" {
    capabilities = ["create", "read", "update", "delete", "list"]
    allowed_parameters = {
    "valid_principals" = ["server2"]
    "*" = []
  }
}

Policy 3:

path "ssh-client-signer/*" {
    capabilities = ["create", "read", "update", "delete", "list"]
    allowed_parameters = {
    "valid_principals" = ["server3"]
    "*" = []
  }
}

When signing a certificate i can make a request as below

vault write ssh-client-signer/sign/my-role -<<"EOH"
{
  "public_key": "ssh-rsa ***",
  "valid_principals": "server1",
  "extension": {
    "permit-pty": ""
  }
}
EOH

and it works for any of the 3 servers. But if i try and make valid_principals a combination of the 3 servers

(ie "valid_principals" : "server1, server2" ) then it does not allow me to sign it because of permissions

Describe the solution you'd like valid_principals in policies to be treated like a list and each individual item in the list evaluated against policies. Something like below

vault write ssh-client-signer/sign/my-role -<<"EOH"
{
  "public_key": "ssh-rsa ***",
  "valid_principals": [ "server1", "server2", "server3" ] ,
  "extension": {
    "permit-pty": ""
  }
}
EOH

or

vault write ssh-client-signer/sign/my-role -<<"EOH"
{
  "public_key": "ssh-rsa ***",
  "valid_principals": "server1, server2, server3" ] ,
  "extension": {
    "permit-pty": ""
  }
}
EOH

and that should allow the user to sign even if the policies are separated out in different policy templates

michelvocks commented 5 years ago

Hi @DamianBis,

Enhancing the existing ACL system to support your use-case is possible but would also introduce a change on how the allowed_parameters parameter currently works. I'm not saying that we are strictly against this but first we should make sure there is no other way to solve your issue.

Since valid_principals is checked against the allowed_users and allowed_domains parameters from the SSH-role, you could potentially create multiple SSH-roles for every valid_principals item:

$ vault write ssh-client-signer/roles/server1 -<<"EOH"
{
  "allow_user_certificates": true,
  "allowed_users": "server1",
  "default_extensions": [
    {
      "permit-pty": ""
    }
  ],
  "key_type": "ca",
  "default_user": "ubuntu",
  "ttl": "30m0s"
}
EOH

$ vault write ssh-client-signer/roles/server2 -<<"EOH"
{
  "allow_user_certificates": true,
  "allowed_users": "server2",
  "default_extensions": [
    {
      "permit-pty": ""
    }
  ],
  "key_type": "ca",
  "default_user": "ubuntu",
  "ttl": "30m0s"
}
EOH
...

This would allow you to assign different roles to users. Users would be still able to sign a key with one principal at a time instead of stacked principals but I think this is fine since the key is usually only used once per SSH connection?

Would this be a suitable workaround to solve your issue?

DamianBis commented 5 years ago

Hey Michel,

I'm already doing something similar to your solution in that i'm just using the same role and signing individual certs, with a singular principal each time.

The problem with this (and your proposed solution) is that end users need to know the principals/servers names, and in an ideal world this would be fine as it would all make sense and be documented. but in the unfortunate world i live in that's not likely to be the case.

If it was updated the way i'm requesting it would mean i could request a certificate with all of a users allowed principals (i've got the logic to do this in my script. no changes in vault required there).

That way as an end user all they need to do is know the IP of the server they want to log into. They run my script, which requests a signed cert with all of the allowed principals they have permissions for. that cert is then used to log into the server.

DamianBis commented 5 years ago

I'm keen/happy to do some code to get this working. just need some guidelines on how it should be implemented.

I've had a look at the code and it would be quite easy to just make it into a list, but is there a preference for there to be a flag to enable the valid_principals to be an additive list. as if the behaviour just changes it would be a breaking change and i could understand some people not wanting it to work this way.