13 KiB
gman - Universal Credential Manager
gman is a command-line tool designed to streamline credential and secret management for your scripts, automations, and
applications. It provides a single, secure interface to store, retrieve, and inject secrets, eliminating the need to
juggle different methods like configuration files or environment variables for each tool.
Overview
The core philosophy of gman is to act as a universal wrapper for any command that requires credentials. You can store
your secrets—like API tokens, passwords, or certificates—in an encrypted vault backed by various providers. Then, you
can either fetch them directly or, more powerfully, execute commands through gman, which securely injects the
necessary secrets as environment variables or command-line flags.
Features
- Secure, Encrypted Storage: All secrets are stored in an encrypted state using strong cryptography.
- Pluggable Providers: Supports different backends for secret storage. The default is a local file-based system.
- Git Synchronization: The
localprovider can synchronize your encrypted secrets across multiple systems using a private Git repository. - Seamless Command Wrapping: Run any command through
gmanto automatically provide it with the secrets it needs (e.g.,gman aws s3 ls). - Customizable Run Profiles: Define how secrets are passed to commands, either as environment variables (default) or as specific command-line flags.
- Secret Name Standardization: Enforces
snake_casefor all secret names to ensure consistency. - Direct Secret Access: Retrieve plaintext secrets directly when needed (e.g.,
gman get my_api_key). - Dry Run Mode: Preview the command and the secrets that will be injected without actually executing it using the
--dry-runflag.
Example Use Cases
Create/Get/Delete Secrets Securely As You Need From Any Configured Provider
# Add a secret to the 'local' provider
echo "someApiKey" | gman add my_api_key
# Retrieve a secret from the 'aws_secrets_manager' provider
gman get -p aws_secrets_manager db_password
# Delete a secret from the 'local' provider
gman delete my_api_key
Automatically Inject Secrets Into Any Command
# Can inject secrets as environment variables into the 'aws' CLI command
gman aws sts get-caller-identity
# Inject secrets into 'docker run' command via '-e' flags
gman docker run --rm --entrypoint env busybox | grep -i 'token'
# Inject secrets into configuration files automatically for the 'managarr' application
gman managarr
Installation
Cargo
If you have Cargo installed, then you can install gman from Crates.io:
cargo install gman
# If you encounter issues installing, try installing with '--locked'
cargo install --locked gman
Configuration
gman is configured via a YAML file located somewhere different for each OS:
Linux
$HOME/.config/gman/config.yml
Mac
$HOME/Library/Application Support/gman/config.yml
Windows
%APPDATA%/Roaming/gman/config.yml
Default Configuration
---
provider: local
password_file: ~/.gman_password
# Optional Git sync settings for the 'local' provider
git_branch: null # Defaults to 'main'
git_remote_url: null # Required for Git sync
git_user_name: null # Defaults to global git config user.name
git_user_email: null # Defaults to global git config user.email
git_executable: null # Defaults to 'git' in PATH
run_configs: null # List of run configurations (profiles)
Providers
gman supports multiple providers for secret storage. The default provider is local, which stores secrets in an
encrypted file on your filesystem. The following table shows the available and planned providers:
Key:
| Symbol | Status |
|---|---|
| ✅ | Supported |
| 🕒 | Planned |
| 🚫 | Won't Add |
| Provider Name | Status | Configuration Docs | Comments |
|---|---|---|---|
local |
✅ | Local | |
aws_secrets_manager |
🕒 | ||
aws_ssm_parameter_store |
🕒 | ||
hashicorp_vault |
🕒 | ||
azure_key_vault |
🕒 | ||
gcp_secret_manager |
🕒 | ||
1password |
🕒 | ||
bitwarden |
🕒 | ||
dashlane |
🕒 | Waiting for CLI support for adding secrets | |
lastpass |
🕒 |
Provider: local
The default local provider stores an encrypted vault file on your filesystem. Any time you attempt to access the local
vault (e.g., adding, retrieving, or deleting secrets), gman will prompt you for the password you used to encrypt the
applicable secrets.
Similar to Ansible Vault, gman lets you store the password in a file for convenience. This is done via the
password_file configuration option. If you choose to use a password file, ensure that it is secured with appropriate
file permissions (e.g., chmod 600 ~/.gman_password). The default file for the password file is ~/.gman_password.
For use across multiple systems, gman can sync with a remote Git repository.
Important Notes for Git Sync:
- You must create the remote repository on your Git provider (e.g., GitHub) before attempting to sync.
- The
git_remote_urlmust be in SSH or HTTPS format (e.g.,git@github.com:your-user/your-repo.git).
Example local provider config for Git sync:
provider: local
git_branch: main
git_remote_url: "git@github.com:my-user/gman-secrets.git"
git_user_name: "Your Name"
git_user_email: "your.email@example.com"
Run Configurations
Run configurations (or "profiles") tell gman how to inject secrets into a command. Three modes of secret injection are
supported:
When you wrap a command with gman and don't specify a specific run configuration via --profile, gman will look for
a profile with a name matching <command>. If found, it injects the specified secrets. If no profile is found, gman
will error out and report that it could not find the run config with that name.
You can manually specify which run configuration to use with the --profile flag. Again, if no profile is found with
that name, gman will error out.
Important: Secret names are always injected in UPPER_SNAKE_CASE format.
Environment Variable Secret Injection
By default, secrets are injected as environment variables. The two required fields are name and secrets.
Example: A profile for the aws CLI.
run_configs:
- name: aws
secrets:
- aws_access_key_id
- aws_secret_access_key
When you run gman aws ..., gman will fetch these two secrets and expose them as environment variables to the aws
process.
Inject Secrets via Command-Line Flags
For applications that don't read environment variables, you can configure gman to pass secrets as command-line flags.
This requires three additional fields: flag, flag_position, and arg_format.
flag: The flag to use (e.g.,-e).flag_position: An integer indicating where to insert the flag in the command's arguments.1is immediately after the command name.arg_format: A string that defines how the secret is formatted. It must contain the placeholders{{key}}and{{value}}.
Example: A profile for docker run that uses the -e flag.
run_configs:
- name: docker
secrets:
- my_app_api_key
- my_app_db_password
flag: -e
flag_position: 2 # In 'docker run ...', the flag comes after 'run', so position 2.
arg_format: "{{key}}={{value}}"
When you run gman docker run my-image, gman will execute a command similar to:
docker run -e MY_APP_API_KEY=... -e MY_APP_DB_PASSWORD=... my-image
Inject Secrets into Files
For applications that require secrets to be provided via files, you can configure gman to automatically populate
specified files with the secret values before executing the command, run the command, and then restore the original
content regardless of command completion status.
This just requires one additional field:
files: A list of absolute file paths where the secret values should be written.
Example: An implicit profile for managarr that injects the specified
secrets into the corresponding configuration file. More than one file can be specified, and if gman can't find any
specified secrets, it will leave the file unchanged.
run_configs:
- name: managarr
secrets:
- radarr_api_key
- sonarr_api_key # Remember that secret names are always converted to UPPER_SNAKE_CASE
files:
- /home/user/.config/managarr/config.yml
And this is what my managarr configuration file looks like:
radarr:
- name: Radarr
host: 192.168.0.105
port: 7878
api_token: '{{RADARR_API_KEY}}' # This will be replaced by gman with the actual secret value
sonarr:
- name: Sonarr
host: 192.168.0.105
port: 8989
api_token: '{{sonarr_api_key}}' # gman is case-insensitive, so this will also be replaced correctly
Then, all you need to do to run managarr with the secrets injected is:
gman managarr
Detailed Usage
Storing and Managing Secrets
All secret names are automatically converted to snake_case.
-
Add a secret:
# The value is read from standard input echo "your-secret-value" | gman add my_api_keyor don't provide a value to add the secret interactively:
gman add my_api_key -
Retrieve a secret:
gman get my_api_key -
Update a secret:
echo "new-secret-value" | gman update my_api_keyor don't provide a value to update the secret interactively:
gman add my_api_key -
List all secret names:
gman list -
Delete a secret:
gman delete my_api_key -
Synchronize with remote secret storage (specific to the configured
provider):gman sync
Running Commands
-
Using a default profile:
# If an 'aws' profile exists, secrets are injected. gman aws sts get-caller-identity -
Specifying a profile:
# Manually specify which profile to use with --profile gman --profile my-docker-profile docker run my-app -
Dry Run:
# See what command would be executed without running it. gman --dry-run aws s3 ls # Output will show: aws -e AWS_ACCESS_KEY_ID=***** ... s3 ls