Skip to main content

Kubernetes integration for Helvetisafe secret management — sidecar agent, Secret sync, and init-container injection

Project description

helvetisafe-vault-k8s

Python package for consuming Helvetisafe secrets in any environment — locally, in CI, or inside a Kubernetes workload. Built on the Helvetisafe Python client and its zero-knowledge encryption model.

Three CLI modes are available:

Mode Command Description
Serve helvetisafe-vault-k8s serve HTTP agent that exposes decrypted secrets on 127.0.0.1
Inject helvetisafe-vault-k8s inject Write secrets to a single env file (--output) or one file per secret (--output-dir)
Sync helvetisafe-vault-k8s sync Sync secrets into a Kubernetes Secret object

Kubernetes deployment manifests and examples are maintained separately in the aegis repository under clients/kubernetes/.

Status

✅ v0.1.0 — available


Installation

pip install helvetisafe-vault-k8s

The sync mode requires the kubernetes extra:

pip install "helvetisafe-vault-k8s[kubernetes]"

Requirements: Python 3.8+ · helvetisafe-client >= 0.1.0 (auto-installed) · kubernetes >= 28.0.0 (optional, sync only)


Configuration

All settings are read from environment variables.

Variable Required Default Description
HELVETISAFE_BASE_URL Base URL of the Helvetisafe instance, e.g. https://vault.helvetisafe.ch
HELVETISAFE_CLIENT_ID OAuth 2.0 client ID
HELVETISAFE_CLIENT_SECRET OAuth 2.0 client secret
HELVETISAFE_PASSWORD one of three Service account password
HELVETISAFE_PRIVATE_KEY_PATH one of three Path to a PEM private key file
HELVETISAFE_PRIVATE_KEY_PEM one of three PEM private key as a string
HELVETISAFE_AGENT_PORT 8080 Port the serve agent listens on
HELVETISAFE_AGENT_HOST 127.0.0.1 Host the serve agent binds to
HELVETISAFE_K8S_NAMESPACE default Kubernetes namespace (sync mode)
HELVETISAFE_K8S_SECRET_NAME Kubernetes Secret name (sync mode)
HELVETISAFE_SECRET_KEYS Comma-separated keys to fetch; empty means all

Exactly one of HELVETISAFE_PASSWORD, HELVETISAFE_PRIVATE_KEY_PATH, or HELVETISAFE_PRIVATE_KEY_PEM must be set.


Modes

Serve

Starts a lightweight HTTP server bound to 127.0.0.1 (loopback only). Any process on the same host can fetch decrypted secrets without implementing any cryptographic logic.

helvetisafe-vault-k8s serve [--port PORT] [--host HOST]
Method Path Description
GET /health Returns {"status": "ok"}
GET /secrets Lists all secret key names
GET /secret/{key} Returns the decrypted key/value pairs as a flat JSON object

The response for GET /secret/{key} is always a flat JSON object. When the secret stores multiple key/value pairs (e.g. all database credentials under one secret path), every pair is returned at the top level. For a single plain-string secret the response is {"<key>": "<value>"}. The Helvetisafe secret path is never included in the response body.

import requests

# Single-value secret → {"database_password": "s3cr3t"}
secret = requests.get("http://localhost:8080/secret/database_password").json()
value = secret["database_password"]

# Multi-value secret → {"DB_HOST": "localhost", "DB_PASS": "s3cr3t"}
db = requests.get("http://localhost:8080/secret/db_credentials").json()
host = db["DB_HOST"]

Inject

Fetches secrets once and materialises them for consumption by the main application. Designed for the init-container pattern: the init-container runs this command to populate a shared emptyDir volume before the main application starts.

Exactly one output mode must be specified.

Option A — single env file (--output)

Writes all secrets to a single file, one KEY=value pair per line.

helvetisafe-vault-k8s inject --output /path/to/secrets.env

Output format (no quoting):

KEY_NAME=plaintext-value
ANOTHER_KEY=another-value

Literal newline characters inside values are replaced with the two-character sequence \n to keep each entry on a single line. No other escaping is applied.

