Skip to main content

Simple, secure, and git-safe secrets management..

Project description


ZeroEnv

Simple, secure, and git-safe secrets management.

PyPI version

FeaturesInstallationUsageHow It WorksTeam WorkflowDockerTestingSecurityCommand Reference

demo

Features

  • AES-256-GCM encryption with unique nonces
  • Git-safe encrypted storage (commit .secrets, not keys)
  • Zero-config initialization
  • No code changes required (injects env vars)
  • No infrastructure dependencies
  • Cross-platform (Windows, macOS, Linux)
  • Export to .env format

Installation

pip install zeroenv

From source:

git clone https://github.com/ropeadope62/zeroenv
cd zeroenv
pip install -e .

Usage

Initialize

zeroenv init

Creates .secrets (encrypted) and .secrets.key (master key). Automatically updates .gitignore.

Add Secrets

zeroenv add DATABASE_URL "postgresql://localhost/mydb"
zeroenv add API_KEY "sk_test_1234567890"

Run Commands

zeroenv run python app.py
zeroenv run npm start
zeroenv run dotnet run

Secrets are injected as environment variables. Your code remains unchanged:

import os
api_key = os.getenv('API_KEY')

List Secrets

zeroenv ls              # Names only
zeroenv ls --values     # Show values

Get Secret

zeroenv get API_KEY

Export

zeroenv export          # .env format
zeroenv export > .env   # Save to file
zeroenv export -f json  # JSON format

Remove Secret

zeroenv rm SECRET_NAME

How It Works

Two-File System

.secrets - Encrypted secrets (safe to commit)

{
  "secrets": {
    "API_KEY": {
      "ciphertext": "aB3dE5fG7hI9jK1...",
      "nonce": "xY9zA1bC2dE3fG4h"
    }
  }
}

.secrets.key - Master key (never commit, auto-gitignored)

aB3dE5fG7hI9jK1lM2nO4pQ6rS8tU0vW1xY2zA3bC4dE5f=

Encryption

  • Algorithm: AES-256-GCM
  • Key size: 256 bits
  • Nonce size: 96 bits (unique per secret)
  • Authenticated encryption (tamper-proof)

Team Usage

While ZeroEnv was designed with individual developers in mind, usage in small teams can be achieved by sharing the master key.

Setup

# Developer 1
zeroenv init
zeroenv add API_KEY "shared-key"
git add .secrets .gitignore
git commit -m "Add encrypted secrets"
git push

Join Team

# Developer 2
git clone repo
cd repo
echo "MASTER_KEY" > .secrets.key  # Received via secure channel
zeroenv ls  # Verify

Encrypted .secrets syncs via git. Master key shared once through secure channel (password manager, encrypted messaging).

CI/CD

Set ZEROENV_MASTER_KEY environment variable:

GitHub Actions

- run: zeroenv run pytest
  env:
    ZEROENV_MASTER_KEY: ${{ secrets.ZEROENV_MASTER_KEY }}

GitLab CI

test:
  script:
    - zeroenv run pytest

Azure Pipelines

- script: zeroenv run pytest
  env:
    ZEROENV_MASTER_KEY: $(ZEROENV_MASTER_KEY)

Containerization / Docker

ZeroEnv works seamlessly with Docker. You can inject secrets into your container at runtime without baking them into the image.

Dockerfile

Install zeroenv in your image:

FROM python:3.9-slim

WORKDIR /app
COPY . .
RUN pip install zeroenv
RUN pip install -r requirements.txt

# Don't set entrypoint here if you want to use zeroenv at runtime
CMD ["python", "app.py"]

Docker Compose

Mount the .secrets file and the master key (via environment variable):

version: '3'
services:
  web:
    build: .
    volumes:
      - ./.secrets:/app/.secrets:ro  # Mount secrets file read-only
    environment:
      - ZEROENV_MASTER_KEY=${ZEROENV_MASTER_KEY}  # Pass key from host
    command: zeroenv run python app.py

Running with Docker

  1. Export the master key on your host:

    export ZEROENV_MASTER_KEY=$(cat .secrets.key)
    
  2. Run the container:

    docker-compose up
    

## Examples

