Keeping your secrets private. Vault Project.
Bài đăng này đã không được cập nhật trong 3 năm
Every project contains secret configuration. Mostly such configurations are stored in .env
files or simply written into config.
When your project really scales up and moreover, secrets change time to time as a matter of security, a better way to store might be required.
There are several alternatives available and most have own purpose (Chef, Puppet, Amazon KMS, Keywhiz). in this article I am going to focus on the Vault Project by Hashicorp.
Concepts of Vault
Vault is an encrypted storage for sensitive data, which uses CLI commands and API endpoints to manage configuration and storage data.
All data is being stored using paths. Every path contains raw value or key/value collection.
Internal Vault ACL contains various permissions to paths.
Initially there is a single admin account which is being used to configure the service.
Sealing
One of main concepts of Vault is sealing. When the vault has been initialized it remains in sealed state and 5 unseal keys are provided.
$ vault init
Unseal Key 1: gaCU7aagpbDuR3L+VSNNXhBQf9Qer+aE+3XleiKwpX1p
Unseal Key 2: r44P+YqSdCwapXMBRHzcJ4/8lCl9+z4xtSjsAEykVKrx
Unseal Key 3: 0u8pfpL1g4wQCWF0WBWQZ3uzrqs2SmVVrP/1e2tZgzXc
Unseal Key 4: blUhaHwJycutj4jo8C3c0AE1dSXGQBZhIvXas9WEl+8c
Unseal Key 5: jHpbbaE0FPxMvdL/wIryDecOaLwmHf+AYQnEvLtcMNpr
Initial Root Token: 56152536-59da-6c77-4305-6d4990606d07
Every unseal key has an equal power, however at least 3 of them are required to unseal the vault.
This is very much useful for security cases when not any person must have full power over the service.
$ vault unseal r44P+YqSdCwapXMBRHzcJ4/8lCl9+z4xtSjsAEykVKrx
Sealed: true
Key Shares: 5
Key Threshold: 3
Unseal Progress: 2
Unseal Nonce: d3828c0f-fa17-f0af-9aad-5d045f9a2d7d
Once you suspect that vault has been compromised or there is any other need to hide all your secrets, any of admin users can seal the vault back.
$ vault seal
Vault is now sealed.
After sealing, not any data can be written or read.
Authentication and policies
The default authentication driver is using token and only one token for root user is created.
Vault supports custom-defined policies for everything. Which means you are free to configure access rights in any way your architecture needs. Also, there is no direct relation of authentication tokens and policies defined. So these procedures can be run independently.
New token is created by sending API or CLI request to /auth/token/create
endpoint.
$ vault write auth/token/create policies=webserver
Key Value
--- -----
token dfaabe18-b572-5245-8b6b-184c3ce13bc1
token_accessor 25e4c0a8-13a9-ff7e-23a1-ab96f7999268
token_duration 168h0m0s
token_renewable true
token_policies [default webserver]
Vault supports following authentication backends as well:
Storages
By default, development server uses in-memory storage, which is not persisted after shut down and does not provide much security.
Vault supports HCL or JSON files for configuration and supports various Storage backends including MySQL, PostgreSQL, Consul etc.
Storages are setup in configuration file and might require a little setup on the backend itself (like creating database in SQL). Read the docs for details.
storage "consul" {
address = "127.0.0.1:8500"
path = "vault"
}
Secret backends
Storing and accessing secrets is the main workflow required with vault. And here Vault provides a lot of convenient features for your connected service to integrate seamlessly.
Every secret backend requires setup. The simplest one is generic
which works as encrypted key/value storage.
It might be used for storing any sensitive data.
$ vault write secret/foo \
zip=zap \
ttl=1h
Success! Data written to: secret/foo
And accessing data:
$ vault read secret/foo
Key Value
--- -----
refresh_interval 3600
ttl 1h
zip zap
The most common use case for such backend is storing something like Oauth secret IDs.
Database backend
Database backend, on the opposite to generic backend, provides seamless integration features to any SQL database.
First you need to mount the database backend to Vault:
$ vault mount database
Successfully mounted 'database' at 'database’!
Next, you need to provide Vault connection url and credentials:
$ vault write database/config/mysql \
plugin_name=mysql-database-plugin \
connection_url="root:mysql@tcp(127.0.0.1:3306)/" \
allowed_roles="readonly,webserver"
And next comes the most interesting part. You can define any custom roles, which execute SQL queries upon create or destroy. This gives you complete freedom of ACL management and granting access rights as well as storing authentication data in your database itself.
$ vault write database/roles/readonly \
db_name=mysql \
creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT ON *.* TO '{{name}}'@'%';" \
default_ttl="1h" \
max_ttl="24h"
Success! Data written to: database/roles/readonly
Notice, how {{password}}
and {{name}}
variables are used. This means that upon each request to this role, new user will be created on SQL database and it’s credentials will be provided to your app.
$ vault read database/creds/readonly
Key Value
--- -----
lease_id database/creds/readonly/2f6a614c-4aa2-7b19-24b9-ad944a8d4de6
lease_duration 1h0m0s
lease_renewable true
password 8cab931c-d62e-a73d-60d3-5ee85139cd66
username v-root-e2978cd0-
Now your app can read the credentials from storage to access SQL database.
Other backends
Vault currently doesn’t support custom backends creation, but this feature will be available soon.
Currently list of backends includes SSH, Consul, AWS, PKI, etc.
Client libraries
How can Vault be connected to your app? Very simple. On most cases it is enough to setup HTTP client, with proper requests to Vault API.
For example the role reading CLI requests mentioned above, can be done using HTTP:
$ curl \
--header "X-Vault-Token: ..." \
https://vault.localhost/v1/database/roles/readonly
But if you want better integration with your code, take a look at official List of Libraries, which includes PHP, Node.js, Java, C#, Go, Ruby and even Ansible.
Conclusion
Currently Vault is one of the most advanced encrypted key/value storages and if you infrastructure intends to grow up, you definitely need to pay attention to it.
All rights reserved