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.6

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.6
File Actions
dotenvage-0.8.6-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details for dotenvage-0.8.6-cp310-abi3-win_amd64.whl
dotenvage-0.8.6-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.10 abi3 Linux glibc 2.17+ x86-64 Details for dotenvage-0.8.6-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
dotenvage-0.8.6-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.10 abi3 Linux glibc 2.17+ ARM64 Details for dotenvage-0.8.6-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
dotenvage-0.8.6-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details for dotenvage-0.8.6-cp310-abi3-macosx_11_0_arm64.whl
dotenvage-0.8.6-cp310-abi3-macosx_10_12_x86_64.whl CPython 3.10 abi3 macOS 10.12+ x86-64 Details for dotenvage-0.8.6-cp310-abi3-macosx_10_12_x86_64.whl

Total release size: 3.1 MB

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

Download URL dotenvage-0.8.6-cp310-abi3-win_amd64.whl
Size 535.4 kB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
4bdc29f71a24d2df27208b1cb2c94b37fab49c917fdc04af48abb8fe164a39ca
BLAKE2b-256 checksum
How to use checksums
2d6070993b6ceca9b5271eff01517b68d8d099c17368e55c0a4b88f5194911b0
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 Oct 27, 2026.

Transparency log

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

Download URL dotenvage-0.8.6-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 649.2 kB
Tags CPython 3.10 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
b8e946cf47b27c21027f4f23ff7209db2bff97ccfcdb14b95d5879d2381f6b56
BLAKE2b-256 checksum
How to use checksums
27e78afcab702e172ad79d0085568ed535406713773d368bf60c3e40454746b9
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 Oct 27, 2026.

Transparency log

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

Download URL dotenvage-0.8.6-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 616.6 kB
Tags CPython 3.10 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
c6b70e56957af44ebc9190f1577556912cb5de9851eeff02e561416bc77c1cf4
BLAKE2b-256 checksum
How to use checksums
30b2112f3a7adb62d3d8a8b9fbc122ffec1adce9a2bf5b8329541ec03cacf2d2
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 Oct 27, 2026.

Transparency log

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

Download URL dotenvage-0.8.6-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
b2fffa60cf0527b891d602b83a3c15992f8d0e7405007f235676b76a2610489b
BLAKE2b-256 checksum
How to use checksums
90fa0afaac6b1adc30fcc9d7e56607322563cd73a2ff700d05e2645f9010b84a
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 Oct 27, 2026.

Transparency log

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

Download URL dotenvage-0.8.6-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
7bc0ec9194d8c25ae005c35e661ba2dccd8a0f2756f6a2d58e9f6425775f0136
BLAKE2b-256 checksum
How to use checksums
f4246db278e0757528ccd55b5ee6be463bda4098316089599392cab4d8417c5d
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 Oct 27, 2026.

Transparency log

Security for dotenvage 0.8.6

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.6-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 Oct 27, 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.6 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