Variables
Define secrets, literals, and dynamic values as environment variables
Variables are the primary way to define configuration values that get exported as environment variables in your dev shell. They support plaintext values, direct secret references, and computed values.
Variable Types
| Type | Description | Resolved At |
|---|---|---|
| LITERAL | Plain text value (stored in value field) | Nix eval time |
ref+sops://...#/KEY | Direct reference to a SOPS file and YAML key | Runtime |
| EXEC / computed | Shell or Nix produced value | Runtime / eval time |
The variable scope is determined by the ID prefix. Secrets are best modeled as direct refs in value:
| ID Prefix | Type | Storage |
|---|---|---|
/var/* | Config (literal or direct secret ref) | value field in Nix config |
/secret/* | Legacy placeholder secret | Transitional only |
/computed/* | Computed | Derived at eval time |
Defining Variables
Variables are defined under stackpanel.variables with a path-style key:
stackpanel.variables = {
"/var/postgres-url" = {
value = "ref+sops://.stack/secrets/dev/web.sops.yaml#/postgres_url";
};
"/var/log-level" = {
value = "info";
};
"/computed/apps/web/port" = {
value = "3000";
};
};The path prefix is metadata for the variable itself. Secret location and encryption are determined by the ref+sops://...#/KEY target and .stack/secrets/.sops.yaml rules.
Managing Variables via CLI
# Set a literal value
stackpanel vars set DATABASE_URL --value "postgresql://localhost:5432/dev"
# Set an encrypted secret
stackpanel vars set API_KEY --value "sk-abc123" --secret --keys dev,prod
# Get a value (decrypts if needed)
stackpanel vars get API_KEY
# List all variables
stackpanel vars list
# Delete a variable
stackpanel vars delete API_KEYLITERAL Variables
The simplest type. The value is set directly in Nix config and baked into the shell at eval time:
"/dev/app-name" = {
key = "APP_NAME";
type = "LITERAL";
value = "myapp";
};Use LITERAL for values that are not sensitive and do not change between machines, such as app names, feature flags, and default URLs.
Direct SOPS References
Preferred secret usage is a direct SOPS ref. The value points at an encrypted file and YAML key.
"/var/stripe-secret-key" = {
value = "ref+sops://.stack/secrets/prod/payments.sops.yaml#/STRIPE_SECRET_KEY";
};At runtime, the value is resolved by decrypting the referenced SOPS file using the recipients configured in .stack/secrets/.sops.yaml.
EXEC Variables
Run a shell command to produce the value dynamically:
"/dev/git-commit" = {
key = "GIT_COMMIT";
type = "EXEC";
value = "git rev-parse --short HEAD";
};
"/dev/timestamp" = {
key = "BUILD_TIMESTAMP";
type = "EXEC";
value = "date -u +%Y-%m-%dT%H:%M:%SZ";
};The command runs at shell entry time, and the output becomes the variable value.
EXEC variables run on every shell entry. Keep the commands fast and side-effect-free. Avoid commands that make network calls or modify state.
Variable Resolution Order
When you enter the dev shell, variables are resolved in this order:
- LITERAL values are set immediately during Nix evaluation
- EXEC commands run and their output is captured
ref+sops://...#/KEYvalues are decrypted at runtime- Other vals references are resolved by the agent
If a variable cannot be resolved (for example, SOPS keys are unavailable or a vals reference fails), the agent logs a warning but continues. Your shell still starts with whatever variables could be resolved.
Per-User Overrides
Variables defined in config.local.nix (gitignored) override shared variables:
# .stack/config.local.nix
{
stackpanel.variables."/var/postgres-url".value = "ref+sops://.stack/secrets/local/web.sops.yaml#/postgres_url";
}This lets individual developers customize connection strings and other values without affecting the team.
Reference
- Options Reference Variables for the full variable schema
- Master Keys for recipient and decryption key management
- Environment Variables for other ways to set env vars