Secrets in a Workspace
Storing Secrets
Devsy can store named secrets locally and inject them into your workspace's
lifecycle commands as environment variables. This lets you keep credentials out
of your devcontainer.json, shell history, and dotenv files.
Secret values are stored using the selected backend. With the default
auto backend, Devsy uses your operating system's keyring when available:
- macOS — Keychain
- Windows — Credential Manager
- Linux — Secret Service (libsecret / GNOME Keyring / KWallet)
When no keyring is available (or the file backend is selected), values are
kept in an age-encrypted file in the Devsy config directory instead. Either way,
only non-sensitive metadata (the secret's name and timestamps) is written in
plaintext. Secrets are scoped to the active context.
Creating a Secret
devsy secret set DB_PASSWORD
You will be prompted for the value without echoing it to the terminal. You can also supply the value non-interactively:
# From standard input (recommended for scripts)
printf '%s' "$MY_VALUE" | devsy secret set DB_PASSWORD --stdin
# From a file
devsy secret set TLS_KEY --from-file ./tls.key
Secret names may contain only letters, digits, and underscores, since they are used directly as environment-variable names.
Listing and Reading Secrets
devsy secret list
devsy secret get DB_PASSWORD
list never prints values. A secret whose value has been removed from the
keyring out-of-band is shown with the orphaned status.
Deleting a Secret
devsy secret delete DB_PASSWORD
Using Secrets in a Workspace
Per Workspace
Reference a stored secret by name when bringing up a workspace with --secret
(repeatable). By default the secret is injected as an environment variable into
lifecycle commands:
devsy workspace up https://github.com/example/repo --secret DB_PASSWORD
Each --secret accepts options as NAME[,type=env|mount][,target=X]:
type=env(default) sets an environment variable;targetoverrides the variable name.type=mountwrites the value to a file at/run/secrets/<target>on an in-memory filesystem, matching the Docker/Podman convention.targetdefaults toNAME. On Kubernetes this uses an in-memoryemptyDir; providers that cannot mount an in-memory filesystem rejecttype=mountwith a clear error, so usetype=envthere.
# Inject under a different environment-variable name
devsy workspace up ... --secret DB_PASSWORD,target=DATABASE_PASSWORD
# Mount as a file at /run/secrets/tls.key
devsy workspace up ... --secret TLS_KEY,type=mount,target=tls.key
For all Workspaces
Bind a secret to the active context so it is injected automatically on every
up, without repeating --secret:
devsy secret attach DB_PASSWORD
devsy secret detach DB_PASSWORD
Bound secret names are stored in your context configuration; deleting a context also deletes its secrets from the keyring.
If a requested or bound secret cannot be found when a workspace is created, the
up fails rather than silently continuing without it.
How Secrets Are Protected
Injected secret values are masked (***) in lifecycle-hook log output, so a
secret echoed by a postCreateCommand will not appear in the workspace logs.
Secret values are delivered to the workspace over Devsy's encrypted agent
tunnel, not embedded in any command line, so they are not exposed in process
listings on the host or inside the container.
Secrets delivered with type=mount are written to an in-memory tmpfs at
/run/secrets, so they are never persisted to a container image layer or to
disk.
Choosing a Storage Backend
Devsy supports two backends for secret values:
keyring— the OS keyring (Keychain / Credential Manager / libsecret).file— an age-encrypted file (secrets.enc) stored alongside the Devsy config.
By default the backend is auto: Devsy uses the keyring when one is available
and falls back to the encrypted file otherwise.
The file backend works with no configuration: Devsy generates and manages an
encryption key for you (stored in the OS keyring when available, otherwise in
secrets.key next to secrets.enc, mode 0600). This protects secrets from
accidental disclosure and casual inspection, but a key stored in secrets.key
offers no protection against someone who can read your Devsy config directory
(they have both the key and the ciphertext). For stronger at-rest protection —
for example against a stolen backup — set a passphrase (see below), which is
never written to disk.
Set a persistent preference per context with the SECRETS_BACKEND option:
devsy context set -o SECRETS_BACKEND=file
Allowed values are auto, keyring, and file. To override the preference for
a single command, set the DEVSY_SECRETS_BACKEND environment variable, which
takes precedence over the context option.
Headless and CI Environments
When the file backend is used (either by preference or because no OS keyring
is available, for example on headless Linux, containers, or CI), Devsy uses an
auto-generated key by default, so no setup is required. For at-rest protection
against a stolen backup or disk, set a passphrase — the encryption key is then
derived from it and never stored:
export DEVSY_SECRETS_PASSPHRASE="…"
devsy secret set DEPLOY_TOKEN --stdin < token.txt
The key source (auto-generated vs. passphrase) is recorded with your secrets. If you later change it — for example by setting a passphrase for secrets that were stored with an auto-generated key — Devsy reports a clear error rather than failing to decrypt. Restore the original setting, or re-create the secrets under the new one.
Managed Environment Variables
For non-sensitive configuration you can store managed environment variables with
devsy env. They share the same per-context store as secrets, but their values
are kept in plaintext in the Devsy config directory (no keyring, no encryption)
and are freely readable:
devsy env set LOG_LEVEL=debug
devsy env set REGION --value us-east-1
devsy env list
devsy env get LOG_LEVEL
devsy env delete LOG_LEVEL
Inject them into a workspace with --env (repeatable), optionally remapping the
variable name with NAME=TARGET:
devsy workspace up ... --env LOG_LEVEL --env REGION=AWS_REGION
Use devsy secret (not devsy env) for anything sensitive: secrets are stored
in the OS keyring or an encrypted file, masked in logs, and delivered over the
agent tunnel.