Kubernetes Integration

Having secrets in bitwarden is good and all, but currently there’s a lack of places the secrets can actually be used. Github Actions is a good first one, however there are more integrations required to make this useful to us.

A pain-point in our devops area is secrets handling in Kubernetes and we were hoping Bitwarden would provide something akin to GitHub - 1Password/onepassword-operator: The 1Password Connect Kubernetes Operator provides the ability to integrate Kubernetes Secrets with 1Password. The operator also handles autorestarting deployments when 1Password items are updated. with this secret manager.

Secrets could be provided in kubernetes using a Mozilla SOPS plugin, or a Secrets CSI implementation, etc.

3 Likes

Hey Roger,

Thanks for sharing your feedback on Bitwarden’s Secrets Manager.

I’m happy to inform you that a Kubernetes integration is one of our top priorities, and we’re actively working on it for upcoming releases.

Your feedback is valuable to the Bitwarden team, and we appreciate your support. If you have any more suggestions or questions, please let us know.

Best regards,
Max

1 Like

Hi everyone,

I work for Red Hat and I have customers that could use a kubernetes or OpenShift solution. An operator or Helm chart would be awesome.

Thanks for your time and consideration

2 Likes

This was a core consideration in why my organization selected 1Password over Bitwarden.

The capabilities of the 1Password Operator and Secrets Injector are very mature and are allowing my team to commit secrets configuration to source control without risk of secrets. Below is an example manifest.

apiVersion: onepassword.com/v1
kind: OnePasswordItem
metadata:
  name: cert-manager-aws-route53-credentials
  namespace: cert-manager
spec:
  itemPath: "vaults/vault-name/items/item-name"

Thanks, @estenrye. We appreciate the feedback and the sample manifest. Expanding integrations support is a continued product focus for Bitwarden Secrets Manager, with the Kubernetes operator being the top priority - you can expect the release in the coming months. I will update this thread as we get closer to launch.

2 Likes

