Skip to main content

dotenvage

PyPI PyPI downloads License: MIT OR Apache-2.0

Python bindings for dotenvage — encrypt secrets in .env files using age encryption (X25519).

Installation

pip install dotenvage
# or with uv
uv add dotenvage

Quick start

import dotenvage

# Generate a new identity (key pair)
manager = dotenvage.SecretManager.generate()
print(f"Public key: {manager.public_key_string()}")

# Encrypt a secret
encrypted = manager.encrypt_value("my-secret-password")
print(f"Encrypted: {encrypted}")
# Output: ENC[AGE:b64:...]

# Decrypt it back
decrypted = manager.decrypt_value(encrypted)
print(f"Decrypted: {decrypted}")
# Output: my-secret-password

# Check if a value is encrypted
print(dotenvage.SecretManager.is_encrypted(encrypted))  # True
print(dotenvage.SecretManager.is_encrypted("plain"))  # False

Loading .env files

import dotenvage

# Load .env files (decrypts encrypted values automatically)
loader = dotenvage.EnvLoader()
loaded_files = loader.load()
print(f"Loaded: {loaded_files}")

# Or get all variables as a dict
variables = loader.get_all_variables()
print(variables)

Auto-detection

dotenvage can detect which keys should be encrypted based on naming patterns:

import dotenvage

# Keys containing PASSWORD, SECRET, KEY, TOKEN, etc. are detected
dotenvage.should_encrypt("API_KEY")  # True
dotenvage.should_encrypt("DATABASE_URL")  # False
dotenvage.should_encrypt("SECRET_TOKEN")  # True

Key discovery

The SecretManager automatically discovers keys in this order:

  1. Auto-discover AGE_KEY_NAME from .env or .env.local files
  2. DOTENVAGE_AGE_KEY environment variable (full identity string)
  3. AGE_KEY environment variable
  4. EKG_AGE_KEY environment variable
  5. OS keychain entry (service: dotenvage or DOTENVAGE_KEYCHAIN_SERVICE; account: AGE_KEY_NAME or {CARGO_PKG_NAME}/dotenvage)
  6. Key file from AGE_KEY_NAME → ~/.local/state/{namespace}/{keyname}.key
  7. Default: ~/.local/state/dotenvage/dotenvage.key

OS keychain lookup currently uses:

  • macOS: Keychain via security
  • Linux/Unix: Secret Service via secret-tool
  • Windows: lookup falls back to file/env sources (no keychain lookup yet); keygen --store os|both stores using cmdkey

AGE_KEY_NAME format is {namespace}/{keyname}, e.g., myapp/production → ~/.local/state/myapp/production.key

API reference

SecretManager

Manager for encrypting and decrypting secrets using age encryption.

class SecretManager:
    def __init__(self) -> None:
        """Create from discovered key file."""

    @staticmethod
    def generate() -> SecretManager:
        """Generate a new random identity (key pair)."""

    @staticmethod
    def from_identity_string(identity: str) -> SecretManager:
        """Create from an age identity string (AGE-SECRET-KEY-...)."""

    @staticmethod
    def is_encrypted(value: str) -> bool:
        """Check if a value is in encrypted format."""

    def public_key_string(self) -> str:
        """Get public key as age1... string."""

    def encrypt_value(self, plaintext: str) -> str:
        """Encrypt to ENC[AGE:b64:...] format."""

    def decrypt_value(self, value: str) -> str:
        """Decrypt if encrypted, otherwise return unchanged."""

EnvLoader

Loader for .env files with automatic decryption.

class EnvLoader:
    def __init__(self) -> None:
        """Create with default SecretManager."""

    @staticmethod
    def with_manager(manager: SecretManager) -> EnvLoader:
        """Create with a specific SecretManager."""

    def load(self) -> list[str]:
        """Load .env files from current directory. Returns loaded paths."""

    def load_from_dir(self, dir: str) -> list[str]:
        """Load .env files from specific directory."""

    def get_all_variable_names(self) -> list[str]:
        """Get all variable names from .env files."""

    def get_all_variable_names_from_dir(self, dir: str) -> list[str]:
        """Get all variable names from .env files in directory."""

    def get_all_variables(self) -> dict[str, str]:
        """Load and return all variables as dict (decrypted)."""

    def get_all_variables_from_dir(self, dir: str) -> dict[str, str]:
        """Load and return all variables from directory (decrypted)."""

    def resolve_env_paths(self, dir: str) -> list[str]:
        """Get ordered list of .env file paths that would be loaded."""

