A minimal, dependency-light bash tool for managing encrypted environment variables using RSA public/private key pairs.
Author: JumpFast Technologies
Managing secrets in configuration files is a common challenge. You want to:
- Store encrypted secrets safely in version control
- Share configuration with your team without exposing sensitive values
- Decrypt secrets at deploy time or runtime
This tool was inspired by Shopify's EJSON,
which pioneered the concept of asymmetric encryption for config files. We
built ejson-to-env as a lightweight alternative that:
- Requires only
bash,jq, andopenssl(no Go/Ruby runtime) - Outputs standard
.envfiles (compatible with Docker, dotenv, etc.) - Uses familiar RSA encryption under the hood
- Fits in a single portable shell script
git clone https://github.com/jumpfast-tech/ejson-to-env.git
cd ejson-to-env
make install # installs to /usr/local/bin/ejson-to-envCustom prefix (e.g. ~/.local/bin):
make install PREFIX=~/.localUninstall:
make uninstallDownloads the latest release asset directly — no git clone needed:
curl -fsSL https://github.com/jumpfast-tech/ejson-to-env/releases/latest/download/ejson-to-env \
-o /usr/local/bin/ejson-to-env && chmod +x /usr/local/bin/ejson-to-envUse the action directly in any workflow — no install step required:
- name: Decrypt secrets
uses: jumpfast-tech/ejson-to-env@v1
with:
private-key: ${{ secrets.EJSON_PRIVATE_KEY }}
# ejson-file: env.ejson (default)
# output-file: .env (default)The action reads env.ejson and writes .env in your workspace.
Add this to your buildspec.yml install phase:
phases:
install:
commands:
- curl -fsSL https://github.com/jumpfast-tech/ejson-to-env/releases/latest/download/ejson-to-env
-o /usr/local/bin/ejson-to-env
- chmod +x /usr/local/bin/ejson-to-env
pre_build:
commands:
- ejson-to-env decryptStore the private key in AWS Secrets Manager or Parameter Store and inject it
as an environment variable named EJ_PRIVATE_KEY.
steps:
- name: alpine
entrypoint: sh
args:
- -c
- |
apk add --no-cache curl jq openssl
curl -fsSL https://github.com/jumpfast-tech/ejson-to-env/releases/latest/download/ejson-to-env \
-o /usr/local/bin/ejson-to-env
chmod +x /usr/local/bin/ejson-to-env
ejson-to-env decrypt
secretEnv:
- EJ_PRIVATE_KEY
availableSecrets:
secretManager:
- versionName: projects/$PROJECT_ID/secrets/ejson-private-key/versions/latest
env: EJ_PRIVATE_KEYA pre-built image is published to the GitHub Container Registry on every release:
# Decrypt env.ejson -> .env in the current directory
docker run --rm \
-e EJ_PRIVATE_KEY="$(cat private.pem)" \
-v "$PWD:/work" -w /work \
ghcr.io/jumpfast-tech/ejson-to-env decryptOr use it as a base/stage in your own Dockerfile:
FROM ghcr.io/jumpfast-tech/ejson-to-env:latest AS secrets
COPY env.ejson /work/
RUN ejson-to-env decrypt --input /work/env.ejson --output /work/.env
FROM your-app-image
COPY --from=secrets /work/.env .Available tags: latest, 1, 1.0, 1.0.0 (semver on each release).
# 1. Generate a new keypair
ejson-to-env gen-keys
# 2. Save the private key securely (printed to terminal)
# Store it in a password manager or secure vault
# 3. Add encrypted secrets (one key at a time, or all at once)
ejson-to-env encrypt --key DB_PASSWORD --value "super_secret_123"
ejson-to-env encrypt --all # encrypts every plain-text value in the file
# 4. Decrypt to .env when needed
export EJ_PRIVATE_KEY="$(cat private.pem)"
ejson-to-env decryptStore your env.ejson file in version control. The public key and encrypted
values are safe to commit. Only holders of the private key can decrypt.
{
"_public_key": "-----BEGIN PUBLIC KEY-----\n...",
"DB_PASSWORD": "EJ[1:encrypted_base64_data]",
"API_KEY": "EJ[1:another_encrypted_value]",
"DEBUG": "true"
}Plain text values (like DEBUG) pass through unchanged.
In your deployment pipeline, inject the private key as a secret environment variable:
# GitHub Actions — using the published action (recommended)
- name: Decrypt secrets
uses: jumpfast-tech/ejson-to-env@v1
with:
private-key: ${{ secrets.EJSON_PRIVATE_KEY }}Generate .env at container startup using the published image:
FROM ghcr.io/jumpfast-tech/ejson-to-env:latest AS secrets
COPY env.ejson /work/
RUN ejson-to-env decrypt --input /work/env.ejson --output /work/.env
FROM your-app-image
COPY --from=secrets /work/.env .
CMD ["myapp"]Maintain separate files for each environment:
# Development
ejson-to-env decrypt -i dev.ejson -o .env.dev
# Production
ejson-to-env decrypt -i prod.ejson -o .env.prod- Generate keys once per environment
- Share the private key securely with authorized team members
- Anyone can add new encrypted secrets using just the public key
- Commit changes to
env.ejsonwithout exposing values
Generate a new RSA keypair. The public key is stored in your ejson file; the private key is printed to the terminal for you to save securely.
ejson-to-env gen-keys [options]
Options:
--output-ejson <file> Output file (default: env.ejson)
--bits <n> Key size in bits (default: 2048)Add or update an encrypted secret in your ejson file.
ejson-to-env encrypt [options]
Options:
--input, -i <file> Input ejson file (default: env.ejson)
--all Encrypt every plain-text value in the file at once
--key <name> Environment variable name (required without --all)
--value <secret> Secret value to encrypt
--value-stdin Read secret from stdin (recommended for scripts)Encrypt all plain-text values at once — useful when you have an existing file with unencrypted values and want to lock it down in one step:
ejson-to-env encrypt --allThis skips _public_key and any values already wrapped as EJ[1:...], so
it's safe to run repeatedly.
Encrypt a single key:
ejson-to-env encrypt --key DB_PASSWORD --value "super_secret"
# Recommended: read from stdin to keep secrets out of shell history
echo "super_secret" | ejson-to-env encrypt --key DB_PASSWORD --value-stdinDecrypt an ejson file to a standard .env file.
ejson-to-env decrypt [options]
Options:
--input, -i <file> Input ejson file (default: env.ejson)
--output, -o <file> Output .env file (default: .env)
--private-key-file <file> Read private key from file
--save-private-key <file> Save EJ_PRIVATE_KEY to file (chmod 600)The private key can be provided via:
EJ_PRIVATE_KEYenvironment variable (recommended)--private-key-fileflag
{
"_public_key": "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----",
"SECRET_KEY": "EJ[1:base64_encrypted_data]",
"PLAIN_KEY": "unencrypted values are fine too"
}_public_key: Required. RSA public key in PEM format.EJ[1:...]: Encrypted values (RSA + base64 encoded).- Plain strings: Passed through as-is to the output
.envfile.
bash(4.0+)jq(JSON processor)openssl(for RSA operations)
All three are available on most Unix systems and in CI environments.
- Never commit private keys. Store them in a secrets manager, vault, or secure environment variable.
- Rotate keys periodically. Generate new keypairs and re-encrypt secrets as part of your security hygiene.
- RSA key size: Default is 2048 bits. Use
--bits 3072or higher for stronger encryption if needed.
A comprehensive test suite is included:
./test-ejson-to-env.shThis project was inspired by the excellent work on Shopify/ejson. Their approach to asymmetric encryption for configuration files shaped our design philosophy. We're grateful to the Shopify team for pioneering this pattern.
BSD 3-Clause License with Attribution. See LICENSE for details.
Copyright (c) 2026 JumpFast Technologies