Hashicorp Vault: Restrict rights given by policy for user allowed to create policies - hashicorp-vault

I came up with the idea to delegate to a user the right to create a policy. The policy assigned to this user would be:
path "sys/policies/acl/user-*"
{
capabilities = ["create", "read", "update", "delete", "list"]
}
Now as the user can create a policy in the path sys/policies/acl/user-*, such policy could contain any rights to any path in Vault which of course is not what I want to achieve. I would like to restrict this policy creation right to a given path. Is this in any way possible in Vault?

There are two ways to do that:
Buy Vault with sentinel support (i believe thats the enterprise version)
Create another service that will be talking to vault when it comes to creating policies and then write your own parsers to allow/deny. Its not going to be that bad as the policies hcl config language is translatable to JSON and once you have JSON you can parse the paths and figure out if its a valid policy or not.

Related

HashiCorp Vault permission denied 403 for AppRole with assigned policy kv v2

I'm having troubles with Vault it returns permission denied 403 error, when I try to get secrets with my k8s AppRole.
I setup vault with kv version 2 engine.
Added policy for my AppRole:
Created secret under "dev/fra1/statement":
When I login with AppRole creds I have response with required policies:
When I try to execute get request with AppRole client_token I this error:
I tried different prefixes and so on (Since people on internet had problems with them).
But then was able to localize the problem, by performing that request with root token, so it went ok:
Now I'm our of ideas, I believe the only place where the problem can be is policy, what I'm doing wrong ?
Ok, so finally figured the right prefix our, it should be:
path "kv/data/dev/*" {
capabilities = ["read"]
}
Really, there is some hell with these prefixes in vault, they should describe it better in docs.
The "secret" prefix is used in v1 of Vault's KV API. v2 uses the mount name, which by default is "kv", but can be anything when you first create the mount for your KV secrets engine.
It is important to note that some tools which use Vault's API still use v1 of the KV API to access secrets, despite that your KV secrets engine may be v2. So you may need two different permissions in your policy.
I'm facing the same issue. I have a secrets engine called TestSecretsEngine and a single secret env. In my policy I add read to the path TestSecretsEngine/data/env to no avail. I'm using the node-vault npm module and it's failing at vault.approleLogin with a 403. It's got to be something with the policy because when I add a nonexistent path, I get a 404 instead.

Unable to list audit devices with "sudo" and "list" capabilities applied to token policy

