Skip to content

dreamph/profy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

profy

Go License

Run any command with profile-based environment variables loaded from config outside your repo.

profy <profile> <command>

What It Does

Need profy behavior
Keep secrets out of git Reads env files from an external config home
Switch environments Uses profiles such as dev, sit, and prod
Merge env files Loads files in order; later files override earlier files
Fail early Checks required_keys before starting the command
Develop with reloads --watch-env restarts the command when env/config files change
Protect config-home path Stores it sealed; profy config hides it by default

Install

Method Command
Go install go install github.com/dreamph/profy@latest
Local build git clone https://github.com/dreamph/profy.git && cd profy && go build -o profy .

Quick Start

Step Command or file Result
1 profy setup --config-home /secure/profy-config Stores profySecret in macOS Keychain or Windows Credential Manager
2 profy init Prompts for project_id and creates .profy.yml
3 /secure/profy-config/<project_id>/profy.json Defines profiles and env files outside the repo
4 profy verify Checks project file, setup, profile config, and env file paths
5 profy dev go run ./cmd/app Runs the command with the dev profile

profy init writes only the project reference:

project_id: myapp

Minimal external config:

/secure/profy-config/
  myapp/
    profy.json
    base.env
    dev.env
    secret/
      dev.env

Minimal profy.json:

{
  "configs": {
    "dev": {
      "files": ["base.env", "dev.env", "secret/dev.env"],
      "required_keys": ["APP_ENV"]
    }
  }
}

Commands

Command Purpose Notes
profy init Create .profy.yml Prompts for project_id; use --file only for a custom path
profy setup --config-home PATH Seal config-home and store profySecret Use --force to replace existing setup
profy verify Check local setup Does not print config-home
profy config Print setup/project metadata Hides config-home
profy config --show-config-home Print config-home Prompts for profySecret first
profy config change-secret Rotate profySecret Requires current secret and new secret confirmation
profy export <project_id> Export project config Prompts for profySecret; writes <project_id>.zip
profy <profile> <command> Run a command with env vars Example: profy dev go run ./cmd/app
profy --print-env <profile> Print redacted env output Does not run a command

Flags

Command Flag Default Description
init --file PATH .profy.yml Project reference file to create
init --force false Overwrite an existing project reference file
setup --config-home PATH $PROFY_CONFIG_HOME or ~/.profy External config directory to seal
setup --force false Replace existing ~/.profy/settings.json
verify --project-file FILE .profy.yml Project reference file to check
verify --config-home PATH resolution order below Check a config home without credential setup
config --project-file FILE .profy.yml Project reference file to read
config --show-config-home false Ask for profySecret and print config-home
run --project-file FILE .profy.yml Project reference file to read
run --config-home PATH resolution order below External config directory
run --override false Env files override existing OS env vars
run --watch-env false Restart command when env/config files change
run --watch-interval DURATION 1s Poll interval, for example 500ms
run -v, --verbose false Print project, profile, and command

Config-home resolution order:

Priority Source
1 --config-home
2 PROFY_CONFIG_HOME
3 Sealed path in ~/.profy/settings.json, opened with the OS credential store
4 ~/.profy

Config Files

File Location Purpose
.profy.yml Project repo Stores project_id only
settings.json ~/.profy/settings.json Stores sealed config-home metadata
profy.json External config home Defines profiles
.env, .yml, .yaml External config home Env values loaded by profiles

Project config can be stored in either layout:

Layout When used
<config-home>/profy.json Direct config home
<config-home>/<project_id>/profy.json Project subdirectory layout

Nested project IDs are supported, for example dir1/myapp.

Profile Schema

Field Type Description
files []string Env/YAML files to load in order
required_keys []string Keys that must be present and non-empty
vault []object Optional HashiCorp Vault KV sources
infisical []object Optional Infisical sources

Load order:

Order Source
1 Existing OS environment
2 Profile files
3 Vault sources
4 Infisical sources
5 Variable expansion
6 required_keys validation

Env Files

Format Supported values
.env KEY=value, quotes, export, comments, variable expansion
YAML Top-level scalar values only
APP_ENV=dev
APP_PORT=8080
DB_DSN=postgres://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}
APP_ENV: dev
APP_PORT: 8080
FEATURE_FLAG: true
EMPTY_VALUE: null

Security Commands

Task Command Notes
Check setup without leaking paths profy verify Prints status only
Show config-home profy config --show-config-home Requires profySecret
Rotate secret profy config change-secret Re-seals config-home
Export config profy export myapp Requires profySecret; refuses to overwrite existing zip

If profySecret is forgotten, profy cannot open the sealed config-home path. If you still know the config-home path, run profy setup --config-home PATH --force to create a new setup.

Examples

Use case Command
Run dev app profy dev go run ./cmd/app
Run production binary profy prod ./myapp
Hot reload with air profy dev air -c .air.toml
Restart when env changes profy --watch-env dev go run ./cmd/app
Print redacted env profy --print-env dev
Use a custom config home profy --config-home /secure/profy-config dev go run ./cmd/app
Verify bundled demo go run . verify --config-home examples/external-config --project-file examples/app/.profy.yml
Run bundled demo go run . --config-home examples/external-config --project-file examples/app/.profy.yml dev go run ./examples/app

Secret Backends

Backend Docs Demo
Vault opt/vault/README.md opt/vault/scripts/test.sh
Infisical opt/infisical/README.md opt/infisical/scripts/test.sh

Exit Codes

Code Meaning
0 Success
1 Runtime/config/setup error
2 Invalid usage

License

MIT

About

Minimal Go library for profile-based config loading from external sources with required key validation.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors