This is snapshot of VSecM’s documentation at version v0.21.4.
Check out the latest version of the documentation.

The next VSecM Contributor Sync will be on…
Thursday, 2024-01-25 at 8:00am Pacific time.

VSecM CLI

edit this page on GitHub ✏️

Introduction

This section contains usage examples and documentation for VSecM Sentinel’s Command Line Interface (CLI).

Finding VSecM Sentinel

First, find which pod belongs to vsecm-system:

kubetctl get po -n vsecm-system

The response to the above command will be similar to the following:

NAME                              READY
vsecm-safe-5f6948c84c-vkrdh       1/1
vsecm-sentinel-5998b5dbfc-lvw44   1/1

There, vsecm-sentinel-5998b5dbfc-lvw44 is the name of the Pod you’d need.

You can also execute a script similar to the following to save the Pod’s name into an environment variable:

SENTINEL=$(kubectl get po -n vsecm-system \
  | grep "vsecm-sentinel-" | awk '{print $1}')

In the following examples, we’ll use $SENTINEL in lieu of the VSecM Sentinel’s Pod name.

Displaying Help Information

VSecM Sentinel has a binary called safe that can be used to interact with VSecM Safe API. You can use the following command to display help information for safe:

kubectl exec $SENTINEL -n vsecm-system -- safe --help

About --help

The output of safe --help will depend on the version of safe you use; however, it will contain useful information about how to use the program.

Registering a Secret for a Workload

Given our workload has the SPIFFE ID "spiffe://vsecm.com/workload/billing/: …[truncated]"

kubectl exec $SENTINEL -n vsecm-system -- safe \
  -w billing \
  -s "very secret value"

will register the secret "very secret value" to billing.

Registering Multiple Secrets

You can use the -a (append) argument to register more than one secret to a workload.

kubectl exec $SENTINEL -n vsecm-system -- safe \
  -w billing \
  -s "first part of the token" \
  -a

kubectl exec $SENTINEL -n vsecm-system -- safe \
  -w billing \
  -s "second part of the token" \
  -a

Encrypting a Secret

Use the -e flag to encrypt a secret.

kubectl exec $SENTINEL -n vsecm-system -- safe \
  -s "very secret value" \
  -e 

# The above command outputs an encrypted string that can be
# securely stored anywhere, including source control systems.

Registering an Encrypted Secret

Again, -e flag can be used to register an encrypted secret to a workload:

kubectl exec $SENTINEL -n vsecm-system -- safe \
  -w billing \
  -s $ENCRYPTED_SECRET \
  -e

Deleting a Secret

To delete the secret associated to a workload, use the -d flag:

kubectl exec $SENTINEL -n vsecm-system -- safe \
  -w billing \
  -d

Choosing a Backing Store

The registered secrets will be encrypted and backed up to VSecM Safe’s Kubernetes volume by default. This behavior can be configured by changing the VSECM_SAFE_BACKING_STORE environment variable that VSecM Safe sees. In addition, this behavior can be overridden on a per-secret basis too.

The following commands stores the secret to the backing volume (default behavior):

kubectl exec $SENTINEL -n vsecm-system -- safe \
  -w billing \
  -s "very secret value" \
  -b file

This one, will not store the secret on file; the secret will only be persisted in memory, and will be lost if VSecM Sentinel needs to restart:

kubectl exec $SENTINEL -n vsecm-system -- safe \
  -w billing \
  -s "very secret value" \
  -b memory

The following will stored the secret on the cluster itself as a Kubernetes Secret. The value of the secret will be encrypted with the public key of VSecM Safe before storing it on the Secret.

kubectl exec $SENTINEL -n vsecm-system -- safe \
  -w billing \
  -s "very secret value" \
  -b cluster

Template Transformations

You can transform how the stored secret is displayed to the consuming workloads:

kubectl exec "$SENTINEL" -n vsecm-system -- safe \
  -w "example" \
  -s '{"username": "root", \
    "password": "SuperSecret", \
    "value": "VSecMRocks"}' \
  -t '{"USER":"{{.username}}", \
    "PASS":"{{.password}}", \
    "VALUE": "{{.value}}"}'

When the workload fetches the secret through the workload API, this is what it sees as the value:

