From 3c216d25bed85fe335dcce5459cd8bdc069cf057 Mon Sep 17 00:00:00 2001 From: Ian Watts Date: Fri, 9 May 2025 14:19:21 -0700 Subject: [PATCH 1/5] Update secrets management docs --- .../example_secretstore_azure_key_vault.md | 124 ++++++++++++++++++ .../secrets-management/external-secrets.md | 83 ++++++++++++ .../vault-getting-started-guide.md | 10 +- .../vault-secrets-management-service.md | 10 +- 4 files changed, 217 insertions(+), 10 deletions(-) create mode 100644 src/docs/secrets-management/example_secretstore_azure_key_vault.md create mode 100644 src/docs/secrets-management/external-secrets.md diff --git a/src/docs/secrets-management/example_secretstore_azure_key_vault.md b/src/docs/secrets-management/example_secretstore_azure_key_vault.md new file mode 100644 index 00000000..50a6459c --- /dev/null +++ b/src/docs/secrets-management/example_secretstore_azure_key_vault.md @@ -0,0 +1,124 @@ +# Example SecretStore - Azure Key Vault + +## Summary +In order to use Azure Key Vault with the External Secrets Operator, a Service Principal must be created with the necessary permissions. A Secret is then created in the namespaces where SecretStore and ExternalSecret resources will be created. + +## Requirements +* Access to your Azure Key Vault +* Access to your OpenShift namespaces +* If using the Azure CLI, podman or docker is recommended + +An Azure service principal can be created using the CLI or by logging in to the Azure Portal. This document describes the CLI process. To use the portal to create the service principal, see [Register a Microsoft Entra app and create a service principal](https://learn.microsoft.com/en-us/entra/identity-platform/howto-create-service-principal-portal). + +## Official Documentation +https://external-secrets.io/latest/provider/azure-key-vault/ + +## Start the Azure CLI Container +We recommend that you run the Docker container for the Azure CLI, because installation of the CLI on your workstation involves a lot of packages and updates, which could potentially cause version issues for other tools you use, and because it's a lot to install for a single task. You are, of course, welcome to install the CLI directly on your workstation. + +You'll need a running Docker server or Podman machine. + +Start the container: +``` +podman run -it mcr.microsoft.com/azure-cli:cbl-mariner2.0 +``` + +Once it's running and you have a command prompt, run `az` to see version and help information. +``` +az +``` + +Log in to Azure by running `az login` in the container and following the instructions. +``` +root [ / ]# az login +To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code ... to authenticate. +``` + +Make a note of the subscription ID in the output of the login command. + +## Create the Service Principal +You will need: +* the subscription ID of your Azure account +* the name of your key vault +* the resource group of your key vault + +In the Azure CLI container, set environment variables, entering the appropriate values: +``` +export SUBSCRIPTION_ID="your-subscription-ID" +export KEY_VAULT_NAME="your-key-vault-name" +export RESOURCE_GROUP="your-key-vaults-resource-group" +export SP_NAME="name-of-service-principal-to-create" +``` + +Run the command to create the service principal: +``` +az ad sp create-for-rbac --name "${SP_NAME}" --role "Key Vault Secrets User" --scopes /subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.KeyVault/vaults/${KEY_VAULT_NAME} --sdk-auth +``` + +Save a copy of the output from this command - you'll need `clientId`, `clientSecret`, and `tenantId`. + +## Create the OpenShift Secret +Create a Secret in your OpenShift namespace. You can use the UI, if you like, or create a YAML manifest and apply it. +``` +kind: Secret +apiVersion: v1 +metadata: + name: azure-key-vault-creds +data: + clientId: MY_CLIENT_ID + clientSecret: MY_CLIENT_SECRET + tenantId: MY_TENANT_ID +type: Opaque +``` + +Apply the manifest: +``` +oc apply -f secret.azure-key-vault-creds.yaml +``` + +## Assign Permissions to Service Principal +In the Azure CLI, get a list of service principals. +``` +az ad sp list --show-mine +``` + +If there are more than one, find the entry with the `displayName` that is equal to your new service principal. Locate the `id` field for that entry and assign it to an environment variable. +``` +export OBJECT_ID="the-service-principals-id" +``` + +Alternatively, let `jq` do it for you: +``` +export OBJECT_ID=`az ad sp list --show-mine | jq -r ".[] | select(.displayName == \"${SP_NAME}\") | .id"` +``` + +Assign permissions: +``` +az keyvault set-policy --name ${KEY_VAULT_NAME} --object-id ${OBJECT_ID} --secret-permissions get list +``` + +## Create a SecretStore +Create a YAML manifest for the SecretStore. Be sure to enter the correct values for the `tenantId` and the name of the Secret that you created above. +``` +apiVersion: external-secrets.io/v1beta1 +kind: SecretStore +metadata: + name: azure-key-vault + namespace: e95e89-dev +spec: + provider: + azurekv: + tenantId: "MY_TENANT_ID" + vaultUrl: https://my-key-vault-name.vault.azure.net/ + authSecretRef: + clientId: + name: azure-key-vault-creds + key: clientId + clientSecret: + name: azure-key-vault-creds + key: clientSecret +``` + +Now you're ready to [create an ExternalSecret](external-secrets.md#create-an-externalsecret). + + diff --git a/src/docs/secrets-management/external-secrets.md b/src/docs/secrets-management/external-secrets.md new file mode 100644 index 00000000..68823c44 --- /dev/null +++ b/src/docs/secrets-management/external-secrets.md @@ -0,0 +1,83 @@ +# External Secrets + +The **External Secrets Operator** is a Kubernetes operator that integrates external secret management systems, such as [Azure Key Vault](https://azure.microsoft.com/en-us/products/key-vault/) and [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html). The operator reads information from external APIs and automatically injects the values into a Kubernetes Secret. + +The goal of External Secrets Operator is to synchronize secrets from external APIs into Kubernetes. ESO uses custom resources `ExternalSecret` and `SecretStore` to provide a user-friendly abstraction for the external API that stores and manages the lifecycle of the secrets for you. + +The operator is installed in each cluster and provides **self-serve functionality**. The External Secrets Operator: +* gives you the flexibility to use any of dozens of secrets management services +* allows you to use a single secrets management service for your hybrid cloud environment +* adds redundancy to your secrets management system + +Refer to the [official External Secrets Operator documentation](https://external-secrets.io/latest/) for more information. + +## How External Secrets Operator works +Secrets integration works by creating a `SecretStore`, which configures the connection and credentials for your external secrets management system, and `ExternalSecrets`, which define exactly which secrets and keys to replicate to OpenShift. + +Create the SecretStore and ExternalSecrets in each namespace where you want to replicate secrets. + +## Create a SecretStore +The SecretStore custom resource contains the address and credentials of the secrets management service. The exact way it is configured depends on the service. + +Documentation for each supported service can be found in the [provider list](https://external-secrets.io/latest/provider/aws-secrets-manager/). Please use that documentation to set up your SecretStore; the process will vary from service to service. + +If you are using Azure Key Vault, refer to [Example SecretStore - Azure Key Vault](example_secretstore_azure_key_vault.md). + +## Create an ExternalSecret +An ExternalSecret contains references to the SecretStore that defines the external service as well as the individual secrets in that external service. + +There is a one to one relationship between ExternalSecrets and OpenShift Secrets. Any secrets (key/value pairs or other kind of secret) that are defined in the ExternalSecret are created within the stated OpenShift Secret. + +The main configuration elements of an ExternalSecret are: +* `.spec.secretStoreRef.name` - the name of the SecretStore to use +* `.spec.target.name` - the name of the OpenShift Secret to create +* `.spec.data[].remoteRef` - the names of the keys in both the external secret and OpenShift Secret + +Here is an example: +``` +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: my-app-1 + namespace: abc123-dev +spec: + refreshInterval: 1h + secretStoreRef: + kind: SecretStore + name: azure-key-vault + target: + creationPolicy: Owner + deletionPolicy: Retain + name: my-app-1 + data: + - remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: dev-db-user + metadataPolicy: None + secretKey: db-user + - remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: dev-db-pass + metadataPolicy: None + secretKey: db-pass +``` + +In this example, we have: +* .spec.secretStoreRef.name = azure-key-vault; this is the name of the SecretStore +* .spec.target.name = my-app-1; this is the name of the OpenShift Secret to create +* .spec.data[].remoteRef.key = dev-db-pass; this is the name of the key in the external secret +* .spec.data[].secretKey = db-pass; this is the name of the key for the key/value pair in the OpenShift Secret + +For more information when creating an ExternalSecret, use the `oc` CLI, such as: +``` +oc explain externalsecret.spec.data +``` + +``` +oc explain externalsecret.spec.refreshInterval +``` + +or edit it in the YAML view in the OpenShift UI and click on the the 'View sidebar' link. + diff --git a/src/docs/secrets-management/vault-getting-started-guide.md b/src/docs/secrets-management/vault-getting-started-guide.md index 77451163..b58a6ad2 100644 --- a/src/docs/secrets-management/vault-getting-started-guide.md +++ b/src/docs/secrets-management/vault-getting-started-guide.md @@ -20,10 +20,10 @@ sort_order: 1 # Vault getting started guide -The Platform Services team has deployed Hashicorp's Vault application with disaster recovery in our Gold service clusters (Gold Kamloops and Gold Calgary), the service is available to all B.C. government development teams on **all clusters** including: Silver, Gold/Golddr and Emerald. +The Platform Services team has deployed Hashicorp's Vault application with disaster recovery in our Gold service clusters (Gold Kamloops and Gold Calgary). The service is available to all B.C. government development teams on **all clusters** including: Silver, Gold/GoldDR and Emerald. The Vault service is available at [https://vault.developer.gov.bc.ca/](https://vault.developer.gov.bc.ca/). -If you are running a test project in the lab clusters, such as KLAB, use a separate Vault service available at [https://vault-lab.developer.gov.bc.ca/](https://vault-lab.developer.gov.bc.ca/). The lab Vault instance is meant to be used for testing purposes by the Platform Services team, there could be frequent changes and outages with the service! +If you are running a test project in the lab clusters, such as KLAB, use the lab instance of Vault at [https://vault-lab.developer.gov.bc.ca/](https://vault-lab.developer.gov.bc.ca/). In this guide, you will learn how to access Vault and deploy a working example using sample secrets from your Vault Mount Points. Mount Points can be thought of as "MiniVaults" or related to paths within a Linux filesystem that can be locked down and secured. @@ -53,7 +53,7 @@ User Access gives authorized users the ability to create and write secrets, whil User Access is controlled through a combination of Red Hat Single-Sign On (KeyCloak) and automation integrated with the [Platform Services Registry](https://registry.developer.gov.bc.ca/). -For each OpenShift Project Set ($LICENSE_PLATE-dev/test/prod/tools - eg: abc123-dev, abc123-test, abc123-prod, abc123-tools), up to two technical contacts would be grant access to Vault due to license limitation. These technical contacts will be given write access to the Mount Points set up by the registry. +For each OpenShift Project Set ($LICENSE_PLATE-dev/test/prod/tools - eg: abc123-dev, abc123-test, abc123-prod, abc123-tools), just the two technical contacts are granted access, due to the user limits of the Vault license. These technical contacts are given write access to the Mount Points set up by the registry. #### Log in to Vault UI @@ -288,11 +288,11 @@ vault.hashicorp.com/agent-limits-mem: '100Mi' Note the additional line under spec with `2. Service Account`. This is the service account that is needed to connect to the Vault. This account has been created already for you in OpenShift so on the surface it's straight forward. -There's a issue to be aware of with using this service account (SA): your application container will also use this SA to pull images and for management. So if you are using an image from tools namespace, make sure to add an ImagePuller rolebinding to the SA. If you are using Artifactory, add the imagePullSecrets to either the SA or the deployment spec. +There's an issue to be aware of with using this service account (SA): your application container will also use this SA to pull images and for management. So if you are using an image from your tools namespace, make sure to add an ImagePuller rolebinding to the SA. If you are using Artifactory, add the imagePullSecrets to either the SA or the deployment spec. **Part 3 - How to use secrets in application container** -The Vault init container will create local files with the secret key-value pairs pulled from Vault server. They are saved at the path `/vault/secrets/` where name is the secret name you specified in the annotation above. Unlike OpenShift secrets (which is not recommended as they are only encoded but not encrypted), they are not presented to app containers as environment variables directly. You will have to source the secret files first! See `3. how to use the secret` from the above example. +The Vault init container will create local files with the secret key-value pairs pulled from Vault. They are saved at the path `/vault/secrets/` where name is the secret name you specified in the annotation above. Unlike OpenShift secrets, they are not presented to app containers as environment variables directly. You will have to source the secret files first! See `3. how to use the secret` from the above example. > Note: there are different ways to use the secrets, check out [more examples here](https://www.vaultproject.io/docs/platform/k8s/injector/examples#vault-agent-injector-examples). diff --git a/src/docs/secrets-management/vault-secrets-management-service.md b/src/docs/secrets-management/vault-secrets-management-service.md index 4992f7a2..ce8bbc55 100644 --- a/src/docs/secrets-management/vault-secrets-management-service.md +++ b/src/docs/secrets-management/vault-secrets-management-service.md @@ -78,7 +78,7 @@ The best source of help is the vibrant community of product teams using Vault fo You can find this highly talented and knowledgeable group in the [#devops-vault channel on Rocket.Chat](https://chat.developer.gov.bc.ca/channel/devops-vault). -For help beyond this contact one of the Vault administrators via the [#devops-sos channel on Rocket.Chat](https://chat.developer.gov.bc.ca/channel/devops-sos). +For help beyond this contact one of the Vault administrators via the [#devops-operations channel on Rocket.Chat](https://chat.developer.gov.bc.ca/channel/devops-operations). ## What does it cost? @@ -92,7 +92,7 @@ Vault interfaces with Kubernetes services to provide authentication via service Rocket.Chat is the primary mode of communication. Specifically, the [#devops-vault](https://chat.developer.gov.bc.ca/channel/devops-vault) channel should be used to engage the community for best practices, configuration and troubleshooting questions. -For cluster wide service notifications that may impact Vault monitor, use the [#devops-alerts channels in Rocket.Chat.](https://chat.developer.gov.bc.ca/channel/devops-alerts) +For cluster wide service notifications that may impact Vault monitor, use the [#devops-alerts channel in Rocket.Chat.](https://chat.developer.gov.bc.ca/channel/devops-alerts) For teams without Rocket.Chat access or to escalate a question or concern, contact us by email at [PlatformServicesTeam@gov.bc.ca](mailto:PlatformServicesTeam@gov.bc.ca). @@ -107,18 +107,18 @@ As part of project onboarding, Kubernetes service accounts are generated for you Product teams can choose to use Vault or ETCD backed Kubernetes Secrets, but it is recommended that Vault be used for secrets. ### Change management -Any changes to the Vault Secrets Management tool will be communicated via #devops-vault and #internal-devops-vault Rocket.Chat channels. For major service update, the Vault Operations team will reach out to product owners for notice. +Any changes to the Vault Secrets Management tool will be communicated via [#devops-vault](https://chat.developer.gov.bc.ca/channel/devops-vault) and [#devops-alerts](https://chat.developer.gov.bc.ca/channel/devops-alerts) Rocket.Chat channels. For major service updates, the Vault Operations team will reach out to product owners for notice. ### Service improvements -Vault Secrets Management improvements including system upgrades, feature integration and issue fixing. The Vault Operations team will be conducting the operation on a scheduled time, with advanced notice in the #devops-vault Rocket.Chat channel. If disruption or downtime is expected during service improvement, the team will discuss on maintenance time in the channel to minimize effects. +Vault Secrets Management improvements include system upgrades, feature integration and issue fixing. The Vault Operations team conduct these operations at scheduled times, with advance notice in the #devops-vault Rocket.Chat channel. If disruption or downtime is expected during service improvement, the team will provide details to help teams prepare and to verify their applications. ### Service level To be determined. ### Security reviews -An STRA for Vault has been completed by the Platform Services team. +A STRA for Vault has been completed by the Platform Services team. --- Related links: From c5fc4314834aabad57663cd969acc7cffc879ee7 Mon Sep 17 00:00:00 2001 From: Ian Watts Date: Wed, 21 May 2025 12:18:05 -0700 Subject: [PATCH 2/5] External Secrets Operator update --- .../example_secretstore_azure_key_vault.md | 46 +++++++++-------- .../secrets-management/external-secrets.md | 51 ++++++++++--------- .../vault-secrets-management-service.md | 6 ++- 3 files changed, 57 insertions(+), 46 deletions(-) diff --git a/src/docs/secrets-management/example_secretstore_azure_key_vault.md b/src/docs/secrets-management/example_secretstore_azure_key_vault.md index 50a6459c..5cc9c649 100644 --- a/src/docs/secrets-management/example_secretstore_azure_key_vault.md +++ b/src/docs/secrets-management/example_secretstore_azure_key_vault.md @@ -1,14 +1,14 @@ # Example SecretStore - Azure Key Vault ## Summary -In order to use Azure Key Vault with the External Secrets Operator, a Service Principal must be created with the necessary permissions. A Secret is then created in the namespaces where SecretStore and ExternalSecret resources will be created. +In order to use Azure Key Vault with the [External Secrets Operator](external-secrets.md), a Service Principal must be created with the necessary permissions. Credentials for the Service Principal are set in a Secret in the namespaces where SecretStore and ExternalSecret resources will be created. ## Requirements * Access to your Azure Key Vault * Access to your OpenShift namespaces * If using the Azure CLI, podman or docker is recommended -An Azure service principal can be created using the CLI or by logging in to the Azure Portal. This document describes the CLI process. To use the portal to create the service principal, see [Register a Microsoft Entra app and create a service principal](https://learn.microsoft.com/en-us/entra/identity-platform/howto-create-service-principal-portal). +An Azure service principal can be created using the CLI or by logging in to the Azure Portal. This document describes the CLI process. To use the Azure portal to create the service principal, see [Register a Microsoft Entra app and create a service principal](https://learn.microsoft.com/en-us/entra/identity-platform/howto-create-service-principal-portal). ## Official Documentation https://external-secrets.io/latest/provider/azure-key-vault/ @@ -38,9 +38,9 @@ Make a note of the subscription ID in the output of the login command. ## Create the Service Principal You will need: -* the subscription ID of your Azure account -* the name of your key vault -* the resource group of your key vault +* The subscription ID of your Azure account +* The name of your key vault +* The resource group of your key vault In the Azure CLI container, set environment variables, entering the appropriate values: ``` @@ -55,25 +55,16 @@ Run the command to create the service principal: az ad sp create-for-rbac --name "${SP_NAME}" --role "Key Vault Secrets User" --scopes /subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.KeyVault/vaults/${KEY_VAULT_NAME} --sdk-auth ``` -Save a copy of the output from this command - you'll need `clientId`, `clientSecret`, and `tenantId`. - -## Create the OpenShift Secret -Create a Secret in your OpenShift namespace. You can use the UI, if you like, or create a YAML manifest and apply it. +Save a copy of the output from this command - you'll need `clientId`, `clientSecret`, and `tenantId`. Set the client credentials as environment variables if you'd like to copy the command below to create the Secret. ``` -kind: Secret -apiVersion: v1 -metadata: - name: azure-key-vault-creds -data: - clientId: MY_CLIENT_ID - clientSecret: MY_CLIENT_SECRET - tenantId: MY_TENANT_ID -type: Opaque +export CLIENT_ID=clientId_from_output +export CLIENT_SECRET=clientSecret_from_output ``` -Apply the manifest: +## Create the OpenShift Secret +Create a Secret in your OpenShift namespace. You can use the UI, if you like, or use the following commands. ``` -oc apply -f secret.azure-key-vault-creds.yaml +oc create secret generic azure-key-vault-creds --from-literal=clientId=${CLIENT_ID} --from-literal=clientSecret=${CLIENT_SECRET} ``` ## Assign Permissions to Service Principal @@ -104,7 +95,7 @@ apiVersion: external-secrets.io/v1beta1 kind: SecretStore metadata: name: azure-key-vault - namespace: e95e89-dev + namespace: abc123-dev spec: provider: azurekv: @@ -119,6 +110,17 @@ spec: key: clientSecret ``` -Now you're ready to [create an ExternalSecret](external-secrets.md#create-an-externalsecret). +Check the status of the new SecretStore. It should show as ready. +``` +status: + capabilities: ReadWrite + conditions: + - lastTransitionTime: "2025-05-21T17:43:07Z" + message: store validated + reason: Valid + status: "True" + type: Ready +``` +Now you're ready to [create an ExternalSecret](external-secrets.md#create-an-externalsecret). diff --git a/src/docs/secrets-management/external-secrets.md b/src/docs/secrets-management/external-secrets.md index 68823c44..764fbe1c 100644 --- a/src/docs/secrets-management/external-secrets.md +++ b/src/docs/secrets-management/external-secrets.md @@ -1,3 +1,23 @@ +--- +title: External secrets + +slug: external-secrets-operator + +description: The External Secrets Operator can link your OpenShift namespace with an external secrets management service. + +keywords: + +page_purpose: Describes the purpose and use of the External Secrets Operator + +audience: developer, technical lead + +author: Ian Watts + +content_owner: Ian Watts + +sort_order: 3 +--- + # External Secrets The **External Secrets Operator** is a Kubernetes operator that integrates external secret management systems, such as [Azure Key Vault](https://azure.microsoft.com/en-us/products/key-vault/) and [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html). The operator reads information from external APIs and automatically injects the values into a Kubernetes Secret. @@ -24,14 +44,9 @@ Documentation for each supported service can be found in the [provider list](htt If you are using Azure Key Vault, refer to [Example SecretStore - Azure Key Vault](example_secretstore_azure_key_vault.md). ## Create an ExternalSecret -An ExternalSecret contains references to the SecretStore that defines the external service as well as the individual secrets in that external service. +An ExternalSecret contains a reference to the SecretStore that defines the external service, as well as the individual secrets to replicate from that external service. -There is a one to one relationship between ExternalSecrets and OpenShift Secrets. Any secrets (key/value pairs or other kind of secret) that are defined in the ExternalSecret are created within the stated OpenShift Secret. - -The main configuration elements of an ExternalSecret are: -* `.spec.secretStoreRef.name` - the name of the SecretStore to use -* `.spec.target.name` - the name of the OpenShift Secret to create -* `.spec.data[].remoteRef` - the names of the keys in both the external secret and OpenShift Secret +There is a one-to-one relationship between ExternalSecrets and OpenShift Secrets. Any secrets (key/value pairs or other kind of secret) that are defined in the ExternalSecret are created within the stated OpenShift Secret. Here is an example: ``` @@ -41,38 +56,28 @@ metadata: name: my-app-1 namespace: abc123-dev spec: - refreshInterval: 1h secretStoreRef: kind: SecretStore + # The name of your SecretStore name: azure-key-vault target: - creationPolicy: Owner - deletionPolicy: Retain + # The name of the Secret in OpenShift. + # It will be created if it does not already exist. name: my-app-1 data: - remoteRef: - conversionStrategy: Default - decodingStrategy: None + # The name of the key in the external secrets system key: dev-db-user - metadataPolicy: None + # The name of the key in the OpenShift secret secretKey: db-user - remoteRef: - conversionStrategy: Default - decodingStrategy: None key: dev-db-pass - metadataPolicy: None secretKey: db-pass ``` -In this example, we have: -* .spec.secretStoreRef.name = azure-key-vault; this is the name of the SecretStore -* .spec.target.name = my-app-1; this is the name of the OpenShift Secret to create -* .spec.data[].remoteRef.key = dev-db-pass; this is the name of the key in the external secret -* .spec.data[].secretKey = db-pass; this is the name of the key for the key/value pair in the OpenShift Secret - For more information when creating an ExternalSecret, use the `oc` CLI, such as: ``` -oc explain externalsecret.spec.data +oc explain externalsecret.spec ``` ``` diff --git a/src/docs/secrets-management/vault-secrets-management-service.md b/src/docs/secrets-management/vault-secrets-management-service.md index ce8bbc55..e53e29bf 100644 --- a/src/docs/secrets-management/vault-secrets-management-service.md +++ b/src/docs/secrets-management/vault-secrets-management-service.md @@ -35,6 +35,7 @@ Non-secrets may be stored in Vault if desired. - [What does it cost?](#what-does-it-cost) - [Support roles, processes, communications (platform operations)](#support-roles-processes-communications-platform-operations) - [Service delivery](#service-delivery) +- [Alternatives](#alternatives) ## Features and functions @@ -114,12 +115,15 @@ Any changes to the Vault Secrets Management tool will be communicated via [#devo Vault Secrets Management improvements include system upgrades, feature integration and issue fixing. The Vault Operations team conduct these operations at scheduled times, with advance notice in the #devops-vault Rocket.Chat channel. If disruption or downtime is expected during service improvement, the team will provide details to help teams prepare and to verify their applications. ### Service level -To be determined. +Enterprise ### Security reviews A STRA for Vault has been completed by the Platform Services team. +## Alternatives +If you would prefer to use a different secrets management system, you may use the External Secrets Operator to link your OpenShift namespace to an external service, such as AWS Secrets Manager or Azure Key Vault. See the [External Secrets Operator documentation](external-secrets.md) for more information. + --- Related links: From 896b81c09102435ed7ee2b99e11cd690db62d54c Mon Sep 17 00:00:00 2001 From: Pilar Solares <131301244+Pilargit12@users.noreply.github.com> Date: Thu, 22 May 2025 14:07:25 -0700 Subject: [PATCH 3/5] Updates - Added pages to index.md and mkdocs.yml - Updated for plain language and active voice @IanKWatts - In visual studio code the system is letting me know that Fenced code blocks should have language specified and provides this link: https://github.com/DavidAnson/markdownlint/blob/v0.37.4/doc/md040.md I am unsure how this affects the code blocks. --- .vscode/settings.json | 29 ++++++++++ mkdocs.yml | 1 + .../example_secretstore_azure_key_vault.md | 57 ++++++++++++------- .../secrets-management/external-secrets.md | 33 ++++++----- src/index.md | 1 + 5 files changed, 85 insertions(+), 36 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..27f4b8ad --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,29 @@ +{ + "cSpell.words": [ + "alertmanager", + "azurekv", + "cicd", + "creds", + "crunchydb", + "Entra", + "externalsecret", + "golddr", + "IDIR", + "imagestreams", + "Kamloops", + "KLAB", + "Kyverno", + "licenseplate", + "linenums", + "myapp", + "nonprod", + "opensource", + "Patroni", + "pids", + "pymdownx", + "rolebinding", + "serviceaccount", + "Sysdig", + "techdocs" + ] +} \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index acaca339..cc0f8245 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -80,6 +80,7 @@ nav: - Secrets management: - Vault getting started guide: docs/secrets-management/vault-getting-started-guide.md - Vault secrets management: docs/secrets-management/vault-secrets-management-service.md + - External secrets: docs/secrets-management/external-secrets.md - Training and learning: - Training from the Platform Services Team: docs/training-and-learning/training-from-the-platform-services-team.md - External training resources: docs/training-and-learning/training-external-resources.md diff --git a/src/docs/secrets-management/example_secretstore_azure_key_vault.md b/src/docs/secrets-management/example_secretstore_azure_key_vault.md index 5cc9c649..5071e2be 100644 --- a/src/docs/secrets-management/example_secretstore_azure_key_vault.md +++ b/src/docs/secrets-management/example_secretstore_azure_key_vault.md @@ -1,34 +1,43 @@ # Example SecretStore - Azure Key Vault ## Summary -In order to use Azure Key Vault with the [External Secrets Operator](external-secrets.md), a Service Principal must be created with the necessary permissions. Credentials for the Service Principal are set in a Secret in the namespaces where SecretStore and ExternalSecret resources will be created. + +In order to use Azure Key Vault with the [External Secrets Operator](external-secrets.md), you need to create a Service Principal with the right permissions. You then store the Service Principal’s credentials in a Kubernetes Secret in each namespace where you’ll create `SecretStore` and `ExternalSecret` resources. ## Requirements + +To complete this setup, you need: + * Access to your Azure Key Vault * Access to your OpenShift namespaces -* If using the Azure CLI, podman or docker is recommended +* Docker or Podman, if you're using the Azure CLI + +You can create the Service Principal using either the Azure CLI or the Azure Portal. This guide uses the CLI method. If you prefer the portal, see [Register a Microsoft Entra app and create a service principal](https://learn.microsoft.com/en-us/entra/identity-platform/howto-create-service-principal-portal). -An Azure service principal can be created using the CLI or by logging in to the Azure Portal. This document describes the CLI process. To use the Azure portal to create the service principal, see [Register a Microsoft Entra app and create a service principal](https://learn.microsoft.com/en-us/entra/identity-platform/howto-create-service-principal-portal). +## Official documentation -## Official Documentation -https://external-secrets.io/latest/provider/azure-key-vault/ +[External Secrets Operator - Azure Key Vault Provider](https://external-secrets.io/latest/provider/azure-key-vault/) ## Start the Azure CLI Container -We recommend that you run the Docker container for the Azure CLI, because installation of the CLI on your workstation involves a lot of packages and updates, which could potentially cause version issues for other tools you use, and because it's a lot to install for a single task. You are, of course, welcome to install the CLI directly on your workstation. -You'll need a running Docker server or Podman machine. +We recommend running the Azure CLI in a Docker or Podman container. Installing the CLI directly on your machine requires many dependencies, which might conflict with other tools or take up unnecessary space if you only need it for this task. + +Make sure you have a running Docker ir Podman environment before starting. Start the container: + ``` podman run -it mcr.microsoft.com/azure-cli:cbl-mariner2.0 ``` Once it's running and you have a command prompt, run `az` to see version and help information. + ``` az ``` Log in to Azure by running `az login` in the container and following the instructions. + ``` root [ / ]# az login To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code ... to authenticate. @@ -37,12 +46,14 @@ To sign in, use a web browser to open the page https://microsoft.com/devicelogin Make a note of the subscription ID in the output of the login command. ## Create the Service Principal -You will need: -* The subscription ID of your Azure account -* The name of your key vault -* The resource group of your key vault -In the Azure CLI container, set environment variables, entering the appropriate values: +To create the Service Principal, make sure you have the following information: + +* Your Azure subscription ID +* The name of your Key Vault +* The resource group of your Key Vault + +You’ll use this information when you run the Azure CLI commands in the next steps: ``` export SUBSCRIPTION_ID="your-subscription-ID" export KEY_VAULT_NAME="your-key-vault-name" @@ -62,34 +73,37 @@ export CLIENT_SECRET=clientSecret_from_output ``` ## Create the OpenShift Secret -Create a Secret in your OpenShift namespace. You can use the UI, if you like, or use the following commands. + +First, create a Secret in your OpenShift namespace to store your Azure Service Principal credentials. You can use the UI, if you like, or use the following commands: ``` oc create secret generic azure-key-vault-creds --from-literal=clientId=${CLIENT_ID} --from-literal=clientSecret=${CLIENT_SECRET} ``` -## Assign Permissions to Service Principal -In the Azure CLI, get a list of service principals. +## Assign permissions to the Service Principal + +Use the Azure CLI, get a list of Service Principals: + ``` az ad sp list --show-mine ``` -If there are more than one, find the entry with the `displayName` that is equal to your new service principal. Locate the `id` field for that entry and assign it to an environment variable. +If you see more than one, look for the one with the `displayName` that is equal to your new Service Principal. Find its `id` for that entry and assign it to an environment variable. ``` export OBJECT_ID="the-service-principals-id" ``` -Alternatively, let `jq` do it for you: +Or, use `jq` to extract it automatically: ``` export OBJECT_ID=`az ad sp list --show-mine | jq -r ".[] | select(.displayName == \"${SP_NAME}\") | .id"` ``` -Assign permissions: +Now assign the right permissions to your Service Principal so it can access Secrets in Azure Key Vault: ``` az keyvault set-policy --name ${KEY_VAULT_NAME} --object-id ${OBJECT_ID} --secret-permissions get list ``` ## Create a SecretStore -Create a YAML manifest for the SecretStore. Be sure to enter the correct values for the `tenantId` and the name of the Secret that you created above. +Next, create a YAML manifest for the `SecretStore`. Be sure to enter the correct values for the `tenantId` and the name of the Secret that you created above. ``` apiVersion: external-secrets.io/v1beta1 kind: SecretStore @@ -110,7 +124,7 @@ spec: key: clientSecret ``` -Check the status of the new SecretStore. It should show as ready. +After creating the YAML manifest, check the status of the new SecretStore. It should show as ready. ``` status: capabilities: ReadWrite @@ -122,5 +136,4 @@ status: type: Ready ``` -Now you're ready to [create an ExternalSecret](external-secrets.md#create-an-externalsecret). - +Once the SecretStore is ready, you can create an [ExternalSecret](external-secrets.md#create-an-externalsecret) to sync your secrets. diff --git a/src/docs/secrets-management/external-secrets.md b/src/docs/secrets-management/external-secrets.md index 764fbe1c..9a90c542 100644 --- a/src/docs/secrets-management/external-secrets.md +++ b/src/docs/secrets-management/external-secrets.md @@ -20,33 +20,38 @@ sort_order: 3 # External Secrets -The **External Secrets Operator** is a Kubernetes operator that integrates external secret management systems, such as [Azure Key Vault](https://azure.microsoft.com/en-us/products/key-vault/) and [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html). The operator reads information from external APIs and automatically injects the values into a Kubernetes Secret. +The **External Secrets Operator (ESO)** is a Kubernetes operator that connects to external secret management systems like [Azure Key Vault](https://azure.microsoft.com/en-us/products/key-vault/) and [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html). The operator reads information from external APIs (systems) and automatically adds them to Kubernetes as Secrets. -The goal of External Secrets Operator is to synchronize secrets from external APIs into Kubernetes. ESO uses custom resources `ExternalSecret` and `SecretStore` to provide a user-friendly abstraction for the external API that stores and manages the lifecycle of the secrets for you. +ESO's main purpose to keep your Kubernetes Secrets in sync with external APIs. It uses custom resources `ExternalSecret` and `SecretStore` to provide a user-friendly abstraction for the external API that stores and manages the lifecycle of the secrets for you. -The operator is installed in each cluster and provides **self-serve functionality**. The External Secrets Operator: -* gives you the flexibility to use any of dozens of secrets management services -* allows you to use a single secrets management service for your hybrid cloud environment -* adds redundancy to your secrets management system +You install ESO in each cluster. It's **self-serve**, so you can: -Refer to the [official External Secrets Operator documentation](https://external-secrets.io/latest/) for more information. +* Choose from many different secret management services +* Use the same service across your hybrid cloud environment +* Add redundancy to your secrets management set up + +For more details, visit the [official External Secrets Operator documentation](https://external-secrets.io/latest/). ## How External Secrets Operator works -Secrets integration works by creating a `SecretStore`, which configures the connection and credentials for your external secrets management system, and `ExternalSecrets`, which define exactly which secrets and keys to replicate to OpenShift. -Create the SecretStore and ExternalSecrets in each namespace where you want to replicate secrets. +To connect to an external secrets management system, you create two resources: + +* A `SecretStore`, which sets up the connection and credentials +* One or more `ExternalSecrets`, which define the specific secrets and keys to copy into OpenShift + +Create both resources in each namespace where you want to replicate secrets. ## Create a SecretStore -The SecretStore custom resource contains the address and credentials of the secrets management service. The exact way it is configured depends on the service. +The `SecretStore` resource stores the address and credentials for your secrets management service. The setup depends on which service you're using. -Documentation for each supported service can be found in the [provider list](https://external-secrets.io/latest/provider/aws-secrets-manager/). Please use that documentation to set up your SecretStore; the process will vary from service to service. +Check the [provider list](https://external-secrets.io/latest/provider/aws-secrets-manager/) for setup instructions specific to your service. -If you are using Azure Key Vault, refer to [Example SecretStore - Azure Key Vault](example_secretstore_azure_key_vault.md). +If you are using Azure Key Vault, see the [Example SecretStore - Azure Key Vault](example_secretstore_azure_key_vault.md). ## Create an ExternalSecret -An ExternalSecret contains a reference to the SecretStore that defines the external service, as well as the individual secrets to replicate from that external service. +An `ExternalSecret` connects to a `SecretStore` and lists the specific secrets you want to copy from the external service. Each `ExternalSecret` creates one OpenShift secret. -There is a one-to-one relationship between ExternalSecrets and OpenShift Secrets. Any secrets (key/value pairs or other kind of secret) that are defined in the ExternalSecret are created within the stated OpenShift Secret. +The key-value pairs or other secret data you define in the `ExternalSecret` are automatically added to the OpenShift secret. Here is an example: ``` diff --git a/src/index.md b/src/index.md index 442a26b4..5d0db943 100644 --- a/src/index.md +++ b/src/index.md @@ -102,6 +102,7 @@ demos of their application. * [Vault getting started guide](docs/secrets-management/vault-getting-started-guide.md) * [Vault secrets management](docs/secrets-management/vault-secrets-management-service.md) +* [External secrets](docs/secrets-management/external-secrets.md) ### Security and privacy compliance From e5fbd04436eaad90659ebd5dec8debdd84d323d2 Mon Sep 17 00:00:00 2001 From: Ian Watts Date: Thu, 22 May 2025 15:04:43 -0700 Subject: [PATCH 4/5] Minor tweaks to external secrets docs --- .../example_secretstore_azure_key_vault.md | 8 ++++---- src/docs/secrets-management/external-secrets.md | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/docs/secrets-management/example_secretstore_azure_key_vault.md b/src/docs/secrets-management/example_secretstore_azure_key_vault.md index 5071e2be..e6ecc61e 100644 --- a/src/docs/secrets-management/example_secretstore_azure_key_vault.md +++ b/src/docs/secrets-management/example_secretstore_azure_key_vault.md @@ -22,7 +22,7 @@ You can create the Service Principal using either the Azure CLI or the Azure Por We recommend running the Azure CLI in a Docker or Podman container. Installing the CLI directly on your machine requires many dependencies, which might conflict with other tools or take up unnecessary space if you only need it for this task. -Make sure you have a running Docker ir Podman environment before starting. +Make sure you have a running Docker or Podman environment before starting. Start the container: @@ -74,14 +74,14 @@ export CLIENT_SECRET=clientSecret_from_output ## Create the OpenShift Secret -First, create a Secret in your OpenShift namespace to store your Azure Service Principal credentials. You can use the UI, if you like, or use the following commands: +First, create a Secret in your OpenShift namespace to store your Azure Service Principal credentials. You can use the UI if you like, or use the following command: ``` oc create secret generic azure-key-vault-creds --from-literal=clientId=${CLIENT_ID} --from-literal=clientSecret=${CLIENT_SECRET} ``` ## Assign permissions to the Service Principal -Use the Azure CLI, get a list of Service Principals: +Using the Azure CLI, get a list of Service Principals: ``` az ad sp list --show-mine @@ -124,7 +124,7 @@ spec: key: clientSecret ``` -After creating the YAML manifest, check the status of the new SecretStore. It should show as ready. +After applying the YAML manifest, check the status of the new SecretStore. It should show as ready. ``` status: capabilities: ReadWrite diff --git a/src/docs/secrets-management/external-secrets.md b/src/docs/secrets-management/external-secrets.md index 9a90c542..94393eb1 100644 --- a/src/docs/secrets-management/external-secrets.md +++ b/src/docs/secrets-management/external-secrets.md @@ -24,7 +24,7 @@ The **External Secrets Operator (ESO)** is a Kubernetes operator that connects t ESO's main purpose to keep your Kubernetes Secrets in sync with external APIs. It uses custom resources `ExternalSecret` and `SecretStore` to provide a user-friendly abstraction for the external API that stores and manages the lifecycle of the secrets for you. -You install ESO in each cluster. It's **self-serve**, so you can: +ESO is available in each cluster. It's **self-serve**, so you can: * Choose from many different secret management services * Use the same service across your hybrid cloud environment From 6c4d12a77834254295ee4588e1a907b81c3d4ce3 Mon Sep 17 00:00:00 2001 From: Ian Watts Date: Thu, 22 May 2025 16:36:53 -0700 Subject: [PATCH 5/5] Add note about encryption of secrets --- src/docs/secrets-management/external-secrets.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/docs/secrets-management/external-secrets.md b/src/docs/secrets-management/external-secrets.md index 94393eb1..f86096df 100644 --- a/src/docs/secrets-management/external-secrets.md +++ b/src/docs/secrets-management/external-secrets.md @@ -32,6 +32,8 @@ ESO is available in each cluster. It's **self-serve**, so you can: For more details, visit the [official External Secrets Operator documentation](https://external-secrets.io/latest/). +Note that OpenShift Secrets are now encrypted on disk, which resolves what was previously a security concern. + ## How External Secrets Operator works To connect to an external secrets management system, you create two resources: