Configuring Veeam Kasten Encryption
Veeam Kasten supports encryption for data and metadata stored in an object store or an NFS file store (e.g., for cross-cloud snapshot migration) via the use of the AES-256-GCM encryption algorithm. Veeam Kasten encryption is always enabled for external data and metadata (more information below), it cannot be disabled.
To maintain the security of the primary encryption key, Passkeys are used to perform envelope encryption. By default, Kasten will create a passphrase-based Passkey. Users can configure multiple passkeys, even from different key management stores, to facilitate key rotation and enhance security by reducing the risk of key compromise. Users may delete passkeys as long as at least one valid passkey remains. This approach ensures flexible key management with uninterrupted access to backup data.
A Passkey API resource is used to add, edit, list or remove a Passkey used for data and metadata encryption.
Bootstrapping Passkeys Before Install
If you do not specify a cluster secret, a Passkey with a random
passphrase will be generated by Veeam Kasten during install. The
randomly generated Passkey can be changed via the Changing
Passkeys instructions.
However, if the passphrase needs to be specified before install, it can
be done via the creation of a Kubernetes secret with a well-known name
(k10-cluster-passphrase
) in the namespace you will install Veeam
Kasten in (default kasten-io
):
Once the cluster secret is set or auto-generated, do not modify or delete the cluster secret directly, please follow the Passkey change workflow below.
Passphrases
A passphrase is used to protect the encryption key used by Veeam Kasten to encrypt application data.
$ kubectl create secret generic k10-cluster-passphrase \
--namespace kasten-io \
--from-literal passphrase=<key>
The Passkey passphrase should be stored separately in a secure location for Veeam Kasten Disaster Recovery.
AWS Customer Managed Keys
An AWS Customer Managed Key (CMK) can also be used to protect the encryption key used by Veeam Kasten to encrypt application data.
$ kubectl create secret generic k10-cluster-passphrase \
--namespace kasten-io \
--from-literal awscmkkeyid=arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
IAM must be configured for Veeam Kasten. Refer to Using AWS IAM Roles for more information on IAM roles.
AWS keys are required while installing Veeam Kasten in order to use the AWS Customer Manager Key. The IAM role is an optional value to be configured if Veeam Kasten should assume a specific role.
$ helm install k10 kasten/k10 --namespace=kasten-io \
--set secrets.awsAccessKeyId="${AWS_ACCESS_KEY_ID}" \
--set secrets.awsSecretAccessKey="${AWS_SECRET_ACCESS_KEY}" \
--set secrets.awsIamRole="${AWS_IAM_ROLE_ARN}"
Following is the AWS policy needed for access to AWS KMS.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"kms:Decrypt",
"kms:Encrypt"
],
"Resource": "arn:aws:kms:::key/${KMS_KEY_ID}"
}
]
}
Additionally, the user/role needs to be added to the corresponding CMK policy as well.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::<AWS ACCOUNT>:role/<ROLE NAME>"
]
},
"Action": "kms:*",
"Resource": "*"
}
]
}
HashiCorp Vault Transit Secrets Engine
HashiCorp Vault Transit Secrets Engine can also be used to protect the encryption key used by Veeam Kasten to encrypt application data.
Refer to the Vault Transit Secret Engine documentation for more information on configuring the transit secret engine.
$ kubectl create secret generic k10-cluster-passphrase \
--namespace kasten-io \
--from-literal vaulttransitkeyname=<vault_transit_key_name> \
--from-literal vaulttransitpath=<vault_transit_path>
In addition to the Transit Secret Engine setup, Veeam Kasten needs to be authorized to access Vault. Either token or kubernetes authentication is supported for the Vault server.
Token Auth
The token
should be provided via a secret.
This method will be deprecated in the future in favor of kubernetes auth
$ kubectl create secret generic vault-creds \
--namespace kasten-io \
--from-literal vault_token=<vault_token>
This may cause the token to be stored in shell history. It is recommended to regularly rotate the token used for accessing Vault.
When a new token is generated, the vault-creds
secret should be
updated with the new token provided below:
$ kubectl patch secret vault-creds \
--namespace kasten-io \
--type='json' -p='[{"op" : "replace" ,"path" : "/data/vault_token" ,"value" : "<updated_vault_token>"}]'
Credentials can be provided with the Helm install or upgrade command using the following flags.
--set vault.address=<vault_server_address> \
--set vault.secretName=vault-creds
Kubernetes Auth
Refer to Configuring Vault Server For Kubernetes Auth prior to installing Veeam Kasten.
After setup is done, credentials can be provided with the Helm install or upgrade command using the following flags:
--set vault.address=<vault_server_address> \
--set vault.role=<vault_role> \
--set vault.serviceAccountTokenPath=<service_account_token_path>
vault.role
is needed to authenticate via kubernetes service account
tokens.
vault.serviceAccountTokenPath
can be left blank if the service account
path was not changed from the default of:
/var/run/secrets/kubernetes.io/serviceaccount/token
vault.secretName
can be provided to the helm install to do a
best-effort fallback to token auth if kubernetes authentication fails.
If not present and kubernetes authentication fails, then the primary key
encryption will not succeed and will return an error.
PassKey Management
Creating Passkeys
A Passkey that represents a passphrase, expects a Kubernetes Secret to be provided which contains the passphrase. This can be done via the creation of a Kubernetes secret in the Veeam Kasten namespace:
$ kubectl create secret generic <secret-name> \
--namespace kasten-io \
--from-literal passphrase=<key>
As shown below, this secret can then be used to create a Passkey. Note that Passkeys are non-namespaced.
$ cat > sample-passkey.yaml <<EOF
apiVersion: vault.kio.kasten.io/v1alpha1
kind: Passkey
metadata:
name: passkey1
spec:
secret:
## Reference to the passkey secret
name: <secret-name>
namespace: kasten-io
EOF
$ kubectl create -f sample-passkey.yaml
vault.kio.kasten.io/passkey1 created
A Passkey can also be used to represent an AWS KMS Customer Managed Key(CMK). The AWS CMK key ID can be provided directly in the passkey.
$ cat > sample-passkey.yaml <<EOF
apiVersion: vault.kio.kasten.io/v1alpha1
kind: Passkey
metadata:
name: passkey2
spec:
awscmkkeyid: arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
EOF
$ kubectl create -f sample-passkey.yaml
vault.kio.kasten.io/passkey2 created
A Passkey
can also be used to represent a HashiCorp Vault Transit
Secrets Engine. The Vault Transit key name and mount path can be
provided directly in the passkey, as shown below.
In addition, a vault authentication role and path to the service account
token used for Vault's Kubernetes Authentication method can be passed
in, vaultauthrole
and vaultk8sserviceaccounttokenpath
, respectively.
This will override those values originally set via the helm install
Kubernetes Auth.
If using Token Auth,
passing in these two values will have the effect of upgrading the
authentication method from Token to Kubernetes. Please ensure your vault
server is properly configured as shown in
Configuring Vault Server for Kubernetes Auth before adding these to the Passkey
.
$ cat > sample-passkey.yaml <<EOF
apiVersion: vault.kio.kasten.io/v1alpha1
kind: Passkey
metadata:
name: passkey3
spec:
vaulttransitkeyname: my-key
vaulttransitpath: my-transit-path
vaultauthrole: my-auth-role
vaultk8sserviceaccounttokenpath: /var/run/secrets/kubernetes.io/serviceaccount/token
EOF
$ kubectl create -f sample-passkey.yaml
vault.kio.kasten.io/passkey3 created
Listing Passkeys
To list all Passkeys, simply run:
$ kubectl get passkeys.vault.kio.kasten.io
NAME VALID
passkey1 true
passkey2 true
Getting Passkeys
To get a specific Passkey, run:
$ kubectl get passkeys.vault.kio.kasten.io passkey1
NAME VALID
passkey1 true
You may see additional Passkey detail by using the -o yaml
option:
$ kubectl get passkeys.vault.kio.kasten.io passkey1 -o yaml
apiVersion: vault.kio.kasten.io/v1alpha1
metadata:
name: passkey1
creationtimestamp: <creation-time>
status:
valid: true
state: Added to Catalog
Deleting Passkeys
You can delete existing Passkeys if they are no longer required. If only a single Passkey exists, it cannot be deleted.
$ kubectl delete passkeys.vault.kio.kasten.io passkey1
vault.kio.kasten.io/passkey1 deleted