Skip to content

Generate environment variables or .env files from various secret providers via URIs

License

Notifications You must be signed in to change notification settings

auth70/salakala

Repository files navigation

salakala 🔒🐟

build npm npm type definitions

We've all been there, sharing .env files in Slack to get an application working quickly while feeling bad about security practices. 🫠

But teams always have a shared secret or password manager, and you already have a way to access it through a CLI or service account, right?

What if you just had a nice little JSON file in your code repository that defined which environment variables to fetch from any manager through URIs?

// salakala.json
{
    "DATABASE_URL": "op://application-secrets/db/url"
}

salakala does exactly that! It wraps around your manager and generates environment variables for you as .env files or by setting variables directly in your environment.

Installation

# Install globally to use the CLI
npm install -g salakala

Usage

  1. Create a salakala.json file in your project (safe to commit to your repository!)
  2. Run salakala to generate your .env file or set environment variables:
# Generate .env file in the current directory (default)
salakala

# Set environment variables in the current shell
salakala -s

# Specify an environment
salakala -e staging

# Specify a different output file
salakala -o .env.local

# Overwrite existing file instead of merging
salakala -w

# Show help
salakala --help

Examples

Flat structure (no environment specific secrets)

// salakala.json
{
    "SECRET_ENV_VALUE": "op://application-secrets/test/test-section"
}

Nested structure (environment specific secrets)

// salakala.json
{
    "development": {
        "SECRET_ENV_VALUE": "op://application-secrets/test/test-section"
    },
    "staging": {
        "SECRET_ENV_VALUE": "op://application-secrets/staging/test-section"
    }
}

Using environment variables in secret paths

You can use environment variables in your secret paths using ${VARIABLE_NAME} syntax:

// salakala.json
{
    "development": {
        "GCP_API_KEY": "gcsm://projects/${PROJECT_ID}/secrets/api-key/versions/latest"
    }
}

The environment variables must of course be set before running:

PROJECT_ID=my-project salakala

Using non-secret values

You can also include regular, non-secret values. Any value that doesn't start with a provider prefix (like op://, gcsm://, etc.) will be passed through:

{
    "development": {
        "DB_PASSWORD": "op://vault/database/password",
        "APP_NAME": "My Development App",
    }
}

In this example:

  • DB_PASSWORD will be fetched from the secret manager
  • APP_NAME will be passed through directly to the generated environment variables

Providers

1Password (op://)

Uses the 1Password CLI to fetch secrets. Requires the op CLI to be installed.

  • ✅ Tested against a real 1Password account in CI
  • 🧑‍💻 Interactive login via invoking op
  • 🤖 Noninteractive login using environment variables

Format:

op://vault-name/item-name/[section-name/]field-name

Example:

op://Personal/AWS/access-key

Bitwarden (bw://)

Uses the Bitwarden CLI (bw) to fetch secrets. Requires the bw CLI to be installed. Supports different vault locations.

  • ✅ Tested against a real Bitwarden account in CI
  • 🧑‍💻 Interactive login via invoking bw
  • 🤖 Noninteractive login using environment variables

Format:

bw://[folder]/item-name-or-id/field::json-key

Example: Plaintext field via item ID:

bw://1c9448b3-3d30-4f01-8d3c-3a4b8d14d00a/password

Example: Plaintext field via item name:

bw://my-folder/my-item/password

Example: JSON field via item name:

bw://my-folder/my-item/notes::foo.bar[1]

This expects that the item has a notes field that is a JSON object. It will return the value of the foo.bar[1] key.

Example: URI from a login item:

bw://my-folder/my-item/uris/0

This would get the first URI from the uris field.


KeePassXC (kp://)
Uses the KeePassXC CLI to fetch secrets from a KeePass database. Requires the `keepassxc-cli` CLI to be installed.
  • ✅ Tested against a real KeePass database in CI
  • 🧑‍💻 Interactive login via invoking keepassxc-cli
  • 🤖 Noninteractive login using environment variables

Format:

kp://path/to/database.kdbx/entry-path/field

Example:

kp:///Users/me/secrets.kdbx/Web/GitHub/Password

Notes:

  • To find field titles, you can use the keepassxc-cli command: keepassxc-cli show "/path/to/database.kdbx" "entry-name"

AWS Secrets Manager (awssm://)

Fetches secrets from AWS Secrets Manager. Requires some form of AWS credentials to be configured. Uses the AWS SDK to fetch secrets.

  • ✅ Tested against a real AWS account in CI
  • 🧑‍💻 Semi-interactive login
  • 🤖 Noninteractive login using environment variables

Format:

awssm://region/secret-name[:key]

Example: Plaintext secret:

awssm://us-east-1/prod/api-key

Example: JSON object:

awssm://us-east-1/prod/database

This will fetch the entire JSON object in the database secret and pass it through as a JSON string.

Example: Specific key in JSON object:

awssm://us-east-1/prod/database::password

This will fetch the password key from the JSON object in the database secret.


Google Cloud Secret Manager (gcsm://)

Fetches secrets from Google Cloud Secret Manager. Requires Google Cloud credentials to be configured. Uses the Google Cloud SDK to fetch secrets.

  • ✅ Tested against a real Google Cloud project in CI
  • 🧑‍💻 Semi-interactive login
  • 🤖 Noninteractive login using environment variables

Format:

gcsm://projects/project-id/secrets/secret-id/versions/version[:key]

Example: Plaintext secret:

gcsm://projects/my-project/secrets/api-key/versions/latest

Example: JSON object:

gcsm://projects/my-project/secrets/database/versions/latest

This will fetch the entire JSON object in the database secret and pass it through as a JSON string.

Example: Specific key in JSON object:

gcsm://projects/my-project/secrets/database/versions/latest::password

This will fetch the password key from the JSON object in the database secret.


LastPass (lp://)

Uses the LastPass CLI to fetch secrets. Requires the lpass CLI to be installed.

❌ Needs testing

Format:

lp://group/item-name[/field]

Example:

lp://Personal/AWS/api-key

Azure Key Vault (azurekv://)

Fetches secrets from Azure Key Vault. Requires Azure credentials to be configured. Uses the Azure SDK to fetch secrets.

❌ Needs testing

Format:

azurekv://vault-name.vault.azure.net/secret-name

Example:

azurekv://my-vault.vault.azure.net/database-password

HashiCorp Vault (hcv://)

Fetches secrets from HashiCorp Vault. Requires the VAULT_ADDR and VAULT_TOKEN environment variables to be set. Uses the HashiCorp Vault SDK to fetch secrets.

❌ Needs testing

Format:

hcv://vault-address/secret/path

Example:

hcv://vault.example.com:8200/secret/data/database/credentials

Doppler (doppler://)

Uses the Doppler CLI to fetch secrets. Requires the Doppler CLI to be installed.

❌ Needs testing

Format:

doppler://project/config/secret-name

Example:

doppler://my-project/dev/DATABASE_URL

Infisical (inf://)

Uses the Infisical CLI to fetch secrets. Requires the Infisical CLI to be installed.

❌ Needs testing

Format:

inf://workspace/environment/secret-name

Example:

inf://my-project/dev/DATABASE_URL

Recommendations

  • ✅ DO commit salakala.json - it should only contain paths to secrets, not the secrets themselves
  • ❌ DON'T commit generated .env files
  • Add .env* to your .gitignore

Contributing

Contributions are welcome! Feel free to submit issues and pull requests.

License

MIT

About

Generate environment variables or .env files from various secret providers via URIs

Resources

License

Stars

Watchers

Forks