Option B — one file per secret (--output-dir)

Writes one file per secret into a directory. The file name is the secret key and the file content is the raw plaintext value (no escaping). The directory is created if it does not exist.

helvetisafe-vault-k8s inject --output-dir /secrets/

Resulting layout:

/secrets/
├── KEY_NAME        # contains: plaintext-value
└── ANOTHER_KEY     # contains: another-value

This format is convenient for workloads that read individual secret files from a mounted volume (e.g. via envFrom with a secretKeyRef, or by reading /secrets/<KEY> directly).

Note: Unlike sync, inject never creates or updates a Kubernetes Secret, even if HELVETISAFE_K8S_SECRET_NAME is set.

Sync

Fetches secrets and creates or updates a Kubernetes Secret object.

helvetisafe-vault-k8s sync [--output /path/to/secrets.env]

Requires the kubernetes extra and a service account with get, create, and update permissions on secrets in the target namespace.


Architecture

Client process
├── Your application
│       └─► GET http://127.0.0.1:8080/secret/db_password   (serve mode)
│
└── helvetisafe-vault-k8s
        ├─► POST https://vault.helvetisafe.ch/oauth/token
        │       ← access_token
        ├─► GET  /api/v1/credentials/org-key
        │       ← encrypted Org Key (RSA-OAEP)
        │   RSA decrypt → Org Key  (in memory only)
        └─► GET  /api/v1/secrets/db_password
                ← AES-256-GCM ciphertext
            AES decrypt → plaintext

Plaintext values never leave the process memory. The Helvetisafe server only ever stores and transmits ciphertext.


Project Structure

helvetisafe-vault-k8s/
├── pyproject.toml
├── src/
│   └── helvetisafe_k8s/
│       ├── agent.py     # Serve mode HTTP server
│       ├── cli.py       # CLI entry point
│       ├── config.py    # Environment-variable config loader
│       └── sync.py      # Inject / sync utilities
└── tests/
    ├── test_agent.py
    ├── test_config.py
    └── test_sync.py

Running Tests

pip install -e ".[dev]"
pytest tests/ -v

Contributing

Contributions are welcome. Please open an issue or pull request in this repository.

License

MIT

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

helvetisafe_vault_k8s-0.1.4.tar.gz (21.6 kB view details)

Uploaded Source

Built Distribution

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

helvetisafe_vault_k8s-0.1.4-py3-none-any.whl (16.6 kB view details)

Uploaded Python 3

File details

Details for the file helvetisafe_vault_k8s-0.1.4.tar.gz.

File metadata

  • Download URL: helvetisafe_vault_k8s-0.1.4.tar.gz
  • Upload date:
  • Size: 21.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for helvetisafe_vault_k8s-0.1.4.tar.gz
Algorithm Hash digest
SHA256 957ef11226946aaab1866224c192ee6e759d4395e6a3ae7a739af0c039635780
MD5 775273a195e141459a868bc7fd26993f
BLAKE2b-256 6a1e17221905edddcfd55f4af747deed35fe12941664d0d31e87f87c6d3b3a47

See more details on using hashes here.

Provenance

The following attestation bundles were made for helvetisafe_vault_k8s-0.1.4.tar.gz:

Publisher: publish-helvetisafe-vault-k8s.yml on TheM0f/helvetisafe-vault-k8s

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file helvetisafe_vault_k8s-0.1.4-py3-none-any.whl.

File metadata

File hashes

Hashes for helvetisafe_vault_k8s-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 411aabb933a62e054b4ae8593ebf62472e025dbeceb6ca88e5107fc1bbce4098
MD5 b659fabfe72db058fdd89ecf331b70a7
BLAKE2b-256 a919e1dc436006da20822e346dcf5548eb40b4531e86e3cf1b8d9c7e7cfe1ef8

See more details on using hashes here.

Provenance

The following attestation bundles were made for helvetisafe_vault_k8s-0.1.4-py3-none-any.whl:

Publisher: publish-helvetisafe-vault-k8s.yml on TheM0f/helvetisafe-vault-k8s

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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