salakala v0.5.3
salakala šš
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 salakalaUsage
- Create a
salakala.jsonfile in your project (safe to commit to your repository!) - Run salakala to generate your
.envfile 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 --helpExamples
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 salakalaUsing 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_PASSWORDwill be fetched from the secret managerAPP_NAMEwill be passed through directly to the generated environment variables
Providers
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-nameExample:
op://Personal/AWS/access-keyUses 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-keyExample: Plaintext field via item ID:
bw://1c9448b3-3d30-4f01-8d3c-3a4b8d14d00a/passwordExample: Plaintext field via item name:
bw://my-folder/my-item/passwordExample: 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/0This would get the first URI from the uris field.
- ā 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/fieldExample:
kp:///Users/me/secrets.kdbx/Web/GitHub/PasswordNotes:
- To find field titles, you can use the
keepassxc-clicommand:keepassxc-cli show "/path/to/database.kdbx" "entry-name"
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-keyExample: JSON object:
awssm://us-east-1/prod/databaseThis 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::passwordThis will fetch the password key from the JSON object in the database secret.
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/latestExample: JSON object:
gcsm://projects/my-project/secrets/database/versions/latestThis 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::passwordThis will fetch the password key from the JSON object in the database secret.
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-keyFetches 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-nameExample:
azurekv://my-vault.vault.azure.net/database-passwordFetches 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/pathExample:
hcv://vault.example.com:8200/secret/data/database/credentialsUses the Doppler CLI to fetch secrets. Requires the Doppler CLI to be installed.
ā Needs testing
Format:
doppler://project/config/secret-nameExample:
doppler://my-project/dev/DATABASE_URLUses the Infisical CLI to fetch secrets. Requires the Infisical CLI to be installed.
ā Needs testing
Format:
inf://workspace/environment/secret-nameExample:
inf://my-project/dev/DATABASE_URLRecommendations
- ā
DO commit
salakala.json- it should only contain paths to secrets, not the secrets themselves - ā DON'T commit generated
.envfiles - Add
.env*to your.gitignore
Contributing
Contributions are welcome! Feel free to submit issues and pull requests.
License
MIT