A kubernetes operator that syncs and decrypts secrets from pass git repositories
Project description
pass
secrets operator
This Kubernetes operator can be used to sync and decrypt secrets from a password store (pass) Git repository. It is proposed as a proof-of-concept and shouldn't be used in any production capacity.
While this approach to secrets management on Kubernetes is more technically challenging, the advantage is that we don't have to rely on a 3rd party SaaS platform, such as Vault or Doppler, to hold our secrets (the obvious benefits these platforms do provide, however, are better user and access management). We may also use this operator in an airgapped environment with a self-hosted git repository.
How it works
From a high level, this operator runs git pull
on an interval to grab updates from a git repository populated with encrypted
secrets by pass
. It maps secrets' paths to key values through the application of a PassSecret
, a CRD,
such as the following.
apiVersion: secrets.premiscale.com/v1alpha1
kind: PassSecret
metadata:
name: mysecret
namespace: pass-operator-test
spec:
encryptedData:
mykey: premiscale/mydata
managedSecret:
name: mysecret
namespace: pass-operator-test
type: Opaque
immutable: false
The above PassSecret
manifest translates to the following Secret
.
apiVersion: v1
kind: Secret
metadata:
name: mysecret
namespace: pass-operator-test
stringData:
mykey: <decrypted contents of premiscale/mydata>
immutable: false
type: Opaque
Use
This operator requires the following items to start successfully.
- private GPG key to decrypt the secrets that have been encrypted with a public key, locally
- local pass store (on your local development machine)
- git repository populated by the local password store
- private SSH key to clone the Git repository
I will go more in-depth and explain these requirements in the following sections.
Private GPG key
The private GPG key is used by pass
to decrypt your secrets that were encrypted on your local machine.
Generating GPG keys
You can find a lot of explanation about how to generate keys with GPG online, but I'll write down my process below for generating keys to use with this operator.
-
First, generate a key.
$ gpg --generate-key gpg (GnuPG) 2.2.27; Copyright (C) 2021 Free Software Foundation, Inc. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Note: Use "gpg --full-generate-key" for a full featured key generation dialog. GnuPG needs to construct a user ID to identify your key. Real name: Emma Doyle Email address: emma@premiscale.com You selected this USER-ID: "Emma Doyle <emma@premiscale.com>" Change (N)ame, (E)mail, or (O)kay/(Q)uit? O We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy. We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy. gpg: key 4B90DE5D5BF143B8 marked as ultimately trusted gpg: revocation certificate stored as '/home/emmadoyle/.gnupg/openpgp-revocs.d/51924ADAFC92656FAFEB672D4B90DE5D5BF143B8.rev' public and secret key created and signed. pub rsa3072 2024-01-12 [SC] [expires: 2026-01-11] 51924ADAFC92656FAFEB672D4B90DE5D5BF143B8 uid Emma Doyle <emma@premiscale.com> sub rsa3072 2024-01-12 [E] [expires: 2026-01-11]
Important: be sure not to specify a password to use your keys.
You'll now see your key on your keyring.
$ gpg --list-keys 51924ADAFC92656FAFEB672D4B90DE5D5BF143B8 pub rsa3072 2024-01-12 [SC] [expires: 2026-01-11] 51924ADAFC92656FAFEB672D4B90DE5D5BF143B8 uid [ultimate] Emma Doyle <emma@premiscale.com> sub rsa3072 2024-01-12 [E] [expires: 2026-01-11]
-
Export your private key and b64 encode it (otherwise it will dump a bunch of binary data to your shell).
$ gpg --armor --export-secret-keys 51924ADAFC92656FAFEB672D4B90DE5D5BF143B8 | base64 ...
Copy this value and update your Helm values.
Password store
Install pass
and initialize a local store using the GPG keys you generated in the last step.
pass init "$GPG_KEY_ID" --path <subpath of ~/.password-store/>
Now, on your local machine,
$ ls -lash ~/.password-store/repo/
total 12K
4.0K drwx------ 2 emmadoyle emmadoyle 4.0K Jan 15 13:36 .
4.0K drwxrwxr-x 13 emmadoyle emmadoyle 4.0K Jan 15 13:36 ..
4.0K -rw------- 1 emmadoyle emmadoyle 41 Jan 15 13:36 .gpg-id
Git repository
From the pass
man page,
...
pass git git-command-args...
If the password store is a git repository, execute a git command
specified by git-command-args.
...
we may easily link our local password store to a remote Git repository. This operator uses git
alongside pass
to pull secret updates.
$ git init ~/.password-store/repo/
$ ls -lash ~/.password-store/repo/
total 16K
4.0K drwx------ 3 emmadoyle emmadoyle 4.0K Jan 15 13:38 .
4.0K drwxrwxr-x 13 emmadoyle emmadoyle 4.0K Jan 15 13:36 ..
4.0K drwxrwxr-x 7 emmadoyle emmadoyle 4.0K Jan 15 13:38 .git
4.0K -rw------- 1 emmadoyle emmadoyle 41 Jan 15 13:36 .gpg-id
Private SSH key
Now add a remote git repository and watch as pass insert
-commands create local commits automatically. Sync your local password store with the remote repo via pass git push
.
Development
Testing
Run unit tests with
poetry run pytest tests/unit
e2e tests against a live environment with
poetry run pytest tests/e2e
And coverage against the codebase with
poetry run coverage run -m pytest
poetry run coverage report -m pytest
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file pass_operator-0.3.0.tar.gz
.
File metadata
- Download URL: pass_operator-0.3.0.tar.gz
- Upload date:
- Size: 25.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.10.6
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 9025ef302f634b154bbfc9d495fd1fd8d8fd53bf256db0924a8111b621ebd0c9 |
|
MD5 | 09a933676b147b91f55f8516c3b204cc |
|
BLAKE2b-256 | 916a5ce95da774a8b5d9d214fa166b43255c0a840d7caddbf4e77ad12badb1d6 |
File details
Details for the file pass_operator-0.3.0-py3-none-any.whl
.
File metadata
- Download URL: pass_operator-0.3.0-py3-none-any.whl
- Upload date:
- Size: 38.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.10.6
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 14816c72bd4fdf72b56d6d8c97cded5713caaecb67afbb998bd81c221af260b7 |
|
MD5 | b7f7e74b50442e30e51cd97c9e97260f |
|
BLAKE2b-256 | 27961d844e04400132e6e3f3126862ecc03c9ec7be1b4c098952fad76653a4d8 |