infisical icon indicating copy to clipboard operation
infisical copied to clipboard

[ENG-175] Kubernetes - Support for additional secret types

Open erkerb4 opened this issue 2 years ago • 2 comments

Feature description

All secrets deployed to Kubernetes via kubernetes-operator and the InfisicalObject are an opaque type secret. It would elevate the capability of the kubernetes-operator if it can support other secret types, such as kubernetes.io/tls, kubernetes.io/basic-auth, kubernetes.io/dockercfg, kubernetes.io/ssh-auth , bootstrap.kubernetes.io/token, etc.

Why would it be useful?

It would be beneficial for Infisical to be able to provide secrets to applications that are not opaque. For example, linkerd application requires secrets to be an kubernetes.io/tls type. We attempted to use opaque, and the application would not function correctly.

Additional context

The Secret type is used to facilitate programmatic handling of the Secret data.

From SyncLinear.com | ENG-175

erkerb4 avatar Oct 09 '23 17:10 erkerb4

Another example of where this would be useful is Bootstrapping a Postgres Cluster using CloudNativePG which uses a secret of type kubernetes.io/basic-auth.

rwarford avatar May 30 '24 16:05 rwarford

UPDATE: According to this comment on issue #2047 an Infisical Provider has been created for the External Secrets Operator. As of the time of this edit it is not yet visible in the External Secrets documentation but it will address the one minor concern I had with the approach I describe below.

ORIGINAL COMMENT: I was able to create a basic-auth secret by using Infisical and the External Secrets Operator.

It was a little inelegant since I can't find a way to connect the External Secrets Operator directly to Infisical.

The approach that worked was to use Infisical to create a regular opaque secret then use the External Secrets Operator's Kubernetes provider to read that secret and create a new basic-auth secret. The net effect is one extra unnecessary opaque secret is created.

The flow is: Infisical -> opaque secret -> External Secrets Operator -> basic-auth secret

This approach will work for any type of Kubernetes secret.

Here is a basic-auth example:

  1. Install Infisical, the Infisi8cal Secrets Operator, and the External Secrets Operator.
  2. Use Infisical and the Infisical Secrets Operator to create a regular opaque secret in the default namespace that has PG_USERNAME and a PG_PASSWORD fields.
  3. Apply apply this manifest:
apiVersion: v1
kind: ServiceAccount
metadata:
  name: secret-reader-account
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: secret-reader
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["secrets"]
  verbs: ["get", "list", "watch"]
- apiGroups:
  - authorization.k8s.io
  resources:
  - selfsubjectaccessreviews
  - selfsubjectrulesreviews
  verbs:
  - create
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: secret-reader-account-binding
subjects:
  - kind: ServiceAccount
    name: secret-reader-account
roleRef:
  kind: Role
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: k8s-store-default-ns
spec:
  provider:
    kubernetes:
      # with this, the store is able to pull only from `default` namespace
      #remoteNamespace: default
      server:
        #url: "https://myapiserver.tld"  # ommit to default to kubernetes.default
        caProvider:
          type: ConfigMap
          name: kube-root-ca.crt
          key: ca.crt
      auth:
        serviceAccount:
          name: secret-reader-account
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: pg-credentials
spec:
  refreshInterval: 1h
  secretStoreRef:
    kind: SecretStore
    name: k8s-store-default-ns  # name of the SecretStore (or kind specified)
  target:
    name: pg-credentials  # name of the k8s Secret to be created
    template:
        type: kubernetes.io/basic-auth
        data:
          username: "{{ .username | toString }}"
          password: "{{ .password | toString }}"
  data:
  - secretKey: username
    remoteRef:
      key: managed-secret
      property: PG_USERNAME

  - secretKey: password
    remoteRef:
      key: managed-secret
      property: PG_PASSWORD

rwarford avatar Jul 01 '24 15:07 rwarford