VMware Secrets Manager

VSecM Architecture

Introduction

This section discusses VMware Secrets Manager architecture and building blocks in greater detail: We will cover VMware Secrets Manager’s system design and project structure.

You don’t have to know about these architectural details to use VMware Secrets Manager; however, understanding how VMware Secrets Manager works as a system can prove helpful when you want to extend, augment, or optimize VMware Secrets Manager.

Also, if you want to contribute to the VMware Secrets Manager source code, knowing what happens under the hood will serve you well.

Components of VMware Secrets Manager

VMware Secrets Manager (VSecM), as a system, has the following components.

SPIRE

SPIRE is not strictly a part of VMware Secrets Manager. However, VMware Secrets Manager uses SPIRE to establish an Identity Control Plane.

SPIRE is what makes communication within VMware Secrets Manager components and workloads possible. It dispatches x.509 SVID Certificates to the required parties to make secure mTLS communication possible.

Check out the official SPIFFE/SPIRE documentation for more information about how SPIRE works internally.

It Is More SPIFFE than SPIRE

Technically, any SPIFFE-compatible Identity Control Plane can be used with VMware Secrets Manager. However, only SPIRE comes as part of the default installation.

VSecM Safe

vsecm-safe stores secrets and dispatches them to workloads.

VSecM Sidecar

vsecm-sidecar is a sidecar that facilitates delivering secrets to workloads.

VSecM Sentinel

vsecm-sentinel is a pod you can shell in and do administrative tasks such as registering secrets for workloads.

Here is a simplified overview of how various actors on a VMware Secrets Manager system interact with each other:

VMware Secrets Manager Components

VSecM Keygen

vsecm-keygen is a utility that generates the root key that VSecM Safe uses, if manual input mode is set. By default, VSecM Safe generates the root key automatically; however, you can opt out from this if you want to control the root key yourself and provide your own key.

You can check out the CLI documentation for more information about how to use VSecM Keygen.

You can also use VSecM Keygen to decrypt secrets that VSecM Safe stores. This will require you to provide the root key that VSecM Safe uses. Again, can check out the CLI documentation for more information.

VSecM Keystone

// TODO: explain.

VSecM Init Container

// TODO: explain.

High-Level Architecture

Dispatching Identities

SPIRE delivers short-lived X.509 SVIDs to VMware Secrets Manager components and consumer workloads.

VSecM Sidecar periodically talks to VSecM Safe to check if there is a new secret to be updated.

Open the image above in a new tab or window to see it in full size:

VMware Secrets Manager Sidecar

Alternatively, you can use VSecM SDK to retrieve secrets from VSecM Safe programmatically:

Using VSecM SDK

Creating Secrets

VSecM Sentinel is the only place where secrets can be created and registered to VSecM Safe.

Creating Secrets

Component and Workload SPIFFE ID Schemas

SPIFFE ID format wor workloads is as follows:

spiffe://vsecm.com/workload/$workloadName
  /ns/{{ .PodMeta.Namespace }}
  /sa/{{ .PodSpec.ServiceAccountName }}
  /n/{{ .PodMeta.Name }}

For the non-vsecm-system workloads that Safe injects secrets, $workloadName is determined by the workload’s ClusterSPIFFEID CRD.

For vsecm-system components, we use vsecm-safe and vsecm-sentinel for the $workloadName (along with other attestors such as attesting the service account and namespace):

spiffe://vsecm.com/workload/vsecm-safe
  /ns/{{ .PodMeta.Namespace }}
  /sa/{{ .PodSpec.ServiceAccountName }}
  /n/{{ .PodMeta.Name }}
spiffe://vsecm.com/workload/vsecm-sentinel
  /ns/{{ .PodMeta.Namespace }}
  /sa/{{ .PodSpec.ServiceAccountName }}
  /n/{{ .PodMeta.Name }}

Persisting Secrets

VSecM Safe uses age encryption by default to securely persist the secrets to disk so that when its Pod is replaced by another Pod for any reason (eviction, crash, system restart, etc.) it can retrieve secrets from a persistent storage.

You Can Swap the Encryption Mechanism

In FIPS-compliant environments, you can use VMware Secrets Manager FIPS-compliant container images that use AES-256-GCM encryption instead of Age.

Check out the Configuration section for more details.

Also, you can opt out from auto-generating the private and public keys and provide your own keys. However, when you do this, you will have to manually unlock VSecM Safe by providing your keys every time it crashes. If you let VSecM Safe auto-generate the keys, you won’t have to do this; so you can #sleepmore.

Again, check out the Configuration section for more details.

Since decryption is relatively expensive, once a secret is retrieved, it is kept in memory and served from memory for better performance. Unfortunately, this also means the amount of secrets you have for all your workloads has to fit in the memory you allocate to VSecM Safe.

Bootstrapping Flow of VSecM Safe

To persist secrets, VSecM Safe needs a way to generate and securely store the initial cryptographic keys that are utilized for decrypting and encrypting the secrets, respectively. After generation, the keys are stored in a Kubernetes Secret that only VSecM Safe can access.

Here is a sequence diagram of the VSecM Safe bootstrapping flow:

VSecM Safe Bootstrapping

Note that, until bootstrapping is complete, VSecM Safe will not respond to any API requests that you make from VSecM Sentinel.

Here is a simplified version of the bootstrapping flow without taking the “manual key input” option into account:

VSecM Safe Bootstrapping

VSecM Safe Pod Layout

Here is what an VSecM Safe Pod looks like at a high level:

VSedM Safe Pod

  • spire-agent-socket: Is a SPIFFE CSI Driver-managed volume that enables SPIRE to distribute X.509 SVIDs to the Pod.
  • /data is the volume where secrets are stored in an encrypted format. You are strongly encouraged to use a persistent volume for production setups to retrieve the secrets if the Pod crashes and restarts.
  • /key is where the secret vsecm-root-key mounts. For security reasons, ensure that only the pod VSecM Safe can read and write to vsecm-root-key and no one else has access. In this diagram, this is achieved by assigning a vsecm-secret-readwriter role to VSecM Safe and using that role to update the secret. Any pod that does not have the role will be unable to read or write to this secret.

If the main container does not have a public/private key pair in memory, it will attempt to retrieve it from the /key volume. If that fails, it will generate a brand new key pair and then store it in the vsecm-root-key secret.

Template Transformation and K8S Secret Generation

VSecM enables you to transform the secrets you register with VSecM Safe using Go template transformations before storing them. This is useful when you want to store a secret in a format that is different from the format you want to use in your workloads.

You can also prefix k8s: to the name of the workload to create a Kubernetes Secret object with the transformed secret. This is useful when you want to inject the secret to a workload using a Kubernetes Secret object instead of VSecM Sidecar or VSecM SDK.

Check out the examples folder for examples of how to use VSecM to transform secrets and generate Kubernetes Secret objects.

Liveness and Readiness Probes

VSecM Safe and VSecM Sentinel use liveness and readiness probes. These probes are tiny web servers that serve at ports 8081 and 8082 by default, respectively.

You can set VSECM_PROBE_LIVENESS_PORT (default :8081) and VSECM_PROBE_READINESS_PORT (default :8082) environment variables to change the ports used for these probes.

When the service is healthy, the liveness probe will return an HTTP 200 success response. When the service is ready to receive traffic, the readiness probe will return an HTTP 200 success response.

Conclusion

This was a deeper overview of VMware Secrets Manager architecture. If you have further questions, feel free to join the VMware Secrets Manager community on Slack and ask them out.

Suggest edits ✏️

results matching ""

    No results matching ""

    «« previous next »»