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:
vops config listSelect another profile for one process or shell:
VOPS_PROFILE=staging vops config listProfile 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:
export VOPS_TOKEN=...vops config set hetznerunset VOPS_TOKENvops config listScaleway 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.
| Provider | Variables |
|---|---|
| Hetzner | HETZNER_TOKEN |
| Scaleway | Provider SCALEWAY_* credential values |
| OVH | OpenStack OS_* values |
| Contabo | CONTABO_CLIENT_ID, CONTABO_CLIENT_SECRET, CONTABO_API_USER, CONTABO_API_PASSWORD |
| Cherry Servers | CHERRY_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:
vops keyring initvops keyring import-env --prunevops keyring statusDerivation 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:
vops keyring unlockvops keyring lockThe 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:
vops keyring drop-legacyThe 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.