A Kubernetes Operator to manage secrets stored in LastPass password manager
Suppose you have some credentials stored in LastPass
$ lpass show example/my-secret --json [ { "id": "8190226423897406876", "name": "my-secret", "fullname": "example/my-secret", "username": "whoami", "password": "s3cr3t", "last_modified_gmt": "1562690587", "last_touch": "0", "group": "example", "url": "https://lastpass.com", "note": "{\"myKey\":\"myValue\"}" } ]Define a LastPass or LastPassGroup Custom Resource to automatically manage the lifecycle of your secrets in Kubernetes
$ cat example/edgelevel_v1alpha1_lastpass_cr.yaml apiVersion: edgelevel.com/v1alpha1 kind: LastPass metadata: name: example-lastpass spec: secretRef: group: example name: my-secret withUsername: true withPassword: true withUrl: true withNote: true syncPolicy: enabled: true refresh: 10 # create a custom resource $ kubectl apply -f example/edgelevel_v1alpha1_lastpass_cr.yamlNOTE: The LastPassGroup custom resource will sync all the secrets in a lastpass folder to kubernetes. The lastpass group will not sync subfolders.
$ cat example/edgelevel_v1alpha1_lastpassgroup_cr.yaml apiVersion: edgelevel.com/v1alpha1 kind: LastPassGroup metadata: name: example-lastpassgruop spec: secretRef: group: example withUsername: true withPassword: true withUrl: true withNote: true syncPolicy: enabled: true refresh: 10 # create a custom resource $ kubectl apply -f example/edgelevel_v1alpha1_lastpassgroup_cr.yamlThe operator will take care of create native Kubernetes secrets and keep them up to date that if they change
# verify $ kubectl get lastpass $ kubectl get secrets # inspect $ kubectl get secret example-lastpass-8190226423897406876 -o yaml apiVersion: v1 data: NOTE: eyJteUtleSI6Im15VmFsdWUifQ== PASSWORD: czNjcjN0 URL: aHR0cHM6Ly9sYXN0cGFzcy5jb20= USERNAME: d2hvYW1p kind: Secret metadata: annotations: fullname: example/my-secret group: example id: "8190226423897406876" lastModifiedGmt: "1562690587" lastTouch: "0" name: my-secret creationTimestamp: "2019-07-09T15:00:13Z" labels: app: lastpass-operator name: example-lastpass-8190226423897406876 namespace: default ownerReferences: - apiVersion: edgelevel.com/v1alpha1 blockOwnerDeletion: true controller: true kind: LastPass name: example-lastpass uid: 0687d5a7-5f02-4ee4-a6c4-011c734f4149 resourceVersion: "113312" selfLink: /api/v1/namespaces/default/secrets/example-lastpass-8190226423897406876 uid: 382008d2-8999-444d-86c8-e4f29eecbe9f type: Opaque # check values $ echo 'czNjcjN0' | base64 --decode s3cr3t $ echo 'eyJteUtleSI6Im15VmFsdWUifQ==' | base64 --decode | jq -c {"myKey":"myValue"}Metrics are exposed by default in Prometheus format, see an example
# port forward kubectl port-forward service/lastpass-operator -n lastpass 8080:8383 # request metrics http :8080/metrics- If you want to understand how the operator works, you should have a look at the
Reconcilemethod defined in lastpass_controller and at the CustomResourceDefinition - The diagram below explains the core logic of the reconcile loop
- The recommended way to install the operator in a cluster is by applying the provided Helm chart
- TODO for a working example you should have a look at niqdev/do-k8s
- This operator has been mainly developed to simplify the secret management of low security environments, if you are a security paranoid you should audit this project and assess if it meets the security standard of your organization
- The operator, for obvious reasons, won't work if you have MFA enabled on LastPass or your credentials "Require Password Reprompt"
- Once this Argo CD feature will be implemented it should allow to bind secrets directly to an
Application
# download source mkdir -p $GOPATH/src/github.com/edgelevel && cd $_ git clone git@github.com:edgelevel/lastpass-operator.git cd lastpass-operator # install operator-sdk .travis/install_operator_sdk.sh # install dependencies go mod download -xRun locally outside the cluster on minkube
# requires virtualbox minikube start # run locally export OPERATOR_NAME=lastpass-operator export LASTPASS_USERNAME=myUsername export LASTPASS_PASSWORD=myPassword # Install CRDs into cluster make install # Start lastpass operator make run # Alternatively you can install and run with make install run Run as a Deployment inside the cluster
# apply chart helm template \ --values chart/values.yaml \ --set lastpass.username="myUsername" \ --set lastpass.password="myPassword" \ chart/ | kubectl apply -n lastpass -f -Debug issues
# verify logs kubectl logs deployment/lastpass-operator -n lastpass -fPublish a new version on DockerHub
# build and publish manually (unsafe) make docker-build IMG=edgelevel/lastpass-operator:X.Y.Z make docker-push IMG=edgelevel/lastpass-operator:X.Y.Z # build and publish using travis git tag vX.Y.Z git push origin --tagsTODO
- add extra Prometheus metrics
- publish to OperatorHub
