Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Vault integration and validation #2226

Merged
merged 10 commits into from
Jan 23, 2017
Merged

Improve Vault integration and validation #2226

merged 10 commits into from
Jan 23, 2017

Conversation

dadgar
Copy link
Contributor

@dadgar dadgar commented Jan 22, 2017

This PR:

  • Validates the token given to Nomad to ensure it has the required capabilities on the needed paths
  • Allows specifying a role to create a token from even if the token is not from the given role.
  • Adds tests to the blacklist pattern of Vault roles (disallowed_policies).
  • updates the Vault API to use the new POST rather than GET methods such that the tokens are not written in the URL.

// Nomad does not have to be created from this role but must have "update"
// capability on "auth/token/create/<create_from_role>". If this value is
// unset and the token is created from a role, the value is defaulted to the
// role the token is from.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? What is the use case, ever, for using a role to create a token to use the role?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backwards compatibility, we are in a point release, would break peoples configs.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has anyone actually set it up like this? There has never been a need for this to be the required setup.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was no other option which is what started this all 👍 If one was using role based tokens, they would be hit by the behavior change

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was always an option, well before the first release with Vault integration.

v.tokenData = &data

// The criteria that must be met for the token to be valid are as follows:
// 1) If token is non-root or is but has a creation ttl
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tokens should never be root unless Nomad is in dev mode.

Copy link
Contributor Author

@dadgar dadgar Jan 23, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't restrict people to that. That is an organizational decision not one Nomad will enforce on people. We just highly discourage it in our docs

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use a root token and would really like to keep doing that... we only use vault for ease of storage, not for the hardcore security and ACL level stuff

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dadgar Per our original discussions around implementation it was never supposed to be allowed outside of dev mode in the first place.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jippi You should still not use root tokens, if for no other reason than that they are quite difficult to generate at this point. Just use a periodic token with policies giving all privileges to /*.

// capabilities the token does have as well as any error that occured.
func (v *vaultClient) hasCapability(path string, required []string) (bool, []string, error) {
caps, err := v.client.Sys().CapabilitiesSelf(path)
if err != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"root" in the required slice should be conditional on Nomad being in dev mode.

vaultTokenRenewPath = "auth/token/renew-self"

// vaultTokenLookupPath is the path used to lookup a token
vaultTokenLookupPath = "auth/token/lookup"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should add auth/token/lookup-self as a lookup possibility. Most tokens can be looked up using that path as it's in the default policy, so if auth/token/lookup doesn't work you should use that instead (and probably prefer it).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did this to limit the set of policies we have to document as Nomad requiring since we can reuse that for both looking our own token up and incoming tokens. But since I guard that validation (https://github.com/hashicorp/nomad/pull/2226/files#diff-87a4c76eca3de54716c55ba6b8c06475R682) I agree. Will make the change

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using lookup-self can be a good secondary option. I agree that keeping lookup there is not an issue.

return v.config.Role
}

return v.tokenData.Role
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't do this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mentioned above why it is like this for now

@@ -602,6 +762,12 @@ func (v *vaultClient) validateRole(role string) error {
multierror.Append(&mErr, fmt.Errorf("Role must have a non-zero period to make tokens periodic."))
}

for _, d := range data.DisallowedPolicies {
if d == "default" {
multierror.Append(&mErr, fmt.Errorf("Role can not disallow allow default policy"))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure it can.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah good catch! That was for me while I was testing something!

// a) Must have read capability for "auth/token/roles/<role_name" (Can just attemp a read)
// b) Must have update capability for path "auth/token/create/<role_name>"
// c) Role must:
// 1) Not allow orphans
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing that this is copypasta from Asana but you probably mean must allow orphans. Or should allow orphans.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was not changing this behavior in this PR. Down the line we may want to relax this constraint and let the operator decide if they would like to allow orphans. But for now we are not allowing it so that when Nomad revokes a token the whole tree is revoked.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By extension this means that if Nomad's token becomes invalid all jobs also now have invalid tokens. This is not the suggested operational model that we tell people to use; we recommend orphan periodic tokens for services. There is no reason to artificially impose this upon administrators; they should be free to use their own judgement, especially since you're already requiring periodic tokens.

// c) Role must:
// 1) Not allow orphans
// 2) Must allow tokens to be renewed
// 3) Must not have an explicit max TTL
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you can limit job length, allowing an explicit max TTL is a decent idea as an additional check.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not a bad idea for those who want it but for now I am keeping it at being a periodic token with no max TTL. We can revisit in another PR/release

// 2) Must allow tokens to be renewed
// 3) Must not have an explicit max TTL
// 4) Must have non-zero period
// 5) If not configured against a role, the token must be root
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If not configured against a role, you still shouldn't require a root token. There's no need. You could require a token that has sudo capability against auth/token/create. Or you could just try to make a token and see if it works.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was based on your own suggestion:

5a) Don't require this, it's nearly the same as requiring a root token.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly. Don't require a root token. You also shouldn't require a sudo token, but if you insist that you really must have something with super high privileges on that endpoint, make it a sudo token so that you aren't encouraging people to pass in root tokens.

What you should do instead is to just try making the token, and it will work or it will not. There's no reason to be running these checks.

@github-actions
Copy link

github-actions bot commented Apr 6, 2023

I'm going to lock this pull request because it has been closed for 120 days ⏳. This helps our maintainers find and focus on the active contributions.
If you have found a problem that seems related to this change, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 6, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants