secenv

Crates.iosecenv
lib.rssecenv
version0.1.0
created_at2025-09-01 01:24:59.390932+00
updated_at2025-09-24 15:30:51.308856+00
descriptionSecure environments.
homepagehttps://github.com/cchexcode/secenv
repositoryhttps://github.com/cchexcode/secenv
max_upload_size
id1819018
size108,241
Alex (cchexcode)

documentation

README

secenv

Secure, profile-based environment variable management with HOCON configuration, optional PGP decryption, and GCP Secret Manager integration.

Features

  • 🔐 PGP decryption (with provided private key): Decrypt values using an ASCII-armored private key you supply
  • ☁️ GCP Secret Manager: Load secrets at runtime using gcloud
  • 🗂️ Profiles: Organize variables by profile (dev, staging, prod, …)
  • 🧩 Multiple providers: literal, environment, file, gcp.plain, gcp.pgp
  • 🧪 Docs & tooling: Built-in manual and shell completion generators
  • Fast & safe: Rust-based CLI

Installation

From source

git clone https://github.com/cchexcode/secenv
cd secenv
cargo build --release

The binary will be at target/release/secenv.

Quick start

1) Create secenv.conf (HOCON)

version = "0.0.0"  # Config version must be compatible with the CLI version

profiles.default.env {
  # Optional regex patterns of variables to keep when executing a command
  # If set, the child environment is cleared first, then only matching host vars are kept.
  # If omitted, the full host environment is kept.
  # keep = ["^PATH$", "^SHELL$", "^LC_.*"]

  vars {
    APP_NAME.literal = "myapp"
    HOME_DIR.environment = "HOME"
    CONFIG_JSON.file = "/etc/myapp/config.json"

    # Retrieve a secret value directly from GCP Secret Manager (plain text)
    DB_PASSWORD.gcp.plain.secret = "projects/123456789/secrets/db-password"

    # Decrypt a PGP-encrypted value using a private key stored in GCP Secret Manager
    # - secret: GCP secret holding the ASCII-armored private key
    # - value.literal: ASCII-armored PGP message (or use value.base64)
    SERVICE_TOKEN.gcp.pgp {
      secret = "projects/123456789/secrets/pgp-private-key"
      value.literal = """
      -----BEGIN PGP MESSAGE-----
      ...
      -----END PGP MESSAGE-----
      """
    }
  }
}

profiles.production.env.vars {
  APP_NAME.literal = "myapp"
  DB_PASSWORD.gcp.plain.secret = "projects/123456789/secrets/prod-db-password"
}

Notes:

  • The version field is validated against the CLI version. The config must not be newer than the CLI, and major versions must match.
  • For gcp.pgp, the private key must be a valid ASCII‑armored OpenPGP private key stored in GCP Secret Manager.

2) Unlock variables

# Print key=value pairs for the default profile
secenv unlock

# Use a specific profile and config path
secenv unlock --config /path/to/secenv.conf --profile production

# Load into current shell (bash/zsh/fish)
eval "$(secenv unlock --profile production)"

To run a command with the variables set:

# Run a program inheriting host environment (default behavior)
secenv unlock --profile production -- env | sort

# With keep configured in the profile, only matching host vars are preserved
secenv unlock --profile production -- printenv | sort

# Execute a command
secenv unlock --profile production -- make deploy

Output format when printing:

APP_NAME=myapp
DB_PASSWORD=...
HOME_DIR=/Users/you

Configuration reference (HOCON)

Top-level

version = "<semver>"
profiles = { <name> = { env = { keep = [<regex>], vars = { ... } } } }

Profiles and environment

profiles.<profile>.env.keep = ["^PATH$", "^LC_.*"]  # optional
profiles.<profile>.env.vars {                          # required
  KEY.literal = "value"
  KEY.environment = "ENV_NAME"
  KEY.file = "/path/to/file"

  # From GCP Secret Manager (plain)
  KEY.gcp.plain.secret = "projects/<project>/secrets/<name>"

  # Decrypt PGP with a private key retrieved from GCP Secret Manager
  KEY.gcp.pgp.secret = "projects/<project>/secrets/<private-key>"
  KEY.gcp.pgp.value.literal = "-----BEGIN PGP MESSAGE-----..."
  # or
  KEY.gcp.pgp.value.base64 = "<base64-encoded-ASCII-armored-message>"
}

Providers

  • literal: Hard-coded string
  • environment: Reads an existing host environment variable
  • file: Reads file contents as string
  • gcp.plain: Reads a secret value directly from GCP Secret Manager
  • gcp.pgp: Fetches a private key from GCP Secret Manager and decrypts a PGP message you provide

Important:

  • Decryption by fingerprint/key ID is not supported. You must provide a private key for decryption (e.g., via gcp.pgp).

CLI reference

Global options:

  • -e, --experimental – enable experimental features

Commands:

unlock

Unlock values and optionally execute a command with the variables set.

secenv unlock [OPTIONS] [--] [COMMAND...]

Options:
  -c, --config <path>     Path to config (default: secenv.conf)
  -p, --profile <name>    Profile name (default: default)

Behavior:

  • Without COMMAND, prints KEY=VALUE lines to stdout.
  • With COMMAND, executes it with variables set. If env.keep is set in the profile, the child environment is cleared first and only host variables matching any regex in keep are preserved; otherwise, the full host environment is kept.

man

Render the manual pages or markdown help.

secenv man --out <directory> --format <manpages|markdown>

autocomplete

Generate shell completion scripts.

secenv autocomplete --out <directory> --shell <bash|zsh|fish|elvish|powershell>

init

Initialize a new HOCON config file.

secenv init [--path <path>] [--force]

Notes:

  • Creates an empty file at --path (default: secenv.conf). You should edit it to add version, profiles, and vars as shown above.

GCP requirements

  • Install and authenticate gcloud (gcloud auth login or service account with suitable permissions).
  • Ensure the identity has access to the relevant secrets (e.g., Secret Manager Secret Accessor).
  • Accepted secret identifier format: projects/<project>/secrets/<name> (optional /versions/<version>; defaults to latest).

Troubleshooting

  • "Profile '' not found": Verify profiles.<name> exists in the config.
  • "Failed to parse HOCON config": Validate HOCON syntax and file path.
  • GCP access errors: Check gcloud authentication, project, permissions, and secret name.
  • PGP decryption errors: Ensure the private key is valid ASCII‑armored and corresponds to the message.

For verbose logs:

RUST_LOG=debug secenv unlock

Contributing

PRs are welcome!

Development

git clone https://github.com/cchexcode/secenv
cd secenv
cargo build
cargo test

License

MIT – see LICENSE.

Related projects

Commit count: 2

cargo fmt