### Django
```bash
zeroenv init
zeroenv add SECRET_KEY "django-key"
zeroenv add DATABASE_URL "postgresql://..."
zeroenv run python manage.py runserver

Node.js

zeroenv init
zeroenv add PORT "3000"
zeroenv add MONGODB_URI "mongodb://..."
zeroenv run npm start

.NET

zeroenv init
zeroenv add ConnectionStrings__Default "Server=..."
zeroenv run dotnet run

Security

Encryption Details

  • Algorithm: AES-256-GCM (AEAD)
  • Key derivation: 256-bit random key via os.urandom()
  • Nonce generation: 96-bit random nonce per encryption
  • Library: Python cryptography package

Command Reference

Command Description
init Initialize ZeroEnv in project
add NAME [VALUE] Add or update secret
get NAME Retrieve secret value
ls [--values] List secrets
rm NAME Remove secret
run COMMAND Run command with secrets
export [-f FORMAT] Export secrets

Dependencies

  • Python 3.8+
  • click - CLI framework
  • rich - Terminal formatting
  • cryptography - AES-256-GCM implementation

Testing

This directory contains comprehensive unit tests to ensure reliability and security.

Why Testing is Critical

I have added some unit tests to validate the core functionality of ZeroEnv, including the cryptography and storage, Data Integrity, CLI Reliability, Edge Case Handling, Regression Prevention, and Cross-Platform Compatibility.

Prerequisites

The tests require pytest and click. You can install the development dependencies with:

pip install pytest click cryptography rich

Running Tests

To run all tests, execute the following command from the project root:

python -m pytest tests

To run tests with verbose output:

python -m pytest tests -v

To run with coverage report:

python -m pytest tests --cov=zeroenv --cov-report=html

Test Structure

test_crypto.py - Cryptographic Operations

Tests the core security layer:

  • Key Generation: Validates 256-bit keys are properly generated
  • Encryption: Ensures plaintext is encrypted correctly with unique nonces
  • Decryption: Verifies encrypted data can be decrypted back to original
  • Key Encoding: Tests base64 encoding/decoding of keys
  • Invalid Inputs: Tests behavior with malformed data or wrong keys
  • Nonce Uniqueness: Ensures each encryption uses a unique nonce

Critical Tests:

  • Different values produce different ciphertexts
  • Same value encrypted twice produces different ciphertexts (due to unique nonces)
  • Decryption with wrong key fails properly
  • Tampered ciphertext is detected

test_storage.py - File Operations & Data Management

Tests the persistence layer:

  • Initialization: Creates .secrets and .secrets.key files correctly
  • File Integrity: Validates JSON structure and metadata
  • Secret CRUD: Add, retrieve, update, delete secrets
  • Key Loading: Properly loads master key from file
  • Error Handling: Missing files, corrupted data, permission errors
  • Metadata: Timestamps and versioning work correctly

Critical Tests:

  • Secrets persist across program restarts
  • Multiple secrets don't interfere with each other
  • File permissions are appropriate
  • Corrupted .secrets file is handled gracefully

test_cli.py - Command Line Interface

Tests the user-facing commands:

  • Init Command: Creates files and updates .gitignore
  • Add Command: Interactive and direct modes work
  • Get Command: Retrieves secrets correctly
  • List Command: Shows secrets with/without values
  • Remove Command: Deletes secrets with confirmation
  • Run Command: Injects environment variables properly
  • Export Command: Outputs in .env and JSON formats
  • Error Messages: Helpful errors for common mistakes

Critical Tests:

  • zeroenv init in already-initialized directory fails gracefully
  • zeroenv add without init shows helpful error
  • Environment variables are properly injected for run
  • Confirmation prompts work for destructive operations
  • Exit codes are correct (0 for success, 1 for errors)

Troubleshooting

If you encounter issues with test_cli.py failing to capture output, ensure you are running the tests from the project root directory.

Common Issues:

  • Import errors: Run pip install -e . from project root
  • File permission errors: Tests create temporary directories - ensure write permissions
  • Flaky tests: Some CLI tests may be environment-dependent - use pytest-xdist for isolation

Development

git clone https://github.com/ropeadope62/zeroenv
cd zeroenv
pip install -e ".[dev]"
pytest

License

MIT

Credits

Built by Dave C. (ropeadope62) artoffailing.com


GitHub @ropeadope62

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

zeroenv-0.1.0.tar.gz (18.9 kB view details)

Uploaded Source

Built Distribution

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

zeroenv-0.1.0-py3-none-any.whl (13.8 kB view details)

Uploaded Python 3

File details

Details for the file zeroenv-0.1.0.tar.gz.

File metadata

  • Download URL: zeroenv-0.1.0.tar.gz
  • Upload date:
  • Size: 18.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.2

File hashes

Hashes for zeroenv-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f5a309e08114ce5bb37a86b9d86fc25e55d2cee68f4e91d57894d1a4c11209d4
MD5 5ee4771d78b507cb909cca62fcb3dae5
BLAKE2b-256 f7ebf8bf09353bd110edbb8a9dbe9dd23bb3913da0ce3cc0803ae0a1f6d87771

See more details on using hashes here.

File details

Details for the file zeroenv-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: zeroenv-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 13.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.2

File hashes

Hashes for zeroenv-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 49e4b285d46eea9edc0f8a644eb204c171ebe16a24091549a1b7604e1bcceaba
MD5 2db6aa06862619cf124d3528898eb53e
BLAKE2b-256 4bb407e5b77da35edf2d259095ddd8b2cbc348668c33995fcf4eb93f9e1bd878

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