Skip to main content

Live Environments

This guide will assist you in integrating Vault++ into your staging or production environment.

Prerequisites

  1. Have a Vault++ account.
  2. Have created an application and added some secrets to non-local environment (for example staging).

Introduction

Vault++ injects secrets into your application during deployment, offering several advantages:

  1. Zero resource overhead: Unlike using an SDK or a wrapper command, this method imposes no additional CPU or memory usage.
  2. Enhanced Security: By reducing the number of secret touchpoints, security is improved. The deployment pipeline, which typically already has access to secrets, serves as the sole touchpoint, eliminating the need for an agent within your infrastructure.
  3. Seamless Integration of Secret Updates: This approach ensures that applications can be redeployed immediately when secrets are updated, maintaining synchronization between deployments and secret changes.
  4. No Token Management: Since secrets are injected directly during deployment, applications do not need to manage or store tokens or credentials to access Vault++, further simplifying secret management and reducing the risk of token leaks.

1. Create a service account

A service account facilitates Vault++ access from your CICD pipeline. To create a service account and integrate it into your CICD pipeline, follow these steps:

  1. Log in to your Vault++ account, choose the desired application, and navigate to the Settings tab.

  2. Find the Service Accounts section and click the Add () button.

  3. Enter a descriptive label, for example CICD - Staging, then press Enter.

  4. A dialog will display the private key and an encryption password. Do not close the dialog as you cannot access these credentials again after closing.

  1. In a new browser tab, open your GitHub repository and click the Settings tab.

  2. Under the Code and automation section in the left sidebar, select Environments.

    info

    Ensure that environment names in GitHub match those in Vault++. If no matching environment exists, create one by clicking the New Environment button.

  3. Select the appropriate environment (e.g., staging) and add the following secrets from the Vault++ dialog:

    • VPP_SERVICE_ACCOUNT_KEY
    • VPP_SERVICE_ACCOUNT_PASSWORD
  4. In the environment settings, configure the Deployment branches and tags to restrict access. Choose Protected branches only or specify selected branches (e.g., main or master) to prevent unauthorized access from unintended branches or pipelines, such as those triggered by pull requests.

    tip

    For repositories on GitHub Free, the Environments feature is unavailable. Instead, use Repository Secrets located under Security → Secrets and Variables → Actions.

    Note that using Repository Secrets exposes the service account to all branches, which is less secure. In this setup, you may grant the service account access to multiple environments in Vault++ during Step 10, as using multiple service accounts offers no additional benefit.

  1. Return to Vault++, close the service account dialog and click the Update Access button (showing as 0 ENVIRONMENTS).

  2. Allow access to the environment you just configured, for example staging, and click Save.
    Best Practice: Assign only one environment per service account to maintain clear separation of access and enhance security.

2. Create export command

To provide secrets for your application, you need to create a vpp export command which you will use in your CICD pipelines.

The vpp export command allows you to export secrets as Kubernetes Opaque Secrets which can be attached to your Kubernetes Deployment. Below is an example of a vpp export command that exports secrets as Kubernetes Opaque Secrets:

# vpp export --help
# Usage: vpp export [options] <file>

# For Kubernetes:
# -o, --output k8s
# -e, --env <env> target environment
# --include <includePrefix...> only export secrets that match provided prefix, for example --include CI_
# --exclude <excludePrefix...> exclude secrets that match provided prefix from being exported, for example --exclude CI_
# --k8s-secret-name <name> Kubernetes secret name
# --k8s-secret-namespace <namespace> Optional Kubernetes secret namespace

vpp export --exclude=CI_ --output=k8s --k8s-secret-name=my-api-secret --env=staging secrets.yaml

kubectl apply -f secrets.yaml # apply the secret resource and make it available in your cluster

Below is an example of a Kubernetes Deployment attaching secrets from Kubernetes Secret resource.

manifests/my-api-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-api-deployment
labels:
app: my-api
spec:
replicas: 3
selector:
matchLabels:
app: my-api
template:
metadata:
labels:
app: my-api
spec:
containers:
- name: api
image: my-api:12345
ports:
- containerPort: 80
env:
- name: DEMO_SECRET_1
valueFrom:
secretKeyRef:
name: my-api-secret
key: DEMO_SECRET_1
- name: DEMO_SECRET_2
valueFrom:
secretKeyRef:
name: my-api-secret
key: DEMO_SECRET_2

If you need more customizations, you can use the YAML export format and load your own custom Kubernetes Secret template.

3. Integrate with CICD

After having a suitable vpp export command for your app, you can start integrating it with your CICD pipelines.

The following is an example of GitHub Actions pipeline for deploying Kubernetes app using Vault++ secrets.

