Install
openclaw skills install @jlacroix82/secrets-managerEncrypted local secret store for OpenClaw agents. AES-256-GCM authenticated encryption with per-secret random IVs, master key in restricted-permission .master-key file. Store, retrieve, rotate, and audit secrets. Safe command injection (writes to temp file by default; --inject-stdout requires --confirm-expose). Master key is recoverable from .master-key file; losing it makes stored secrets unrecoverable.
openclaw skills install @jlacroix82/secrets-managerEncrypted local secret store. AES-256-GCM authenticated encryption. Master key auto-generated on first store and stored in the skill's private storage directory with restricted permissions (owner-only).
Important: If you lose
.master-key, all stored secrets become unrecoverable. Back it up.
null from decrypt (no partial decryption)SECRETS_MASTER_KEY=<hex> env var--get --raw Prints Plaintext to stdoutThe secret value goes to stdout, which may be captured in:
Use only when piping to a private process:
node secrets-manager.js --get --raw api-key > /tmp/api-key.txt
# Restrict file permissions after writing
--inject Default: Safe (writes to temp file with restricted permissions)By default, --inject "command {{secret}}" substitutes and writes to a private temp file. The resolved command is NEVER printed to stdout unless you pass both flags:
--inject-stdout --confirm-expose "command {{secret}}"
The skill refuses to print the resolved command without --confirm-expose.
Rotated secrets keep the old encrypted value as retired. Rotate again to discard the archive. There is no --undo for archival.
Encrypted secrets and master key stored in the skill's private storage directory with restricted permissions (owner-only). Override via --dir <path> or SECRETS_DIR=<path>.
This skill requires the following capabilities:
| Permission | Scope | Reason |
|---|---|---|
fs.read | Private storage | Read encrypted secrets and master key |
fs.write | Private storage | Write encrypted secrets, master key, permission rules |
run-cli | CLI invocation | Invoke secrets-manager.js for store/get/rotate/audit operations |
elevated | File permissions | Set restricted permissions on secret files to ensure owner-only access |
Elevation is required only for restricted permission enforcement on files outside the user's home directory. Within $HOME, the skill uses standard file operations without elevation.
node skills/secrets-manager/secrets-manager.js --store openai-key sk-abc123
# Output: [secrets-manager] Stored: openai-key (masked: sk-****23)
node skills/secrets-manager/secrets-manager.js --get openai-key
# Output: [secrets-manager] openai-key: sk-****23
node skills/secrets-manager/secrets-manager.js --get --raw openai-key > /tmp/key.txt
# Output: sk-abc123 (captured to file)
node skills/secrets-manager/secrets-manager.js --list
node skills/secrets-manager/secrets-manager.js --delete old-key
node skills/secrets-manager/secrets-manager.js --rotate openai-key
# New random value generated, old encrypted value archived as retired
node skills/secrets-manager/secrets-manager.js --rotate --all
node skills/secrets-manager/secrets-manager.js --audit
node skills/secrets-manager/secrets-manager.js --audit --expired
node skills/secrets-manager/secrets-manager.js --audit --stale
node skills/secrets-manager/secrets-manager.js --inject "curl -H 'Authorization: Bearer {{openai-key}}' https://api.openai.com/v1/chat"
# Output: [secrets-manager] ✅ Injected 1 secret(s) into: /tmp/secrets-inject-12345-1234567890.sh
# [secrets-manager] Run with: sh /tmp/secrets-inject-12345-1234567890.sh
Then run the command (the secrets are in the temp file with restricted permissions):
sh /tmp/secrets-inject-12345-1234567890.sh
node skills/secrets-manager/secrets-manager.js --inject-stdout --confirm-expose "echo {{openai-key}}"
# Will print: [secrets-manager] ⚠️ Resolved command below contains 1 secret value(s) in plaintext:
# echo sk-abc123
The skill refuses to print the resolved command without --confirm-expose. This is to prevent accidental secret leaks to logs.
node skills/secrets-manager/secrets-manager.js --status
SECRETS_MASTER_KEY env var overrideretired (encrypted, recoverable until next rotate){{secret_name}} placeholders replaced in command strings--inject-stdout AND --confirm-exposeData stored in the skill's private storage directory:
Override storage location:
--dir /path/to/secrets
# or env var
SECRETS_DIR=/path/to/secrets node secrets-manager.js --status
Override master key:
SECRETS_MASTER_KEY=<64-hex-chars> node secrets-manager.js --get openai-key
When handling secrets:
--store <name> <value> writes AES-256-GCM ciphertext--get (not --get --raw) for display--inject writes to temp file, doesn't leak--audit during heartbeatsSECRETS_MASTER_KEY env var for ephemeral/CI environments--inject never prints secrets; --inject-stdout requires explicit confirmationRestricted file permissions ensure only the file owner can read secrets. This skill follows a least-privilege approach:
$HOME: Standard file permission changes are sufficient; no elevated access required.$HOME (e.g., shared or system directories): Elevation may be needed to set restrictive permissions. The skill requests elevation only for the specific permission operation, not for reading or writing secrets.All secret storage files are dynamically managed by the skill itself within a private data directory. These are encrypted storage locations with restricted permissions, not hardcoded credentials.
--get --raw or --inject-stdout --confirm-expose| Approach | Encryption | Setup | Audit | Rotation | Recovery |
|---|---|---|---|---|---|
| Environment vars | None | Medium | None | Manual | N/A |
| .env files | None | Low | None | Manual | N/A |
| Secrets Manager | AES-256-GCM | None | Auto | Auto | With .master-key |
| Vault service | Various | High | Auto | Auto | Yes |
Secrets Manager gives you real encryption + rotation + audit with zero external dependencies.