Frequency Developer Gateway - Vault Integration

This guide describes how to set up and integrate HashiCorp Vault for managing and securely storing secrets used by the Frequency Developer Gateway services. The integration allows sensitive data such as API tokens, account seed phrases, and credentials to be securely managed through Vault, rather than hardcoding them in Kubernetes manifests.

Prerequisites

  1. Vault installed and running.
  2. Kubernetes cluster (with Frequency Developer Gateway deployed).
  3. Helm installed (for deploying Vault and Frequency Developer Gateway).
  4. Vault configured with Kubernetes authentication.

Table of Contents


1. Overview

Vault is used to manage and securely inject secrets into the Frequency Developer Gateway services, such as:

  • account-service: Stores provider access tokens and account seed phrases.
  • content-publishing-service: Manages IPFS authentication secrets.
  • content-watcher-service: Handles watcher credentials and IPFS secrets.
  • graph-service: Manages provider access tokens and account details.

2. Vault Setup

2.1 Enable Key-Value (KV) Secret Engine

To store secrets in Vault, you must first enable the KV secret engine. You can do this with the following command:

vault secrets enable -path=secret kv

2.2 Create Secrets

Vault allows you to store your secrets under a defined path. For the Frequency Developer Gateway, secrets are stored under paths like secret/data/frequency-gateway/[service-name]. You can add secrets using the Vault CLI.

For example, to create secrets for the account service:

vault kv put secret/frequency-gateway/account PROVIDER_ACCESS_TOKEN=<your-access-token> PROVIDER_ACCOUNT_SEED_PHRASE=<your-seed-phrase>

Similarly, create secrets for other services:

  • Content Publishing Service:

    vault kv put secret/frequency-gateway/content-publishing IPFS_BASIC_AUTH_USER=<username> IPFS_BASIC_AUTH_SECRET=<password> PROVIDER_ACCOUNT_SEED_PHRASE=<your-seed-phrase>
    
  • Content Watcher Service:

    vault kv put secret/frequency-gateway/content-watcher IPFS_BASIC_AUTH_USER=<username> IPFS_BASIC_AUTH_SECRET=<password>
    
  • Graph Service:

    vault kv put secret/frequency-gateway/graph PROVIDER_ACCESS_TOKEN=<your-access-token> PROVIDER_ACCOUNT_SEED_PHRASE=<your-seed-phrase>
    

2.3 Set Up Kubernetes Authentication

To allow your Kubernetes cluster to access secrets in Vault, you need to configure Vault's Kubernetes authentication method.

  1. Enable Kubernetes Auth Method:

    vault auth enable kubernetes
    
  2. Configure the Kubernetes Auth Method:

    Get the Kubernetes service account token and CA certificate, then configure Vault with this information:

    vault write auth/kubernetes/config \
      token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
      kubernetes_host="https://<KUBERNETES_HOST>:6443" \
      kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
    
  3. Create a Vault Role for Frequency Developer Gateway:

    Bind the Vault role to the appropriate Kubernetes service accounts, which allows the Frequency Developer Gateway pods to retrieve secrets.

    vault write auth/kubernetes/role/frequency-gateway-role \
      bound_service_account_names=frequency-gateway \
      bound_service_account_namespaces=default \
      policies=default \
      ttl=24h
    

3. Integrating Vault with Frequency Developer Gateway

3.1 Helm Configuration

Update your values.yaml file to enable Vault integration for Frequency Developer Gateway deployment. Here's an example configuration:

vault:
  enabled: true  # Enable Vault integration
  address: "http://vault.default.svc.cluster.local:8200"
  role: "frequency-gateway-role"
  tokenSecretName: "vault-token"
  tokenSecret: "root"
  secretsPath: "secret/data/frequency-gateway"

For each service (e.g., account-service, content-publishing-service) in the Frequency Developer Gateway, add a similar configuration to the values.yaml file.

Deploy or upgrade the Frequency Developer Gateway Helm chart with:

helm upgrade --install frequency-gateway ./helm/frequency-gateway -f values.yaml

3.2 Creating External Secret and Secret Store

