Skip to main content

envcat get


title: envcat get audience: Developer difficulty: Intermediate estimated_read_time: 15 min prerequisites:

  • CLI installed
  • Access to env.cat service
  • Browser for approval related_pages:
  • ./installation.md
  • ../device-approval.md
  • ../api-reference/requests.md

Request environment variables from env.cat and inject them into your shell.

Synopsis

envcat get [flags]

The envcat get command creates an approval request, displays a URL/QR code for browser approval, waits for the user to approve, receives encrypted secrets, and outputs them in the specified format.

Description

How it works:

  1. Generate keypair - CLI creates ephemeral Ed25519 keypair
  2. Create request - POST to /api/v1/requests with public key
  3. Display approval URL - Show URL and QR code in terminal
  4. Poll for approval - Check server every 3 seconds for up to 5 minutes
  5. Receive ciphertext - Get encrypted secrets from server
  6. Decrypt locally - Decrypt with private key (only CLI can decrypt)
  7. Output - Print shell exports, Fish commands, or write .env file

Security:

  • End-to-end encryption - Server never sees plaintext secrets
  • Ephemeral keys - New keypair generated for each request
  • Single-use - Request deleted after approval
  • Zero-trust - No long-lived credentials

Flags

--api-base

Type: string
Default: https://env.cat
Required: No

API base URL for the env.cat instance.

Examples:

# Production instance (default)
envcat get --bundle dev/api

# Self-hosted instance
envcat get --api-base https://envcat.yourcompany.com

# Ngrok tunnel for testing
envcat get --api-base https://abc123.ngrok.app

