hasura / graphql-engine

Blazing fast, instant realtime GraphQL APIs on your DB with fine grained access control, also trigger webhooks on database events.
https://hasura.io
Apache License 2.0
31.09k stars 2.77k forks source link

Kubernetes sealed secrets for storing hasura secrets #6505

Open venom90 opened 3 years ago

venom90 commented 3 years ago

Hello Team,

I'm trying to encrypt HASURA_GRAPHQL_ADMIN_SECRET and HASURA_GRAPHQL_DATABASE_URL using Kubernetes sealed secrets.

Following is my k8s secret: hasura.secrets.yaml

apiVersion: v1
kind: Secret
metadata:
  name: hasura-secrets
  namespace: staging
stringData:
  adminsecret: "<SECRET IN PLAIN TEXT>"
  dburl: "postgres://<USERNAME>:<PASSWORD><HOST_NAME>:<PORT>/<DATABASE>"

Then I converted my secrets to encrypted format using kubeseal

kubeseal < hasura/hasura.secrets.yaml --cert cert.pem -o yaml > hasura/hasura.sealedsecrets.yaml

It generated following sealed secret:

apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  creationTimestamp: null
  name: hasura-secrets
  namespace: staging
spec:
  encryptedData:
    adminsecret: <ENCRYPTED ADMIN SECRET>
    dburl: <ENCRYPTED DB PATH>
  template:
    metadata:
      creationTimestamp: null
      name: hasura-secrets
      namespace: staging

Once I deploy this sealed secret it is creating k8s secret in the cluster. The problem is sealed secret is now converting the encrypted data into base64 instead of plain text.

I'm using it in deployment.yaml like following:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: hasura
    hasuraService: custom
  name: hasura
  namespace: staging
spec:
  replicas: 2
  selector:
    matchLabels:
      app: hasura
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: hasura
    spec:
      containers:
      - image: hasura/graphql-engine:v1.3.3
        imagePullPolicy: IfNotPresent
        name: hasura
        env:
        ## Admin secret
        - name: HASURA_GRAPHQL_ADMIN_SECRET
          valueFrom:
            secretKeyRef:
              name: hasura-secrets
              key: adminsecret
        ## Database URL
        - name: HASURA_GRAPHQL_DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: hasura-secrets
              key: dburl
        ## enable the console served by server
        - name: HASURA_GRAPHQL_ENABLE_CONSOLE
          valueFrom:
            configMapKeyRef:
              name: hasura-configmap
              key: enable_console
        ## enable debugging mode. It is recommended to disable this in production
        - name: HASURA_GRAPHQL_DEV_MODE
          valueFrom:
            configMapKeyRef:
              name: hasura-configmap
              key: dev_mode
        ports:
        - containerPort: 8080
          protocol: TCP
        resources: {}

Since the secret is now in base64 Hasura GraphQL engine is failing to start. Is there a way to somehow convert the base64 string into plain text or pass base64 as it is to these environment variables and Hasura engine converts into plain text?

tirumaraiselvan commented 3 years ago

This is perhaps a bug in sealed secrets, as the docs mention: https://kubernetes.io/docs/concepts/configuration/secret/#consuming-secret-values-from-environment-variables

Inside a container that consumes a secret in the environment variables, the secret keys appear as normal environment variables containing the base64 decoded values of the secret data. This is the result of commands executed inside the container from the example above:

secretKeyRef is expected to supply the decoded value to the container.