{"USER": "root", "PASS": "SuperSecret", "VALUE": "VSecMRocks"}

Instead of this default transformation, you can output it as yaml too:

kubectl exec "$SENTINEL" -n vsecm-system -- safe \
  -w "example" \
  -s '{"username": "root", \
    "password": "SuperSecret", \
    "value": "VSecMRocks"}' \
  -t '{"USER":"{{.username}}", \
    "PASS":"{{.password}}", \
    "VALUE": "{{.value}}"}' \
  -f yaml

The above command will result in the following secret value to the workload that receives it:

USER: root
PASS: SuperSecret
VALUE: VSecMRocks

"json" Is the Default Value

If you don’t specify the -f flag, it will default to "json".

You can create a YAML secret value without the -t flag too. In that case VSecM Safe will assume an identity transformation:

kubectl exec "$SENTINEL" -n vsecm-system -- safe \
  -w "example" \
  -s '{"username": "root", \
    "password": "SuperSecret", \
    "value": "VSecMRocks"}' \
  -f yaml

The above command will result in the following secret value to the workload that receives it:

username: root
password: SuperSecret
value: VSecMRocks

If you provide -f json as the format argument, the secret will have to be a strict JSON. Otherwise, VSecM Sentinel will try to come up with a reasonable value, and not raise an error; however the output will likely be in a format that the workload is not expecting.

Gotcha

If -t is given, the -s argument will have to be a valid JSON regardless of what is chosen for -f.

The following is also possible:

kubectl exec "$SENTINEL" -n vsecm-system -- safe \
  -w "example" \
  -s 'USER»»»{{.username}}'

and will result in the following as the secret value for the workload:

USER»»»root

Or, equivalently:

kubectl exec "$SENTINEL" -n vsecm-system -- safe \
  -w "example" \
  -s 'USER»»»{{.username}}' \
  -f json

Will provide the following to the workload:

USER»»»root

Similarly, the following will not raise an error:

kubectl exec "$SENTINEL" -n vsecm-system -- safe \
  -w "example" \
  -s 'USER»»»{{.username}}' \
  -f yaml

To transform the value to YAML, or JSON, -s has to be a valid JSON.

Creating Kubernetes Secrets

VSecM Safe-managed secrets can be interpolated onto Kubernetes secrets if a template transformation is given.

Let’s take the following as an example:

kubectl exec "$SENTINEL" -n vsecm-system -- safe \
  -w "billing" \
  -n "finance" \
  -s '{"username": "root", "password": "SuperSecret"}' \
  -t '{"USERNAME":"{{.username}}", "PASSWORD":"{{.password}}"' \
  -k

The -k flag hints VSecM Safe that the secret will be synced with a Kubernetes Secret. -n tells that the namespace of the secret is "finance".

Before running this command, a secret with the following manifest should exist in the cluster:

apiVersion: v1
kind: Secret
metadata:
  name: vsecm-secret-billing
  namespace: finance
type: Opaque

The vsecm-secret- prefix is required for VSecM Safe to locate the Secret. Also metadata.namespace attribute should match the namespace that’s provided with the -n flag to VSecM Sentinel.

After executing the command the secret will contain the new values in its data: section.

kubectl describe secret vsecm-secret-billing -n finance

# Output:
#   Name:         vsecm-secret-billing
#   Namespace:    finance
#   Labels:       <none>
#   Annotations:  <none>
#
#   Type:  Opaque
#
#   Data
#   ====
#   USERNAME:  137 bytes
#   PASSWORD:  196 bytes

Setting the Master Secret Manually

VSecM Safe uses a master secret to encrypt the secrets that are stored. Typically, this master secret is stored as a Kubernetes secret for your convenience. However, if you want you can set VSECM_MANUAL_KEY_INPUT to "true" and provide the master secret manually.

Although this approach enhances security, it also means that you will have to provide the master secret to VSecM Safe whenever the pod is evicted, or crashes, or restarts for any reason. Since, this brings a mild operational inconvenience, it is not enabled by default.

kubectl exec "$SENTINEL" -n vsecm-system -- vsecm \
  --input-keys "AGE-SECRET-KEY-1RZU…\nage1…\na6…ceec"
  
# Output:
#
# OK

results matching ""

    No results matching ""