Secrets Management in GitOps Workflows

Secrets Management in GitOps Workflows

GitOps principles dictate that Git repositories should contain all infrastructure configuration, but secrets present a unique challenge. Storing secrets in Git repositories, even encrypted, violates security best practices. GitOps implementations must integrate with external secret management systems to handle sensitive data securely.

The External Secrets Operator pattern has emerged as a leading solution for Kubernetes-based GitOps. This operator synchronizes secrets from external systems like HashiCorp Vault, AWS Secrets Manager, or Azure Key Vault into Kubernetes secrets. Git repositories contain references to secrets rather than actual values, maintaining GitOps principles while ensuring security.

# External Secrets Operator configuration for GitOps
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: vault-backend
  namespace: production
spec:
  provider:
    vault:
      server: "https://vault.internal.com:8200"
      path: "secret"
      version: "v2"
      auth:
        kubernetes:
          mountPath: "kubernetes"
          role: "gitops-production"
          serviceAccountRef:
            name: "external-secrets"

---
# External secret definition in Git
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: application-secrets
  namespace: production
spec:
  refreshInterval: 15m
  secretStoreRef:
    name: vault-backend
    kind: SecretStore
  target:
    name: app-secrets
    creationPolicy: Owner
    template:
      engineVersion: v2
      data:
        database-url: |
          postgresql://{{ .username }}:{{ .password }}@{{ .host }}:5432/{{ .database }}
  data:
    - secretKey: username
      remoteRef:
        key: production/database
        property: username
    - secretKey: password
      remoteRef:
        key: production/database
        property: password
    - secretKey: host
      remoteRef:
        key: production/database
        property: host
    - secretKey: database
      remoteRef:
        key: production/database
        property: database

---
# Sealed Secrets alternative for smaller deployments
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  name: api-credentials
  namespace: production
spec:
  encryptedData:
    api-key: AgBvV+N6L6X8W5wL... # Encrypted with cluster's public key
    api-secret: AgCdGH3zS6nB5F9K...
  template:
    metadata:
      name: api-credentials
      namespace: production
    type: Opaque

Secrets rotation in GitOps environments requires coordination between secret stores and deployed applications. Automated rotation should update secrets in external stores while applications retrieve new values dynamically. GitOps repositories might need updates for secret references but should never contain actual secret values.