Functions

def should_encrypt(key: str) -> bool:
    """Check if key name should be encrypted based on patterns."""

License

Copyright © 2026 DataRoad Inc, Delaware, USA, trading as Legra.

Licensed under either the MIT license or the Apache License, Version 2.0, at your option.

Metadata

Release files for dotenvage 0.8.20

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for dotenvage 0.8.20
File Actions
dotenvage-0.8.20-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details for dotenvage-0.8.20-cp310-abi3-win_amd64.whl
dotenvage-0.8.20-cp310-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl CPython 3.10 abi3 Linux glibc 2.17+ x86-64 Details for dotenvage-0.8.20-cp310-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
dotenvage-0.8.20-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl CPython 3.10 abi3 Linux glibc 2.17+ ARM64 Details for dotenvage-0.8.20-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl
dotenvage-0.8.20-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details for dotenvage-0.8.20-cp310-abi3-macosx_11_0_arm64.whl
dotenvage-0.8.20-cp310-abi3-macosx_10_12_x86_64.whl CPython 3.10 abi3 macOS 10.12+ x86-64 Details for dotenvage-0.8.20-cp310-abi3-macosx_10_12_x86_64.whl

Total release size: 3.1 MB

Release files / dotenvage-0.8.20-cp310-abi3-win_amd64.whl

Download URL dotenvage-0.8.20-cp310-abi3-win_amd64.whl
Size 535.4 kB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
b49be75728c2736be7e09fb6bc5081ed9d0dfbd9f277973ce81e7b00cf5e4913
BLAKE2b-256 checksum
How to use checksums
9180d7d743926d23e1031b7b066db76a1d6fba2fd33668c5e0f219d1b7a98c9a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 10, 2026.

Transparency log

Release files / dotenvage-0.8.20-cp310-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl

Download URL dotenvage-0.8.20-cp310-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Size 649.1 kB
Tags CPython 3.10 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
d7ba8676ec88460f50ef94fe72e3fc296755cab263ced0bb6b201819f3e28c2a
BLAKE2b-256 checksum
How to use checksums
63edbc996d03da00eaaf8e36661c8978d3cb8c52e83f70052500c02da41fb8b5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 10, 2026.

Transparency log

Release files / dotenvage-0.8.20-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl

Download URL dotenvage-0.8.20-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl
Size 616.4 kB
Tags CPython 3.10 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
9029c15f975429a307e5064e4d0adfb9a2621dbf355ffaa2f3d00bac8fc262e9
BLAKE2b-256 checksum
How to use checksums
15e57f6637afe576ae403165ff2c02b38f3bc789a3fffdf7f4116153c37e7a9c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 10, 2026.

Transparency log

Release files / dotenvage-0.8.20-cp310-abi3-macosx_11_0_arm64.whl

Download URL dotenvage-0.8.20-cp310-abi3-macosx_11_0_arm64.whl
Size 647.1 kB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
901c748c5f740a307a8cd546a7dec5097a5ebe70799bb9c68bdeb966f91b7061
BLAKE2b-256 checksum
How to use checksums
7d6b7cd95801729d4f907a9aa282eeb5177a746f76e3d3c4a1df64380a0f09b5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 10, 2026.

Transparency log

Release files / dotenvage-0.8.20-cp310-abi3-macosx_10_12_x86_64.whl

Download URL dotenvage-0.8.20-cp310-abi3-macosx_10_12_x86_64.whl
Size 659.7 kB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
4598cfddb5901989c1b01494ca6d1578378815e05e1d06e3be4d11ee2657754d
BLAKE2b-256 checksum
How to use checksums
284b55f61b607fb58614f7eefd76fa500064174020c3e49fd280dce8d169c9c3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 10, 2026.

Transparency log

Security for dotenvage 0.8.20

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 5 files in this release have been uploaded with provenance metadata.

Select from 5 files

Attestation for dotenvage-0.8.20-cp310-abi3-win_amd64.whl

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 10, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.8.20 This release

5 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page