.github/workflows/example-kubernetes.yaml
name: Deploy Kubernetes App
on:
push:
branches:
- main
jobs:
deploy:
name: Build and Deploy App
# Environment is only available on GitHub paid plans.
# If you are not on GitHub paid plans, you can remove the following line.
environment: ${{ inputs.environment || 'staging' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Install the vpp cli
- uses: vaultplusplus/setup@latest


# You can store credentials for your CICD pipeline using the same Application in Vault++.
# You can use a prefix, for example CI_, to easily filter the secrets.
#
# We will touch more on ${{ inputs.environment || 'staging' }} in the next step.
#
# Exporting to $GITHUB_OUTPUT will make secrets available as steps.vpp.outputs.XXXX to subsequent steps
# You can also export to $GITHUB_ENV to make secrets available as environment variables for subsequent steps
- id: vpp
run: vpp export --include CI_ -o github --env=${{ inputs.environment || 'staging' }} $GITHUB_OUTPUT
env:
VPP_SERVICE_ACCOUNT_KEY: ${{ secrets.VPP_SERVICE_ACCOUNT_KEY }}
VPP_SERVICE_ACCOUNT_PASSWORD: ${{ secrets.VPP_SERVICE_ACCOUNT_PASSWORD }}


# Example Login to AWS
- uses: aws-actions/configure-aws-credentials@v4
with:
# accessing CICD secrets using ${{ steps.<step-id>.outputs.<SECRET_KEY> }}
aws-access-key-id: ${{ steps.vpp.outputs.CI_AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ steps.vpp.outputs.CI_AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ steps.vpp.outputs.CI_AWS_REGION }}

- run: aws eks update-kubeconfig --name ${{ steps.vpp.outputs.CI_EKS_CLUSTER }} --region ${{ steps.vpp.outputs.CI_AWS_REGION }}

- id: login-ecr
uses: aws-actions/amazon-ecr-login@v1

- run: |
docker build -t $ECR_REGISTRY/my-api:$IMAGE_TAG .
docker push $ECR_REGISTRY/my-api:$IMAGE_TAG
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
IMAGE_TAG: ${{ github.sha }}

# Export secrets as Kubernetes Opaque Secret and run kubectl apply to make it available for your Deployment.
# Exclude secrets with CI_ prefix from the export.
- run: |
vpp export --exclude=CI_ --output=k8s --k8s-secret-name=my-api-secret --env=${{ inputs.environment || 'staging' }} .tmp-api-secrets.yaml
kubectl apply -f .tmp-api-secrets.yaml
env:
VPP_SERVICE_ACCOUNT_KEY: ${{ secrets.VPP_SERVICE_ACCOUNT_KEY }}
VPP_SERVICE_ACCOUNT_PASSWORD: ${{ secrets.VPP_SERVICE_ACCOUNT_PASSWORD }}

- run: |
sed -i.bak "s|DOCKER_IMAGE|$ECR_REGISTRY/my-api:$IMAGE_TAG|g" manifests/my-api-deployment.yaml
kubectl apply -f manifests/my-api-deployment.yaml
kubectl apply -f manifests/my-api-service.yaml
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
IMAGE_TAG: ${{ github.sha }}

You may notice the use of ${{ inputs.environment || 'staging' }} in the pipeline above. Vault++ will provide inputs.environment to your pipeline (as shown in the next step) so it knows which environment needs to be deployed. You can specify a default value in case you trigger the pipeline using another method, such as on push. In this example, the default value will be staging.

4. Enable sync

Next, we will enable automatic sync, so that every time you update secrets in Vault++, the pipeline will be triggered, and your app will be redeployed with the new secrets.

  1. Add a new workflow_dispatch trigger to your current pipeline as follows:

    .github/workflows/example-app.yaml
    name: Deploy App
    on:
    push:
    branches:
    - main
    # Workflow dispatch allows you to trigger this pipeline from your Actions tab on your GitHub project page.
    # It also allows Vault++ to trigger this pipeline using a webhook.
    workflow_dispatch:
    inputs:
    action:
    required: true
    type: choice
    options:
    - sync # 'sync' is what we want to trigger now
    - rotate # we will integrate secret rotations in the next guide!
    # This is where your CICD pipeline gets ${{ inputs.environment || 'staging' }} from.
    environment:
    # 'type: environment' is only available on GitHub paid plans.
    # If you do not have access to it, you can change it into a 'type: choice', for example:
    # type: choice
    # options:
    # - staging
    # - prod
    type: environment
    required: true


    jobs:
    deploy:
    name: Build and Deploy App
    # Environment is only available on GitHub paid plans.
    environment: ${{ inputs.environment || 'staging' }}
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    # Install the vpp cli
    - uses: vaultplusplus/setup@latest

    ## rest of the pipeline...

    Then commit and push your changes.

  2. Go to Vault++, select your application and go to the Settings tab.

  3. Find the CI Integrations section and click the Add () button.

  4. Select GitHub Actions and follow the instructions to install the Vault++ GitHub App to your GitHub account.

  5. Select the target repository, the workflow you just created, and the target ref (branch or tag). Then click the Save () button.

  6. Click the Update Trigger button (showing as 0 ENVIRONMENTS) and enable all your live Environments.

Congratulations! 🎉 Your application is now secured end-to-end with Vault++! In the next guide, you will learn how to prevent leaks with Vault++ Pre-commit Check.