npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

salakala

v1.3.4

Published

Generate environment variables from various secret providers via URIs in JSON files, checked into your repository

Downloads

118

Readme

salakala

Generate environment variables from (multiple) secret providers using a JSON configuration file checked into your repository. Output to .env files or export directly to your shell, or use in CI environments. Supports JSON field access, secret synchronization between providers, and more. Contains an extensive test suite with full end-to-end coverage.

{
    "DATABASE_URL": "op://application-secrets/db/url",
    "API_KEY": "awssm://us-east-1/prod/api-key"
}

Integrates with 1Password, Bitwarden, AWS Secrets Manager, Google Cloud Secret Manager, Azure Key Vault, KeePass, and LastPass.

Installation

Install globally to use as a regular CLI:

npm install -g salakala

Or install in your project:

npm install --save-dev salakala

and then add a script to your package.json:

"scripts": {
    "salakala": "salakala"
}

Usage

Create a salakala.json configuration file in your project root, then run salakala to fetch secrets and generate environment variables.

Basic Commands

salakala                    # Generate .env file from salakala.json
salakala -s                 # Export variables to current shell
salakala -e staging         # Use specific environment configuration
salakala -i config.json     # Use alternative input file
salakala -o .env.local      # Write to alternative output file
salakala -w                 # Overwrite existing file instead of merging

salakala import             # Import variables to secret provider (interactive)
salakala import -i .env.prod # Import from specific file

salakala sync               # Synchronize secrets between providers
salakala sync --dry-run     # Preview sync without writing

salakala --help             # Show help

Configuration

Flat structure for single-environment setups:

{
    "DATABASE_URL": "op://vault/database/url",
    "API_KEY": "awssm://us-east-1/prod/api-key"
}

Nested structure for environment-specific secrets:

{
    "development": {
        "DATABASE_URL": "op://vault/dev-database/url",
        "API_KEY": "awssm://us-east-1/dev/api-key"
    },
    "production": {
        "DATABASE_URL": "op://vault/prod-database/url",
        "API_KEY": "awssm://us-east-1/prod/api-key"
    }
}

Use ${VARIABLE_NAME} syntax to reference environment variables in secret paths:

{
    "development": {
        "API_KEY": "gcsm://projects/${PROJECT_ID}/secrets/api-key/versions/latest"
    }
}

Ensure variables are set before execution:

PROJECT_ID=my-project salakala

Include static configuration alongside secrets. Values without provider prefixes are passed through unchanged:

{
    "DB_PASSWORD": "op://vault/database/password",
    "APP_NAME": "My Application",
    "LOG_LEVEL": "info"
}

Extract specific fields from JSON-structured secrets using the :: separator.

Syntax:

provider://path/to/secret::jsonKey

The :: separator instructs salakala to fetch the secret, parse it as JSON, extract the specified field, and return it as a string.

Supported patterns:

  • Simple key: ::username
  • Nested object: ::database.host or ::api.credentials.key
  • Array index: ::servers[0] or ::endpoints[1].url
  • First array item: ::items[]

Example:

Given a secret containing:

{
  "database": {
    "host": "localhost",
    "credentials": {
      "username": "admin", 
      "password": "secret123"
    }
  },
  "servers": ["web1", "web2", "api"]
}

Extract specific fields:

{
  "DB_HOST": "op://vault/config::database.host",
  "DB_USER": "op://vault/config::database.credentials.username",
  "DB_PASS": "op://vault/config::database.credentials.password",
  "WEB_SERVER": "op://vault/config::servers[0]"
}

Secret Synchronization

Synchronize secrets across multiple providers using src and dst configuration.

Configuration

{
  "production": {
    "src": {
      "API_KEY": "op://vault/api-key/password",
      "DATABASE_URL": "op://vault/database/connection-string"
    },
    "dst": {
      "API_KEY": [
        "gcsm://projects/my-project/secrets/api-key/versions/latest"
      ],
      "DATABASE_URL": [
        "gcsm://projects/my-project/secrets/db-url/versions/latest",
        "awssm://us-east-1/prod/database-url"
      ]
    }
  }
}
  • src: Source provider URIs for reading secrets
  • dst: Destination provider URIs for writing secrets (supports multiple destinations per secret)
  • Only secrets defined in dst will be synchronized

Sync Commands

salakala sync                # Sync all secrets in dst
salakala sync -e production  # Sync specific environment
salakala sync -s API_KEY     # Sync single secret
salakala sync --dry-run      # Preview changes without writing
salakala sync -y             # Skip prompts and overwrite (for CI/automation)

Conflict Resolution

When a secret exists at the destination, you will be prompted unless using the -y flag:

  • Y - Overwrite this secret
  • N - Skip this secret
  • D - Show diff between current and new value
  • A - Overwrite all remaining conflicts
  • Q - Quit synchronization

Use salakala sync -y in CI/CD pipelines to automatically overwrite without prompts.

Importing from .env Files

Import existing environment variables from .env files into secret providers. The interactive wizard guides you through selecting variables, choosing a provider, and configuring storage.

