Secrets¶
Secrets Management¶
drun v2 provides secure, built-in secrets management for storing and retrieving sensitive data like API keys, passwords, and tokens.
Features¶
- Automatic Project Isolation: Secrets are automatically namespaced by project name from drun config
- Platform Integration: Uses native keychains (macOS Keychain, Windows Credential Manager, Linux Secret Service)
- Automatic Fallback: Seamlessly falls back to AES-256-GCM encrypted file storage when platform keychain is unavailable or has permission issues
- Interpolation Support: Access secrets directly in strings using
{secret('key')} - Namespace Override: Optionally specify custom namespaces for shared secrets
Secret Operations¶
Setting Secrets¶
# Basic usage (automatic project namespace)
secret set "api_key" to "secret123"
secret set "db_password" to "super_secure_pass"
# With custom namespace
secret set "shared_token" to "token456" in namespace "team-shared"
# From environment variable
secret set "github_token" to ${GITHUB_TOKEN}
Retrieving Secrets¶
# In interpolation (recommended)
info "Connecting with key: {secret('api_key')}"
run "curl -H 'Authorization: Bearer {secret('api_key')}' https://api.example.com"
# With default value
info "Webhook: {secret('webhook_url', 'https://default.webhook.com')}"
# From custom namespace
info "Token: {secret('shared_token', '', 'team-shared')}"
Checking Secret Existence¶
# Check if secret exists
secret exists "api_key"
# With namespace
secret exists "shared_token" in namespace "team-shared"
Listing Secrets¶
# List all secrets in current project namespace
secret list
# List from custom namespace
secret list from namespace "team-shared"
Deleting Secrets¶
# Delete secret
secret delete "api_key"
# Delete from custom namespace
secret delete "shared_token" from namespace "team-shared"
Complete Example¶
version: 2.0
project "api-deployment" version "1.0":
task "configure":
info "Setting up secrets..."
secret set "api_key" to prompt "Enter API key:" masked
secret set "db_password" to prompt "Enter database password:" masked
success "Secrets configured"
task "deploy":
depends on "configure"
# Check if secrets exist
secret exists "api_key"
secret exists "db_password"
# Use secrets in deployment
run """
kubectl create secret generic app-secrets \
--from-literal=api-key={secret('api_key')} \
--from-literal=db-password={secret('db_password')}
"""
success "Deployed with secrets"
task "cleanup":
info "Removing secrets..."
secret delete "api_key"
secret delete "db_password"
success "Secrets removed"
Security Features¶
- Per-Project Isolation: Secrets are automatically scoped to project names, preventing accidental access
- Platform Keychains: Integrates with OS-native secure storage when available
- Encrypted Storage: AES-256-GCM encryption with PBKDF2 key derivation for fallback storage
- Memory Safety: Secure clearing of sensitive data from memory
- Input Validation: Keys, namespaces, and values are validated before storage
secret() Function¶
The secret() builtin function allows seamless secret access in interpolations:
Syntax:
{secret('key')} # Get from current project namespace
{secret('key', 'default')} # Get with default value
{secret('key', '', 'namespace')} # Get from specific namespace
Examples:
# Simple usage
info "API Key: {secret('api_key')}"
# With default for optional secrets
run "webhook_url={secret('webhook', 'https://default.com')}"
# From shared namespace
run "deploy --token {secret('deploy_token', '', 'ci-secrets')}"
# In complex strings
run "curl -u admin:{secret('password')} https://api.example.com"
CLI Secret Management¶
In addition to managing secrets within tasks, drun provides a standalone cmd:secret command for managing secrets directly from the command line. This is useful for:
- Setting up secrets before running tasks
- Managing secrets across multiple projects
- Inspecting and listing stored secrets
- Team collaboration via shared namespaces
Command Syntax¶
# Add secrets
xdrun cmd:secret add <key> [value] [flags]
# List secrets
xdrun cmd:secret list [flags]
xdrun cmd:secret list-all [flags]
# Remove secrets
xdrun cmd:secret remove <key> [flags]
Namespace Flags¶
--project,-p: Use project scope (auto-detects project name from drun config)--global,-g: Use global scope (shared across all projects)--namespace <name>,-n <name>: Use custom namespace
Automatic Workspace Detection:
When you run cmd:secret commands without specifying a namespace, drun automatically detects your project name from the current workspace's .drun/spec.drun or configured drun file. This provides automatic project isolation without manual namespace management.
Examples¶
Add Secrets:
# Add to default namespace (auto-detects project if in workspace, prompts for value)
xdrun cmd:secret add api_key
# Add with masked input (secure)
xdrun cmd:secret add api_key --masked
# Add to global scope
xdrun cmd:secret add --global shared_token "team-token-123"
# Add to project scope (auto-detects project name from drun config)
xdrun cmd:secret add --project db_password "secret-pass"
# Add to custom namespace
xdrun cmd:secret add --namespace team-alpha team_key "alpha-secret"
List Secrets:
# List in default namespace (auto-detects project if in workspace)
xdrun cmd:secret list
# List in global scope
xdrun cmd:secret list --global
# List in project scope (auto-detects project name)
xdrun cmd:secret list --project
# List all secrets across all namespaces
xdrun cmd:secret list-all
# Show secret values (use with caution)
xdrun cmd:secret list --show-values
Remove Secrets:
# Remove from default namespace (auto-detects project if in workspace)
xdrun cmd:secret remove api_key
# Remove from global scope
xdrun cmd:secret rm --global shared_token # 'rm' is an alias
# Remove from project scope (auto-detects project name)
xdrun cmd:secret delete --project db_password # 'delete' is an alias
Using CLI-Managed Secrets in Tasks¶
Secrets managed via CLI are accessible in tasks using the secret() function:
version: 2.0
project "my-app" version "1.0":
task "deploy":
# Access project-scoped secret
info "Deploying with key: {secret('api_key')}"
# Access global secret
info "Team token: {secret('shared_token', '', 'global')}"
# Access custom namespace secret
info "Alpha key: {secret('team_key', '', 'team-alpha')}"
Security Notes¶
- Masked Input: Use
--maskedflag for secure password entry - Command History: Avoid passing secrets directly on command line
- Show Values: Only use
--show-valuesin secure environments - Platform Storage: Secrets stored in native keychains (macOS Keychain, Windows Credential Manager, Linux Secret Service)
Best Practices¶
- Use Project Namespaces: Let drun automatically scope secrets to projects
- Set Defaults: Provide sensible defaults for optional secrets
- Clean Up: Delete secrets after use in temporary workflows
- Audit Access: Use
secret listto review stored secrets - Avoid Hardcoding: Never commit secrets to version control
Project AI Skill Installation¶
In addition to executing tasks, xdrun can install project-level AI guidance files for repositories that use drun. This helps assistants such as Codex, Claude Code, Cursor, and Copilot understand the expected drun/xdrun workflow.
Command Syntax¶
xdrun cmd:skill install drun-basics [--target <directory>] [--force]
Installed Files¶
The drun-basics bundle installs a shared guide plus agent-specific entrypoints:
.drun/ai/drun-basics.md.codex/skills/drun-basics/SKILL.md.cursor/rules/drun-basics.mdcAGENTS.mdCLAUDE.md.github/copilot-instructions.md
Behavior¶
- Managed blocks: For mergeable markdown entrypoints such as
AGENTS.md,CLAUDE.md, and.github/copilot-instructions.md, drun inserts or updates a named managed block instead of replacing the whole file. - Default mode: Creates missing standalone guidance files and skips existing standalone generated files.
- Force mode:
--forceoverwrites existing standalone generated files. - Target directory:
--targetinstalls the bundle into another repository root.
Example¶
# Install guidance into the current repository
xdrun cmd:skill install drun-basics
# Install into a sibling repository and overwrite existing generated files
xdrun cmd:skill install basics --target ../my-service --force