Skip to main content

base classes for microservice servers and matrix display pages

Project description

SecretManager

Important note!

With no gymnastics, this works with Python 3.12 and earlier. It may fail with Python 3.13 (or later) - see details for a fix here

Why a SecretManager?

I've been considering the "where does the first secret live?" question for a while now. Kubernetes is not a secrets management platform, though it provides some functionailty in that regard. The 'typical' solutions for pure Kubernetes-controlled secrets still leave that 'first secret' exposed - somewhere. This library is my latest attempt at protecting that first secret inside HashiCorp's vault.

History (well my history with this question)

  • Store all of the secrets in a JSON 'dict', and copy that into each of my images. Works, but wildly insecure - but also very handy for development without access to the Kubernetes cluster.

  • Create a library to manage (encrypt/decrypt) 'SecureDicts' -- JSON 'dict' with plaintext keys, and AES256 encrypted values. dict is now reasonably secure, but I was left with trying to provide the AES256 key to the running container. At this point I implemented code to (1) store the AES256 key as a Kubernetes secret, (2) access that secret directly from the secret (no mounting, no environment variables), and (3) decrypt the secret values. Works, more secure, and a bit easier to understand from a code development standpoint - but the AES256 key is still 'exposed'. (perhaps the basis for a future method - reading the AES256 key from the Vault?)

  • Cram the whole JSON dict into one secret, read that secret and "Bob's your uncle...". My base class for my microservices reads the secret on initialization, extracts the values it requires, and then destroys the objects that accessed the secret. Works, performant, obscured, but not really secure - though there are no traces of the secret visible in the images, or container other than the couple of values required for the particular microservice.

  • Switched values from JSON to YAML format (easier to manage the plaintext), broke the YAML into three chunks - common configuration (no really sensitive secrets - used by every microservice), app-specific configuration (no really sensitive values - only required by a couple of the microservices), and secrets (three really sensitive values - used by a couple of microservices). The two sets of configuration values were mounted into the containers as environment variables, as were the individually necessary secrets. Works, relatively easy to manage, really insecure.

Which brings us up to date...

The latest Concept

This current scheme integrates Kubernetes secrets to store the ciphertext (AES256 encrypted) version of the JSON dict. It also integrates with a self-managed (doesn't have to be) HashiCorp Vault configured for kubernetes authentication, and Transit key-based encrypt/decrypt as a service with rotable keys. All of the necessary functions are wrapped into the SecretManager package.

Beyond the library and the Vault, there are three Python components that comprise the solution:

  • encryptonator.py is run once* to read the plaintext file (text-based, but no formatting assumed), encrypt that file with the transit key, and load the ciphertext into the target Kubernetes secret. (once* at startup, and anytime the base plaintext is changed)

  • readstub.py which is a surrogate implementation for reading the ciphertext from the Kubernetes secret, and decrypting the secret resulting in a usable set of values.

  • recryptonator.py which implements the key rotation which is central to this new, more secure implementation. The recryptonator periodically reads the ciphertext from the Kubernetes secret, decrypts it, rotates the transit key, reencrypts the secrets with the new key, and stores the new ciphertext back in the Kubernetes secret. The periodicity is achieved by running a CronJob in the Kubernetes cluster - in the example - every day at 3:00AM. It can certainly be run more frequently as the whole process takes no more tham 150ms (with substantial logging).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dekeyrej_secretmanager-0.9.0.tar.gz (8.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dekeyrej_secretmanager-0.9.0-py3-none-any.whl (8.7 kB view details)

Uploaded Python 3

File details

Details for the file dekeyrej_secretmanager-0.9.0.tar.gz.

File metadata

  • Download URL: dekeyrej_secretmanager-0.9.0.tar.gz
  • Upload date:
  • Size: 8.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for dekeyrej_secretmanager-0.9.0.tar.gz
Algorithm Hash digest
SHA256 21fb4a034c539880abca0aa4ef6b17921f37fb3a8be8a0f23684ced28dde7399
MD5 456294b00bcc36d88fbc1ba3e4d336f8
BLAKE2b-256 a38521c76f6f2d3b340b3da877bee54030a7c9f9dc516413cb42ebd7d61cba40

See more details on using hashes here.

File details

Details for the file dekeyrej_secretmanager-0.9.0-py3-none-any.whl.

File metadata

File hashes

Hashes for dekeyrej_secretmanager-0.9.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4bfef63e4986769809bb588871e1d2b1f967e8bfe7206202caaa1e4dff31f1cf
MD5 8cbd561347a62a10cf004548b22d94a6
BLAKE2b-256 bff227b56e3cca7f5b3c695fd9ec198a48c5a93cce8e5541d182e431193a761d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page