Published: May 21, 2024 by Isaac Johnson
Last week we looked at Vaultwarden, the Rust based clone of Bitwarden.
Today, let’s look at Bitwarden itself. While Bitwarden has a commercial offering, their source code and backend are completely Open-source. We’ll try to setup the Kubernetes version (spoiler: some success, but ingress issues persist), then look at the SaaS offering and some of it’s features.
We’ll take a look at export/import between Wardens (Vault and Bit) and explore browser extensions. We’ll check out the Android app and touch on costs (actually quite reasonable).
Let’s dig in!
Installation
There are a lot of install options for Bitwarden but we’ll start with their Helm charts for a native Kubernetes deployment.
We want to get the values.yaml to edit. To do this, let’s add their chart repo and show values to a file
$ helm repo add bitwarden https://charts.bitwarden.com/
"bitwarden" has been added to your repositories
$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "bitwarden" chart repository
...Unable to get an update from the "freshbrewed" chart repository (https://harbor.freshbrewed.science/chartrepo/library):
failed to fetch https://harbor.freshbrewed.science/chartrepo/library/index.yaml : 404 Not Found
...Unable to get an update from the "myharbor" chart repository (https://harbor.freshbrewed.science/chartrepo/library):
failed to fetch https://harbor.freshbrewed.science/chartrepo/library/index.yaml : 404 Not Found
...Successfully got an update from the "azure-samples" chart repository
...Successfully got an update from the "portainer" chart repository
...Successfully got an update from the "ngrok" chart repository
...Successfully got an update from the "nfs" chart repository
...Successfully got an update from the "opencost" chart repository
...Successfully got an update from the "adwerx" chart repository
...Successfully got an update from the "opencost-charts" chart repository
...Successfully got an update from the "actions-runner-controller" chart repository
...Successfully got an update from the "openfunction" chart repository
...Successfully got an update from the "kuma" chart repository
...Successfully got an update from the "rhcharts" chart repository
...Successfully got an update from the "hashicorp" chart repository
...Successfully got an update from the "novum-rgi-helm" chart repository
...Successfully got an update from the "zabbix-community" chart repository
...Successfully got an update from the "makeplane" chart repository
...Successfully got an update from the "sonarqube" chart repository
...Successfully got an update from the "lifen-charts" chart repository
...Successfully got an update from the "nginx-stable" chart repository
...Successfully got an update from the "gitea-charts" chart repository
...Successfully got an update from the "elastic" chart repository
...Successfully got an update from the "harbor" chart repository
...Successfully got an update from the "sumologic" chart repository
...Successfully got an update from the "akomljen-charts" chart repository
...Successfully got an update from the "rook-release" chart repository
...Successfully got an update from the "datadog" chart repository
...Successfully got an update from the "incubator" chart repository
...Successfully got an update from the "argo-cd" chart repository
...Successfully got an update from the "rancher-latest" chart repository
...Successfully got an update from the "crossplane-stable" chart repository
...Successfully got an update from the "uptime-kuma" chart repository
...Successfully got an update from the "newrelic" chart repository
...Successfully got an update from the "gitlab" chart repository
...Successfully got an update from the "prometheus-community" chart repository
...Successfully got an update from the "jfelten" chart repository
...Successfully got an update from the "btungut" chart repository
...Successfully got an update from the "confluentinc" chart repository
...Successfully got an update from the "kube-state-metrics" chart repository
...Successfully got an update from the "dapr" chart repository
...Successfully got an update from the "ingress-nginx" chart repository
...Successfully got an update from the "longhorn" chart repository
...Successfully got an update from the "kiwigrid" chart repository
...Successfully got an update from the "jetstack" chart repository
...Successfully got an update from the "spacelift" chart repository
...Successfully got an update from the "castai-helm" chart repository
...Successfully got an update from the "openproject" chart repository
...Successfully got an update from the "kubecost" chart repository
...Successfully got an update from the "signoz" chart repository
...Successfully got an update from the "openzipkin" chart repository
...Successfully got an update from the "open-telemetry" chart repository
...Successfully got an update from the "ananace-charts" chart repository
...Successfully got an update from the "grafana" chart repository
...Unable to get an update from the "epsagon" chart repository (https://helm.epsagon.com):
Get "https://helm.epsagon.com/index.yaml": dial tcp: lookup helm.epsagon.com on 172.22.64.1:53: server misbehaving
...Successfully got an update from the "bitnami" chart repository
Update Complete. ⎈Happy Helming!⎈
I’ll create a namespace in anticipation
$ kubectl create ns bitwarden
namespace/bitwarden created
Then fetch the values to a file
$ helm show values bitwarden/self-host --devel > my-bw-values.yaml
I’ll edit some of the values - such as Ingress and Storageclass name
# Optional - Override the chart name if desired
fullnameOverride: ""
nameOverride: ""
general:
# Domain name for the service
domain: "bitwarden.tpk.pw"
ingress:
# Set to false if using a custom ingress
enabled: true
# Current supported values for ingress type include: nginx
className: "nginx"
## - Annotations to add to the Ingress resource.
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
# nginx.ingress.kubernetes.io/use-regex: "true"
# nginx.ingress.kubernetes.io/rewrite-target: /$1
## - Labels to add to the Ingress resource
labels: {}
# Certificate options
tls:
# TLS certificate secret name
name: bitwarden-tls
# Cluster cert issuer (ex. Let's Encrypt) name if one exists
clusterIssuer: azuredns-tpkpw
# Ingress path configuration - The samples provided are for Nginx. Examples with other Ingress providers are in the chart Readme on GitHub
I can create the A Record
$ az account set --subscription "Pay-As-You-Go" && az network dns record-set a add-record -g idjdnsrg -z tpk.pw -a 75.73.224.240 -n bitwarden
{
"ARecords": [
{
"ipv4Address": "75.73.224.240"
}
],
"TTL": 3600,
"etag": "fa9b2914-8414-4c0c-8627-215e1b2d4fb9",
"fqdn": "bitwarden.tpk.pw.",
"id": "/subscriptions/d955c0ba-13dc-44cf-a29a-8fed74cbb22d/resourceGroups/idjdnsrg/providers/Microsoft.Network/dnszones/tpk.pw/A/bitwarden",
"name": "bitwarden",
"provisioningState": "Succeeded",
"resourceGroup": "idjdnsrg",
"targetResource": {},
"type": "Microsoft.Network/dnszones/A"
}
I needed to get the Host ID and Key from https://bitwarden.com/host/.
It doesn’t cost anything and used by sales and security to send updates. Small price to pay, I suppose
Before I can move forward I need to create a secret
$ kubectl create secret generic custom-secret -n bitwarden \
-from-literal=globalSet> --from-literal=globalSettings__installation__id="b************************************2" \
> --from-literal=globalSettings__installation__key="7****************************h" \
> --from-literal=globalSettings__mail__smtp__username="apikey" \
> --from-literal=globalSettings__mail__smtp__password="SG.U**********************************************************************4" \
--from-litera> --from-literal=globalSettings__yubico__clientId="REPLACE" \
--from> --from-literal=globalSettings__yubico__key="REPLACE" \
> --from-literal=globalSettings__hibpApiKey="REPLACE" \
--fro> --from-literal=SA_PASSWORD="REPLACE"
secret/custom-secret created
Now I can install
$ helm upgrade bitwarden bitwarden/self-host --install --namespace bitwarden --values my-bw-values.yaml
Release "bitwarden" does not exist. Installing it now.
Error: failed post-install: 1 error occurred:
* timed out waiting for the condition
I think it was due to the PVCs
$ kubectl get pvc -n bitwarden
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
bitwarden-self-host-mssqlbackups Pending local-path 96m
bitwarden-self-host-mssqldata Pending local-path 96m
bitwarden-self-host-dataprotection Pending local-path 96m
bitwarden-self-host-attachments Pending local-path 96m
bitwarden-self-host-mssqllog Pending local-path 96m
bitwarden-self-host-licenses Pending local-path 96m
I tried a second time round with ‘managed-nfs-storage’
$ helm upgrade bitwarden bitwarden/self-host --install --namespace bitwarden --values my-bw-values.yaml
Release "bitwarden" does not exist. Installing it now.
Error: failed post-install: 1 error occurred:
* timed out waiting for the condition
$ kubectl get pvc -n bitwarden
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
bitwarden-self-host-mssqllog Bound pvc-055d61c6-c020-4f9e-ba18-2197077acc92 10Gi RWX managed-nfs-storage 3m32s
bitwarden-self-host-dataprotection Bound pvc-7448e6da-c878-45d3-adcd-97884f3cb268 1Gi RWX managed-nfs-storage 3m32s
bitwarden-self-host-licenses Bound pvc-c42740d2-e9e5-4455-aefa-9cc1c823169d 1Gi RWX managed-nfs-storage 3m32s
bitwarden-self-host-mssqlbackups Bound pvc-7e1689f8-0693-4928-a1cf-fe8b8b094fa7 1Gi RWX managed-nfs-storage 3m32s
bitwarden-self-host-attachments Bound pvc-7fdf610e-9a5e-41b7-a524-9f704f56e5af 1Gi RWX managed-nfs-storage 3m32s
bitwarden-self-host-mssqldata Bound pvc-03894d3d-626d-4b1e-90e4-a2b8b3976a3f 10Gi RWX managed-nfs-storage 3m32s
Seems it is the MSQL this time causing troubles
$ kubectl get pods -n bitwarden
NAME READY STATUS RESTARTS AGE
bitwarden-self-host-notifications-54466bbfff-jtmtq 1/1 Running 0 7m26s
bitwarden-self-host-icons-5d568bd579-gkn88 1/1 Running 0 7m26s
bitwarden-self-host-identity-7dcd9f5dc5-mdjjm 1/1 Running 0 7m26s
bitwarden-self-host-events-575499c877-tvsmm 1/1 Running 0 7m26s
bitwarden-self-host-web-76d589c6b4-29sw7 1/1 Running 0 7m26s
bitwarden-self-host-attachments-55c87f9748-dhxkc 1/1 Running 0 7m26s
bitwarden-self-host-api-685dbdcbb5-snpzx 1/1 Running 0 7m26s
bitwarden-self-host-sso-5756c5d654-hdjjl 1/1 Running 1 (3m37s ago) 7m26s
bitwarden-self-host-admin-5d7f7dfb8c-2qs9z 1/1 Running 1 (3m5s ago) 7m26s
bitwarden-self-host-mssql-0 0/1 CrashLoopBackOff 5 (96s ago) 7m26s
Let’s take a look
builder@DESKTOP-QADGF36:~/Workspaces/vaultwarden$ kubectl get pods -n bitwarden
NAME READY STATUS RESTARTS AGE
bitwarden-self-host-notifications-54466bbfff-jtmtq 1/1 Running 0 8m48s
bitwarden-self-host-icons-5d568bd579-gkn88 1/1 Running 0 8m48s
bitwarden-self-host-identity-7dcd9f5dc5-mdjjm 1/1 Running 0 8m48s
bitwarden-self-host-events-575499c877-tvsmm 1/1 Running 0 8m48s
bitwarden-self-host-web-76d589c6b4-29sw7 1/1 Running 0 8m48s
bitwarden-self-host-attachments-55c87f9748-dhxkc 1/1 Running 0 8m48s
bitwarden-self-host-api-685dbdcbb5-snpzx 1/1 Running 0 8m48s
bitwarden-self-host-sso-5756c5d654-hdjjl 1/1 Running 2 (79s ago) 8m48s
bitwarden-self-host-admin-5d7f7dfb8c-2qs9z 1/1 Running 2 (37s ago) 8m48s
bitwarden-self-host-mssql-0 0/1 Running 6 (2m58s ago) 8m48s
builder@DESKTOP-QADGF36:~/Workspaces/vaultwarden$ kubectl describe pod bitwarden-self-host-mssql-0 -n bitwarden | tail -n 13
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 8m49s default-scheduler 0/3 nodes are available: pod has unbound immediate PersistentVolumeClaims. preemption: 0/3 nodes are available: 3 Preemption is not helpful for scheduling..
Normal Scheduled 8m48s default-scheduler Successfully assigned bitwarden/bitwarden-self-host-mssql-0 to hp-hp-elitebook-850-g2
Normal Pulled 7m59s kubelet Successfully pulled image "mcr.microsoft.com/mssql/server:2022-CU11-ubuntu-22.04" in 40.138857515s (40.138882568s including waiting)
Normal Pulled 7m42s kubelet Successfully pulled image "mcr.microsoft.com/mssql/server:2022-CU11-ubuntu-22.04" in 320.383449ms (320.390237ms including waiting)
Normal Pulled 6m55s kubelet Successfully pulled image "mcr.microsoft.com/mssql/server:2022-CU11-ubuntu-22.04" in 288.149992ms (288.169048ms including waiting)
Normal Pulling 6m1s (x4 over 8m39s) kubelet Pulling image "mcr.microsoft.com/mssql/server:2022-CU11-ubuntu-22.04"
Normal Pulled 6m1s kubelet Successfully pulled image "mcr.microsoft.com/mssql/server:2022-CU11-ubuntu-22.04" in 284.072665ms (284.08735ms including waiting)
Normal Created 6m1s (x4 over 7m58s) kubelet Created container bitwarden-self-host-mssql
Normal Started 6m1s (x4 over 7m58s) kubelet Started container bitwarden-self-host-mssql
Warning BackOff 3m39s (x20 over 7m19s) kubelet Back-off restarting failed container bitwarden-self-host-mssql in pod bitwarden-self-host-mssql-0_bitwarden(2989c2ed-f395-4dac-a49f-692f1f24dbc0)
Looks like its the DB password at fault
2024-05-12 19:47:34.81 Server External governance manager initialized
2024-05-12 19:47:34.89 spid49s ERROR: Unable to set system administrator password: Password validation failed. The password does not meet SQL Server password policy requirements because it is too short. The password must be at least 8 characters..
2024-05-12 19:47:34.89 spid49s An error occurred during server setup. See previous errors for more information.
2024-05-12 19:47:34.90 spid49s SQL Trace was stopped due to server shutdown. Trace ID = '1'. This is an informational message only; no user action is required.
Which I didn’t set (left the default)
--from-literal=SA_PASSWORD="REPLACE"
Installing after fixing the SA password:
$ helm upgrade bitwarden bitwarden/self-host --install --namespace bitwarden --values my-bw-values.yaml
Release "bitwarden" does not exist. Installing it now.
NAME: bitwarden
LAST DEPLOYED: Sun May 12 15:26:50 2024
NAMESPACE: bitwarden
STATUS: deployed
REVISION: 1
TEST SUITE: None
Which showed the pods are now running
$ kubectl get pods -n bitwarden
NAME READY STATUS RESTARTS AGE
bitwarden-self-host-identity-7dcd9f5dc5-bt8qt 1/1 Running 0 3m43s
bitwarden-self-host-web-76d589c6b4-dgxkc 1/1 Running 0 3m43s
bitwarden-self-host-attachments-55c87f9748-rq26t 1/1 Running 0 3m43s
bitwarden-self-host-icons-5d568bd579-lw4mm 1/1 Running 0 3m42s
bitwarden-self-host-notifications-54466bbfff-fjddn 1/1 Running 0 3m43s
bitwarden-self-host-sso-5756c5d654-btsxz 1/1 Running 0 3m43s
bitwarden-self-host-api-685dbdcbb5-qj56p 1/1 Running 0 3m43s
bitwarden-self-host-events-575499c877-8lxq5 1/1 Running 0 3m43s
bitwarden-self-host-admin-5d7f7dfb8c-x87pk 1/1 Running 0 3m43s
bitwarden-self-host-mssql-0 1/1 Running 0 3m43s
$ kubectl get ingress -n bitwarden
NAME CLASS HOSTS ADDRESS PORTS AGE
bitwarden-self-host-ingress nginx bitwarden.tpk.pw 80, 443 4m16s
I’m starting to get stumped.
The deployment is fine, the pods are fine, yet the service won’t route
builder@DESKTOP-QADGF36:~/Workspaces/vaultwarden$ helm upgrade bitwarden bitwarden/self-host --install --namespace bitwarden --values my-bw-values.yaml
Release "bitwarden" does not exist. Installing it now.
NAME: bitwarden
LAST DEPLOYED: Sun May 12 15:44:36 2024
NAMESPACE: bitwarden
STATUS: deployed
REVISION: 1
TEST SUITE: None
builder@DESKTOP-QADGF36:~/Workspaces/vaultwarden$ kubectl get pods -n bitwarden
NAME READY STATUS RESTARTS AGE
bitwarden-self-host-web-76d589c6b4-4nbp5 1/1 Running 0 13h
bitwarden-self-host-events-575499c877-nzj6v 1/1 Running 0 13h
bitwarden-self-host-icons-5d568bd579-7tzwj 1/1 Running 0 13h
bitwarden-self-host-notifications-54466bbfff-5pbpj 1/1 Running 0 13h
bitwarden-self-host-attachments-55c87f9748-m6m45 1/1 Running 0 13h
bitwarden-self-host-admin-5d7f7dfb8c-dp8j4 1/1 Running 0 13h
bitwarden-self-host-identity-7dcd9f5dc5-xmhbj 1/1 Running 0 13h
bitwarden-self-host-sso-5756c5d654-97qpx 1/1 Running 0 13h
bitwarden-self-host-api-685dbdcbb5-5l9ss 1/1 Running 0 13h
bitwarden-self-host-mssql-0 1/1 Running 0 13h
I can port-forward to the service without issue:
$ kubectl port-forward svc/bitwarden-self-host-web -n bitwarden 5000:5000
Forwarding from 127.0.0.1:5000 -> 5000
Forwarding from [::1]:5000 -> 5000
Handling connection for 5000
Handling connection for 5000
Handling connection for 5000
Handling connection for 5000
I’m going to try and build out a new Ingress myself to see if I can debug this.
To do that, I’ll get another URL, this time using AWS Route53
$ aws route53 change-resource-record-sets --hosted-zone-id Z39E8QFU0F9PZP --change-batch file://r53-bitwarden.json
{
"ChangeInfo": {
"Id": "/change/C08820402CFVLOYKVGC1N",
"Status": "PENDING",
"SubmittedAt": "2024-05-13T10:44:38.605Z",
"Comment": "CREATE bitwarden fb.s A record "
}
}
I replicated the blocks into the framework for a working Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
ingress.kubernetes.io/ssl-redirect: "true"
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
name: bitwarden
spec:
rules:
- host: bitwarden.freshbrewed.science
http:
paths:
- backend:
service:
name: bitwarden-self-host-web
port:
number: 5000
path: /(.*)
pathType: ImplementationSpecific
- backend:
service:
name: bitwarden-self-host-attachments
port:
number: 5000
path: /attachments/(.*)
pathType: ImplementationSpecific
- backend:
service:
name: bitwarden-self-host-api
port:
number: 5000
path: /api/(.*)
pathType: ImplementationSpecific
- backend:
service:
name: bitwarden-self-host-icons
port:
number: 5000
path: /icons/(.*)
pathType: ImplementationSpecific
- backend:
service:
name: bitwarden-self-host-notifications
port:
number: 5000
path: /notifications/(.*)
pathType: ImplementationSpecific
- backend:
service:
name: bitwarden-self-host-events
port:
number: 5000
path: /events/(.*)
pathType: ImplementationSpecific
- backend:
service:
name: bitwarden-self-host-sso
port:
number: 5000
path: /(sso/.*)
pathType: ImplementationSpecific
- backend:
service:
name: bitwarden-self-host-identity
port:
number: 5000
path: /(identity/.*)
pathType: ImplementationSpecific
- backend:
service:
name: bitwarden-self-host-admin
port:
number: 5000
path: /(admin/?.*)
pathType: ImplementationSpecific
tls:
- hosts:
- bitwarden.freshbrewed.science
secretName: bitwarden-fbs-tls
Then applied
$ kubectl apply -f ./bitwarden.ingress.fbs.yaml -n bitwarden
ingress.networking.k8s.io/bitwarden created
Once the cert is satisified
$ kubectl get cert -n bitwarden
NAME READY SECRET AGE
bitwarden-tls True bitwarden-tls 14h
bitwarden-fbs-tls True bitwarden-fbs-tls 2m8s
I can give it a try.
still no go.
I think there is an app misconfiguration. I can see the app loads /app/index.html
But my Nginx logs display
2024/05/13 10:55:09 [error] 2722#2722: *11321608 open() "/etc/nginx/html/favicon.ico" failed (2: No such file or directory), client: 180.149.25.35, server: bitwarden.freshbrewed.science, request: "GET /favicon.ico HTTP/1.1", host: "bitwarden.freshbrewed.science", referrer: "https://bitwarden.freshbrewed.science/"
180.149.25.35 - - [13/May/2024:10:55:09 +0000] "GET /favicon.ico HTTP/1.1" 404 153 "https://bitwarden.freshbrewed.science/" "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/99.0.4844.47 Mobile/15E148 Safari/604.1" "-"
If I reduce my ingress to just
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
ingress.kubernetes.io/ssl-redirect: "true"
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
name: bitwarden
spec:
rules:
- host: bitwarden.freshbrewed.science
http:
paths:
- backend:
service:
name: bitwarden-self-host-web
port:
number: 5000
path: /
pathType: Prefix
tls:
- hosts:
- bitwarden.freshbrewed.science
secretName: bitwarden-fbs-tls
(which cuts out a lot of endpoints, but does expose the front door)
That works
I pivoted from the regexp and ImplementationSpecific routes to Prefix types.
Seems to start up
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
ingress.kubernetes.io/ssl-redirect: "true"
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
name: bitwarden
spec:
rules:
- host: bitwarden.freshbrewed.science
http:
paths:
- backend:
service:
name: bitwarden-self-host-web
port:
number: 5000
path: /
pathType: Prefix
- backend:
service:
name: bitwarden-self-host-attachments
port:
number: 5000
path: /attachments/
pathType: Prefix
- backend:
service:
name: bitwarden-self-host-api
port:
number: 5000
path: /api/
pathType: ImplementationSpecific
- backend:
service:
name: bitwarden-self-host-icons
port:
number: 5000
path: /icons/
pathType: Prefix
- backend:
service:
name: bitwarden-self-host-notifications
port:
number: 5000
path: /notifications/
pathType: Prefix
- backend:
service:
name: bitwarden-self-host-events
port:
number: 5000
path: /events/
pathType: Prefix
- backend:
service:
name: bitwarden-self-host-sso
port:
number: 5000
path: /sso/
pathType: Prefix
- backend:
service:
name: bitwarden-self-host-identity
port:
number: 5000
path: /identity/
pathType: Prefix
- backend:
service:
name: bitwarden-self-host-admin
port:
number: 5000
path: /admin/
pathType: Prefix
tls:
- hosts:
- bitwarden.freshbrewed.science
secretName: bitwarden-fbs-tls
I saw an error on signup
But it did create the account
However, ‘Send email’ seems to have an issue
I realized I used the wrong SMTP url
smtpHost: "smtp.sendgrid.com"
should be
smtpHost: "smtp.sendgrid.net"
I tried a few tricks, including coming up with a set of commands to rotate all but the database pod
kubectl delete pods -n bitwarden -l app.kubernetes.io/instance=bitwarden,app.kubernetes.io/component=api
kubectl delete pods -n bitwarden -l app.kubernetes.io/instance=bitwarden,app.kubernetes.io/component=events
kubectl delete pods -n bitwarden -l app.kubernetes.io/instance=bitwarden,app.kubernetes.io/component=notifications
kubectl delete pods -n bitwarden -l app.kubernetes.io/instance=bitwarden,app.kubernetes.io/component=web
kubectl delete pods -n bitwarden -l app.kubernetes.io/instance=bitwarden,app.kubernetes.io/component=admin
kubectl delete pods -n bitwarden -l app.kubernetes.io/instance=bitwarden,app.kubernetes.io/component=icons
kubectl delete pods -n bitwarden -l app.kubernetes.io/instance=bitwarden,app.kubernetes.io/component=identity
kubectl delete pods -n bitwarden -l app.kubernetes.io/instance=bitwarden,app.kubernetes.io/component=sso
kubectl delete pods -n bitwarden -l app.kubernetes.io/instance=bitwarden,app.kubernetes.io/component=attachments
But it didn’t seem to take.
I decided to uninstall and reinstall
builder@DESKTOP-QADGF36:~/Workspaces/vaultwarden$ helm delete bitwarden -n bitwarden
release "bitwarden" uninstalled
builder@DESKTOP-QADGF36:~/Workspaces/vaultwarden$ kubectl get pvcs -n bitwarden
error: the server doesn't have a resource type "pvcs"
builder@DESKTOP-QADGF36:~/Workspaces/vaultwarden$ helm upgrade bitwarden bitwarden/self-host --install --namespace bitwarden --values my-bw-values.yaml
Release "bitwarden" does not exist. Installing it now.
NAME: bitwarden
LAST DEPLOYED: Mon May 13 06:29:58 2024
NAMESPACE: bitwarden
STATUS: deployed
REVISION: 1
TEST SUITE: None
The re-install seemed to work
I can also see a positive confirmation on my Twilio/Sendgrid test page
I used, for reference
admins: "isaac@freshbrewed.science"
email:
# Email address used for invitations, typically no-reply@smtp-host
replyToEmail: "isaac@freshbrewed.science"
# Your SMTP server hostname (recommended) or IP address
smtpHost: "smtp.sendgrid.net"
# The SMTP port used by the SMTP server
smtpPort: "587"
# Whether your SMTP server uses an encryption protocol, "true" for SSL, "false" for TLS
smtpSsl: "false"
# Custom labels to add throughout the installation
Where the email matches my Sendgrid validated user
I also got a validation email to use
Even though I verified it, I still see the decoration on the right. Perhaps there is just a delay?
I tried to create a folder, didn’t work. I tried to create an item - also didn’t work
When we add that to the “Premium” feature of copying a totp token to the clipboard, I’m starting to reconsider keeping this app
SaaS
Okay, I’m not going to waste more time self-hosting.
Let’s try the SaaS offering by signing up at https://vault.bitwarden.com/#/register?layout=default
The sign-up is similar to the one I saw in self-hosted, albeit there is a captcha check
Once created, I am greeted with a similar dashboard. However here, it would appear, I can also import data and add a browser extension.
I verified my email and it seems that took
I could create a secret just fine
Import from VaultWarden
I wanted to see if I could transfer the data out of VaultWarden to a SaaS Bitwarden.
To me, that might be the larger value of a SaaS Bitwarden - getting support and moving to a managed instance for HA.
I exported as JSON from VaultWarden (bottom) and imported as JSON Bitwarden data to the SaaS instance (above)
There was no issue in importing the two test fields I had in VaultWarden up to now
I checked one password just to be certain
Export
Can we go the other way?
Let’s create a new key we can be certain came from SaaS then export, and import to our on-prem instance
Premium
I take back what I said about Premium.
All they want is $10/year for up to 6 users and family sharing. That barely covers hosting - I think that is more than a reasonable ask.
App
It’s fine for a password manager to work on the web, but I need to see it work on my phone as well.
I installed from Google Play here and it worked.
The app blocks screenshots by default, but you can disable that in the “other” settings
Now I can show you that I have all the same accounts listed
Browser Extension
They also have a Chrome Browser Extension
I’ll try my self-hosted VaultWarden to start
In configuring my browser extension, I need to give details about my ‘self-hosted’ option
I can then use those for the login
To test, I’ll log out of the SaaS option and when I go to login again, I have a “new item” drop down that let’s me add credentials
I’ll now try using those to login from the web to the SaaS instance
Which completely worked
Summary
We took a bit longer than I would have liked to try and get the helm install to work. I could have moved to the Docker compose instance as detailed here, but I already had Vaultwarden up and didn’t need to add another instance.
We then tested the SaaS offering and looked at export and import to Vaultwarden. Knowing that our secrets are portable is a big win for Bitwarden. When looking at the pricing of the commercial offering, I was really impressed by the low costs and I might actually buy this as a new secret store for the family accounts.
Lastly, we looked briefly at the Android App app (there is an iOS app too) and Chrome Browser exentsion. I need to sit with the chrome extension a bit. I might try the Firefox one next.