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!
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
EDIT3: Removed AI helper comment