Skip to content

File Reference

This page documents all files that Hush creates, reads, and manages.

File Overview

FileCommittedPurpose
hush.yamlYesConfiguration file
.sops.yamlYesSOPS encryption config
.env.encryptedYesEncrypted shared secrets
.env.development.encryptedYesEncrypted development secrets
.env.production.encryptedYesEncrypted production secrets
.env.localNoPersonal overrides (unencrypted)
.env.developmentNoGenerated development env
.env.productionNoGenerated production env
.dev.varsNoGenerated Wrangler secrets

Configuration Files

hush.yaml

The main configuration file. Defines sources and targets.

sources:
shared: .env
development: .env.development
production: .env.production
targets:
- name: root
path: .
format: dotenv

Location: Repository root
Commit: Yes
Created by: hush init or manually

.sops.yaml

SOPS configuration file. Defines which keys can encrypt/decrypt.

creation_rules:
- encrypted_regex: '.*'
age: age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Location: Repository root
Commit: Yes
Created by: Manually (SOPS requirement)

Source Files (Unencrypted)

These are your original .env files before encryption.

.env

Shared variables used across all environments.

Terminal window
DATABASE_URL=postgres://user:pass@host/db
STRIPE_SECRET_KEY=sk_xxx
EXPO_PUBLIC_API_URL=${API_BASE}/v1

.env.development

Development-specific overrides.

Terminal window
API_BASE=http://localhost:8787
DEBUG=true

.env.production

Production-specific overrides.

Terminal window
API_BASE=https://api.example.com
DEBUG=false

.env.local

Personal overrides. Never encrypted, never committed.

Terminal window
# Your personal settings
DEBUG=verbose
SKIP_AUTH=true

Encrypted Files

These are the SOPS-encrypted versions of your source files. Safe to commit.

.env.encrypted

Encrypted version of .env (shared secrets).

.env.development.encrypted

Encrypted version of .env.development.

.env.production.encrypted

Encrypted version of .env.production.

Created by: hush encrypt
Commit: Yes
Used by: hush decrypt, hush set

Generated Files

These are created by hush decrypt and should not be committed.

.env.development / .env.production

Generated dotenv files for the current environment.

Created by: hush decrypt
Location: Each target’s path
Commit: No

.dev.vars

Generated Wrangler secrets file.

Created by: hush decrypt (for format: wrangler targets)
Location: Target’s path
Commit: No

.env.*.json

Generated JSON format.

Created by: hush decrypt (for format: json targets)
Commit: No

.env.*.sh

Generated shell script.

Created by: hush decrypt (for format: shell targets)
Commit: No

Typical Project Structure

  • .sops.yaml # SOPS config (committed)
  • hush.yaml # Hush config (committed)
  • .env.encrypted # Encrypted shared (committed)
  • .env.development.encrypted # Encrypted dev (committed)
  • .env.production.encrypted # Encrypted prod (committed)
  • .env.local # Personal overrides (NOT committed)
  • .env.development # Generated (NOT committed)
  • Directorypackages/
    • Directoryapp/
      • .env.development # Generated (NOT committed)
    • Directoryapi/
      • .dev.vars # Generated (NOT committed)

Add these entries to your .gitignore:

Terminal window
# Hush - Source files (unencrypted)
.env
.env.development
.env.production
.env.local
# Hush - Generated files
.env.*.json
.env.*.sh
.dev.vars
# Keep encrypted files
!.env.encrypted
!.env.*.encrypted

Age Key File

SOPS uses age for encryption. Your private key is stored at:

~/.config/sops/age/key.txt

Key Format

# created: 2024-01-01T00:00:00Z
# public key: age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
AGE-SECRET-KEY-1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Multiple Keys

For team environments, each member has their own key. All public keys are listed in .sops.yaml:

creation_rules:
- encrypted_regex: '.*'
age: >-
age1alice...,
age1bob...,
age1charlie...

Anyone with any of these private keys can decrypt the secrets.