Skip to content

Configuration and credentials

vops stores operational state locally under ~/.config/vops/. Profiles isolate credentials, SSH keys, inventory and plans so a staging context cannot accidentally resolve the production profile’s secrets.

Profile selection

The default profile is used when no override is present:

Terminal window
vops config list

Select another profile for one process or shell:

Terminal window
VOPS_PROFILE=staging vops config list

Profile data lives under:

~/.config/vops/profiles/<profile>/

Do not point multiple concurrent users at the same writable profile directory.

Encrypted local configuration

For Hetzner, supply the token without putting its value in a command argument:

Terminal window
export VOPS_TOKEN=...
vops config set hetzner
unset VOPS_TOKEN
vops config list

Scaleway accepts VOPS_ACCESS_KEY and VOPS_SECRET_KEY, or the corresponding --access-key and --secret-key flags. OVH, Contabo and Cherry Servers use the environment-file route described below.

The encrypted local store refuses to replace an existing credential unless the user passes --force. Replacement has no implicit previous version, so verify the new credential before discarding the old one.

The legacy encrypted form uses AES-256-GCM but keeps its key in a neighboring file. It protects against casual plaintext disclosure, not an attacker who can read the complete profile directory.

Environment-file route

vops can also read provider variables from ~/.config/vops/profiles/<profile>/.env or the current repository’s .env. This route is plaintext and is the user’s responsibility to protect.

ProviderVariables
HetznerHETZNER_TOKEN
ScalewayProvider SCALEWAY_* credential values
OVHOpenStack OS_* values
ContaboCONTABO_CLIENT_ID, CONTABO_CLIENT_SECRET, CONTABO_API_USER, CONTABO_API_PASSWORD
Cherry ServersCHERRY_API_KEY, CHERRY_PROJECT_ID; CHERRY_IMAGE when provisioning requires a plan-specific image

Avoid entering a secret as a visible command argument when an interactive prompt or environment variable is available.

Seal the profile

The keyring migrates credentials into a vault whose key is derived from a passphrase:

Terminal window
vops keyring init
vops keyring import-env --prune
vops keyring status

Derivation uses scrypt and domain-separated keys. The passphrase-derived key is held only in memory by a small local process with a sliding lifetime.

Unlock and lock explicitly:

Terminal window
vops keyring unlock
vops keyring lock

The CLI prompts only when an operation actually needs a credential. A public provider query or local inventory read should not force a vault unlock.

For non-interactive use, VOPS_PASSPHRASE supplies the passphrase to the credential path. Treat it as a high-value process secret.

Complete the migration

keyring init and keyring import-env --prune retain recovery material. After the new vault has been verified:

Terminal window
vops keyring drop-legacy

The command refuses to drop the legacy material unless the sealed vault opens. This is the irreversible point of the migration.

SSH keys

New keys managed by vops live below the profile’s keys/ directory. Importing an existing private key is different: vops stores a reference to the original path and never copies the private file.

Only the public half is uploaded to a provider or authorized on a host.

Output redaction

Human logs and --json output must not contain provider tokens, registry tokens, application secrets, private key contents or reusable agent session tokens. The exception is a value the user explicitly asked to reveal, such as vops app credentials --show; handle that terminal output accordingly.