Vault. You may need to set the following environment variable with the correct
address of your Vault server to use this utility::
- export VAULT_ADDR='http://vault-server:8200'
+ export VAULT_ADDR='https://vault-server-fqdn:8200'
Vault secrets engines
=====================
Gateway can be configured to authenticate to Vault using the
`Token authentication method`_ or a `Vault agent`_.
+Most tokens in Vault have limited lifetimes and powers. The only
+sort of Vault token that does not have a lifetime are root tokens.
+For all other tokens, it is necesary to periodically refresh them,
+either by performing initial authentication, or by renewing the token.
+Ceph does not have any logic to perform either operation.
+The simplest best way to use Vault tokens with ceph is to
+also run the Vault agent and have it refresh the token file.
+When the Vault agent is used in this mode, file system permissions
+can be used to restrict who has the use of tokens.
+
+Instead of having Vault agent refresh a token file, it can be told
+to act as a proxy server. In this mode, Vault will add a token when
+necessary and add it to requests passed to it before forwarding them on
+to the real server. Vault agent will still handle token renewal just
+as it would when storing a token in the filesystem. In this mode, it
+is necessary to properly secure the network path rgw uses to reach the
+Vault agent, such as having the Vault agent listen only to localhost.
+
+Token policies for the object gateway
+-------------------------------------
+
+All Vault tokens have powers as specified by the polices attached
+to that token. Multiple policies may be associated with one
+token. You should only use the policy necessary for your
+configuration.
+
+When using the kv secret engine with the object gateway::
+
+ vault policy write rgw-kv-policy -<<EOF
+ path "secret/data/*" {
+ capabilities = ["read"]
+ }
+ EOF
+
+When using the transit secret engine with the object gateway::
+
+ vault policy write rgw-transit-policy -<<EOF
+ path "transit/keys/*" {
+ capabilities = [ "create", "update" ]
+ denied_parameters = {"exportable" = [], "allow_plaintext_backup" = [] }
+ }
+
+ path "transit/keys/*" {
+ capabilities = ["read", "delete"]
+ }
+
+ path "transit/keys/" {
+ capabilities = ["list"]
+ }
+
+ path "transit/keys/+/rotate" {
+ capabilities = [ "update" ]
+ }
+
+ path "transit/*" {
+ capabilities = [ "update" ]
+ }
+ EOF
+
+If you had previously used an older version of ceph with the
+transit secret engine, you might need the following policy::
+
+ vault policy write old-rgw-transit-policy -<<EOF
+ path "transit/export/encryption-key/*" {
+ capabilities = ["read"]
+ }
+ EOF
+
+
Token authentication
--------------------
-.. note:: Token authentication is not recommended for production environments.
+.. note: Never use root tokens with ceph in production environments.
The token authentication method expects a Vault token to be present in a
plaintext file. The Object Gateway can be configured to use token authentication
with the following settings::
rgw crypt vault auth = token
- rgw crypt vault token file = /etc/ceph/vault.token
- rgw crypt vault addr = http://vault-server:8200
+ rgw crypt vault token file = /run/.rgw-vault-token
+ rgw crypt vault addr = https://vault-server-fqdn:8200
+Adjust these settinsg to match your configuration.
For security reasons, the token file must be readable by the Object Gateway
-only. Also, the Object Gateway should be given a Vault token with a restricted
-policy that allows it to fetch keyrings from a specific path only. Such a policy
-can be created in Vault using the command line utility as in the following
-examples::
+only.
- vault policy write rgw-kv-policy -<<EOF
- path "secret/data/*" {
- capabilities = ["read"]
- }
- EOF
+You might set up vault agent as follows::
- vault policy write rgw-transit-policy -<<EOF
- path "transit/export/encryption-key/*" {
- capabilities = ["read"]
- }
- EOF
+ vault write auth/approle/role/rgw-ap \
+ token_policies=rgw-transit-policy,default \
+ token_max_ttl=60m
-Once the policy is created, a token can be generated by a Vault administrator::
+Change the policy here to match your configuration.
- vault token create -policy=rgw-kv-policy
+Get the role-id::
-Sample output::
+ vault read auth/approle/role/rgw-ap/role-id -format=json | \
+ jq -r .data.role_id
+
+Store the output in some file, such as /usr/local/etc/vault/.rgw-ap-role-id
+
+Get the secret-id::
+
+ vault read auth/approle/role/rgw-ap/role-id -format=json | \
+ jq -r .data.role_id
+
+Store the output in some file, such as /usr/local/etc/vault/.rgw-ap-secret-id
+
+Create configuration for the Vault agent, such as::
+
+ pid_file = "/run/rgw-vault-agent-pid"
+ auto_auth {
+ method "AppRole" {
+ mount_path = "auth/approle"
+ config = {
+ role_id_file_path ="/usr/local/etc/vault/.rgw-ap-role-id"
+ secret_id_file_path ="/usr/local/etc/vault/.rgw-ap-secret-id"
+ remove_secret_id_file_after_reading ="false"
+ }
+ }
+ sink "file" {
+ config = {
+ path = "/run/.rgw-vault-token"
+ }
+ }
+ }
+ vault {
+ address = "https://vault-server-fqdn:8200"
+ }
+
+Then use systemctl or another method of your choice to run
+a persistent daemon with the following arguments::
- Key Value
- --- -----
- token s.72KuPujbc065OdWB71poOmIq
- token_accessor jv95ZYBUFv6Ss84x7SCSy6lZ
- token_duration 768h
- token_renewable true
- token_policies ["default" "rgw-kv-policy"]
- identity_policies []
- policies ["default" "rgw-kv-policy"]
+ /usr/local/bin/vault agent -config=/usr/local/etc/vault/rgw-agent.hcl
-The actual token, displayed in the ``Value`` column of the first line of the
-output, must be saved in a file as plaintext.
+Once the vault agent is running, the token file should be populated
+with a valid token.
Vault agent
-----------
settings::
rgw crypt vault auth = agent
- rgw crypt vault addr = http://localhost:8100
+ rgw crypt vault addr = http://127.0.0.1:8100
+
+You might set up vault agent as follows::
+
+ vault write auth/approle/role/rgw-ap \
+ token_policies=rgw-transit-policy,default \
+ token_max_ttl=60m
+
+Change the policy here to match your configuration.
+
+Get the role-id:
+ vault read auth/approle/role/rgw-ap/role-id -format=json | \
+ jq -r .data.role_id
+
+Store the output in some file, such as /usr/local/etc/vault/.rgw-ap-role-id
+
+Get the secret-id:
+ vault read auth/approle/role/rgw-ap/role-id -format=json | \
+ jq -r .data.role_id
+
+Store the output in some file, such as /usr/local/etc/vault/.rgw-ap-secret-id
+
+Create configuration for the Vault agent, such as::
+
+ pid_file = "/run/rgw-vault-agent-pid"
+ auto_auth {
+ method "AppRole" {
+ mount_path = "auth/approle"
+ config = {
+ role_id_file_path ="/usr/local/etc/vault/.rgw-ap-role-id"
+ secret_id_file_path ="/usr/local/etc/vault/.rgw-ap-secret-id"
+ remove_secret_id_file_after_reading ="false"
+ }
+ }
+ }
+ cache {
+ use_auto_auth_token = true
+ }
+ listener "tcp" {
+ address = "127.0.0.1:8100"
+ tls_disable = true
+ }
+ vault {
+ address = "https://vault-server-fqdn:8200"
+ }
+
+Then use systemctl or another method of your choice to run
+a persistent daemon with the following arguments::
+
+ /usr/local/bin/vault agent -config=/usr/local/etc/vault/rgw-agent.hcl
+
+Once the vault agent is running, you should find it listening
+to port 8100 on localhost, and you should be able to interact
+with it using the vault command.
Vault namespaces
================
Using the Transit engine
------------------------
-Keys created with the Transit engine must be exportable in order to be used for
-server-side encryption with the Object Gateway. An exportable key can be created
-with the command line utility as follows::
+Keys created for use with the Transit engine should no longer be marked
+exportable. They can be created with::
- vault write -f transit/keys/mybucketkey exportable=true
+ vault write -f transit/keys/mybucketkey
The command above creates a keyring, which contains a key of type
``aes256-gcm96`` by default. To verify that the key was correctly created, use
the following command::
- vault read transit/export/encryption-key/mybucketkey/1
+ vault read transit/mybucketkey
Sample output::
Key Value
--- -----
- keys map[1:-gbTI9lNpqv/V/2lDcmH2Nq1xKn6FPDWarCmFM2aNsQ=]
- name mybucketkey
- type aes256-gcm96
-
-Note that in order to read the key created with the Transit engine, the full
-path must be provided including the key version.
+ derived false
+ exportable false
+ name mybucketkey
+ type aes256-gcm96
Configure the Ceph Object Gateway
=================================
Choose the Vault authentication method, e.g.::
rgw crypt vault auth = token
- rgw crypt vault token file = /etc/ceph/vault.token
- rgw crypt vault addr = http://vault-server:8200
+ rgw crypt vault token file = /run/.rgw-vault-token
+ rgw crypt vault addr = https://vault-server-fqdn:8200
Or::
rgw crypt vault prefix = /v1/secret/data
-Or, in the case of exportable transit keys::
+Or, when using the transit secret engine::
- rgw crypt vault prefix = /v1/transit/export/encryption-key
+ rgw crypt vault prefix = /v1/transit
In the example above, the Gateway would only fetch transit encryption keys under
-``http://vault-server:8200/v1/transit/export/encryption-key``.
+``https://vault-server:8200/v1/transit``.
+
+Transit engine compatibility support
+------------------------------------
+The transit engine has compatibility support for previous
+versions of ceph, which used the transit engine as a simple key store.
+
+There is a a "compat" option which can be given to the transit
+engine to configure the compatibility support,
+
+To entirely disable backwards support, use::
+
+ rgw crypt vault secret engine = transit compat=0
+
+This will be the default in future verisons. and is safe to use
+for new installs using the current version.
+
+This is the normal default with the current version::
+
+ rgw crypt vault secret engine = transit compat=1
+
+This enables the new engine for newly created objects,
+but still allows the old engine to be used for old objects.
+In order to access old and new objects, the vault token given
+to ceph must have both the old and new transit policies.
+
+To force use of only the old engine, use::
+
+ rgw crypt vault secret engine = transit compat=2
+
+This mode is automatically selected if the vault prefix
+ends in export/encryption-key, which was the previously
+documented setting.
Upload object
=============
aws --endpoint=http://radosgw:8000 s3 cp plaintext.txt s3://mybucket/encrypted.txt --sse=aws:kms --sse-kms-key-id myproject/mybucketkey
-As an example, for the transit engine, using the AWS command-line client::
+As an example, for the transit engine (new flavor), using the AWS command-line client::
- aws --endpoint=http://radosgw:8000 s3 cp plaintext.txt s3://mybucket/encrypted.txt --sse=aws:kms --sse-kms-key-id mybucketkey/1
+ aws --endpoint=http://radosgw:8000 s3 cp plaintext.txt s3://mybucket/encrypted.txt --sse=aws:kms --sse-kms-key-id mybucketkey
The Object Gateway will fetch the key from Vault, encrypt the object and store
it in the bucket. Any request to download the object will make the Gateway
http://vaultserver:8200/v1/secret/data/myproject/mybucketkey
-In the transit engine example above, the Gateway would fetch the secret from::
+In the transit engine example above, the Gateway would encrypt the secret using this key::
- http://vaultserver:8200/v1/transit/export/encryption-key/mybucketkey/1
+ http://vaultserver:8200/v1/transit/mybucketkey
.. _Server-Side Encryption: ../encryption
.. _Vault: https://www.vaultproject.io/docs/