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.3.tar.gz (20.9 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.3-py3-none-any.whl (16.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: helvetisafe_vault_k8s-0.1.3.tar.gz
  • Upload date:
  • Size: 20.9 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.3.tar.gz
Algorithm Hash digest
SHA256 77da5e79182bfbc6041a245ee39b9c0995c57d3f847fd9623b7012999616b9a3
MD5 6891d68fd428cfd3ce21c93b56faf7ab
BLAKE2b-256 dbc6919c37bdba8e5051bd50c4671ee3cd6f35f7ca399ce3bc96d96dc8fba52b

See more details on using hashes here.

Provenance

The following attestation bundles were made for helvetisafe_vault_k8s-0.1.3.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.3-py3-none-any.whl.

File metadata

File hashes

Hashes for helvetisafe_vault_k8s-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 a2c801257d6f12aecb5d97293fd2b36b490dd1762c189b21fa154dfd46a13a12
MD5 ff6a87216ca6d6015a77b238f7dbea22
BLAKE2b-256 a6b411c95c69c4217f82126ef22c2e405b077d9487ae3abc1a3e9f7736165dea

See more details on using hashes here.

Provenance

The following attestation bundles were made for helvetisafe_vault_k8s-0.1.3-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