Install

To install Vault using this component, there are a few things to decide and prepare.

Backups

By default, backups using k8up are enabled. For this to work k8up needs to be installed on the same cluster using the k8up component.

By default, the component uses the following configuration:

backup:
  enabled: true
  schedule: '*/13 * * * *'
  keepjobs: 5
  password: '?{vaultkv:${cluster:tenant}/${cluster:name}/vault/${_instance}/backup/password}'
  bucket:
    name: '${_instance}-backup'
    accesskey: '?{vaultkv:${cluster:tenant}/${cluster:name}/vault/${_instance}/backup/s3_access_key}'
    secretkey: '?{vaultkv:${cluster:tenant}/${cluster:name}/vault/${_instance}/backup/s3_secret_key}'

The backup configuration expects that there is a bucket with the name ${INSTANCE}-backup.

The three referenced secrets need to be added to the Vault instance associated with the Lieutenant instance managing the cluster on which this component is installed:

  • The password to use for backup encryption in key clusters/kv/${TENANT_ID}/${CLUSTER_ID}/vault/${INSTANCE}/backup/password}

  • The access key for the bucket in key clusters/kv/${TENANT_ID}/${CLUSTER_ID}/vault/${INSTANCE}/backup/s3_access_key}

  • The secret key for the bucket in key clusters/kv/${TENANT_ID}/${CLUSTER_ID}/vault/${INSTANCE}/backup/s3_secret_key}

Unless you explicitly configure multiple instances of the component, a single vault instance will be deployed. In this case, ${INSTANCE} will simply be vault. See Multiple Instances for more details on how to deploy multiple Vault instances using this component.

LDAP

By default, only the backup service account and the root user has access to vault. You have the option to add more authentication methods and policies. Here is an example to add Vault access to all people in an LDAP group.

config:
  auth:
    - type: ldap
      description: LDAP auth
      options:
        listing_visibility: "unauth"
      config:
        url: ldaps://ldap.server.net:636
        binddn: "uid=vault-service,ou=Special Users,dc=server,dc=net"
        bindpass: '?{vaultkv:${cluster:tenant}/${cluster:name}/vault/${_instance}/ldappass}'
        userattr: uid
        userdn: "ou=vault,ou=Service Access,ou=Views,dc=server,dc=net"
        groupdn: "ou=Groups,dc=vshn,dc=net"
        groupattr: cn
      groups:
        vault-root:
          policies: cluster-root
  policies:
    - name: cluster-root
      rules: |
        path "clusters/*" {
          capabilities = ["create", "read", "update", "delete", "list"]
        }

Under the hood, this component uses bank-vaults to configure vault. This reference provides more details on how to configure policies and authentication methods.

Lieutenant Integration

If your Vault should interact with a Lieutenant instance, we need to add some policies and authentication methods. See the how-to on integrating Lieutenant.

Multiple Instances

This component is able to deploy multiple instances of Vault on the same cluster. You can deploy multiple instances of Vault by instantiating the component. The following configuration creates two Vault instances named vault-prod and vault-test.

applications:
  - vault as vault-prod
  - vault as vault-test
parameters:
  vault_prod:
    config:
      auth:
        - type: ldap
          description: LDAP auth
          options:
            listing_visibility: "unauth"
          config:
            url: ldaps://ldap.server.net:636
            binddn: "uid=vault-service,ou=Special Users,dc=server,dc=net"
            bindpass: '?{vaultkv:${cluster:tenant}/${cluster:name}/vault/${_instance}/ldappass}'
            userattr: uid
            userdn: "ou=vault,ou=Service Access,ou=Views,dc=server,dc=net"
            groupdn: "ou=Groups,dc=vshn,dc=net"
            groupattr: cn
          groups:
            vault-root:
              policies: cluster-root
      policies:
        - name: cluster-root
          rules: |
            path "clusters/*" {
              capabilities = ["create", "read", "update", "delete", "list"]
            }
  vault_test:
    backup:
      enabled: false

This will deploy a production vault with LDAP access named vault-prod to the namespace vault-prod. And a test vault without backups named vault-test to the namespace vault-test.

When instantiating a component the ${INSTANCE} parameter is set to the instance’s name. For the production Vault, the parameter is set to vault-prod and for the test Vault it’s set to vault-test.

There are some things to consider when deploying multiple instances of Vault:

  • No two instances are allowed to have the same name. This includes instances of other components. You should never name an instance the same name as other components. Naming your Vault instance argocd can break in unexpected ways. In general it’s a good idea to prefix your instance with vault-.

  • You can overwrite both the name and namespace of the instance. Two instances can either have the same name or be in the same namespace. If two instances have the same name and namespace bad things will break in unexpected ways.

  • If two instances are deployed to the same namespace, they can in principle read each others secrets. This means in practice you will want to put the production vault in a separate namespace.

More information on how component instantiation works can be found here.

OIDC Integration

Vault has the option to authenticate users through OIDC. This guide describes the manual setup of the Vault OIDC integration for a Vault instance which is associated with a Lieutenant instance.

It should also be possible to configure OIDC integration through the component. However, this requires a client secret which should be stored in Vault. We don’t recommend configuring OIDC through the component when integrating Vault with Lieutenant as this will introduce a dependency for Vault on itself making setup and disaster recovery more difficult.

Configure OIDC Provider

This guide assumes that the OIDC provider is a Keycloak instance, but other OIDC providers should also work.

We first need to create an OIDC client for Vault.

  1. In the appropriate realm, create a OIDC client with:

    Access Type: Confidential
    Redirect URLs:
      - https://${VAULT_URL}/ui/vault/auth/oidc/oidc/callback
      - https://${VAULT_URL}/oidc/callback
      - http://localhost:8250/oidc/callback
  2. Add a role syn-root under the Roles tab in the OIDC client

  3. Under the Mappers tab add a User Client Role mapper. Choose the created OIDC client as the Client ID and set the Token Claim Name to groups.

  4. Open the Keycloak group or user that should get access to Vault and add them to the syn-root role of the created OIDC client.

  5. Copy client secret of the created OIDC client located in the Credentials tab of the client.

Configure Vault

  1. Add a new OIDC Authenication Method in the Vault UI under the Access tab with the following configuration

    List method when unauthenticated: true
    OIDC discovery URI: https://${KEYCLOAK_URL}/auth/realms/${REALM}
    Default role: default
    OIDC client ID: ${CLIENT_ID}
    OIDC client Secret: ${CLIENT_SECRET}
  2. Open a CLI connection to Vault, you can do this by clicking on the CLI icon in the UI, and enter

    vault write auth/oidc/role/default \
          allowed_redirect_uris="https://${VAULT_URL}/ui/vault/auth/oidc/oidc/callback" \
          allowed_redirect_uris="https://${VAULT_URL}/oidc/callback" \
          allowed_redirect_uris="http://localhost:8250/oidc/callback" \
          user_claim="sub" \
          policies="default" \
          groups_claim="groups"

    At this point you should be able to login to Vault using OIDC, but after the login you shouldn’t be able to access anything but the cubbyhole.

  3. Under the Access tab in the Vault UI create a new group called syn-root. The group should be of Type: external and add the syn-root policy to it (or any other policy you would like the OIDC users to have).

  4. Open the newly created group and add an alias with name syn-root and OIDC as the Auth Backend

When logging in with an OIDC user you should now be able to see the cluster/kv secret engine.