Import Command

salakala import              # Interactive wizard (prompts for file or paste)
salakala import -i .env.prod # Import from specific file

You will be walked through the import process.

Storage Modes

Stores all variables as JSON in a single secret field. Ideal for providers supporting multiple fields (1Password, Bitwarden, KeePass, LastPass).

Advantages:

  • Fewer secrets to manage
  • Atomic updates
  • Better organization
  • Reduced API calls

Example output:

{
  "production": {
    "src": {
      "API_KEY": "op://vault/app-config/config::API_KEY",
      "DATABASE_URL": "op://vault/app-config/config::DATABASE_URL",
      "SECRET_KEY": "op://vault/app-config/config::SECRET_KEY"
    },
    "dst": {}
  }
}

The JSON bundle is stored in op://vault/app-config/config and individual fields are extracted using :: syntax.

Stores each variable as a separate field (1Password, Bitwarden, etc.) or separate secret (AWS, GCP, etc.).

Advantages:

  • Granular access control per secret
  • Independent versioning
  • Works with all providers

Example output (multi-field provider):

{
  "production": {
    "src": {
      "API_KEY": "op://vault/app-config/API_KEY",
      "DATABASE_URL": "op://vault/app-config/DATABASE_URL"
    },
    "dst": {}
  }
}

Example output (single-value provider):

{
  "production": {
    "src": {
      "API_KEY": "awssm://us-east-1/prod/API_KEY",
      "DATABASE_URL": "awssm://us-east-1/prod/DATABASE_URL"
    },
    "dst": {}
  }
}

Example Workflow

# Import production secrets from .env.production
salakala import -i .env.production

# Interactive prompts:
# ✓ Select variables: [x] DATABASE_URL [x] API_KEY [x] SECRET_KEY
# ✓ Provider: 1Password (op://)
# ✓ Vault: production-vault
# ✓ Item: app-secrets
# ✓ Store as JSON? Yes
# ✓ Field name: config
# ✓ Environment: production

# Creates salakala.json and writes secrets to 1Password
# Use the generated config:
salakala -e production

Tips

  • JSON bundle storage is recommended for better organization and fewer API calls
  • For cloud providers (AWS, GCP), JSON bundle creates one secret with all variables
  • Use dst configuration later to sync imported secrets to other providers
  • The import wizard validates all inputs before writing

Providers

Requirements: 1Password CLI (op)

Features:

  • Tested in CI
  • Interactive login
  • Non-interactive login via environment variables
  • Write support
  • JSON field access

Format:

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

Example:

op://Personal/AWS/access-key
op://Development/config/database::host

Requirements: Bitwarden CLI (bw)

Features:

  • Tested in CI
  • Interactive login
  • Non-interactive login via environment variables
  • Write support

Format:

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

Examples:

Access by item ID:

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

Access by item name and folder:

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

Access JSON field in notes:

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

Access login URIs:

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

Requirements: KeePassXC CLI (keepassxc-cli)

Features:

  • Tested in CI
  • Interactive login
  • Non-interactive login via environment variables
  • Write support (interactive mode only)
  • JSON field access

Format:

kp://path/to/database.kdbx/entry-path/field[::jsonKey]

Example:

kp:///Users/me/secrets.kdbx/Web/GitHub/Password
kp:///Users/me/secrets.kdbx/Config/Notes::database.host

Note: Use keepassxc-cli show "/path/to/database.kdbx" "entry-name" to list available fields.

Requirements: AWS credentials (AWS CLI or environment variables)

Features:

  • Tested in CI
  • Write support
  • Uses AWS SDK (AWS CLI not required)

Format:

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

Examples:

Plaintext secret:

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

Entire JSON object:

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

Specific JSON field:

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

Requirements: Google Cloud credentials (gcloud CLI or service account)

Features:

  • Tested in CI
  • Write support
  • Uses Google Cloud SDK (gcloud CLI not required)

Format:

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

Examples:

Plaintext secret:

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

Entire JSON object:

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

Specific JSON field:

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

Requirements: Azure credentials

Features:

  • Needs testing
  • Write support
  • Uses Azure SDK
  • JSON field access

Format:

azurekv://vault-name.vault.azure.net/secret-name[::jsonKey]

Example:

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

Requirements: LastPass CLI (lpass)

Features:

  • Tested in CI
  • Interactive login
  • Non-interactive login via environment variables
  • Write support
  • JSON field access

Format:

lp://folder/item-name/field[::jsonKey]

Example:

lp://work-secrets/api-credentials/password
lp://work-secrets/config/notes::database.host

Adding New Providers

Extend the SecretProvider class and add it to the providers map in src/lib/SecretsManager.ts. Contributions with tests are welcome.

Best Practices

  • Commit salakala.json to version control (contains only secret references, not secrets)
  • Do not commit generated .env files
  • Add .env* to .gitignore

Acknowledgments

Thank you 1Password for sponsoring a team license used for testing.

License

MIT