To securely connect Kubernetes resources with Vault, you need to use the External Secrets and Secret Store. This allows Kubernetes services to dynamically fetch secrets from Vault.

  1. Create a Secret Store:

    Create a SecretStore resource to configure how Kubernetes connects to Vault.

    Example configuration for Vault backend:

    apiVersion: external-secrets.io/v1beta1
    kind: SecretStore
    metadata:
      name: vault-secret-store
      namespace: default
    spec:
      provider:
        vault:
          server: "{{ .Values.vault.address }}"
          path: "secret"
          version: "v2"
          auth:
            tokenSecretRef:
              name: vault-token
              key: root
    

    Apply the SecretStore configuration:

     kubectl apply -f secret-store.yaml
    
  2. Create the External Secret:

    Example Helm template for ExternalSecret resources:

    {{- if .Values.vault.enabled }}
    
    apiVersion: external-secrets.io/v1beta1
    kind: ExternalSecret
    metadata:
      name: account-secret
    spec:
      backendType: vault
      vault:
        server: "{{ .Values.vault.address }}"
        path: "{{ .Values.vault.secretsPath }}/account"
        version: "v2"
        auth:
          tokenSecretRef:
            name: "{{ .Values.vault.tokenSecretName }}"
            key: "{{ .Values.vault.tokenSecret }}"
    
      data:
        - key: PROVIDER_ACCESS_TOKEN
          name: PROVIDER_ACCESS_TOKEN
        - key: PROVIDER_ACCOUNT_SEED_PHRASE
          name: PROVIDER_ACCOUNT_SEED_PHRASE
    ---
    apiVersion: external-secrets.io/v1beta1
    kind: ExternalSecret
    metadata:
      name: content-publishing-secret
    spec:
      backendType: vault
      vault:
        server: "{{ .Values.vault.address }}"
        path: "{{ .Values.vault.secretsPath }}/content-publishing"
        version: "v2"
        auth:
          tokenSecretRef:
            name: "{{ .Values.vault.tokenSecretName }}"
            key: "{{ .Values.vault.tokenSecret }}"
    
      data:
        - key: IPFS_BASIC_AUTH_USER
          name: IPFS_BASIC_AUTH_USER
        - key: IPFS_BASIC_AUTH_SECRET
          name: IPFS_BASIC_AUTH_SECRET
        - key: PROVIDER_ACCOUNT_SEED_PHRASE
          name: PROVIDER_ACCOUNT_SEED_PHRASE
    
    ---
    apiVersion: external-secrets.io/v1beta1
    kind: ExternalSecret
    metadata:
      name: graph-secret
    spec:
      backendType: vault
      vault:
        server: "{{ .Values.vault.address }}"
        path: "{{ .Values.vault.secretsPath }}/graph"
        version: "v2"
        auth:
          tokenSecretRef:
            name: "{{ .Values.vault.tokenSecretName }}"
            key: "{{ .Values.vault.tokenSecret }}"
    
      data:
        - key: PROVIDER_ACCESS_TOKEN
          name: PROVIDER_ACCESS_TOKEN
        - key: PROVIDER_ACCOUNT_SEED_PHRASE
          name: PROVIDER_ACCOUNT_SEED_PHRASE
    
    {{- end }}
    

3.3 Handling Single-Value Secrets

For single-value secrets, use the ExternalSecret configuration to point to a specific key.

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: account-secret
spec:
  backendType: vault
  vault:
    server: "{{ .Values.vault.address }}"
    path: "{{ .Values.vault.secretsPath }}/account"
    version: "v2"
    auth:
      tokenSecretRef:
        name: "{{ .Values.vault.tokenSecretName }}"
        key: "{{ .Values.vault.tokenSecret }}"
  data:
    - key: PROVIDER_ACCESS_TOKEN
      name: PROVIDER_ACCESS_TOKEN

4. Accessing Secrets

Once Vault is integrated, services in the Frequency Developer Gateway will automatically retrieve secrets at runtime.

4.1 Using CLI

To manually retrieve secrets using the Vault CLI:

vault kv get secret/frequency-gateway/account
vault kv get secret/frequency-gateway/content-publishing
vault kv get secret/frequency-gateway/content-watcher
vault kv get secret/frequency-gateway/graph

To retrieve specific fields:

vault kv get -field=PROVIDER_ACCESS_TOKEN secret/frequency-gateway/account

5. Troubleshooting

  • Vault Access Errors: Ensure that the Kubernetes authentication method is correctly configured, and the service accounts are bound to the appropriate Vault roles.
  • Secrets Not Being Retrieved: Double-check your values.yaml file for correct Vault paths and the service's configuration for secret access.

For more information, refer to the Vault documentation.

6. References