[ENG-175] Kubernetes - Support for additional secret types
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
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.
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:
- Install Infisical, the Infisi8cal Secrets Operator, and the External Secrets Operator.
- 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.
- 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