hashicorp / vault

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

Add other subject attributes than CN on PKI signing #4562

Open bluecmd opened 6 years ago

bluecmd commented 6 years ago

Feature Request:

To easy be able to sign certificates to be used for Kubernetes client TLS auth the O= attribute in the subject needs to be easily set when signing.

Right now my options are limited to creating a new role for every user or using sign-verbatim, which requires me to create the CSR and thus requires me to touch the user's private key - not really ideal.

jefferai commented 6 years ago

That's only necessary for group membership according to the docs.

I suppose we could maybe allow globs in O values, if someone wants to PR that. Not really ideal IMHO. It'd be way better if Kubernetes used something more sensible though, like SANs.

bluecmd commented 6 years ago

It is only for group memberships, that's correct - but that's kind of a central thing.

While I agree that certainly it's not the nicest solution, it is what they have currently.

jefferai commented 6 years ago

Doesn't that mean though that you only need a new role per group?

bluecmd commented 6 years ago

No, one per every combination of groups possible - right?

jgiles commented 6 years ago

re: Kubernetes authentication, see also https://github.com/hashicorp/vault/issues/3839#issuecomment-390979103

@bluecmd you were intending to have folks dynamically specify the set of Kubernetes groups in vault write requests, rather than defining the set of groups on the PKI role?

I ask because we're planning a model where Kubernetes secret roles are associated with fixed Kubernetes groups - roughly speaking, a Vault-defined role maps to a particular set of Kubernetes permissions. This model is analogous to the AWS or Database secret backends, where a Vault backend "role" is associated with an IAM role/policy or a DB user creation+grant statement respectively. To me, this seems simpler for operators than managing all the Kubernetes group assignment controls directly in the Vault policy layer. We've had a lot of human error in Vault policy parameter restrictions.

Do you really need to support a combinatorial number effective permission sets?

bluecmd commented 6 years ago

Maybe some background on what we're doing.

The way this works for us is that we have an authentication portal, a SSO if you will, that the humans log in every day on. This authentication portal mints all the credentials the user need to access production resources, for example it mints a personal Vault token, a persona Kubernetes certificate, and a personal SSH certificate.

The users can obviously be part of many many groups, and these groups give certain access in Kubernetetes.

The authentication portal is the authority on what permissions to grant to the user, and does all the mapping between our LDAP groups and policies to apply, but given that a user should have a single certificate to access Kubernetes all the group memberships needs to be encoded in it. If we could say "mint a certificate using role X + Y + Z" and have the group memberships somehow be additive that would work, but given that groups are encoded in the DN I don't see any feasible way that Vault could implement that. In lieu of this, our authentication portal needs to construct the full DN, which is fine by me - but there is no way to give this information to Vault today, other than doing a full new CSR.

For all our existing credential generation (except for Vault token) we sign the private key material the user presents, essentially making it impossible for us to accidentally leak the private key material or otherwise compromise it. As Vault do not allow us to provide a full DN override however, we cannot do this and are force to generate a private key for the user, which we don't want. Hence this bug.

I have a design document I can share on a per person basis if you need even more background, but you can get the more nitty gritty details by looking at our code.

Does that make things a bit clearer about what our problem is?

jefferai commented 6 years ago

It sounds like https://github.com/hashicorp/vault/issues/3839#issuecomment-390979103 would be a much more ideal approach to your problem -- your authentication server could use it to pull out bearer tokens rather than have humans have to deal with mutual TLS.

bluecmd commented 6 years ago

These are offline systems, so they cannot talk to Vault. When the user has gotten the cert, it will be valid for 20h and they can take their cert with them across VPNs and whatnot to authenticate with the off-prem clusters.

jefferai commented 6 years ago

How is that different from a bearer token issued by Kubernetes?

bluecmd commented 6 years ago

Wouldn't that require an active webhook query back to talk to Vault to validate the token for every API request?

jefferai commented 6 years ago