Notes:

  • Include protocol (https:// recommended)
  • Do not include trailing slash
  • Always use HTTPS in production

--bundle

Type: string
Default: ""
Required: No (but recommended)

Bundle name or ID to request secrets from.

Examples:

# Request by name (hierarchical)
envcat get --bundle dev/api
envcat get --bundle staging/frontend
envcat get --bundle prod/database

# Request by ID (UUID)
envcat get --bundle a1b2c3d4-e5f6-7890-abcd-ef1234567890

Naming conventions:

{environment}/{service}
dev/api
staging/api
prod/api

{team}/{project}
team-alpha/mobile
team-beta/analytics

{purpose}/{environment}
database/dev
cache/prod

What happens:

  • If provided: Approval UI pre-selects this bundle
  • If omitted: User chooses bundle during approval

Best practice: Always specify --bundle for automation and clarity.


--keys

Type: string slice (comma-separated)
Default: nil (all keys in bundle)
Required: No

Specific keys to request from the bundle.

Examples:

# Request single key
envcat get --bundle dev/api --keys DATABASE_URL

# Request multiple keys (comma-separated, no spaces)
envcat get --bundle dev/api --keys DATABASE_URL,REDIS_URL,API_KEY

# Request with spaces (quote the value)
envcat get --bundle dev/api --keys "DATABASE_URL, REDIS_URL"

Approval behavior:

  • Approval UI shows only requested keys
  • User cannot approve keys not in the request
  • Reduces secrets exposure (principle of least privilege)

Use cases:

# Only need database credentials
envcat get --bundle dev/api --keys DATABASE_URL,DB_PASSWORD

# Only need API key for testing
envcat get --bundle prod/payments --keys STRIPE_SECRET_KEY

# Exclude sensitive keys when debugging
envcat get --bundle prod/api --keys PORT,LOG_LEVEL,NODE_ENV

--format

Type: string
Default: sh
Allowed values: sh, fish, .env
Required: No

Output format for environment variables.

Format: sh (default)

Shell-safe exports for bash/zsh:

envcat get --bundle dev/api --format sh

Output:

export DATABASE_URL='postgres://user:pass@localhost:5432/db'
export API_KEY='sk_live_abc123xyz'
export PORT='3000'

Usage:

# Inject into current shell
eval "$(envcat get --bundle dev/api --format sh)"

# Verify variables loaded
echo $DATABASE_URL

Quoting: Values wrapped in single quotes with proper escaping for special characters.

Format: fish

Fish shell exports:

envcat get --bundle dev/api --format fish

Output:

set -x DATABASE_URL postgres://user:pass@localhost:5432/db
set -x API_KEY sk_live_abc123xyz
set -x PORT 3000

Usage:

# Fish shell
envcat get --bundle dev/api --format fish | source

# Verify
echo $DATABASE_URL

Format: .env

Dotenv file format:

envcat get --bundle dev/api --format .env

Output:

DATABASE_URL=postgres://user:pass@localhost:5432/db
API_KEY=sk_live_abc123xyz
PORT=3000

Usage:

# Write to file
envcat get --bundle dev/api --format .env > .env

# Or use --write flag (recommended)
envcat get --bundle dev/api --write .env

Notes:

  • No export prefix
  • No quotes (unless value contains special chars)
  • Compatible with Docker, direnv, dotenv libraries

--write

Type: string
Default: ""
Required: No

Write output to a file instead of stdout. Implies --format .env.

Examples:

# Write to .env
envcat get --bundle dev/api --write .env

# Write to custom path
envcat get --bundle dev/api --write config/.env.local

# Write to absolute path
envcat get --bundle prod/db --write /etc/myapp/.env

Behavior:

  • Sets format to .env automatically (ignores --format flag)
  • Creates file with 0600 permissions (owner read/write only)
  • Overwrites existing file (no prompt)
  • Displays warning if file is in git repository

File permissions:

envcat get --bundle dev/api --write .env
ls -l .env
# -rw------- 1 user user 256 Oct 22 15:30 .env

Git warning:

envcat get --bundle dev/api --write .env
# ⚠️ Warning: .env appears to be in a git repository.
# Make sure to add it to .gitignore to avoid committing secrets!

Loading into shell:

# Write file
envcat get --bundle dev/api --write .env

# Load into shell
set -a && source .env && set +a

--file

Type: string
Default: ""
Required: No

Alias for --write. Works identically.

Examples:

# Identical to --write
envcat get --bundle dev/api --file .env
envcat get --bundle dev/api --file config/.env.local

Why both flags?

  • --write - Consistent with other CLI tools
  • --file - Shorter, more intuitive for some users

Choose whichever you prefer. Both work the same way.


-h, --help

Show help for envcat get command.

envcat get --help

Examples

Basic Usage

Request all keys from a bundle:

envcat get --bundle dev/api

Output:

┌─────────────────────────────────────────┐
│ Approval Required │
│ │
│ Open this URL in your browser: │
│ https://env.cat/approve/abc123xyz │
│ │
│ Or scan this QR code: │
│ ████ ▄▄▄▄▄ █▀█ █▄▀▀▀█▄█ ▄▄▄▄▄ ████ │
│ ... │
│ │
│ Waiting for approval... │
│ (expires in 4:58) │
└─────────────────────────────────────────┘

# After approval:
✓ Approved! Received 3 variable(s)

export DATABASE_URL='postgres://user:pass@localhost:5432/db'
export API_KEY='sk_live_abc123xyz'
export PORT='3000'

Inject into current shell:

eval "$(envcat get --bundle dev/api)"

Verify:

echo $DATABASE_URL
# postgres://user:pass@localhost:5432/db

echo $API_KEY
# sk_live_abc123xyz

Benefits:

  • No files created (ephemeral)
  • No cleanup needed
  • Secrets only in current shell session

Write to .env File

Create .env file:

envcat get --bundle dev/api --file .env

Output:

┌─────────────────────────────────────────┐
│ Approval Required │
│ ... │
└─────────────────────────────────────────┘

✓ Approved! Received 3 variable(s)

✓ Written to .env

Load into shell:

set -a && source .env && set +a

Cleanup:

rm .env

Request Specific Keys

Only request database credentials:

envcat get --bundle dev/api --keys DATABASE_URL,DB_PASSWORD

Approval UI shows:

  • ✓ DATABASE_URL
  • ✓ DB_PASSWORD
  • (other keys not shown)

Fish Shell

Fish shell integration:

envcat get --bundle dev/api --format fish | source

Output:

set -x DATABASE_URL postgres://...
set -x API_KEY sk_live_abc123xyz
set -x PORT 3000

CI/CD Integration

GitHub Actions:

- name: Get secrets
run: |
curl -fsSL https://env.cat/cli/install.sh | sh
envcat get --bundle ci/github --file .env
source .env

Note: CI/CD approval requires automation (future feature) or pre-approved tokens.

Multiple Environments

Switch environments easily:

# Development
eval "$(envcat get --bundle dev/api)"
npm run dev

# Staging (new shell)
eval "$(envcat get --bundle staging/api)"
npm run dev

# Production (new shell)
eval "$(envcat get --bundle prod/api)"
npm start

Docker Compose

Generate .env for Docker:

envcat get --bundle dev/api --file .env
docker-compose up

docker-compose.yml:

services:
api:
env_file:
- .env

Subshell (Isolated Environment)

Run command with secrets in isolated subshell:

(eval "$(envcat get --bundle dev/api)" && npm start)

Benefits:

  • Secrets only available during npm start
  • Parent shell unaffected
  • Automatic cleanup when subshell exits

Common Patterns

Daily Development Workflow

Morning routine:

cd ~/projects/myapp
eval "$(envcat get --bundle dev/api)"
npm run dev

Client Switching (Freelancers)

Switch between client projects:

# Client A
cd ~/clients/client-a
eval "$(envcat get --bundle client-a/api)"

# Client B
cd ~/clients/client-b
eval "$(envcat get --bundle client-b/api)"

Testing with Production Data

Use production secrets for local testing:

eval "$(envcat get --bundle prod/api --keys DATABASE_URL)"
npm run test:integration

Warning: Only request what you need to reduce exposure.

Direnv Integration

.envrc file:

#!/bin/bash
eval "$(envcat get --bundle dev/api)"

Usage:

cd ~/projects/myapp
# direnv automatically loads secrets

Troubleshooting

Request Expired

Error:

Error: request expired after 300 seconds

Solution:

Run command again and approve faster (5-minute window).

envcat get --bundle dev/api

Approval URL 404

Error:

# Browser shows "Request not found"

Solution:

  • Check URL is complete (entire URL copied)
  • Request may have expired (run envcat get again)
  • Verify API base URL is correct

No Variables Received

Output:

⚠️  No variables received

Reasons:

  • No keys selected during approval
  • Bundle is empty
  • Network error during approval

Solution:

Run again and select keys during approval.

Git Warning

Warning:

⚠️  Warning: .env appears to be in a git repository.
Make sure to add it to .gitignore to avoid committing secrets!

Solution:

Add to .gitignore:

echo ".env" >> .gitignore
git add .gitignore
git commit -m "Add .env to gitignore"

Permission Denied (Write)

Error:

Error: write .env: permission denied

Solution:

Check directory permissions:

ls -ld .
# drwxr-xr-x 10 user user 4096 Oct 22 15:30 .

# If needed, fix permissions
chmod u+w .

SSL Certificate Error

Error:

Error: x509: certificate signed by unknown authority

Solution:

Update CA certificates or use self-signed cert flag (development only):

# Development only - do not use in production
export GODEBUG=x509ignoreCN=0

Advanced Usage

Custom Polling Interval

Future feature: Customize polling interval

envcat get --bundle dev/api --poll-interval 1s

Timeout Override

Future feature: Custom timeout

envcat get --bundle dev/api --timeout 10m

Offline Mode

Future feature: Use cached secrets when offline

envcat get --bundle dev/api --offline

Exit Codes

CodeMeaning
0Success
1General error
2Request expired
3Approval denied
4Network error
5Decryption failed

Usage in scripts:

if envcat get --bundle dev/api --file .env; then
echo "Secrets loaded successfully"
docker-compose up
else
echo "Failed to get secrets (exit code: $?)"
exit 1
fi

See Also