I'm trying to issue a vault CLI call to list the currently enabled audit devices. I have defined a policy against sys/audit which defines "sudo" and "list" capabilities (among others). I have been issued a token with that policy applied. However when I run vault audit list, I get a "permission denied" error.
What capabilities do I need to add to my policy in order for this to work? This is being done in a bootstrap script. (The additional capabilities currently included are because I do an 'enable' if the result of 'list' turns up that auditing is disabled. I'm trying to limit the permissions of this token to just the absolute minimum required for the two operations needed in this context.)
Policy (named "aud"):
path "sys/audit/*" {
capabilities = ["list", "read", "create", "update", "sudo"]
}
Token issuance (done elsewhere, logged in with root token):
vault token create --id=my-token --policy=aud
My script (where I attempt to use the token to login and check audit device status):
vault login my-token
vault audit list
vault audit enable file <options>
Error:
Error listing audits: Error making API request.
URL: GET http://< obfuscated >:8200/v1/sys/audit
Code: 403. Errors:
* 1 error occurred:
* permission denied
The subsequent 'vault audit enable' call works, so I know the capabilities are sufficient for that. But I'm unsure what change I need to make so that vault audit list works, since I already have "sudo" along with "list" and "read" capabilities.
It turns out that a wildcard policy for path "sys/audit/*" won't match against a request to sys/audit (no suffix). So in fact two separate path declarations are necessary.
First, for the vault audit list, this policy is sufficient:
path "sys/audit" {
capabilities = ["list", "read", "sudo"]
}
... and then for vault audit enable, the broader policy against the wildcard:
path "sys/audit/*" {
capabilities = ["create", "update", "sudo"]
}
This second one could be tightened up to only match against sys/audit/file as well.

How does a Secret .yaml file keep secret (username/password safe) as base64 could be decoded

In deployment.yaml file, we don't add username and password but refer them using secret. This way,the username/password don't get stored in code repositories. In secret.yaml, the username and password are encoded in base64 (which can be decoded). From best practice persepective, doesn't secret.yaml also get source-controlled somewhere (thereby also storing the username/password in version control). If so, what is the benefit of using Secret ?
There are a few aspects to be considered when keeping k8s secrets secret.
Data encryption at rest
There's the configuration option --encryption-provider-config, which instructs the api server whether and how to encrypt data in etcd. There's lots more in the docs.
Authorization
Role Based Access Control is one authz possibility for k8s. Using it, access to secrets can be restricted, so not every user or service account can see secrets, already existing in the cluster, think of kubectl get secret others-secret -n some-ns -o yaml. With RBAC you can create roles with specific sets of permissions - allowing or not access to secrets per namespace - and then assign those roles to users, groups or even service accounts, as you see fit.
Secrets manifests and VCS
3.1 Encryption
There are quite a few tools allowing for encryption of files with sensitive data, which would allow you to commit the file with the secrets to a version control system, if that's what you need. A simpler one would be mozilla SOPS and one somewhat sophisticated and complex might be Vault for example. Whichever it is, it would definitely be nice if not necessary, to be possible to easily integrate it in any delivery pipeline.
3.2 Don't store secrets manifests
An alternative approach to the above would be to not store any files with secrets. Create the secret and with regular cluster backups (tools like velero for instance) you should have nothing to worry about.
As you said, secrets are not encrypted but only base64 encoded. Where secrets really add value is that they allow you to keep your passwords, keys, tokens out of your codebase/git repos. If you push your code to Github, you will not be pushing your secrets there. For this reason they are called secrets and add a layer of safety.
However, if someone gets access to your cluster, secrets will be mere plaintext to them.
The recommended way to store the secrets is to use a vault.
https://www.hashicorp.com/blog/injecting-vault-secrets-into-kubernetes-pods-via-a-sidecar
Good one. Some time ago I already answered Kubernetes secret is really secret? question, check there all the info.
If you configure the secret through a manifest (JSON or YAML) file
which has the secret data encoded as base64, sharing this file or
checking it in to a source repository means the secret is compromised.
Base64 encoding is not an encryption method and is considered the same
as plain text.

Hashicorp Vault: Readonly policy not working

I am exploring Hashicorp Vault, and I am trying to create a read-only policy. This policy should only allow users to read key(s).
Below is the policy definition:
path "transit/*" {
capabilities = ["read", "list"]
}
I am trying to read key under secrets/transit (API Call: http://127.0.0.1:8200/v1/transit/keys/key1)
I am using the below CLI command to get the key (key1 in this case):
bash-5.1# vault read transit/keys/key1
However I get the below error:
Error reading transit/keys/key1: Error making API request.
URL: GET http://127.0.0.1:8200/v1/transit/keys/key1
Code: 403. Errors:
* 1 error occurred:
* permission denied
The same command works with the master token, So I guess there is nothing wrong with the command itself, but the problem is with the policy.
Interestingly, if I grant more access to the policy as below, then I can access the keys which is really confusing. I don't want to grant users create/update/delete access.
path "transit/*" {
capabilities = ["create", "update", "read", "delete", "list"]
}
Can someone point me where I am mistaken? Thanks.
Apparently, I changed the policy name and the same policy definition mentioned above started working as expected. I'm still not sure why or what was wrong with old policy name.

vault (hashicorp) add new policy to existing users/tokens

I created a user with a policy:
$ vault token create -renewable -policy=admin_policy Key Value
--- -----
token s.kG0Kdb8d2DSOUHv3AMzw5tdO
token_accessor Do57Fg9DpiMv1j6t3oysZoz9
token_duration 900h
token_renewable true
token_policies ["admin_policy" "default"]
identity_policies []
policies ["admin_policy" "default"]
And now I want to add policy to the token. How should I do it?
Or I created user:
vault write auth/userpass/users/test3 password=test -policy=admin_policy
Success! Data written to: auth/userpass/users/test3
And now I want add a policy to the user:
vault write auth/userpass/users/test3 password=test -policy=admin_policy -policy=crm_sales_policy
Success! Data written to: auth/userpass/users/test3
But nothing has changed.
At first I was also confusing about how to update policies on user, but I found the document has been updated, the API is /auth/userpass/users/:username/policies, so you can update the policies like this:
vault write auth/userpass/users/bob123/policies policies="foo,bar"
official reference
You can't add policy to an existing token.
So you would have to create a new token with said policy(or policies).
Generally it's better if your upstream auth source(say LDAP, etc) would handle assigning policies to users, but you are welcome to do it at the vault level too.
Also note, tokens are tied to their parent, so they expire when their parent token expires, unless you add -orphan
Tokens generally should not have a very long life. Vault's claim to fame here is that secrets and tokens should be short-lived, so that if they do leak, the harm is minimal.