/bitwarden-k8s-secrets-manager

Operator which syncs secrets from bitwarden to kubernetes secrets

Primary LanguagePythonGNU General Public License v3.0GPL-3.0

Bitwarden K8s Secrets Manager

A kubernetes operator which synchronizes secrets from Bitwarden™ Secrets Manager.

This operator is designed to be installed in a cluster to manage secrets in namespaces in any namespace.

Installation

A Helm chart is provided for installation. It can be installed directly with helm or by using the helm chart as a source for ArgoCD.

Installation with Helm

helm repo add bitwarden-k8s-secrets-manager https://rhpds.github.io/bitwarden-k8s-secrets-manager
helm install bitwarden-k8s-secrets-manager bitwarden-k8s-secrets-manager/bitwarden-k8s-secrets-manager

Installation with ArgoCD

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: bitwarden-k8s-secrets-manager
  namespace: openshift-gitops
spec:
  destination:
    name: in-cluster
  project: default
  helm:
    path: helm
    repoURL: https://github.com/rhpds/bitwarden-k8s-secrets-manager.git
    targetRevision: {{ .Values.bitwardenK8sSecretsManager.version }}

Configuration

A custom resource definition is provided to allow creation of BitwardenSyncConfig resources.

The Helm chart supports creating BitwardenSyncConfigs on installation with values specifying a dictionary in the values with the key being the BitwardenSyncConfig name and the value being the spec.

Example

Example default BitwardenSyncConfig:

apiVersion: bitwarden-k8s-secrets-manager.demo.redhat.com/v1
kind: BitwardenSyncConfig
metadata:
  name: default
  namespace: bitwarden-k8s-secrets-manager
spec:
  accessTokenSecret:
    name: bitwarden-access-token
  secrets:
  # Bitwarden secret named "app_secret_key" is a simple string value synced
  # to secret "app-secret-key" in "app-namespace" under data item "token".
  - name: app-secret-key
    namespace: app-namespace
    data:
      token:
        secret: app_secret_key

  # Bitwarden secret named "app_database_auth" has a value in YAML or JSON dict
  # format with keys "server", "username", and "password".
  # Secret is synced to secret "app-database-auth" in "app-namespace" with
  # labels "app.kubernetes.io/name" with a value "example-app" and
  # "database-server" with value that exposes the server value.
  - name: app-database-auth
    namespace: app-namespace
    data:
      server:
        secret: app_database_auth
        key: server
      username:
        secret: app_database_auth
        key: username
      password:
        secret: app_database_auth
        key: password
      database:
        secret: app_database_auth
        key: dbname
      port:
        secret: app_database_auth
        key: dbport
    labels:
      app.kubernetes.io/name:
        value: example-app
      database-server:
        secret: app_database_auth
        key: server

Example Bitwarden Secrets Manager values for using these entries.

Secrets Manager Secret

Name:
-------------------------------------------------------------------------------
app_database_auth
-------------------------------------------------------------------------------

Value:

server: productiondb.example.com password: <our_really_strong_c0mpl#X_PASSWORD!> username: tannerite dbname: tracking dbport: 12345


Example BitwardenSyncSecret which uses default BitwardenSyncConfig:

apiVersion: bitwarden-k8s-secrets-manager.demo.redhat.com/v1
kind: BitwardenSyncSecret
metadata:
  name: myapp-db
  namespace: myapp
spec:
  data:
    server:
      secret: ldap_creds
      key: server
    bind_dn:
      secret: ldap_creds
      key: bind_dn
    bind_pw:
      secret: ldap_creds
      key: bind_password
  labels:
    app.kubernetes.io/name:
      value: example-app
    ldap-server:
      secret: ldap_creds
      key: server
    env:
      secret: ldap_creds
      key: environment

Example Bitwarden Secrets Manager values for using these entries.

Secrets Manager Secret

Name:
-------------------------------------------------------------------------------
ldap_creds
-------------------------------------------------------------------------------

Value:

server: ldap.mydomain.example.com bind_dn: uid=clustera-euwest2-robot,cn=users,dc=mydomain,dc=example,dc=com bind_password: <ANOTHER_hideously_COMPL3X_PASSW0$%> environment: dev


Example Bitwarden Secrets Manager values for combining two separate secrets into one k8s secret - assumes yaml-formatted data to create a dict.

NOTE: if "key" is not defined here, then the whole secret is dumped out
under the entry in the combined secret
apiVersion: bitwarden-k8s-secrets-manager.demo.redhat.com/v1
kind: BitwardenSyncSecret
metadata:
  name: myapp-db
  namespace: myapp
spec:
  data:
    ldap:
      secret: ldap_creds
    database:
      secret: app_database_auth
Example BitwardenSyncSecret which uses non-YAML formatted secrets:

  Note: it is possible to have multiple secrets like this - just make sure no
  "key:" is defined under the secret name

apiVersion: bitwarden-k8s-secrets-manager.demo.redhat.com/v1 kind: BitwardenSyncSecret metadata: name: myapp-db namespace: myapp spec: data: conf.d_ssl.conf: secret: apache_config labels: app.kubernetes.io/name: value: example-app

Example Bitwarden Secrets Manager values for using these entries.

Secrets Manager Secret

Name:

apache_config

Value:

Listen 443 https

SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
SSLSessionCache         shmcb:/run/httpd/sslcache(512000)
SSLSessionCacheTimeout  300
SSLRandomSeed startup file:/dev/urandom  256
SSLRandomSeed connect builtin
SSLCryptoDevice builtin

<VirtualHost _default_:443>

ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
LogLevel warn
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite HIGH:3DES:!aNULL:!MD5:!SEED:!IDEA
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key

<Files ~ "\.(cgi|shtml|phtml|php3?)$">
    SSLOptions +StdEnvVars
</Files>
<Directory "/var/www/cgi-bin">
    SSLOptions +StdEnvVars
</Directory>

BrowserMatch "MSIE [2-5]" \
         nokeepalive ssl-unclean-shutdown \
         downgrade-1.0 force-response-1.0

CustomLog logs/ssl_request_log \
          "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

</VirtualHost>
Example BitwardenSyncSecret which uses secrets from 2 specific projects from
   YAML-formatted secrets.

NOTE: this is useful if you have secrets that have the same values defined and
   you need to combine two different entries from different projects

apiVersion: bitwarden-k8s-secrets-manager.demo.redhat.com/v1 kind: BitwardenSyncSecret metadata: name: myapp-db namespace: myapp_uat_munging spec: data: server: project: superdupersecret_prod secret: app_database_auth key: server username: project: supersecret_uat secret: app_database_auth key: username password: project: supersecret_uat secret: app_database_auth key: password