3-add-example-for-periodic-orphan-token #4

Merged
hygienic-books merged 7 commits from 3-add-example-for-periodic-orphan-token into master 2023-04-25 00:23:44 +00:00
2 changed files with 203 additions and 104 deletions

103
README.md
View File

@ -32,7 +32,7 @@ Log out. Never again use the `root` token unless there's a good reason.
Get the Vault command-line client via [vaultproject.io/downloads](https://www.vaultproject.io/downloads). It'll install the Vault service itself along with the command-line client. Just ignore the service or keep it disabled via `systemctl disable --now vault.service`. You only need the `vault` binary. Get the Vault command-line client via [vaultproject.io/downloads](https://www.vaultproject.io/downloads). It'll install the Vault service itself along with the command-line client. Just ignore the service or keep it disabled via `systemctl disable --now vault.service`. You only need the `vault` binary.
* Authenticate against Vault: ### Authenticate against Vault:
``` ```
export VAULT_ADDR='https://fully.qualified.domain.name/' export VAULT_ADDR='https://fully.qualified.domain.name/'
vault login vault login
@ -42,7 +42,9 @@ Get the Vault command-line client via [vaultproject.io/downloads](https://www.va
``` ```
Enter your personal alias' token, do not ever again use the `root` token. Enter your personal alias' token, do not ever again use the `root` token.
* Enable audit file device (in non-Vault-speak "the audit log file"): ### Auditing
Enable audit file device (in non-Vault-speak "the audit log file"):
``` ```
# Enable # Enable
vault audit enable file file_path=/vault/logs/audit.log vault audit enable file file_path=/vault/logs/audit.log
@ -60,7 +62,10 @@ Get the Vault command-line client via [vaultproject.io/downloads](https://www.va
---- ---- ----------- ---- ---- -----------
file/ file n/a file/ file n/a
``` ```
* We're going to allow all human users to change their own `userpass` password. The policy to do so is at [policies/human/change-own-password.hcl](policies/human/change-own-password.hcl). For a hands-on example of an actual password change via HTTP API see [Hands-on](#hands-on) but first:
### Humans may change their own password
We're going to allow all human users to change their own `userpass` password. The policy to do so is at [policies/human/change-own-password.hcl](policies/human/change-own-password.hcl). For a hands-on example of an actual password change via HTTP API see [Hands-on](#hands-on) but first:
* Before you can load the policy into Vault you need to replace the string `ACCESSOR` in it with _your_ particular `userpass` accessor. Get it like so: * Before you can load the policy into Vault you need to replace the string `ACCESSOR` in it with _your_ particular `userpass` accessor. Get it like so:
``` ```
@ -94,7 +99,9 @@ Get the Vault command-line client via [vaultproject.io/downloads](https://www.va
``` ```
Entity IDs are coming from `vault list identity/entity/id` and/or `vault read identity/entity/name/<name>`. Entity IDs are coming from `vault list identity/entity/id` and/or `vault read identity/entity/name/<name>`.
* Optionally [policies/cfgmgmt/cfgmgmt.hcl](policies/cfgmgmt/cfgmgmt.hcl) gets you started with read-only secrets access for example for a config management tool like Ansible. ### Ready-only secrets access
Optionally [policies/cfgmgmt/cfgmgmt.hcl](policies/cfgmgmt/cfgmgmt.hcl) gets you started with read-only secrets access for example for a config management tool like Ansible.
You'll want to create an Ansible entity and a `userpass` alias. Think of the alias as glue that ties an auth method to an entity. This in turn allows you to specify policy that applies to the entity, gets inherited by aliases and lastly inherited by auth methods. You'll want to create an Ansible entity and a `userpass` alias. Think of the alias as glue that ties an auth method to an entity. This in turn allows you to specify policy that applies to the entity, gets inherited by aliases and lastly inherited by auth methods.
@ -102,13 +109,17 @@ Get the Vault command-line client via [vaultproject.io/downloads](https://www.va
From here on out it's just more of what you already did, feel free to make this fit your own approach. From here on out it's just more of what you already did, feel free to make this fit your own approach.
* Optionally from [policies/kv-writer/kv-writer.hcl](policies/kv-writer/kv-writer.hcl) load a policy that allows affected entities to create `kv` secrets, create new versions for existing secrets and to traverse the UI directory structure of secrets. Entities with this policy will not be able to read secrets nor see if versions exist at a given location. ### Write-only access
Optionally from [policies/kv-writer/kv-writer.hcl](policies/kv-writer/kv-writer.hcl) load a policy that allows affected entities to create `kv` secrets, create new versions for existing secrets and to traverse the UI directory structure of secrets. Entities with this policy will not be able to read secrets nor see if versions exist at a given location.
Permission to also read/view secrets is commented out in the policy file in case you do need this feature. Permission to also read/view secrets is commented out in the policy file in case you do need this feature.
Assign the policy to a group as needed. Assign the policy to a group as needed.
* As a similar narrowly scoped use case consider a Zabbix monitoring instance that may need access to credentials, session IDs, tokens or other forms of authentication to monitor machines and services. ### Zabbix credentials storage
As a similar narrowly scoped use case consider a Zabbix monitoring instance that may need access to credentials, session IDs, tokens or other forms of authentication to monitor machines and services.
Here's one suggestion to set up the basics for Zabbix. Here's one suggestion to set up the basics for Zabbix.
@ -117,10 +128,13 @@ Get the Vault command-line client via [vaultproject.io/downloads](https://www.va
* Add an alias of type `userpass` to the entity. * Add an alias of type `userpass` to the entity.
* Within the `userpass` auth method create a user (an account if you will) with the same name as the alias you just created so in this case `zabbix`, set a password for the account * Within the `userpass` auth method create a user (an account if you will) with the same name as the alias you just created so in this case `zabbix`, set a password for the account
Now tie it all together by creating a group named `rbacgroup_zabbix`. Add the `zabbix` entity to it and make it use the policy `zabbix`. At this point the policy does not yet exist which is fine, you can set a policy name and Vault will offer to `Add new policy`, see screenshot below. Don't worry, this will not actually add a new policy - empty, broken or otherwise. Vault will simply link your group to the policy `zabbix` which does not exist. You'll get to that in a minute. Now tie it all together by creating a group named `rbacgroup_zabbix`. Add the `zabbix` entity to it and make it use the policy `zabbix`. At this point the policy does not yet exist which is fine, you can set a policy name and Vault will simply link your group to the policy `zabbix` which does not exist. You'll get to that in a minute.
Like so: Like so:
![Vault 1.11.3 Create Group menu](https://i.imgur.com/3Ni53BE.png)
![Vault 1.12.0 Create Group menu](https://i.imgur.com/mTbyZjk.png)
#### Group ID replacement
Next up check out [policies/zabbix/zabbix.hcl](policies/zabbix/zabbix.hcl). Do some light replacement before importing it into Vault. The policy file contains a few occurrences of the string `GROUPID`, replace them with the group ID of `rbacgroup_zabbix`. Next up check out [policies/zabbix/zabbix.hcl](policies/zabbix/zabbix.hcl). Do some light replacement before importing it into Vault. The policy file contains a few occurrences of the string `GROUPID`, replace them with the group ID of `rbacgroup_zabbix`.
* Via Vault's UI you can get the group ID at `Access > Groups > rbacgroup_zabbix`. * Via Vault's UI you can get the group ID at `Access > Groups > rbacgroup_zabbix`.
@ -171,6 +185,79 @@ Get the Vault command-line client via [vaultproject.io/downloads](https://www.va
https://f.q.d.n/ui/vault/secrets/kv/list/for_rbacgroup_zabbix https://f.q.d.n/ui/vault/secrets/kv/list/for_rbacgroup_zabbix
``` ```
### Permission to create orphan tokens
The next example will explain orphan tokens. If you've followed examples above your Vault instance will have an `administrators` group with an `administrator` policy assigned to it. Users in that group will already have `write` access to `auth/token/create-orphan` so you can just use one of your `administrators` entities to follow along.
### Periodic and orphan tokens
As an alternative to the Zabbix example above you may want a token that auto-renews itself as long as it gets regularly used and that can outlive its parent entity.
By default a token is associated with the entity that created it, as a consequence a token cannot outlive the maximum time to live configured for its parent entity. In order to decouple a token from its parent entity and for a token to live longer than its parent entity you can make it an _orphan_ token.
A token created with a `period` - a time value indicating its maximum time to live - is considered a _periodic_ token. Unless a token is also orphaned its time to live still remains limited to that of its parent entity.
The first few prep steps will sound familiar from the Zabbix paragraph above. For example's sake let's assume we want the `remco` file generator (see [github.com/HeavyHorst/remco](https://github.com/HeavyHorst/remco)) to have Vault access:
* Create an entity `remco` without a policy
* Add an alias of type `userpass` also named `remco` to the entity
* Within the `userpass` auth method create a user (an account if you will) with the same name as the alias you just created so in this case `remco`, set a password for the account
Create a group named `rbacgroup_remco`. Add the `remco` entity to it and make it use the policy `remco`. At this point the policy does not yet exist which is fine, you can set a policy name and Vault will simply link your group to the policy `remco` which does not exist. You'll get to that in a minute.
Next up we'll be working with [policies/remco/remco.hcl](policies/remco/remco.hcl). In that file replace `GROUPID` with the actual group ID of `rbacgroup_remco`, refer to paragraph [Group ID replacement](#group-id-replacement) for a how-to guide. Continue reading there until you reach the point talking about logging in to Vault as the newly created user then return here.
For our `remco` example application we want a periodic orphan token.
Log in to Vault with `userpass` and an account that has `write` access to `auth/token/create-orphan`, for example an administrator as detailed in [Permission to create orphan tokens](#permission-to-create-orphan-tokens) above. Get the account's token. Send the following API command to create a periodic orphan token:
```
curl --silent --location --header 'X-Vault-Token: <token>' \
--request POST \
--data '{"ttl":"768h","renewable":true,"display_name":"remco populates config files with secrets"}' \
'https://f.q.d.n/v1/auth/token/create-orphan'
```
We're choosing our `ttl` of 768 hours on purpose. This equals 32 days which is the default server setting in `max_lease_ttl` that any token created by a non-`root` user can have. Feel free to reconfigure this server-side on your end and to pick a longer `ttl` value as needed. For our use case 32 days is plenty of time.
Write down the generated `client_token`.
Lastly don't forget to create some key value pairs underneath `kv/rbacgroup_remco` that the token can access.
#### Token lifecycle management
Revoke an orphan token like so via Vault CLI client. See [Authenticate against Vault](#authenticate-against-vault) at the top for how to authenticate your Vault CLI client and then:
```
vault token revoke -accessor <token-accessor-here>.
```
Find all orphan tokens by their accessor like so. This requires `list` access to `auth/token/accessors`. Members of the `administrators` group outlined above have this.
```
vault list -format json auth/token/accessors |\
jq -r .[] |\
xargs -I '{}' vault token lookup -format json -accessor '{}' |\
jq -r 'select((.data.entity_id=="") and (.data.orphan==true) and (.data.path=="auth/token/create-orphan"))'
```
Output will for example look like:
```
{
"request_id": "170d8a93-7b61-9ec2-9df7-ad7a8ca0be88",
"lease_id": "",
"lease_duration": 0,
"renewable": false,
"data": {
"accessor": "66IzIsoOpXycYqF33JmfIb8G",
...
"entity_id": "",
...
},
"warnings": null
}
```
Where the `accessor` ID (here `66IzIsoOpXycYqF33JmfIb8G`) is what you're going to want to use in your CLI command `vault token revoke`.
## Clean-up ## Clean-up
If during any of the above steps you've used the Vault command-line client to authenticate against Vault with your `root` token make sure that client's `~/.vault-token` file is deleted. It contains the verbatim `root` token. If during any of the above steps you've used the Vault command-line client to authenticate against Vault with your `root` token make sure that client's `~/.vault-token` file is deleted. It contains the verbatim `root` token.

12
policies/remco/remco.hcl Normal file
View File

@ -0,0 +1,12 @@
# Allow listing secret parent-child connections (as in UI hierarchy). Subdir
# underneath 'kv' secrets engine will remain hidden though, user has to
# manually open up
# ${VAULT_ADDR}/ui/vault/secrets/kv/list/for_{{identity.groups.ids.GROUPID.name}}
path "kv/metadata/for_{{identity.groups.ids.GROUPID.name}}/*" {
capabilities = ["list"]
}
# Grant read-only access to secrets
path "kv/data/for_{{identity.groups.ids.GROUPID.name}}/*" {
capabilities = ["read"]
}