Did you actually look at that link? It proposes a Kubernetes secrets backend that fetches Kubernetes-generated bearer tokens. Your auth portal could fetch such a bearer token (or could even just do it directly from Kubernetes) after which it's up to Kubernetes, not Vault, to authenticate the token when you talk to it.

jgiles commented 6 years ago

Sadly, @bluecmd is correct in saying that for https://github.com/hashicorp/vault/issues/3839#issuecomment-390979103 the Kubernetes cluster will have to "phone" home to Vault with a webhook in order to verify the bearer token. It's not every request (TokenReview results are cached for a configurable period of time, default 2 minutes).

For our use-case, this is fine - we already have many reasons Kubernetes needs to talk to Vault (e.g. Kubernetes auth for pods, pods getting secrets, underlying EC2 nodes getting secrets).

jefferai commented 6 years ago

Maybe I misunderstood then. I thought in #3839 you were suggesting that Vault gets Kubernetes to issue a bearer token, which Kubernetes can then authenticate itself.

jgiles commented 6 years ago

Yeah, the Kubernetes "webhook authentication" mode basically just delegates token issuance and authentication to some external system. https://github.com/hashicorp/vault/issues/3839#issuecomment-390979103 is about making Vault able to serve as that system.

A potential "feature request" for that proposed backend would be support for client-cert based creds in addition to bearer tokens. Essentially this would involve running a stripped-down version of the PKI backend, with the API tuned for ease-of-use specifically with Kubernetes.

But, this isn't in-scope for the initial implementation... we're putting together the webhook-based authentication largely to get around the Kubernetes-side shortcomings of the client certs.

bluecmd commented 6 years ago

So given that #3839 appears out of scope, how do you feel about at least adding a full DN override if not all the DN parts for CSR signing?

mwielgoszewski commented 6 years ago

@jefferai I'm running into an issue where I'd like to specify serialNumber attributes in subjects. I can do this today by specifying a custom OID (2.5.4.5) by passing `allowed_other_sans="2.5.4.5;utf8:*" in the role configuration, but this field is not regularly parsed by various applications.

I can also pass a CSR to the sign-verbatim endpoint, but as the documents suggest it is a very highly trusted and potentially dangerous endpoint. In my case, I want to enforce compliance with specific EKU's and not allow CSR's to override them.

Please let me know if I should open a separate issue or submit a PR to support this.

jefferai commented 6 years ago

It's basically the same ask, but if you are going to submit a PR to support only that (as opposed to the other attributes requested on this ticket), then it should be a separate issue.

You should format the role parameter as allowed_serial_numbers using a TypeCommaStringSlice and support globbing (see other examples in the code). That way a simple glob of * is sufficient to allow users to specify any serial number they want, but you can also force certain prefix or suffix values.

niteshsinha commented 4 years ago

Hello @catsby @jefferai , is there a timeline on this feature? (to allow updating other Subject attributes)

also for the referenced PR #4694 . I couldn't find any property allowed_serial_numbers in the documentation : https://www.vaultproject.io/api-docs/secret/pki#create-update-role

am in looking at the wrong place?

cipherboy commented 2 years ago

@niteshsinha Just a heads up, it turns out this was missing from the API docs (it was available from vault path-help though). This has been fixed and should now appear there too.

cipherboy commented 2 years ago

For a brain dump context, there's two hard parts of this:

  1. How do you specify the generated subject? A Subject is a Sequence of Sets of (Type=Value) tuples. Just adding an ou=<list> parameter to the request gives you some base ability, yes, but might not be expressive enough (see the other PKI issues on that topic, especially where people have created certs outside of Vault and imported them as issuers).
  2. How do you do validation? Likely you'll either end up with a construction like allowed_domains + the various other parameters it supports and the role and issue API specs just get that much more complicated.

To clarify, a lot of these already exist on the role. This allows an operator to control common parts of the subject (O, OU, &c), and only have the requester set CN. However, there is no per-request override of these values; a separate role would be necessary for each distinct partial subject. That is what this issue tracks.