It would be great to have a list of pending integrations on your help section (https://bitwarden.com/help/github-actions-integration/), along with approximate timelines. We’re very interested in the kubernetes integrations.

In my opinion, the whole concept of using long lived access tokens for machine account is completely flawed. Kubernetes, GitHub actions, GCP, etc. all have the concept of workload identity using OIDC JWT tokens. Ideally, we should be able to use existing workload identity mechanisms to authenticate to Bitwarden Secrets manager. Then, any Kubernetes operator or secrets store drive could leverage that for authentication without the need for access tokens. The plus side is that once you add support for workload identity, all these cloud platforms immediately also gain keyless auth. Any platform that can leverage SPIFEE/SPIRE could then also take advantage of keyless auth. @Max_Bitwarden is there any plans for workload identity/federated credential support? Should that be a separate request?

Should work similar to how it works in Google or Azure:

Would more investment into External Secrets Operator make sense?

There is already the webhook integration for bitwarden vault, but native secret manager integration would be more ideal.

1 Like

Hello Max

Do you have an updated roadmap on when things like the K8S integration will be ready?

Thanks

1 Like

I have seen the updated on Vault Hours 40, I see its in early Beta, when will it be released to Public Beta, looking forward to this coming out :slight_smile:

Hey all and @shinrath,

Apologies for the delayed response. I’m excited to share that our Kubernetes Operator is now in public beta! You can find the documentation here: Bitwarden Secrets Manager Kubernetes Operator Documentation.

1 Like

@dronenb
Thanks a lot for your feedback. Bitwarden Secrets Manager is end-to-end encrypted and follows a zero-trust architecture, which makes integrating workload identity mechanisms challenging.

When creating an access token for Bitwarden Secrets Manager, a new encryption key is generated on the client side to encrypt the user’s organization key. This encrypted key is stored in Bitwarden’s database and can only be decrypted by the access token that created it. The access token, formatted as [version].[access-token-id].[client-secret]:[encryption-key], is generated client-side and shown to the user once, without being stored.

During authentication, the encrypted organization key is sent back to the client and decrypted using the access token’s encryption key. This allows the client to access and decrypt stored data.

We currently dont have a secure method to store and share the organization’s key via OpenID Connect trust relationships. OpenID Connect isn’t my area of expertise, so any ideas on how to make this work are more than welcome :slight_smile:

It might be a good idea to open a separate feature request to discuss this further and gather more input.

Hello!

I’ve been checking out this Bitwarden integration, and it looks promising, but I have some thoughts on the current approach.

The documentation mentions:

Each namespace where a BitwardenSecret is created will require a Kubernetes secret be created to authenticate against Secrets Manager.

This implies that every project needs a Bitwarden token with API access. If that’s the case, then potentially every pod within that namespace could also access the token (with default RBAC settings).

I understand the idea of having a machine account per project for a 1:1 security model, where each namespace accesses only its secrets. However, it seems this might actually expand the potential attack surface rather than reducing it.

In my 25 years of experience working with clients, I’ve noticed a few patterns:

  • Secrets often end up in git repositories.
  • Creating a token for each namespace is unlikely to be common practice.
  • Most won’t customize RBAC to tighten security.

We all know people tend to take the path of least resistance! :wink:

My suggestion:

What if we allowed secrets for the access token to be centralized in a dedicated namespace? Then, BitwardenSecret resources could reference those tokens without the pods in the project needing direct access.

Here’s a quick example:

apiVersion: k8s.bitwarden.com/v1
kind: BitwardenSecret
metadata:
  labels:
    app.kubernetes.io/name: bitwardensecret
    app.kubernetes.io/instance: bitwardensecret-sample
    app.kubernetes.io/part-of: sm-operator
    app.kubernetes.io/managed-by: kustomize
    app.kubernetes.io/created-by: sm-operator
  name: bitwardensecret-sample
  namespace: bw-namespace # Will work because matches bw-*
spec:
  secretName: bw-sample-secret
  map:
    - bwSecretId: asdasdkasjhdasgasdasd
      secretKeyName: test01
      authToken:
        secretName: bw-auth-token-01
        namespace: my-bw-namespace-secrets
        secretKey: token.   
        organizationIdKey: organizationId
    - bwSecretId: dklfjhdjkfghjkdfghkjdfghgdfk
      secretKeyName: test02
      authToken:
        secretName: bw-auth-token-02
        namespace: my-bw-namespace-secrets
        secretKey: token
        organizationIdKey: organizationId


# note that secretName secretKey and organizationIdKey  
# is additional security at no cost because you could use a random 
# name or have a secret with merged tokens to reduce trash around your k8s
---
apiVersion: v1
stringData:
  token: asdasdasd==
  organizationId: blah-0a00-46cc-856b-blah
  allowedNamespaces: |
    default
    bw*
kind: Secret
metadata:
  name: bw-auth-token-01
  namespace: my-bw-namespace-secrets
---
apiVersion: v1
stringData:
  token: ortyiourtyuiortyiou==
  organizationId: ble-0a00-46cc-856b-bleh
  allowedNamespaces: |
    default
    bw*
kind: Secret
metadata:
  name: bw-auth-token-02
  namespace: my-bw-namespace-secrets
---
apiVersion: v1
stringData:
  tokenASD: asdhjkashdkjahsdkjash==
  organizationASD: bli-0a00-46cc-856b-bli
  tokenFGH: asdhjkashdkjahsdkjash==
  organizationFGH: bli-0a00-46cc-856b-bli
  allowedNamespaces: |
    custom-app099
kind: Secret
metadata:
  name: bw-multi-auth-token
  namespace: my-bw-namespace-secrets

This approach could significantly reduce the attack surface while still allowing for the current design if desired.

Alternatively, adding a default/fallback machine account could simplify things even further. It would reduce the information shared with each namespace and minimize the required configuration.

Additional thought:

The organizationId seems like potential oversharing. It’s great to have the option to pass it, but it might be better not to expose it in all the BitwardenSecret resources. The bwSecretId should be sufficient for developers.

Just my two cents!

Let me know what you think!

EDIT2: I was sounding a little too pompous :slight_smile:
EDIT3: Removed AI helper comment :sweat_smile:

3 Likes

Hello Max,

I’m testing Secrets Manager Kubernetes Operator to synchronize passwords from bitwarden. Is it not possible to apply a filter to retrieve a single secret in a project? I’m using a token that has rights to a specific project, but all the secrets in that project are synchronized in the same kubernetes secret.

I have given sm-operator a whirl recently, and I have to say that in comparison to the tooling I am used to; that being vault-secrets-operator and external-secrets, I feel that the implementation is off the mark and it being in “beta” rather than “alpha” is a terminology mistake in my opinion…

I am also troubled by the fact that the CRDs/API is versioned as v1 directly rather than a v1alpha1 or some other moniker, this makes upgrading super difficult/dangerous in the future, I have little trust that the API at present will remain stable even in the next version ending up in super broken changes without effectively managing revisions for those of us using GitOps.

Additionally, there are non-trivial and frankly, dangerous bug(s) in the current release; here is an example: I tried to sync several secrets from Secrets Manager through sm-operator to k8s secrets, and it seems that for each secret you sync it just adds it to the operator pay load and every secret gets all the other secret values put into it. Only using their GUID’s as the keys where the specified secret will have the key names specified.

The fact this can happen really shows the whole “secret-per-namespace” idea for security really isn’t needed, which I will get into a little more below…

Like others on here, I feel that limiting users to a secret per namespace for syncing is also a mistake… When using external-secrets for instance, I will typically just create a ClusterSecretStore and reference that when creating further resources (there is similar in the vault operator also). This is a must-have for those of us in a single-tenancy cluster where it becomes super tedious to manage credentials per namespace (it becomes a process of duplication of the same secret in each required namespace, frankly) and while this can be simplified with something like Kyverno, I’d rather not have to rely on it.

I am super grateful that you have decided to embark on a first-party support endeavour here for Kubernetes, I just don’t think that the experience is there (yet) and that research into the way it’s done in the broader industry was perhaps overlooked?

I will continue to use other solutions for now, and will keep a bare-bones deployment in my homelab to touch base with it as long as it develops, but I feel it’s many, many versions away from being useful (I didn’t even get into things like arbitrary templating, etc being missing here :slight_smile:)