{"id":"701319f0-78ab-4f73-88b0-413b2247258f","entityType":"agent","slug":"clawhub-jlacroix82-secrets-manager","name":"secrets-manager","canonicalUrl":"https://www.xpersona.co/agent/clawhub-jlacroix82-secrets-manager","canonicalPath":"/agent/clawhub-jlacroix82-secrets-manager","generatedAt":"2026-10-10T10:43:37.946Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T06:53:23.949Z","emptyReason":null},"description":"Encrypted 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.","descriptionLabel":"Source description","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.6K downloads reported by the source. Last updated 10/10/2026.","installCommand":"clawhub skill install s175p518b8g47fx6r9zyvs95ks876t4t:secrets-manager","sourceUrl":"https://clawhub.ai/jlacroix82/secrets-manager","homepage":"https://clawhub.ai/jlacroix82/skills/secrets-manager","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/jlacroix82/secrets-manager","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/jlacroix82/skills/secrets-manager","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":64,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"secrets-manager technical dossier on Xpersona with agent coverage, OPENCLEW support, and live trust metadata."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-10T06:53:23.949Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T06:53:23.949Z","emptyReason":null},"stars":null,"forks":null,"downloads":1608,"packageName":null,"latestVersion":"1.1.19","tractionLabel":"1.6K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T06:53:23.949Z","emptyReason":null},"lastUpdatedAt":"2026-10-10T06:53:23.949Z","lastCrawledAt":"2026-10-10T06:53:23.949Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-11T06:53:23.949Z","lastVerifiedAt":null,"highlights":[{"version":"1.1.19","createdAt":"2026-09-13T12:23:12.890Z","changelog":"**Skill 1.1.19 adds safe command injection and clarifies permission, storage, and leak prevention.** - New `--inject` mode: inject secrets into commands via temp file with restricted permissions (owner-only); blocks leaking to stdout by default. - To print resolved commands with secrets to stdout, user must provide both `--inject-stdout` and `--confirm-expose` for explicit confirmation. - Permissions updated: now claims `fs`, `env`, `exec`, `shell`, `elevated` to enforce strict storage protections. - Documentation and warnings expanded in README and SKILL.md, including main security exposures, rotation/archive rules, and usage guidance. - Storage, audit, and rotation features unchanged; injection and leak-prevention are strengthened. - Changelog and outdated docs files removed; new vetting report added.","fileCount":12,"zipByteSize":22646},{"version":"1.1.18","createdAt":"2026-08-15T20:11:26.319Z","changelog":"## secrets-manager v1.1.18 - Breaking: `--get --raw` now requires explicit `--confirm-expose` flag to print plaintext secret values, preventing accidental exposure. - Security: Stronger warnings and documentation for plaintext exposure risks; updated all usage examples for safer piping practices. - Docs: Clarified that the skill has no internal access-control system; removed inaccurate mention of permissions.json. - Cleanup: Removed unused/obsolete skill-card.md file. - General: Improved in-line documentation and updated usage sections for clarity.","fileCount":12,"zipByteSize":19617},{"version":"1.1.17","createdAt":"2026-08-04T17:09:41.570Z","changelog":"- Minor update and metadata cleanup. - Removed obsolete skill-card.md file. - Updated clawhub.yaml and documentation formatting. - No changes to core functionality or interfaces.","fileCount":12,"zipByteSize":19070},{"version":"1.1.16","createdAt":"2026-08-04T16:44:32.233Z","changelog":"- Removed the permissions subsystem; there is now no per-secret access-control layer. - Updated documentation to reflect that all stored secrets are readable by the running agent/process, and isolation is enforced only by file permissions. - Removed references to `permissions.json` and per-secret authorization from configuration docs. - Deleted unused or outdated documentation file (`skill-card.md`).","fileCount":12,"zipByteSize":18832},{"version":"1.1.15","createdAt":"2026-08-04T15:22:20.261Z","changelog":"- Updated internal documentation and tests. - Removed the unused skill-card.md file. - No user-visible functional changes.","fileCount":12,"zipByteSize":17801},{"version":"1.1.14","createdAt":"2026-08-03T11:25:04.345Z","changelog":"**secrets-manager v1.1.14 — Pure encrypted store, command injection split out** - Removed all command/script injection features from this skill (no more temp file/script generation, no `--inject` or `--inject-stdout` support). - This skill now only provides: encrypt+store, retrieve (masked/raw), list, rotate, audit, delete secrets — never writes plaintext to disk or generates commands. - Use the new/separate `secrets-inject` skill for securely injecting secrets into shell commands. - Updated documentation and description to reflect the new boundaries and remove all injection-related instructions. - Reduced privilege: no longer generates executable scripts, further minimizing risk of accidental secret exposure. - `skill-card.md` file removed (was redundant).","fileCount":12,"zipByteSize":19070},{"version":"1.1.13","createdAt":"2026-08-03T02:49:09.344Z","changelog":"- Skill description in SKILL.md updated to include all supported modes, including new --cleanup-tmp and expanded audit/injection details. - Permissions block added to SKILL.md to specify filesystem, environment, and crypto access. - Outdated skill-card.md file removed.","fileCount":12,"zipByteSize":21626},{"version":"1.1.12","createdAt":"2026-08-02T20:07:33.943Z","changelog":"**Major update with new features, enhanced security, and expanded documentation:** - Added command injection with safe and explicit exposure modes (temp file by default, stdout with confirmation). - Improved audit and rotation system: track rotation deadlines, rotation status, and secret age; support for auditing for expiration and staleness. - Updated storage and configuration options: secrets and keys stored under `memory/secrets/`, with override via `--dir` or environment. - Expanded documentation: detailed usage, security notes, feature set, and comparison table. - New and reorganized test files for more comprehensive testing. - Now requires explicit confirmation for exposing secrets on stdout (`--inject-stdout --confirm-expose`).","fileCount":12,"zipByteSize":21274}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s175p518b8g47fx6r9zyvs95ks876t4t:secrets-manager","setupComplexity":"low","setupSteps":["Install using `clawhub skill install s175p518b8g47fx6r9zyvs95ks876t4t:secrets-manager` in an isolated environment before connecting it to live workloads.","No published capability contract is available yet, so validate auth and request/response behavior manually.","Review the upstream CLAWHUB listing at https://clawhub.ai/jlacroix82/secrets-manager before using production credentials."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-jlacroix82-secrets-manager/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-jlacroix82-secrets-manager/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-jlacroix82-secrets-manager/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-jlacroix82-secrets-manager/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-jlacroix82-secrets-manager/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-jlacroix82-secrets-manager/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-10T10:43:37.941Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-jlacroix82-secrets-manager/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-jlacroix82-secrets-manager/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-jlacroix82-secrets-manager/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-jlacroix82-secrets-manager/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T06:53:23.949Z","emptyReason":null},"readme":"Skill: secrets-manager\n\nOwner: jlacroix82\n\nSummary: Encrypted 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.\n\nTags: latest:1.1.15, security-fix:1.1.0\n\nVersion history:\n\nv1.1.19 | 2026-09-13T12:23:12.890Z | auto\n\n**Skill 1.1.19 adds safe command injection and clarifies permission, storage, and leak prevention.**\n\n- New `--inject` mode: inject secrets into commands via temp file with restricted permissions (owner-only); blocks leaking to stdout by default.\n- To print resolved commands with secrets to stdout, user must provide both `--inject-stdout` and `--confirm-expose` for explicit confirmation.\n- Permissions updated: now claims `fs`, `env`, `exec`, `shell`, `elevated` to enforce strict storage protections.\n- Documentation and warnings expanded in README and SKILL.md, including main security exposures, rotation/archive rules, and usage guidance.\n- Storage, audit, and rotation features unchanged; injection and leak-prevention are strengthened.\n- Changelog and outdated docs files removed; new vetting report added.\n\nv1.1.18 | 2026-08-15T20:11:26.319Z | auto\n\n## secrets-manager v1.1.18\n\n- Breaking: `--get --raw` now requires explicit `--confirm-expose` flag to print plaintext secret values, preventing accidental exposure.\n- Security: Stronger warnings and documentation for plaintext exposure risks; updated all usage examples for safer piping practices.\n- Docs: Clarified that the skill has no internal access-control system; removed inaccurate mention of permissions.json.\n- Cleanup: Removed unused/obsolete skill-card.md file.\n- General: Improved in-line documentation and updated usage sections for clarity.\n\nv1.1.17 | 2026-08-04T17:09:41.570Z | auto\n\n- Minor update and metadata cleanup.\n- Removed obsolete skill-card.md file.\n- Updated clawhub.yaml and documentation formatting.\n- No changes to core functionality or interfaces.\n\nv1.1.16 | 2026-08-04T16:44:32.233Z | auto\n\n- Removed the permissions subsystem; there is now no per-secret access-control layer.\n- Updated documentation to reflect that all stored secrets are readable by the running agent/process, and isolation is enforced only by file permissions.\n- Removed references to `permissions.json` and per-secret authorization from configuration docs.\n- Deleted unused or outdated documentation file (`skill-card.md`).\n\nv1.1.15 | 2026-08-04T15:22:20.261Z | auto\n\n- Updated internal documentation and tests.\n- Removed the unused skill-card.md file.\n- No user-visible functional changes.\n\nv1.1.14 | 2026-08-03T11:25:04.345Z | auto\n\n**secrets-manager v1.1.14 — Pure encrypted store, command injection split out**\n\n- Removed all command/script injection features from this skill (no more temp file/script generation, no `--inject` or `--inject-stdout` support).\n- This skill now only provides: encrypt+store, retrieve (masked/raw), list, rotate, audit, delete secrets — never writes plaintext to disk or generates commands.\n- Use the new/separate `secrets-inject` skill for securely injecting secrets into shell commands.\n- Updated documentation and description to reflect the new boundaries and remove all injection-related instructions.\n- Reduced privilege: no longer generates executable scripts, further minimizing risk of accidental secret exposure.\n- `skill-card.md` file removed (was redundant).\n\nv1.1.13 | 2026-08-03T02:49:09.344Z | auto\n\n- Skill description in SKILL.md updated to include all supported modes, including new --cleanup-tmp and expanded audit/injection details.\n- Permissions block added to SKILL.md to specify filesystem, environment, and crypto access.\n- Outdated skill-card.md file removed.\n\nv1.1.12 | 2026-08-02T20:07:33.943Z | auto\n\n**Major update with new features, enhanced security, and expanded documentation:**\n\n- Added command injection with safe and explicit exposure modes (temp file by default, stdout with confirmation).\n- Improved audit and rotation system: track rotation deadlines, rotation status, and secret age; support for auditing for expiration and staleness.\n- Updated storage and configuration options: secrets and keys stored under `memory/secrets/`, with override via `--dir` or environment.\n- Expanded documentation: detailed usage, security notes, feature set, and comparison table.\n- New and reorganized test files for more comprehensive testing.\n- Now requires explicit confirmation for exposing secrets on stdout (`--inject-stdout --confirm-expose`).\n\nv1.1.11 | 2026-08-02T19:56:16.388Z | auto\n\n- Ported skill to Hermes: now stores secrets in `~/.hermes/secrets/` and uses `HERMES_SECRETS_MASTER_KEY`/`HERMES_SECRETS_DIR` env vars.\n- Simplified documentation, focusing on direct set/get/list/delete/rotate/audit usage for secrets.\n- Clarified scope: only for skill/workflow secrets (not Hermes provider/system auth).\n- Enforced security defaults: masked output, atomic file writes, strict permissions (0600), never logs secrets.\n- Removed redundant files and legacy OpenClaw-specific instructions.\n\nv1.1.10 | 2026-08-02T16:51:27.702Z | auto\n\n- Removed the skill-card.md file, consolidating documentation into SKILL.md.\n- Updated skill manifest in clawhub.yaml.\n- Minor changes to code and/or configuration (secrets-manager.js, clawhub.yaml) with no user-facing behavioral change documented.\n\nv1.1.9 | 2026-07-23T02:01:03.648Z | user\n\nReal AES-256-GCM encryption (replaces base64 obfuscation). Auto-generated master key in .master-key (chmod 0600), per-secret random IVs, auth tag tamper detection. Safe --inject default: writes resolved command to chmod 0600 temp file (no secret leak to stdout). --inject-stdout requires explicit --confirm-expose. Module exports added for testing. All 47 self-tests passing. SKILL.md and README.md now accurately describe encryption behavior. Added capabilities/permissions metadata to clawhub.yaml.\n\nv1.1.8 | 2026-07-22T17:48:56.673Z | auto\n\n- Removed an unused or obsolete test file: test/test-secrets-simple.js\n- Minor adjustments made to configuration (clawhub.yaml) with no impact on user-facing functionality\n- No changes to features, API, or workflow—functionality remains the same\n\nv1.1.7 | 2026-07-22T16:55:42.946Z | auto\n\nsecrets-manager v1.1.7\n\n- Documentation updated to include a new security remediation note.\n- No changes to functionality or usage.\n\nv1.1.6 | 2026-07-22T16:44:34.649Z | user\n\nSecurity fixes + audit remediation\n\nv1.1.5 | 2026-07-22T16:41:39.882Z | user\n\nSecurity: obfuscate not encrypt, remove fake undo, redact stdout\n\nv1.1.4 | 2026-07-22T16:38:35.326Z | user\n\nSecurity fixes: renamed encrypt→obfuscate, removed fake undo, redacted stdout\n\nv1.1.3 | 2026-07-22T16:26:12.531Z | user\n\nSecurity fix: renamed encrypt→obfuscate, removed fake --undo flag, redacted raw secrets from stdout\n\nv1.1.2 | 2026-07-22T16:24:50.185Z | user\n\nSecurity improvements: clearer data handling warnings, updated descriptions to match behavior. Version bump for audit re-scan.\n\nv1.1.1 | 2026-07-21T18:51:37.778Z | auto\n\n- Refined security documentation: now clarifies secrets use XOR+base64 for obfuscation (not AES-256-GCM), with updated risk and threat model.\n- Updated warnings about plaintext master key storage and clarified audit/rotation protocols.\n- Revised command usage examples, emphasizing risks of `--raw`/`--inject` modes and the importance of periodic audits.\n- Improved documentation layout, focusing on transparency and best-practice recommendations for agent users.\n- Removed redundant or outdated content and files, including the old skill-card.\n\nv1.1.0 | 2026-07-20T01:55:42.979Z | user\n\nAES-256-GCM encryption overhaul: replaced base64 with real crypto, master key separation, stderr-only diagnostics, GCM tamper detection. 48 tests passing.\n\nv1.0.0 | 2026-07-18T21:40:58.454Z | user\n\nInitial release: 29/29 self-tests, AES-256-GCM encryption, key management (set/get/delete/list), secret injection into strings, update/overwrite, bulk operations. Zero external dependencies. Rebuilt from scratch after file corruption.\n\nArchive index:\n\nArchive v1.1.19: 12 files, 22646 bytes\n\nFiles: clawhub.yaml (2043b), README.md (7445b), secrets-manager.js (26023b), skill-card.md (2590b), SKILL.md (10505b), test-final.js (2802b), test.txt (8b), test/run-tests.js (2044b), test/test-secrets.js (2496b), tests/run-self-tests.js (11102b), VET-REPORT.md (613b), _meta.json (135b)\n\nFile v1.1.19:SKILL.md\n\n---\nname: secrets-manager\nversion: 1.1.19\ndescription: Encrypted 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.\npermissions: [\"fs\", \"env\", \"exec\", \"shell\", \"elevated\"]\n---\n\n# Secrets Manager 🔐\n\n**Encrypted 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).\n\n> **Important**: If you lose `.master-key`, all stored secrets become unrecoverable. Back it up.\n\n## ⚠️ Important Warnings\n\n### Encryption: AES-256-GCM (Authenticated)\n- 256-bit master key, per-secret 96-bit random IV, 128-bit GCM auth tag\n- Tampered ciphertext returns `null` from decrypt (no partial decryption)\n- Master key stored in the skill's private storage directory with restricted permissions (owner-only)\n- Override via `SECRETS_MASTER_KEY=<hex>` env var\n- Losing the master key = all secrets unrecoverable\n\n### `--get --raw` Prints Plaintext to stdout\nThe secret value goes to stdout, which may be captured in:\n- Shell history / terminal scrollback\n- Process logs / journald / syslog\n- CI/CD pipeline output\n- Agent transcripts / OpenClaw session history\n\nUse only when piping to a private process:\n```bash\nnode secrets-manager.js --get --raw api-key > /tmp/api-key.txt\n# Restrict file permissions after writing\n```\n\n### `--inject` Default: Safe (writes to temp file with restricted permissions)\nBy 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:\n```bash\n--inject-stdout --confirm-expose \"command {{secret}}\"\n```\nThe skill refuses to print the resolved command without `--confirm-expose`.\n\n### Rotation: Old Values Are Archived\nRotated secrets keep the old encrypted value as `retired`. Rotate again to discard the archive. There is no `--undo` for archival.\n\n### Storage Location\nEncrypted 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>`.\n\n## Permissions\n\nThis skill requires the following capabilities:\n\n| Permission | Scope | Reason |\n|---|---|---|\n| `fs.read` | Private storage | Read encrypted secrets and master key |\n| `fs.write` | Private storage | Write encrypted secrets, master key, permission rules |\n| `run-cli` | CLI invocation | Invoke `secrets-manager.js` for store/get/rotate/audit operations |\n| `elevated` | File permissions | Set restricted permissions on secret files to ensure owner-only access |\n\nElevation 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.\n\n## Quick Start\n\n### Store a secret\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --store openai-key sk-abc123\n# Output: [secrets-manager] Stored: openai-key (masked: sk-****23)\n```\n\n### Get a secret (masked by default)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --get openai-key\n# Output: [secrets-manager] openai-key: sk-****23\n```\n\n### Get raw value (when needed for injection)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --get --raw openai-key > /tmp/key.txt\n# Output: sk-abc123 (captured to file)\n```\n\n### List all secrets (names + metadata, NOT values)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --list\n```\n\n### Delete a secret\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --delete old-key\n```\n\n### Rotate a secret\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --rotate openai-key\n# New random value generated, old encrypted value archived as retired\n```\n\n### Rotate all secrets\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --rotate --all\n```\n\n### Audit for security issues\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --audit\nnode skills/secrets-manager/secrets-manager.js --audit --expired\nnode skills/secrets-manager/secrets-manager.js --audit --stale\n```\n\n### Inject secrets into a command (safe default)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --inject \"curl -H 'Authorization: Bearer {{openai-key}}' https://api.openai.com/v1/chat\"\n# Output: [secrets-manager] ✅ Injected 1 secret(s) into: /tmp/secrets-inject-12345-1234567890.sh\n#         [secrets-manager]    Run with: sh /tmp/secrets-inject-12345-1234567890.sh\n```\n\n**Then run the command** (the secrets are in the temp file with restricted permissions):\n```bash\nsh /tmp/secrets-inject-12345-1234567890.sh\n```\n\n### Inject to stdout (DANGEROUS — requires explicit confirmation)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --inject-stdout --confirm-expose \"echo {{openai-key}}\"\n# Will print: [secrets-manager] ⚠️ Resolved command below contains 1 secret value(s) in plaintext:\n#              echo sk-abc123\n```\n\nThe skill **refuses** to print the resolved command without `--confirm-expose`. This is to prevent accidental secret leaks to logs.\n\n### Status overview\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --status\n```\n\n## Features\n\n### Encryption\n- **AES-256-GCM** authenticated encryption\n- 256-bit master key (auto-generated on first store)\n- 96-bit per-secret random IV\n- 128-bit GCM auth tag (tamper detection)\n- Master key in the skill's private storage directory with restricted permissions (owner-only)\n- `SECRETS_MASTER_KEY` env var override\n\n### Rotation Tracking\n- 90-day default rotation cycle per secret\n- Automatic expiration warnings (audit --stale at 70% of cycle)\n- One-command rotation with new random value generation\n- Old values archived as `retired` (encrypted, recoverable until next rotate)\n\n### Audit System\n- Detects expired secrets past rotation date\n- Flags secrets approaching rotation deadline (70% threshold)\n- Identifies weak patterns (common prefixes, short length <8 chars)\n- Detects decryption failures (tampered ciphertext or wrong master key)\n- Reports rotation age for each secret\n\n### Safe Command Injection\n- `{{secret_name}}` placeholders replaced in command strings\n- **Default**: writes resolved command to a temp file with restricted permissions, prints path only\n- **Opt-in stdout**: requires both `--inject-stdout` AND `--confirm-expose`\n- No secret values ever reach stdout by default\n\n## Configuration\n\nData stored in the skill's private storage directory:\n- Encrypted secrets file (restricted permissions)\n- Master key file (restricted permissions)\n- Per-secret access rules (restricted permissions)\n\nOverride storage location:\n```bash\n--dir /path/to/secrets\n# or env var\nSECRETS_DIR=/path/to/secrets node secrets-manager.js --status\n```\n\nOverride master key:\n```bash\nSECRETS_MASTER_KEY=<64-hex-chars> node secrets-manager.js --get openai-key\n```\n\n## Agent Protocol\n\nWhen handling secrets:\n\n1. **Store with encryption** — `--store <name> <value>` writes AES-256-GCM ciphertext\n2. **Default to masked output** — `--get` (not `--get --raw`) for display\n3. **Use safe inject by default** — `--inject` writes to temp file, doesn't leak\n4. **Audit regularly** — `--audit` during heartbeats\n5. **Rotate proactively** — rotate secrets flagged as expiring\n6. **Back up the master key** — without it, stored secrets are unrecoverable\n\n## Security\n\n### Encryption & Storage\n- **AES-256-GCM authenticated encryption** — secrets are encrypted at rest, not base64-encoded\n- **Master key** in the skill's private storage directory with restricted permissions — back it up\n- For production-grade secrets with HSM-backed keys, use a real vault (HashiCorp, AWS Secrets Manager, OS keychain)\n- `SECRETS_MASTER_KEY` env var for ephemeral/CI environments\n- Default `--inject` never prints secrets; `--inject-stdout` requires explicit confirmation\n\n### Elevation & Least-Privilege\nRestricted file permissions ensure only the file owner can read secrets. This skill follows a least-privilege approach:\n\n- **Within `$HOME`**: Standard file permission changes are sufficient; no elevated access required.\n- **Outside `$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.\n- **Best-effort enforcement**: If permission changes fail (e.g., access denied), the skill continues and logs a warning rather than aborting. Secrets are still encrypted regardless of file permissions.\n- **No persistent privilege**: Elevation is requested per-operation and released immediately after permission changes complete.\n\n### Credential Path Management\nAll 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.\n\n## What This Skill Does NOT Do\n\n- Does NOT store secrets in plaintext or base64 — all values are AES-256-GCM encrypted\n- Does NOT print secret values to stdout unless explicitly requested via `--get --raw` or `--inject-stdout --confirm-expose`\n- Does NOT install npm packages\n- Does NOT phone home or transmit secrets anywhere\n- Does NOT log secret values\n- Does NOT require a separate key server — master key is a local file\n\n## Comparison\n\n| Approach | Encryption | Setup | Audit | Rotation | Recovery |\n|----------|-----------|-------|-------|----------|----------|\n| Environment vars | None | Medium | None | Manual | N/A |\n| .env files | None | Low | None | Manual | N/A |\n| **Secrets Manager** | **AES-256-GCM** | **None** | **Auto** | **Auto** | **With .master-key** |\n| Vault service | Various | High | Auto | Auto | Yes |\n\n**Secrets Manager gives you real encryption + rotation + audit with zero external dependencies.**\n\n## Design Principles\n\n1. **Zero setup** — Works immediately, no config needed\n2. **No dependencies** — Pure Node.js crypto, no npm packages\n3. **Safe by default** — Masked output, safe inject, encrypted at rest\n4. **Transparent** — Audit reports show exactly what's wrong\n5. **Recoverable** — Master key + encrypted secrets = full recovery\n\n<!-- clawhub-sync: 2026-07-22 v1.1.9 security audit remediation -->\n\nFile v1.1.19:README.md\n\n# Secrets Manager\n\n**Encrypted local secret storage for OpenClaw agents.** AES-256-GCM authenticated encryption, rotation tracking, audit, and safe command injection.\n\n> **TL;DR**: Secrets are encrypted at rest with AES-256-GCM. The master key is stored separately in `.master-key` with restricted permissions (owner-only). If you lose `.master-key`, your secrets are unrecoverable — back it up.\n\n## Features\n\n- **AES-256-GCM Encryption** — secrets encrypted at rest with a 256-bit master key and per-secret random 96-bit IVs. Authenticated encryption (GCM auth tag) detects tampering.\n- **Secure Storage** — `store`, `get`, `list`, `delete` lifecycle\n- **Auto-Expiry & Rotation** — 90-day default rotation cycle with audit reporting\n- **Safe Command Injection** — substitutes `{{placeholder}}` and writes to a private temp file with restricted permissions by default. NEVER prints secrets to stdout unless you opt in.\n- **Masked Output** — default output shows masked values (`sup****ue`)\n- **Status & Audit** — health checks, expired/stale secret reporting\n- **Zero External Dependencies** — pure Node.js `crypto` module\n\n## ⚠️ Security Warnings\n\n### Raw Mode (`--get --raw`) Prints Secrets to stdout\nThe secret value goes to stdout, which may be captured in:\n- Shell history / terminal scrollback\n- Process logs / journald / syslog\n- CI/CD pipeline output\n- Agent transcripts / OpenClaw session history\n- Downstream tool output\n\nUse only when piping directly to a private process or writing to a file with restricted permissions:\n```bash\nnode secrets-manager.js --get --raw api-key > /tmp/api-key.txt\n# Restrict file permissions after writing\n```\n\n### Command Injection (`--inject`) Default: Safe\nBy default, `--inject` substitutes `{{secrets}}` and writes the resolved command to a temp file with restricted permissions, then prints **only the file path** to stdout. Run the command with `sh /path/to/file`.\n\nTo print the resolved command to stdout (DANGEROUS — leaks secrets to logs), use **both** flags:\n```bash\nnode secrets-manager.js --inject-stdout --confirm-expose \"curl -H 'Authorization: Bearer {{api-key}}' https://api.example.com\"\n```\nThe skill will refuse to print the resolved command unless you pass `--confirm-expose`.\n\n### Master Key Backup\nThe master key is stored in a restricted-permission file within the skill's private data directory (owner-only). If you lose this file, all stored secrets are unrecoverable. Back it up to a secure location (encrypted disk, password manager, OS keychain).\n\nYou can also use `SECRETS_MASTER_KEY=<hex>` env var instead of the file (useful for ephemeral environments).\n\n### Not for Production Credentials (But Better Than Plain JSON)\nThis is a local agent tool with file-based key storage. For production-grade secret management with HSM-backed keys, audit trails, and access policies, use HashiCorp Vault, AWS Secrets Manager, etc. That said, **this skill provides real AES-256-GCM encryption** — secrets are not stored in plaintext or base64.\n\n## Permissions\n\n| Permission | Scope | Reason |\n|---|---|---|\n| `fs.read` | `$SECRETS_DIR/` | Read encrypted secrets and master key |\n| `fs.write` | `$SECRETS_DIR/` | Write encrypted secrets, master key, permission rules |\n| `exec` | CLI | Run `secrets-manager.js` for store/get/rotate/audit |\n| `elevated` | File permissions | Set restricted permissions on sensitive files (owner-only access) |\n\n## Security\n\n### Least-Privilege Elevation\nThe skill sets restricted file permissions to ensure only the owner can read secrets. Elevation is only needed when managing files outside `$HOME`. Within the user's home directory, standard file permission operations suffice without elevated privileges.\n\n### Credential Path Management\nAll 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.\n\n## Installation\n\n```bash\n# Auto-loaded by OpenClaw via the skill registry.\n# For standalone use:\nconst SM = require('./secrets-manager.js');\nSM.storeSecret('api-key', 'sk-abc123');\n```\n\n## Commands\n\n```\nstore <name> <value>        Store a secret (encrypted)\nget <name>                  Get secret (masked)\nget <name> --raw            Get secret (⚠️ raw value to stdout)\nlist                        List all secret names + metadata\ndelete <name>               Delete a secret\nrotate <name>               Generate new random value\nrotate --all                Rotate all secrets\ninject <command>            Substitute {{secrets}} → write to temp file (safe)\ninject-stdout --confirm-expose <command>\n                            Substitute and print (DANGEROUS)\naudit                       Check for expired/stale secrets\nstatus                      Show storage health\n```\n\n## API (require as module)\n\n```javascript\nconst SM = require('./secrets-manager.js');\n\nSM.storeSecret('api-key', 'sk-abc123');\nconst value = SM.getSecret('api-key');              // returns plaintext value\nconst masked = SM.getSecret('api-key');             // prints masked, returns value\nSM.listSecrets();                                    // prints table\nSM.deleteSecret('api-key');\nSM.rotateSecret('api-key');\nSM.auditSecrets('expired');\nSM.showStatus();\n```\n\n## Security Architecture\n\n- **AES-256-GCM** authenticated encryption (256-bit key, 96-bit IV per secret, 128-bit auth tag)\n- **Master key** auto-generated on first `store`, stored in `$SECRETS_DIR/.master-key` with restricted permissions (owner-only)\n- **Per-secret IVs** — same plaintext encrypted twice produces different ciphertext\n- **Auth tag verification** — tampered ciphertext returns `null` from decrypt (no partial decryption)\n- **Atomic file writes** — temp file + rename to prevent corruption on crash\n- **Restricted permissions** on all sensitive files (POSIX)\n- **No external dependencies** — pure Node.js `crypto`\n\n## Data Layout\n\nThe skill stores data in a private directory (default: `memory/secrets/` under the workspace root; override with `SECRETS_DIR` env var):\n\n- **Master key file** — 32 random bytes as hex, restricted permissions (owner-only)\n- **Encrypted secrets file** — AES-256-GCM ciphertext with per-secret IV and auth tag\n- **Permissions file** — Per-secret access rules (optional)\n- **Temp injection registry** — Tracks temporary command files for auto-cleanup\n\n## Testing\n\n```bash\n# Self-test suite (isolated temp directory)\nnode tests/run-self-tests.js\n\n# Quick smoke test\nnode test/run-tests.js\n```\n\n### Test Coverage\n\n| Suite | Tests | Status |\n|---|---|---|\n| Self-tests (isolated) | 29 | ✅ Passing |\n| Quick tests | 9 | ✅ Passing |\n\n## Examples\n\n**Store an API key:**\n```javascript\nSM.storeSecret('github-token', 'ghp_abc123...');\n```\n\n**Get for use in a script:**\n```javascript\nconst key = SM.getSecret('github-token');  // returns plaintext (handle carefully)\n```\n\n**Audit for expired secrets:**\n```javascript\nSM.auditSecrets('expired');\n```\n\n**Rotate all secrets:**\n```javascript\nSM.rotateAllSecrets();\n```\n\n**Inject into a command (safe):**\n```bash\n$ node secrets-manager.js --inject \"curl -H 'Authorization: Bearer {{api-key}}' https://api.example.com\"\n[secrets-manager] ✅ Injected 1 secret(s) into: /tmp/secrets-inject-12345-1234567890.sh\n[secrets-manager]    Run with: sh /tmp/secrets-inject-12345-1234567890.sh\n$ sh /tmp/secrets-inject-12345-1234567890.sh\n# ... command output ...\n```\n\nFile v1.1.19:_meta.json\n\n{\n  \"ownerId\": \"kn7b6eyf5vc7khg5fr63pjm8xd82qvw5\",\n  \"slug\": \"secrets-manager\",\n  \"version\": \"1.1.19\",\n  \"publishedAt\": 1789302192890\n}\n\nFile v1.1.19:skill-card.md\n\n## Description:\n\nEncrypted 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 a restricted temp file by default and requires explicit confirmation before printing resolved commands. Losing the master key makes stored secrets unrecoverable.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[jlacroix82](https://clawhub.ai/user/jlacroix82)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and agent operators use this skill to store, retrieve, rotate, audit, and inject local secrets for OpenClaw workflows while keeping default display output masked.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Credential values may be exposed through argv, persistent temp scripts, or audit output.\n\nMitigation: Review and fix credential handling before storing high-value production credentials; prefer masked output and default temp-file injection until the release has been remediated.\n\nRisk: The release requests shell and elevated permissions that may be broader than necessary.\n\nMitigation: Limit deployment to reviewed environments, constrain the storage directory, and confirm that elevated permissions are only used for restrictive file-permission enforcement.\n\nRisk: The local master key is required to recover stored secrets.\n\nMitigation: Back up the master key to a secure location and test recovery before relying on the store for important credentials.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/jlacroix82/skills/secrets-manager)\n- [Publisher profile](https://clawhub.ai/user/jlacroix82)\n- [README](artifact/README.md)\n- [Vetting report](artifact/VET-REPORT.md)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Shell commands, Files, Configuration]\n\n**Output Format:** [CLI text output, masked secret values by default, and restricted-permission temp shell scripts for command injection]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May emit plaintext secrets only when explicitly requested through raw retrieval or confirmed stdout injection.]\n\n## Skill Version(s):\n\n1.1.19 (source: frontmatter and server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v1.1.19:VET-REPORT.md\n\n# Vetting Report: secrets-manager\n**Date:** 2026-09-13 08:11 EDT\n**Vetter:** JARVIS (skill-vetter skill)\n**Source:** local (/home/jarvis/.openclaw/workspace)\n**Verdict:** PASS\n**Risk score:** 8/100\n\n## Findings\n\n### Critical\n- (none)\n\n### Warnings\n- 1 network URLs\n- No description in frontmatter\n\n### Notes\n- (none)\n\n## Permission footprint\n- Tools requested: exec process read write \n\n## Network footprint\nhttps://api.openai.com/v1/chat\n\n## Side effects\n- Reads: SKILL.md\n- Writes: VET-REPORT.md (this file)\n- Network: 1 distinct hosts\n\n## Verdict rationale\nScore 8/100 with 0 critical findings and 2 warnings.\n\nFile v1.1.19:clawhub.yaml\n\nslug: secrets-manager\nname: secrets-manager\nowner: jlacroix82\ndescription: Encrypted 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. Permissions: filesystem.read-write, environment.read, crypto.aes-256-gcm.\nversion: 1.1.19\ntype: skill\nauthor: OpenClaw\nlicense: MIT\nkeywords:\n  - secrets\n  - encryption\n  - aes-256-gcm\n  - rotation\n  - audit\n  - key-management\ncapabilities:\n  - filesystem\n  - environment\n  - crypto\nentry: SKILL.md\ndependencies: []\npermissions:\n  - name: filesystem.read-write\n    description: Read/write encrypted data files in the private data directory (restricted permissions)\n  - name: environment.read\n    description: Read SECRETS_DIR and SECRETS_MASTER_KEY environment variables\n  - name: crypto.aes-256-gcm\n    description: Encrypt/decrypt secrets with AES-256-GCM authenticated encryption\n  - name: elevated\n    description: Set restricted permissions on secret files; required only when $SECRETS_DIR is outside $HOME. Least-privilege: elevation used solely for file permission enforcement, not for reading or writing secrets.\ndata_retention:\n  secrets: 'AES-256-GCM encrypted, restricted permissions, persists until deleted'\n  master_key: '256-bit key in .master-key file, restricted permissions'\n  temp_files: 'restricted permissions, /tmp/secrets-inject-*.sh, auto-cleaned on rotate/delete/cleanup; tracked in .tmp-injections.json'\nsecurity_notes:\n  - 'Master key auto-generated on first store; backup is your responsibility'\n  - 'Losing .master-key = unrecoverable secrets'\n  - 'Plaintext only printed via explicit --get --raw or --inject-stdout --confirm-expose'\n  - 'Temp injection files auto-cleaned on rotate/delete/cleanup; tracked in .tmp-injections.json'\n\nFile v1.1.19:test.txt\n\nTesting\n\nArchive v1.1.18: 12 files, 19617 bytes\n\nFiles: CHANGELOG.txt (1178b), clawhub.yaml (2051b), README.md (4978b), secrets-manager.js (20279b), skill-card.md (2953b), SKILL.md (8024b), test-final.js (2549b), test.txt (8b), test/run-tests.js (1713b), test/test-secrets.js (2243b), tests/run-self-tests.js (9255b), _meta.json (135b)\n\nFile v1.1.18:SKILL.md\n\n---\nname: secrets-manager\ndescription: >-\n  Encrypted local secret store for OpenClaw agents. AES-256-GCM authenticated\n  encryption with per-secret random IVs, master key in chmod 0600 .master-key\n  file. A PURE STORE: it encrypts, retrieves, lists, rotates, audits, and deletes\n  secrets — it never writes plaintext secrets to disk or generates executable\n  command scripts. Modes: --store (encrypt+write), --get (masked; --raw\n  --confirm-expose prints plaintext to stdout), --list (names+metadata only), --delete (irreversible),\n  --rotate and --rotate --all (generate new random values, archive old as\n  retired), --audit / --audit --expired / --audit --stale (exposure/rotation\n  checks), --status. Supports SECRETS_DIR and SECRETS_MASTER_KEY env overrides.\n  For injecting secrets into shell commands, use the separate `secrets-inject`\n  skill (high-privilege). Master key is recoverable from .master-key file;\n  losing it makes stored secrets unrecoverable.\npermissions:\n  - filesystem.read-write\n  - environment.read\n  - crypto.aes-256-gcm\n---\n\n# Secrets Manager 🔐\n\n**Encrypted local secret store.** AES-256-GCM authenticated encryption. Master key auto-generated on first store and stored in `memory/secrets/.master-key` (chmod 0600).\n\n> **Important**: If you lose `.master-key`, all stored secrets become unrecoverable. Back it up.\n\n## ⚠️ Important Warnings\n\n### Encryption: AES-256-GCM (Authenticated)\n- 256-bit master key, per-secret 96-bit random IV, 128-bit GCM auth tag\n- Tampered ciphertext returns `null` from decrypt (no partial decryption)\n- Master key stored in `memory/secrets/.master-key` with chmod 0600\n- Override via `SECRETS_MASTER_KEY=<hex>` env var\n- Losing the master key = all secrets unrecoverable\n\n### `--get --raw` Prints Plaintext to stdout (requires `--confirm-expose`)\nThe secret value goes to stdout, which may be captured in:\n- Shell history / terminal scrollback\n- Process logs / journald / syslog\n- CI/CD pipeline output\n- Agent transcripts / OpenClaw session history\n\nThe skill **refuses** to print the raw value unless you pass **both** `--raw` AND `--confirm-expose`:\n```bash\nnode secrets-manager.js --get --raw api-key --confirm-expose\n```\nUse only when piping directly to a private process (never write plaintext to /tmp):\n```bash\nnode secrets-manager.js --get --raw api-key --confirm-expose | your-private-process\n```\n\n### Rotation: Old Values Are Archived\nRotated secrets keep the old encrypted value as `retired`. Rotate again to discard the archive. There is no `--undo` for archival.\n\n### Storage Location\n`memory/secrets/secrets.json` (chmod 0600) plus `memory/secrets/.master-key` (chmod 0600). Override via `--dir <path>` or `SECRETS_DIR=<path>`.\n\n## Quick Start\n\n### Store a secret\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --store openai-key sk-abc123\n# Output: [secrets-manager] Stored: openai-key (masked: sk-****23)\n```\n\n### Get a secret (masked by default)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --get openai-key\n# Output: [secrets-manager] openai-key: sk-****23\n```\n\n### Get raw value (when you must pass it to another tool)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --get --raw openai-key --confirm-expose\n# Output: sk-abc123 (piped to stdout — requires BOTH --raw AND --confirm-expose)\n```\n\n> ⚠️ Never redirect raw output into /tmp or other world-readable locations. Pipe directly to the consuming process or to a file with restricted permissions in a private directory.\n\n### List all secrets (names + metadata, NOT values)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --list\n```\n\n### Delete a secret\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --delete old-key\n```\n\n### Rotate a secret\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --rotate openai-key\n# New random value generated, old encrypted value archived as retired\n```\n\n### Rotate all secrets\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --rotate --all\n```\n\n### Audit for security issues\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --audit\nnode skills/secrets-manager/secrets-manager.js --audit --expired\nnode skills/secrets-manager/secrets-manager.js --audit --stale\n```\n\n### Status overview\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --status\n```\n\n## Features\n\n### Encryption\n- **AES-256-GCM** authenticated encryption\n- 256-bit master key (auto-generated on first store)\n- 96-bit per-secret random IV\n- 128-bit GCM auth tag (tamper detection)\n- Master key in `memory/secrets/.master-key` (chmod 0600)\n- `SECRETS_MASTER_KEY` env var override\n\n### Rotation Tracking\n- 90-day default rotation cycle per secret\n- Automatic expiration warnings (audit --stale at 70% of cycle)\n- One-command rotation with new random value generation\n- Old values archived as `retired` (encrypted, recoverable until next rotate)\n\n### Audit System\n- Detects expired secrets past rotation date\n- Flags secrets approaching rotation deadline (70% threshold)\n- Identifies weak patterns (common prefixes, short length <8 chars)\n- Detects decryption failures (tampered ciphertext or wrong master key)\n- Reports rotation age for each secret\n\n## Configuration\n\nData stored in: `memory/secrets/`\n- `secrets.json` — encrypted secrets (chmod 0600)\n- `.master-key` — 256-bit master key as hex (chmod 0600)\n\nNote: This skill has NO access-control / permissions subsystem. All stored\nsecrets are readable by the same agent/process that runs this skill. There is\nno per-secret authorization layer — isolation is provided only by filesystem\npermissions (chmod 0600 on the data files) and by keeping `.master-key` private.\n\nOverride storage location:\n```bash\n--dir /path/to/secrets\n# or env var\nSECRETS_DIR=/path/to/secrets node secrets-manager.js --status\n```\n\nOverride master key:\n```bash\nSECRETS_MASTER_KEY=<64-hex-chars> node secrets-manager.js --get openai-key\n```\n\n## Agent Protocol\n\nWhen handling secrets:\n\n1. **Store with encryption** — `--store <name> <value>` writes AES-256-GCM ciphertext\n2. **Default to masked output** — `--get` (not `--get --raw --confirm-expose`) for display\n3. **Audit regularly** — `--audit` during heartbeats\n5. **Rotate proactively** — rotate secrets flagged as expiring\n6. **Back up `.master-key`** — without it, stored secrets are unrecoverable\n\n## Security Notes\n\n- **AES-256-GCM authenticated encryption** — secrets are encrypted at rest, not base64-encoded\n- **Master key** in `memory/secrets/.master-key` (chmod 0600) — back it up\n- For production-grade secrets with HSM-backed keys, use a real vault (HashiCorp, AWS Secrets Manager, OS keychain)\n- `SECRETS_MASTER_KEY` env var for ephemeral/CI environments\n\n## What This Skill Does NOT Do\n\n- Does NOT store secrets in plaintext or base64 — all values are AES-256-GCM encrypted\n- Does NOT print secret values to stdout unless explicitly requested via `--get --raw --confirm-expose`\n- Does NOT install npm packages\n- Does NOT phone home or transmit secrets anywhere\n- Does NOT log secret values\n- Does NOT require a separate key server — master key is a local file\n\n## Comparison\n\n| Approach | Encryption | Setup | Audit | Rotation | Recovery |\n|----------|-----------|-------|-------|----------|----------|\n| Environment vars | None | Medium | None | Manual | N/A |\n| .env files | None | Low | None | Manual | N/A |\n| **Secrets Manager** | **AES-256-GCM** | **None** | **Auto** | **Auto** | **With .master-key** |\n| Vault service | Various | High | Auto | Auto | Yes |\n\n**Secrets Manager gives you real encryption + rotation + audit with zero external dependencies.**\n\n## Design Principles\n\n1. **Zero setup** — Works immediately, no config needed\n2. **No dependencies** — Pure Node.js crypto, no npm packages\n3. **Safe by default** — Masked output, encrypted at rest, no plaintext-on-disk\n4. **Transparent** — Audit reports show exactly what's wrong\n5. **Recoverable** — Master key + encrypted secrets = full recovery\n\n<!-- clawhub-sync: 2026-07-22 v1.1.9 security audit remediation -->\n\nFile v1.1.18:README.md\n\n# Secrets Manager 🔐\n\n**Encrypted local secret store.** AES-256-GCM authenticated encryption, rotation\ntracking, audit, and delete. A **PURE STORE** — it encrypts, retrieves, lists,\nrotates, audits, and deletes secrets. It does **not** generate executable command\nscripts and does **not** write plaintext secrets to disk.\n\n> **Important**: If you lose `.master-key`, all stored secrets become unrecoverable. Back it up.\n\n## Security model\n\n- **AES-256-GCM** authenticated encryption (tamper → decrypt returns `null`)\n- 256-bit master key, auto-generated on first store, stored in\n  `memory/secrets/.master-key` (chmod 0600)\n- Per-secret random 96-bit IV, 128-bit GCM auth tag\n- Encrypted secrets persist in `memory/secrets/secrets.json` (chmod 0600)\n- No plaintext secrets are ever written to disk or to logs\n\n## Quick Start\n\n```bash\n# Store a secret (encrypted at rest)\nnode secrets-manager.js --store openai-key sk-abc123\n# → Stored: openai-key (masked: sk-****23)\n\n# Get a secret (masked by default)\nnode secrets-manager.js --get openai-key\n# → openai-key: sk-****23\n\n# Get the raw value (prints to stdout — requires BOTH --raw AND --confirm-expose; pipe to a private process, never to /tmp)\nnode secrets-manager.js --get --raw openai-key --confirm-expose\n\n# List secret names + metadata (never values)\nnode secrets-manager.js --list\n\n# Delete a secret (irreversible)\nnode secrets-manager.js --delete old-key\n\n# Rotate a secret (generates a new random value; old value archived as retired)\nnode secrets-manager.js --rotate openai-key\n\n# Rotate all secrets\nnode secrets-manager.js --rotate --all\n\n# Audit for exposure / rotation issues\nnode secrets-manager.js --audit\nnode secrets-manager.js --audit --expired\nnode secrets-manager.js --audit --stale\n\n# Status overview\nnode secrets-manager.js --status\n```\n\n## Features\n\n- **Encryption** — AES-256-GCM, per-secret IV, authenticated (tamper detection)\n- **Rotation tracking** — 90-day default cycle, expiration warnings, one-command rotation\n- **Audit system** — flags expired/stale secrets, weak patterns, decryption failures\n- **Masked by default** — values never printed unless explicitly requested via `--get --raw --confirm-expose`\n- **Zero plaintext-on-disk** — secrets are encrypted at rest; no temp scripts are generated\n\n## Configuration\n\nData stored in `memory/secrets/`:\n- `secrets.json` — encrypted secrets (chmod 0600)\n- `.master-key` — 256-bit master key as hex (chmod 0600)\n\nThis skill has NO per-secret access-control subsystem. All secrets are readable\nby the same agent/process that runs this skill; isolation is provided only by\nfilesystem permissions (chmod 0600 on the data files) and by keeping\n`.master-key` private.\n\nOverride storage location:\n```bash\nSECRETS_DIR=/path/to/secrets node secrets-manager.js --status\n```\n\nOverride master key (ephemeral/CI only):\n```bash\nSECRETS_MASTER_KEY=<64-hex-chars> node secrets-manager.js --get openai-key\n```\n> Never set `SECRETS_MASTER_KEY` in shared, containerized, CI, or logged\n> environments — anyone who can read process env or logs can recover the key.\n> Prefer the file-based `.master-key` (chmod 0600) on a single-user host.\n\n## Agent Protocol\n\n1. **Store with encryption** — `--store <name> <value>` writes AES-256-GCM ciphertext\n2. **Default to masked output** — `--get` (not `--get --raw`) for display\n3. **Audit regularly** — `--audit` during heartbeats\n4. **Rotate proactively** — rotate secrets flagged as expiring\n5. **Back up `.master-key`** — without it, stored secrets are unrecoverable\n\n## Security Notes\n\n- AES-256-GCM authenticated encryption — secrets encrypted at rest, not base64\n- Master key in `memory/secrets/.master-key` (chmod 0600) — back it up\n- For production-grade secrets with HSM-backed keys, use a real vault\n  (HashiCorp, AWS Secrets Manager, OS keychain)\n- `SECRETS_MASTER_KEY` env var for ephemeral/CI environments\n- **No plaintext is written to disk** — the store only ever holds ciphertext\n\n## What This Skill Does NOT Do\n\n- Does NOT store secrets in plaintext or base64 — all values are AES-256-GCM encrypted\n- Does NOT print secret values to stdout unless explicitly requested via `--get --raw`\n- Does NOT generate executable command scripts (no `--inject`)\n- Does NOT install npm packages\n- Does NOT phone home or transmit secrets anywhere\n- Does NOT log secret values\n- Does NOT require a separate key server — master key is a local file\n\n## Design Principles\n\n1. **Zero setup** — Works immediately, no config needed\n2. **No dependencies** — Pure Node.js crypto, no npm packages\n3. **Safe by default** — Masked output, encrypted at rest, no plaintext-on-disk\n4. **Transparent** — Audit reports show exactly what's wrong\n5. **Recoverable** — Master key + encrypted secrets = full recovery\n\n> **Need to inject a secret into a shell command?** Use the separate\n> `secrets-inject` skill (high-privilege, clearly labeled). This store\n> deliberately does not do that.\n\nFile v1.1.18:_meta.json\n\n{\n  \"ownerId\": \"kn7b6eyf5vc7khg5fr63pjm8xd82qvw5\",\n  \"slug\": \"secrets-manager\",\n  \"version\": \"1.1.18\",\n  \"publishedAt\": 1786824686319\n}\n\nFile v1.1.18:skill-card.md\n\n## Description:\n\nEncrypted local secret store for OpenClaw agents that uses AES-256-GCM authenticated encryption to store, retrieve, list, rotate, audit, and delete secrets without writing plaintext secrets to disk.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[jlacroix82](https://clawhub.ai/user/jlacroix82)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and agents use this skill to manage local encrypted secrets, including storing, retrieving masked values, rotating credentials, auditing stale or weak secrets, and deleting entries. It is intended for trusted single-user or single-agent environments where filesystem permissions and master-key handling are acceptable controls.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: A user or agent with access to the same process and files can read stored secrets because the skill has no per-secret access-control boundary.\n\nMitigation: Use only in trusted single-user or single-agent environments and rely on restrictive filesystem permissions for the secrets directory and master key.\n\nRisk: Losing .master-key makes encrypted secrets unrecoverable.\n\nMitigation: Back up .master-key securely and store the backup separately from routine logs or shared workspaces.\n\nRisk: Using SECRETS_MASTER_KEY in shared, logged, containerized, or CI environments can expose the master key.\n\nMitigation: Prefer the file-based .master-key on a trusted host and avoid setting SECRETS_MASTER_KEY where environment variables may be observed or logged.\n\nRisk: Raw secret output can leak through terminal scrollback, logs, transcripts, or redirected files.\n\nMitigation: Use masked output by default and use raw output only with explicit confirmation when piping directly to a private consuming process.\n\nRisk: Deleting a secret is irreversible without a backup of the encrypted store.\n\nMitigation: Back up secrets.json before deleting secrets that may need recovery.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/jlacroix82/skills/secrets-manager)\n- [README.md](artifact/README.md)\n- [SKILL.md](artifact/SKILL.md)\n\n## Skill Output:\n\n**Output Type(s):** [text, shell commands, configuration, files, guidance]\n\n**Output Format:** [Plain text CLI output with masked values by default, optional raw stdout only with explicit confirmation, and local encrypted JSON storage files.]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Stores encrypted secrets and the master key under the configured secrets directory with restrictive file permissions where supported.]\n\n## Skill Version(s):\n\n1.1.18 (source: server release metadata and clawhub.yaml)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v1.1.18:clawhub.yaml\n\nslug: secrets-manager\nname: secrets-manager\nowner: jlacroix82\ndescription: \"Encrypted local secret store for OpenClaw agents. A PURE STORE: AES-256-GCM authenticated encryption with per-secret random IVs, master key in chmod 0600 .master-key file. Modes: store, get (masked; --raw prints plaintext), list (names+metadata only), delete (irreversible), rotate / rotate --all (archive old as retired), audit (--expired/--stale), status. NEVER writes plaintext secrets to disk or generates executable command scripts — command injection lives in the separate secrets-inject skill. SECRETS_DIR and SECRETS_MASTER_KEY env overrides supported. Losing .master-key makes secrets unrecoverable.\"\nversion: 1.1.18\ntype: skill\nauthor: OpenClaw\nlicense: MIT\nkeywords:\n  - secrets\n  - encryption\n  - aes-256-gcm\n  - rotation\n  - audit\n  - key-management\ncapabilities:\n  - filesystem\n  - environment\n  - crypto\nentry: SKILL.md\ndependencies: []\npermissions:\n  - name: filesystem.read-write\n    description: Read/write data files in memory/secrets/ (secrets.json chmod 0600, .master-key chmod 0600)\n  - name: environment.read\n    description: Read SECRETS_DIR and SECRETS_MASTER_KEY environment variables\n  - name: crypto.aes-256-gcm\n    description: Encrypt/decrypt secrets with AES-256-GCM authenticated encryption\ndata_retention:\n  secrets: 'AES-256-GCM encrypted, chmod 0600, persists until deleted'\n  master_key: '256-bit key in .master-key file, chmod 0600'\nsecurity_notes:\n  - 'Master key auto-generated on first store; backup is your responsibility'\n  - 'Losing .master-key = unrecoverable secrets'\n  - 'Plaintext only printed via explicit --get --raw (to stdout); no plaintext written to disk'\n  - 'SECRETS_MASTER_KEY env override: NEVER set it in shared, containerized, CI, or logged environments — anyone who can read process env or logs can recover the key. Prefer the file-based .master-key (chmod 0600) on a single-user host.'\n  - 'Command injection / secret substitution is NOT provided here; use the separate secrets-inject skill (high-privilege).'\n\nFile v1.1.18:CHANGELOG.txt\n\nSecrets Manager v1.1.17 — Audit-finding remediation (2026-08-04)\n\n- Made data paths lazy (getWorkspace/getDataDir/getSecretsFile/getMasterKeyFile as\n  functions) so the --dir flag and SECRETS_DIR env var are actually honored.\n  Previously WORKSPACE/DATA_DIR were resolved once at module load, so --dir was a\n  deceptive no-op (secrets were still written to the default location). Now --dir\n  reliably redirects storage.\n- Split master-key access into loadMasterKey() (READ-ONLY, no file creation) and\n  ensureMasterKey() (WRITE, generates on first store). Read-only paths (--get,\n  --audit, --status, --list) no longer create or mutate the .master-key file as a\n  side effect.\n- Audit no longer prints plaintext value prefixes. Weak/pattern findings now flag\n  the secret NAME only, never a decrypted value, removing the \"plaintext-derived\n  prefixes during audit\" disclosure.\n- Removed the unenforced --confirm-expose flag from the parser (it was advertised\n  but getSecret never checked it). --raw prints plaintext directly with an explicit\n  warning, as documented.\n\nNo crypto changes — still AES-256-GCM with per-secret IV and authenticated\ndecryption (tamper -> null).\n\nFile v1.1.18:test.txt\n\nTesting\n\nArchive v1.1.17: 12 files, 19070 bytes\n\nFiles: CHANGELOG.txt (1178b), clawhub.yaml (2051b), README.md (4940b), secrets-manager.js (19644b), skill-card.md (2470b), SKILL.md (7505b), test-final.js (2549b), test.txt (8b), test/run-tests.js (1713b), test/test-secrets.js (2243b), tests/run-self-tests.js (9255b), _meta.json (135b)\n\nFile v1.1.17:SKILL.md\n\n---\nname: secrets-manager\ndescription: >-\n  Encrypted local secret store for OpenClaw agents. AES-256-GCM authenticated\n  encryption with per-secret random IVs, master key in chmod 0600 .master-key\n  file. A PURE STORE: it encrypts, retrieves, lists, rotates, audits, and deletes\n  secrets — it never writes plaintext secrets to disk or generates executable\n  command scripts. Modes: --store (encrypt+write), --get (masked; --raw prints\n  plaintext to stdout), --list (names+metadata only), --delete (irreversible),\n  --rotate and --rotate --all (generate new random values, archive old as\n  retired), --audit / --audit --expired / --audit --stale (exposure/rotation\n  checks), --status. Supports SECRETS_DIR and SECRETS_MASTER_KEY env overrides.\n  For injecting secrets into shell commands, use the separate `secrets-inject`\n  skill (high-privilege). Master key is recoverable from .master-key file;\n  losing it makes stored secrets unrecoverable.\npermissions:\n  - filesystem.read-write\n  - environment.read\n  - crypto.aes-256-gcm\n---\n\n# Secrets Manager 🔐\n\n**Encrypted local secret store.** AES-256-GCM authenticated encryption. Master key auto-generated on first store and stored in `memory/secrets/.master-key` (chmod 0600).\n\n> **Important**: If you lose `.master-key`, all stored secrets become unrecoverable. Back it up.\n\n## ⚠️ Important Warnings\n\n### Encryption: AES-256-GCM (Authenticated)\n- 256-bit master key, per-secret 96-bit random IV, 128-bit GCM auth tag\n- Tampered ciphertext returns `null` from decrypt (no partial decryption)\n- Master key stored in `memory/secrets/.master-key` with chmod 0600\n- Override via `SECRETS_MASTER_KEY=<hex>` env var\n- Losing the master key = all secrets unrecoverable\n\n### `--get --raw` Prints Plaintext to stdout\nThe secret value goes to stdout, which may be captured in:\n- Shell history / terminal scrollback\n- Process logs / journald / syslog\n- CI/CD pipeline output\n- Agent transcripts / OpenClaw session history\n\nUse only when piping to a private process:\n```bash\nnode secrets-manager.js --get --raw api-key > /tmp/api-key.txt && chmod 600 /tmp/api-key.txt\n```\n\n### Rotation: Old Values Are Archived\nRotated secrets keep the old encrypted value as `retired`. Rotate again to discard the archive. There is no `--undo` for archival.\n\n### Storage Location\n`memory/secrets/secrets.json` (chmod 0600) plus `memory/secrets/.master-key` (chmod 0600). Override via `--dir <path>` or `SECRETS_DIR=<path>`.\n\n## Quick Start\n\n### Store a secret\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --store openai-key sk-abc123\n# Output: [secrets-manager] Stored: openai-key (masked: sk-****23)\n```\n\n### Get a secret (masked by default)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --get openai-key\n# Output: [secrets-manager] openai-key: sk-****23\n```\n\n### Get raw value (when you must pass it to another tool)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --get --raw openai-key > /tmp/key.txt\n# Output: sk-abc123 (captured to file)\n```\n\n### List all secrets (names + metadata, NOT values)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --list\n```\n\n### Delete a secret\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --delete old-key\n```\n\n### Rotate a secret\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --rotate openai-key\n# New random value generated, old encrypted value archived as retired\n```\n\n### Rotate all secrets\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --rotate --all\n```\n\n### Audit for security issues\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --audit\nnode skills/secrets-manager/secrets-manager.js --audit --expired\nnode skills/secrets-manager/secrets-manager.js --audit --stale\n```\n\n### Status overview\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --status\n```\n\n## Features\n\n### Encryption\n- **AES-256-GCM** authenticated encryption\n- 256-bit master key (auto-generated on first store)\n- 96-bit per-secret random IV\n- 128-bit GCM auth tag (tamper detection)\n- Master key in `memory/secrets/.master-key` (chmod 0600)\n- `SECRETS_MASTER_KEY` env var override\n\n### Rotation Tracking\n- 90-day default rotation cycle per secret\n- Automatic expiration warnings (audit --stale at 70% of cycle)\n- One-command rotation with new random value generation\n- Old values archived as `retired` (encrypted, recoverable until next rotate)\n\n### Audit System\n- Detects expired secrets past rotation date\n- Flags secrets approaching rotation deadline (70% threshold)\n- Identifies weak patterns (common prefixes, short length <8 chars)\n- Detects decryption failures (tampered ciphertext or wrong master key)\n- Reports rotation age for each secret\n\n## Configuration\n\nData stored in: `memory/secrets/`\n- `secrets.json` — encrypted secrets (chmod 0600)\n- `.master-key` — 256-bit master key as hex (chmod 0600)\n\nNote: This skill has NO access-control / permissions subsystem. All stored\nsecrets are readable by the same agent/process that runs this skill. There is\nno per-secret authorization layer — isolation is provided only by filesystem\npermissions (chmod 0600 on the data files) and by keeping `.master-key` private.\n\nOverride storage location:\n```bash\n--dir /path/to/secrets\n# or env var\nSECRETS_DIR=/path/to/secrets node secrets-manager.js --status\n```\n\nOverride master key:\n```bash\nSECRETS_MASTER_KEY=<64-hex-chars> node secrets-manager.js --get openai-key\n```\n\n## Agent Protocol\n\nWhen handling secrets:\n\n1. **Store with encryption** — `--store <name> <value>` writes AES-256-GCM ciphertext\n2. **Default to masked output** — `--get` (not `--get --raw`) for display\n3. **Audit regularly** — `--audit` during heartbeats\n5. **Rotate proactively** — rotate secrets flagged as expiring\n6. **Back up `.master-key`** — without it, stored secrets are unrecoverable\n\n## Security Notes\n\n- **AES-256-GCM authenticated encryption** — secrets are encrypted at rest, not base64-encoded\n- **Master key** in `memory/secrets/.master-key` (chmod 0600) — back it up\n- For production-grade secrets with HSM-backed keys, use a real vault (HashiCorp, AWS Secrets Manager, OS keychain)\n- `SECRETS_MASTER_KEY` env var for ephemeral/CI environments\n\n## What This Skill Does NOT Do\n\n- Does NOT store secrets in plaintext or base64 — all values are AES-256-GCM encrypted\n- Does NOT print secret values to stdout unless explicitly requested via `--get --raw`\n- Does NOT install npm packages\n- Does NOT phone home or transmit secrets anywhere\n- Does NOT log secret values\n- Does NOT require a separate key server — master key is a local file\n\n## Comparison\n\n| Approach | Encryption | Setup | Audit | Rotation | Recovery |\n|----------|-----------|-------|-------|----------|----------|\n| Environment vars | None | Medium | None | Manual | N/A |\n| .env files | None | Low | None | Manual | N/A |\n| **Secrets Manager** | **AES-256-GCM** | **None** | **Auto** | **Auto** | **With .master-key** |\n| Vault service | Various | High | Auto | Auto | Yes |\n\n**Secrets Manager gives you real encryption + rotation + audit with zero external dependencies.**\n\n## Design Principles\n\n1. **Zero setup** — Works immediately, no config needed\n2. **No dependencies** — Pure Node.js crypto, no npm packages\n3. **Safe by default** — Masked output, encrypted at rest, no plaintext-on-disk\n4. **Transparent** — Audit reports show exactly what's wrong\n5. **Recoverable** — Master key + encrypted secrets = full recovery\n\n<!-- clawhub-sync: 2026-07-22 v1.1.9 security audit remediation -->\n\nFile v1.1.17:README.md\n\n# Secrets Manager 🔐\n\n**Encrypted local secret store.** AES-256-GCM authenticated encryption, rotation\ntracking, audit, and delete. A **PURE STORE** — it encrypts, retrieves, lists,\nrotates, audits, and deletes secrets. It does **not** generate executable command\nscripts and does **not** write plaintext secrets to disk.\n\n> **Important**: If you lose `.master-key`, all stored secrets become unrecoverable. Back it up.\n\n## Security model\n\n- **AES-256-GCM** authenticated encryption (tamper → decrypt returns `null`)\n- 256-bit master key, auto-generated on first store, stored in\n  `memory/secrets/.master-key` (chmod 0600)\n- Per-secret random 96-bit IV, 128-bit GCM auth tag\n- Encrypted secrets persist in `memory/secrets/secrets.json` (chmod 0600)\n- No plaintext secrets are ever written to disk or to logs\n\n## Quick Start\n\n```bash\n# Store a secret (encrypted at rest)\nnode secrets-manager.js --store openai-key sk-abc123\n# → Stored: openai-key (masked: sk-****23)\n\n# Get a secret (masked by default)\nnode secrets-manager.js --get openai-key\n# → openai-key: sk-****23\n\n# Get the raw value (prints to stdout — use only when you must pass it onward)\nnode secrets-manager.js --get --raw openai-key > /tmp/key.txt && chmod 600 /tmp/key.txt\n\n# List secret names + metadata (never values)\nnode secrets-manager.js --list\n\n# Delete a secret (irreversible)\nnode secrets-manager.js --delete old-key\n\n# Rotate a secret (generates a new random value; old value archived as retired)\nnode secrets-manager.js --rotate openai-key\n\n# Rotate all secrets\nnode secrets-manager.js --rotate --all\n\n# Audit for exposure / rotation issues\nnode secrets-manager.js --audit\nnode secrets-manager.js --audit --expired\nnode secrets-manager.js --audit --stale\n\n# Status overview\nnode secrets-manager.js --status\n```\n\n## Features\n\n- **Encryption** — AES-256-GCM, per-secret IV, authenticated (tamper detection)\n- **Rotation tracking** — 90-day default cycle, expiration warnings, one-command rotation\n- **Audit system** — flags expired/stale secrets, weak patterns, decryption failures\n- **Masked by default** — values never printed unless explicitly requested via `--get --raw`\n- **Zero plaintext-on-disk** — secrets are encrypted at rest; no temp scripts are generated\n\n## Configuration\n\nData stored in `memory/secrets/`:\n- `secrets.json` — encrypted secrets (chmod 0600)\n- `.master-key` — 256-bit master key as hex (chmod 0600)\n\nThis skill has NO per-secret access-control subsystem. All secrets are readable\nby the same agent/process that runs this skill; isolation is provided only by\nfilesystem permissions (chmod 0600 on the data files) and by keeping\n`.master-key` private.\n\nOverride storage location:\n```bash\nSECRETS_DIR=/path/to/secrets node secrets-manager.js --status\n```\n\nOverride master key (ephemeral/CI only):\n```bash\nSECRETS_MASTER_KEY=<64-hex-chars> node secrets-manager.js --get openai-key\n```\n> Never set `SECRETS_MASTER_KEY` in shared, containerized, CI, or logged\n> environments — anyone who can read process env or logs can recover the key.\n> Prefer the file-based `.master-key` (chmod 0600) on a single-user host.\n\n## Agent Protocol\n\n1. **Store with encryption** — `--store <name> <value>` writes AES-256-GCM ciphertext\n2. **Default to masked output** — `--get` (not `--get --raw`) for display\n3. **Audit regularly** — `--audit` during heartbeats\n4. **Rotate proactively** — rotate secrets flagged as expiring\n5. **Back up `.master-key`** — without it, stored secrets are unrecoverable\n\n## Security Notes\n\n- AES-256-GCM authenticated encryption — secrets encrypted at rest, not base64\n- Master key in `memory/secrets/.master-key` (chmod 0600) — back it up\n- For production-grade secrets with HSM-backed keys, use a real vault\n  (HashiCorp, AWS Secrets Manager, OS keychain)\n- `SECRETS_MASTER_KEY` env var for ephemeral/CI environments\n- **No plaintext is written to disk** — the store only ever holds ciphertext\n\n## What This Skill Does NOT Do\n\n- Does NOT store secrets in plaintext or base64 — all values are AES-256-GCM encrypted\n- Does NOT print secret values to stdout unless explicitly requested via `--get --raw`\n- Does NOT generate executable command scripts (no `--inject`)\n- Does NOT install npm packages\n- Does NOT phone home or transmit secrets anywhere\n- Does NOT log secret values\n- Does NOT require a separate key server — master key is a local file\n\n## Design Principles\n\n1. **Zero setup** — Works immediately, no config needed\n2. **No dependencies** — Pure Node.js crypto, no npm packages\n3. **Safe by default** — Masked output, encrypted at rest, no plaintext-on-disk\n4. **Transparent** — Audit reports show exactly what's wrong\n5. **Recoverable** — Master key + encrypted secrets = full recovery\n\n> **Need to inject a secret into a shell command?** Use the separate\n> `secrets-inject` skill (high-privilege, clearly labeled). This store\n> deliberately does not do that.\n\nFile v1.1.17:_meta.json\n\n{\n  \"ownerId\": \"kn7b6eyf5vc7khg5fr63pjm8xd82qvw5\",\n  \"slug\": \"secrets-manager\",\n  \"version\": \"1.1.17\",\n  \"publishedAt\": 1785863381570\n}\n\nFile v1.1.17:skill-card.md\n\n## Description:\n\nSecrets Manager provides an encrypted local secret store for OpenClaw agents using AES-256-GCM, with masked retrieval, listing, rotation, auditing, deletion, and local master-key management.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[jlacroix82](https://clawhub.ai/user/jlacroix82)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and agent operators use this skill to store, retrieve, rotate, audit, and delete local OpenClaw secrets without writing plaintext secrets to disk.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Raw secret output can expose plaintext through terminal scrollback, logs, shared files, CI output, or agent transcripts.\n\nMitigation: Use masked retrieval by default, avoid --get --raw unless necessary, and never redirect plaintext secrets into shared locations such as /tmp.\n\nRisk: Stored secrets are readable by any trusted local agent or process that can access the secret store and master key.\n\nMitigation: Install only inside a trusted local agent/process boundary and keep the chmod 0600 secret data and .master-key files private.\n\nRisk: Loss or exposure of .master-key can make secrets unrecoverable or compromise all stored secrets.\n\nMitigation: Back up .master-key securely and avoid using SECRETS_MASTER_KEY in shared, containerized, CI, or logged environments.\n\nRisk: Delete and rotate operations can remove active values or change credentials unexpectedly.\n\nMitigation: Require explicit user intent before delete or rotate operations and review downstream consumers before rotating secrets.\n\n## Reference(s):\n\n- [Secrets Manager ClawHub listing](https://clawhub.ai/jlacroix82/skills/secrets-manager)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, Shell commands, Configuration, Guidance]\n\n**Output Format:** [Markdown guidance with inline shell commands and text command output]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Masked secret values are the default; raw plaintext can be emitted only when --get --raw is explicitly used.]\n\n## Skill Version(s):\n\n1.1.17 (source: server release metadata and CHANGELOG.txt, released 2026-08-04)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v1.1.17:clawhub.yaml\n\nslug: secrets-manager\nname: secrets-manager\nowner: jlacroix82\ndescription: \"Encrypted local secret store for OpenClaw agents. A PURE STORE: AES-256-GCM authenticated encryption with per-secret random IVs, master key in chmod 0600 .master-key file. Modes: store, get (masked; --raw prints plaintext), list (names+metadata only), delete (irreversible), rotate / rotate --all (archive old as retired), audit (--expired/--stale), status. NEVER writes plaintext secrets to disk or generates executable command scripts — command injection lives in the separate secrets-inject skill. SECRETS_DIR and SECRETS_MASTER_KEY env overrides supported. Losing .master-key makes secrets unrecoverable.\"\nversion: 1.1.17\ntype: skill\nauthor: OpenClaw\nlicense: MIT\nkeywords:\n  - secrets\n  - encryption\n  - aes-256-gcm\n  - rotation\n  - audit\n  - key-management\ncapabilities:\n  - filesystem\n  - environment\n  - crypto\nentry: SKILL.md\ndependencies: []\npermissions:\n  - name: filesystem.read-write\n    description: Read/write data files in memory/secrets/ (secrets.json chmod 0600, .master-key chmod 0600)\n  - name: environment.read\n    description: Read SECRETS_DIR and SECRETS_MASTER_KEY environment variables\n  - name: crypto.aes-256-gcm\n    description: Encrypt/decrypt secrets with AES-256-GCM authenticated encryption\ndata_retention:\n  secrets: 'AES-256-GCM encrypted, chmod 0600, persists until deleted'\n  master_key: '256-bit key in .master-key file, chmod 0600'\nsecurity_notes:\n  - 'Master key auto-generated on first store; backup is your responsibility'\n  - 'Losing .master-key = unrecoverable secrets'\n  - 'Plaintext only printed via explicit --get --raw (to stdout); no plaintext written to disk'\n  - 'SECRETS_MASTER_KEY env override: NEVER set it in shared, containerized, CI, or logged environments — anyone who can read process env or logs can recover the key. Prefer the file-based .master-key (chmod 0600) on a single-user host.'\n  - 'Command injection / secret substitution is NOT provided here; use the separate secrets-inject skill (high-privilege).'\n\nFile v1.1.17:CHANGELOG.txt\n\nSecrets Manager v1.1.17 — Audit-finding remediation (2026-08-04)\n\n- Made data paths lazy (getWorkspace/getDataDir/getSecretsFile/getMasterKeyFile as\n  functions) so the --dir flag and SECRETS_DIR env var are actually honored.\n  Previously WORKSPACE/DATA_DIR were resolved once at module load, so --dir was a\n  deceptive no-op (secrets were still written to the default location). Now --dir\n  reliably redirects storage.\n- Split master-key access into loadMasterKey() (READ-ONLY, no file creation) and\n  ensureMasterKey() (WRITE, generates on first store). Read-only paths (--get,\n  --audit, --status, --list) no longer create or mutate the .master-key file as a\n  side effect.\n- Audit no longer prints plaintext value prefixes. Weak/pattern findings now flag\n  the secret NAME only, never a decrypted value, removing the \"plaintext-derived\n  prefixes during audit\" disclosure.\n- Removed the unenforced --confirm-expose flag from the parser (it was advertised\n  but getSecret never checked it). --raw prints plaintext directly with an explicit\n  warning, as documented.\n\nNo crypto changes — still AES-256-GCM with per-secret IV and authenticated\ndecryption (tamper -> null).\n\nFile v1.1.17:test.txt\n\nTesting\n\nArchive v1.1.16: 12 files, 18832 bytes\n\nFiles: CHANGELOG.txt (1133b), clawhub.yaml (2051b), README.md (4940b), secrets-manager.js (18544b), skill-card.md (3074b), SKILL.md (7505b), test-final.js (2549b), test.txt (8b), test/run-tests.js (1713b), test/test-secrets.js (2243b), tests/run-self-tests.js (9203b), _meta.json (135b)\n\nFile v1.1.16:SKILL.md\n\n---\nname: secrets-manager\ndescription: >-\n  Encrypted local secret store for OpenClaw agents. AES-256-GCM authenticated\n  encryption with per-secret random IVs, master key in chmod 0600 .master-key\n  file. A PURE STORE: it encrypts, retrieves, lists, rotates, audits, and deletes\n  secrets — it never writes plaintext secrets to disk or generates executable\n  command scripts. Modes: --store (encrypt+write), --get (masked; --raw prints\n  plaintext to stdout), --list (names+metadata only), --delete (irreversible),\n  --rotate and --rotate --all (generate new random values, archive old as\n  retired), --audit / --audit --expired / --audit --stale (exposure/rotation\n  checks), --status. Supports SECRETS_DIR and SECRETS_MASTER_KEY env overrides.\n  For injecting secrets into shell commands, use the separate `secrets-inject`\n  skill (high-privilege). Master key is recoverable from .master-key file;\n  losing it makes stored secrets unrecoverable.\npermissions:\n  - filesystem.read-write\n  - environment.read\n  - crypto.aes-256-gcm\n---\n\n# Secrets Manager 🔐\n\n**Encrypted local secret store.** AES-256-GCM authenticated encryption. Master key auto-generated on first store and stored in `memory/secrets/.master-key` (chmod 0600).\n\n> **Important**: If you lose `.master-key`, all stored secrets become unrecoverable. Back it up.\n\n## ⚠️ Important Warnings\n\n### Encryption: AES-256-GCM (Authenticated)\n- 256-bit master key, per-secret 96-bit random IV, 128-bit GCM auth tag\n- Tampered ciphertext returns `null` from decrypt (no partial decryption)\n- Master key stored in `memory/secrets/.master-key` with chmod 0600\n- Override via `SECRETS_MASTER_KEY=<hex>` env var\n- Losing the master key = all secrets unrecoverable\n\n### `--get --raw` Prints Plaintext to stdout\nThe secret value goes to stdout, which may be captured in:\n- Shell history / terminal scrollback\n- Process logs / journald / syslog\n- CI/CD pipeline output\n- Agent transcripts / OpenClaw session history\n\nUse only when piping to a private process:\n```bash\nnode secrets-manager.js --get --raw api-key > /tmp/api-key.txt && chmod 600 /tmp/api-key.txt\n```\n\n### Rotation: Old Values Are Archived\nRotated secrets keep the old encrypted value as `retired`. Rotate again to discard the archive. There is no `--undo` for archival.\n\n### Storage Location\n`memory/secrets/secrets.json` (chmod 0600) plus `memory/secrets/.master-key` (chmod 0600). Override via `--dir <path>` or `SECRETS_DIR=<path>`.\n\n## Quick Start\n\n### Store a secret\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --store openai-key sk-abc123\n# Output: [secrets-manager] Stored: openai-key (masked: sk-****23)\n```\n\n### Get a secret (masked by default)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --get openai-key\n# Output: [secrets-manager] openai-key: sk-****23\n```\n\n### Get raw value (when you must pass it to another tool)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --get --raw openai-key > /tmp/key.txt\n# Output: sk-abc123 (captured to file)\n```\n\n### List all secrets (names + metadata, NOT values)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --list\n```\n\n### Delete a secret\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --delete old-key\n```\n\n### Rotate a secret\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --rotate openai-key\n# New random value generated, old encrypted value archived as retired\n```\n\n### Rotate all secrets\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --rotate --all\n```\n\n### Audit for security issues\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --audit\nnode skills/secrets-manager/secrets-manager.js --audit --expired\nnode skills/secrets-manager/secrets-manager.js --audit --stale\n```\n\n### Status overview\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --status\n```\n\n## Features\n\n### Encryption\n- **AES-256-GCM** authenticated encryption\n- 256-bit master key (auto-generated on first store)\n- 96-bit per-secret random IV\n- 128-bit GCM auth tag (tamper detection)\n- Master key in `memory/secrets/.master-key` (chmod 0600)\n- `SECRETS_MASTER_KEY` env var override\n\n### Rotation Tracking\n- 90-day default rotation cycle per secret\n- Automatic expiration warnings (audit --stale at 70% of cycle)\n- One-command rotation with new random value generation\n- Old values archived as `retired` (encrypted, recoverable until next rotate)\n\n### Audit System\n- Detects expired secrets past rotation date\n- Flags secrets approaching rotation deadline (70% threshold)\n- Identifies weak patterns (common prefixes, short length <8 chars)\n- Detects decryption failures (tampered ciphertext or wrong master key)\n- Reports rotation age for each secret\n\n## Configuration\n\nData stored in: `memory/secrets/`\n- `secrets.json` — encrypted secrets (chmod 0600)\n- `.master-key` — 256-bit master key as hex (chmod 0600)\n\nNote: This skill has NO access-control / permissions subsystem. All stored\nsecrets are readable by the same agent/process that runs this skill. There is\nno per-secret authorization layer — isolation is provided only by filesystem\npermissions (chmod 0600 on the data files) and by keeping `.master-key` private.\n\nOverride storage location:\n```bash\n--dir /path/to/secrets\n# or env var\nSECRETS_DIR=/path/to/secrets node secrets-manager.js --status\n```\n\nOverride master key:\n```bash\nSECRETS_MASTER_KEY=<64-hex-chars> node secrets-manager.js --get openai-key\n```\n\n## Agent Protocol\n\nWhen handling secrets:\n\n1. **Store with encryption** — `--store <name> <value>` writes AES-256-GCM ciphertext\n2. **Default to masked output** — `--get` (not `--get --raw`) for display\n3. **Audit regularly** — `--audit` during heartbeats\n5. **Rotate proactively** — rotate secrets flagged as expiring\n6. **Back up `.master-key`** — without it, stored secrets are unrecoverable\n\n## Security Notes\n\n- **AES-256-GCM authenticated encryption** — secrets are encrypted at rest, not base64-encoded\n- **Master key** in `memory/secrets/.master-key` (chmod 0600) — back it up\n- For production-grade secrets with HSM-backed keys, use a real vault (HashiCorp, AWS Secrets Manager, OS keychain)\n- `SECRETS_MASTER_KEY` env var for ephemeral/CI environments\n\n## What This Skill Does NOT Do\n\n- Does NOT store secrets in plaintext or base64 — all values are AES-256-GCM encrypted\n- Does NOT print secret values to stdout unless explicitly requested via `--get --raw`\n- Does NOT install npm packages\n- Does NOT phone home or transmit secrets anywhere\n- Does NOT log secret values\n- Does NOT require a separate key server — master key is a local file\n\n## Comparison\n\n| Approach | Encryption | Setup | Audit | Rotation | Recovery |\n|----------|-----------|-------|-------|----------|----------|\n| Environment vars | None | Medium | None | Manual | N/A |\n| .env files | None | Low | None | Manual | N/A |\n| **Secrets Manager** | **AES-256-GCM** | **None** | **Auto** | **Auto** | **With .master-key** |\n| Vault service | Various | High | Auto | Auto | Yes |\n\n**Secrets Manager gives you real encryption + rotation + audit with zero external dependencies.**\n\n## Design Principles\n\n1. **Zero setup** — Works immediately, no config needed\n2. **No dependencies** — Pure Node.js crypto, no npm packages\n3. **Safe by default** — Masked output, encrypted at rest, no plaintext-on-disk\n4. **Transparent** — Audit reports show exactly what's wrong\n5. **Recoverable** — Master key + encrypted secrets = full recovery\n\n<!-- clawhub-sync: 2026-07-22 v1.1.9 security audit remediation -->\n\nFile v1.1.16:README.md\n\n# Secrets Manager 🔐\n\n**Encrypted local secret store.** AES-256-GCM authenticated encryption, rotation\ntracking, audit, and delete. A **PURE STORE** — it encrypts, retrieves, lists,\nrotates, audits, and deletes secrets. It does **not** generate executable command\nscripts and does **not** write plaintext secrets to disk.\n\n> **Important**: If you lose `.master-key`, all stored secrets become unrecoverable. Back it up.\n\n## Security model\n\n- **AES-256-GCM** authenticated encryption (tamper → decrypt returns `null`)\n- 256-bit master key, auto-generated on first store, stored in\n  `memory/secrets/.master-key` (chmod 0600)\n- Per-secret random 96-bit IV, 128-bit GCM auth tag\n- Encrypted secrets persist in `memory/secrets/secrets.json` (chmod 0600)\n- No plaintext secrets are ever written to disk or to logs\n\n## Quick Start\n\n```bash\n# Store a secret (encrypted at rest)\nnode secrets-manager.js --store openai-key sk-abc123\n# → Stored: openai-key (masked: sk-****23)\n\n# Get a secret (masked by default)\nnode secrets-manager.js --get openai-key\n# → openai-key: sk-****23\n\n# Get the raw value (prints to stdout — use only when you must pass it onward)\nnode secrets-manager.js --get --raw openai-key > /tmp/key.txt && chmod 600 /tmp/key.txt\n\n# List secret names + metadata (never values)\nnode secrets-manager.js --list\n\n# Delete a secret (irreversible)\nnode secrets-manager.js --delete old-key\n\n# Rotate a secret (generates a new random value; old value archived as retired)\nnode secrets-manager.js --rotate openai-key\n\n# Rotate all secrets\nnode secrets-manager.js --rotate --all\n\n# Audit for exposure / rotation issues\nnode secrets-manager.js --audit\nnode secrets-manager.js --audit --expired\nnode secrets-manager.js --audit --stale\n\n# Status overview\nnode secrets-manager.js --status\n```\n\n## Features\n\n- **Encryption** — AES-256-GCM, per-secret IV, authenticated (tamper detection)\n- **Rotation tracking** — 90-day default cycle, expiration warnings, one-command rotation\n- **Audit system** — flags expired/stale secrets, weak patterns, decryption failures\n- **Masked by default** — values never printed unless explicitly requested via `--get --raw`\n- **Zero plaintext-on-disk** — secrets are encrypted at rest; no temp scripts are generated\n\n## Configuration\n\nData stored in `memory/secrets/`:\n- `secrets.json` — encrypted secrets (chmod 0600)\n- `.master-key` — 256-bit master key as hex (chmod 0600)\n\nThis skill has NO per-secret access-control subsystem. All secrets are readable\nby the same agent/process that runs this skill; isolation is provided only by\nfilesystem permissions (chmod 0600 on the data files) and by keeping\n`.master-key` private.\n\nOverride storage location:\n```bash\nSECRETS_DIR=/path/to/secrets node secrets-manager.js --status\n```\n\nOverride master key (ephemeral/CI only):\n```bash\nSECRETS_MASTER_KEY=<64-hex-chars> node secrets-manager.js --get openai-key\n```\n> Never set `SECRETS_MASTER_KEY` in shared, containerized, CI, or logged\n> environments — anyone who can read process env or logs can recover the key.\n> Prefer the file-based `.master-key` (chmod 0600) on a single-user host.\n\n## Agent Protocol\n\n1. **Store with encryption** — `--store <name> <value>` writes AES-256-GCM ciphertext\n2. **Default to masked output** — `--get` (not `--get --raw`) for display\n3. **Audit regularly** — `--audit` during heartbeats\n4. **Rotate proactively** — rotate secrets flagged as expiring\n5. **Back up `.master-key`** — without it, stored secrets are unrecoverable\n\n## Security Notes\n\n- AES-256-GCM authenticated encryption — secrets encrypted at rest, not base64\n- Master key in `memory/secrets/.master-key` (chmod 0600) — back it up\n- For production-grade secrets with HSM-backed keys, use a real vault\n  (HashiCorp, AWS Secrets Manager, OS keychain)\n- `SECRETS_MASTER_KEY` env var for ephemeral/CI environments\n- **No plaintext is written to disk** — the store only ever holds ciphertext\n\n## What This Skill Does NOT Do\n\n- Does NOT store secrets in plaintext or base64 — all values are AES-256-GCM encrypted\n- Does NOT print secret values to stdout unless explicitly requested via `--get --raw`\n- Does NOT generate executable command scripts (no `--inject`)\n- Does NOT install npm packages\n- Does NOT phone home or transmit secrets anywhere\n- Does NOT log secret values\n- Does NOT require a separate key server — master key is a local file\n\n## Design Principles\n\n1. **Zero setup** — Works immediately, no config needed\n2. **No dependencies** — Pure Node.js crypto, no npm packages\n3. **Safe by default** — Masked output, encrypted at rest, no plaintext-on-disk\n4. **Transparent** — Audit reports show exactly what's wrong\n5. **Recoverable** — Master key + encrypted secrets = full recovery\n\n> **Need to inject a secret into a shell command?** Use the separate\n> `secrets-inject` skill (high-privilege, clearly labeled). This store\n> deliberately does not do that.\n\nFile v1.1.16:_meta.json\n\n{\n  \"ownerId\": \"kn7b6eyf5vc7khg5fr63pjm8xd82qvw5\",\n  \"slug\": \"secrets-manager\",\n  \"version\": \"1.1.16\",\n  \"publishedAt\": 1785861872233\n}\n\nFile v1.1.16:skill-card.md\n\n## Description:\n\nSecrets Manager is a local encrypted secret store for OpenClaw agents that stores, retrieves, lists, rotates, audits, and deletes secrets using AES-256-GCM with a local master key.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[jlacroix82](https://clawhub.ai/user/jlacroix82)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and agents use this skill to manage local secrets with encrypted-at-rest storage, masked retrieval, rotation tracking, audit checks, and irreversible deletion. It is intended for a local single-user or single-agent trust boundary, not as a multi-user access-control system.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The security review marks this credential-handling skill as requiring review because some controls are under-scoped for shared or multi-agent environments.\n\nMitigation: Install only within a single-user or single-agent local trust boundary, and use an OS keychain or external vault for production, CI, shared hosts, or multi-agent deployments.\n\nRisk: Secrets retrieved with --get --raw are printed to stdout and may be captured in logs, terminal history, CI output, or agent transcripts.\n\nMitigation: Avoid --get --raw unless stdout is protected; when raw access is required, pipe or redirect only to a private process or a chmod 0600 file.\n\nRisk: The security guidance says not to rely on the CLI --dir flag until fixed and to verify where secrets are written.\n\nMitigation: Prefer SECRETS_DIR for storage-location overrides and verify the resolved secrets directory before storing credentials.\n\nRisk: The skill has no per-secret access-control layer; any process that can run the skill and access the master key can read stored secrets.\n\nMitigation: Protect the data directory and .master-key with filesystem permissions, limit host access, and avoid sharing the same store across users or agents.\n\nRisk: Losing the local .master-key makes stored secrets unrecoverable.\n\nMitigation: Back up the master key securely and keep the backup separate from logs, transcripts, and shared environments.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/jlacroix82/skills/secrets-manager)\n- [README](artifact/README.md)\n- [Release changelog](artifact/CHANGELOG.txt)\n\n## Skill Output:\n\n**Output Type(s):** [text, shell commands, configuration, guidance]\n\n**Output Format:** [Plain text CLI output with masked values by default; raw plaintext may be printed only when explicitly requested.]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Writes encrypted local secret records and a local master key file; does not produce public Markdown.]\n\n## Skill Version(s):\n\n1.1.16 (source: server release metadata and artifact changelog, released 2026-08-04)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v1.1.16:clawhub.yaml\n\nslug: secrets-manager\nname: secrets-manager\nowner: jlacroix82\ndescription: \"Encrypted local secret store for OpenClaw agents. A PURE STORE: AES-256-GCM authenticated encryption with per-secret random IVs, master key in chmod 0600 .master-key file. Modes: store, get (masked; --raw prints plaintext), list (names+metadata only), delete (irreversible), rotate / rotate --all (archive old as retired), audit (--expired/--stale), status. NEVER writes plaintext secrets to disk or generates executable command scripts — command injection lives in the separate secrets-inject skill. SECRETS_DIR and SECRETS_MASTER_KEY env overrides supported. Losing .master-key makes secrets unrecoverable.\"\nversion: 1.1.16\ntype: skill\nauthor: OpenClaw\nlicense: MIT\nkeywords:\n  - secrets\n  - encryption\n  - aes-256-gcm\n  - rotation\n  - audit\n  - key-management\ncapabilities:\n  - filesystem\n  - environment\n  - crypto\nentry: SKILL.md\ndependencies: []\npermissions:\n  - name: filesystem.read-write\n    description: Read/write data files in memory/secrets/ (secrets.json chmod 0600, .master-key chmod 0600)\n  - name: environment.read\n    description: Read SECRETS_DIR and SECRETS_MASTER_KEY environment variables\n  - name: crypto.aes-256-gcm\n    description: Encrypt/decrypt secrets with AES-256-GCM authenticated encryption\ndata_retention:\n  secrets: 'AES-256-GCM encrypted, chmod 0600, persists until deleted'\n  master_key: '256-bit key in .master-key file, chmod 0600'\nsecurity_notes:\n  - 'Master key auto-generated on first store; backup is your responsibility'\n  - 'Losing .master-key = unrecoverable secrets'\n  - 'Plaintext only printed via explicit --get --raw (to stdout); no plaintext written to disk'\n  - 'SECRETS_MASTER_KEY env override: NEVER set it in shared, containerized, CI, or logged environments — anyone who can read process env or logs can recover the key. Prefer the file-based .master-key (chmod 0600) on a single-user host.'\n  - 'Command injection / secret substitution is NOT provided here; use the separate secrets-inject skill (high-privilege).'\n\nFile v1.1.16:CHANGELOG.txt\n\nSecrets Manager v1.1.16 — Audit-finding remediation (2026-08-04)\n\n- Removed the phantom permissions.json subsystem. The code never read or wrote\n  permissions.json, and status no longer reports \"Permissions rules\". Documented\n  explicitly that this skill has NO per-secret access-control layer; isolation is\n  provided only by filesystem chmod 0600 on secrets.json/.master-key and by\n  keeping .master-key private.\n- Workspace resolution is now deterministic (fixed repo-root, no upward walk\n  searching for MEMORY.md), matching the env-manager fix and removing the\n  workspace-discovery behavior the audit flagged.\n- getSecret --raw: corrected the misleading \"NEVER print unless explicitly\n  confirmed\" comment. --raw prints the plaintext directly with no confirmation\n  gate; the warning now tells operators to redirect to a protected file.\n- deleteSecret: added an explicit IRREVERSIBLE warning (no prompt, no undo) so\n  operators are not surprised by permanent, unrecoverable destruction.\n\nNo crypto changes — still AES-256-GCM with per-secret IV and authenticated\ndecryption (tamper -> null). Master key handling unchanged.\n\nFile v1.1.16:test.txt\n\nTesting\n\nArchive v1.1.15: 12 files, 17801 bytes\n\nFiles: CHANGELOG.txt (777b), clawhub.yaml (2051b), README.md (4751b), secrets-manager.js (18133b), skill-card.md (2239b), SKILL.md (7253b), test-final.js (2549b), test.txt (8b), test/run-tests.js (1713b), test/test-secrets.js (2243b), tests/run-self-tests.js (9203b), _meta.json (135b)\n\nFile v1.1.15:SKILL.md\n\n---\nname: secrets-manager\ndescription: >-\n  Encrypted local secret store for OpenClaw agents. AES-256-GCM authenticated\n  encryption with per-secret random IVs, master key in chmod 0600 .master-key\n  file. A PURE STORE: it encrypts, retrieves, lists, rotates, audits, and deletes\n  secrets — it never writes plaintext secrets to disk or generates executable\n  command scripts. Modes: --store (encrypt+write), --get (masked; --raw prints\n  plaintext to stdout), --list (names+metadata only), --delete (irreversible),\n  --rotate and --rotate --all (generate new random values, archive old as\n  retired), --audit / --audit --expired / --audit --stale (exposure/rotation\n  checks), --status. Supports SECRETS_DIR and SECRETS_MASTER_KEY env overrides.\n  For injecting secrets into shell commands, use the separate `secrets-inject`\n  skill (high-privilege). Master key is recoverable from .master-key file;\n  losing it makes stored secrets unrecoverable.\npermissions:\n  - filesystem.read-write\n  - environment.read\n  - crypto.aes-256-gcm\n---\n\n# Secrets Manager 🔐\n\n**Encrypted local secret store.** AES-256-GCM authenticated encryption. Master key auto-generated on first store and stored in `memory/secrets/.master-key` (chmod 0600).\n\n> **Important**: If you lose `.master-key`, all stored secrets become unrecoverable. Back it up.\n\n## ⚠️ Important Warnings\n\n### Encryption: AES-256-GCM (Authenticated)\n- 256-bit master key, per-secret 96-bit random IV, 128-bit GCM auth tag\n- Tampered ciphertext returns `null` from decrypt (no partial decryption)\n- Master key stored in `memory/secrets/.master-key` with chmod 0600\n- Override via `SECRETS_MASTER_KEY=<hex>` env var\n- Losing the master key = all secrets unrecoverable\n\n### `--get --raw` Prints Plaintext to stdout\nThe secret value goes to stdout, which may be captured in:\n- Shell history / terminal scrollback\n- Process logs / journald / syslog\n- CI/CD pipeline output\n- Agent transcripts / OpenClaw session history\n\nUse only when piping to a private process:\n```bash\nnode secrets-manager.js --get --raw api-key > /tmp/api-key.txt && chmod 600 /tmp/api-key.txt\n```\n\n### Rotation: Old Values Are Archived\nRotated secrets keep the old encrypted value as `retired`. Rotate again to discard the archive. There is no `--undo` for archival.\n\n### Storage Location\n`memory/secrets/secrets.json` (chmod 0600) plus `memory/secrets/.master-key` (chmod 0600). Override via `--dir <path>` or `SECRETS_DIR=<path>`.\n\n## Quick Start\n\n### Store a secret\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --store openai-key sk-abc123\n# Output: [secrets-manager] Stored: openai-key (masked: sk-****23)\n```\n\n### Get a secret (masked by default)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --get openai-key\n# Output: [secrets-manager] openai-key: sk-****23\n```\n\n### Get raw value (when you must pass it to another tool)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --get --raw openai-key > /tmp/key.txt\n# Output: sk-abc123 (captured to file)\n```\n\n### List all secrets (names + metadata, NOT values)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --list\n```\n\n### Delete a secret\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --delete old-key\n```\n\n### Rotate a secret\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --rotate openai-key\n# New random value generated, old encrypted value archived as retired\n```\n\n### Rotate all secrets\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --rotate --all\n```\n\n### Audit for security issues\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --audit\nnode skills/secrets-manager/secrets-manager.js --audit --expired\nnode skills/secrets-manager/secrets-manager.js --audit --stale\n```\n\n### Status overview\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --status\n```\n\n## Features\n\n### Encryption\n- **AES-256-GCM** authenticated encryption\n- 256-bit master key (auto-generated on first store)\n- 96-bit per-secret random IV\n- 128-bit GCM auth tag (tamper detection)\n- Master key in `memory/secrets/.master-key` (chmod 0600)\n- `SECRETS_MASTER_KEY` env var override\n\n### Rotation Tracking\n- 90-day default rotation cycle per secret\n- Automatic expiration warnings (audit --stale at 70% of cycle)\n- One-command rotation with new random value generation\n- Old values archived as `retired` (encrypted, recoverable until next rotate)\n\n### Audit System\n- Detects expired secrets past rotation date\n- Flags secrets approaching rotation deadline (70% threshold)\n- Identifies weak patterns (common prefixes, short length <8 chars)\n- Detects decryption failures (tampered ciphertext or wrong master key)\n- Reports rotation age for each secret\n\n## Configuration\n\nData stored in: `memory/secrets/`\n- `secrets.json` — encrypted secrets (chmod 0600)\n- `.master-key` — 256-bit master key as hex (chmod 0600)\n- `permissions.json` — per-secret access rules (chmod 0600)\n\nOverride storage location:\n```bash\n--dir /path/to/secrets\n# or env var\nSECRETS_DIR=/path/to/secrets node secrets-manager.js --status\n```\n\nOverride master key:\n```bash\nSECRETS_MASTER_KEY=<64-hex-chars> node secrets-manager.js --get openai-key\n```\n\n## Agent Protocol\n\nWhen handling secrets:\n\n1. **Store with encryption** — `--store <name> <value>` writes AES-256-GCM ciphertext\n2. **Default to masked output** — `--get` (not `--get --raw`) for display\n3. **Audit regularly** — `--audit` during heartbeats\n5. **Rotate proactively** — rotate secrets flagged as expiring\n6. **Back up `.master-key`** — without it, stored secrets are unrecoverable\n\n## Security Notes\n\n- **AES-256-GCM authenticated encryption** — secrets are encrypted at rest, not base64-encoded\n- **Master key** in `memory/secrets/.master-key` (chmod 0600) — back it up\n- For production-grade secrets with HSM-backed keys, use a real vault (HashiCorp, AWS Secrets Manager, OS keychain)\n- `SECRETS_MASTER_KEY` env var for ephemeral/CI environments\n\n## What This Skill Does NOT Do\n\n- Does NOT store secrets in plaintext or base64 — all values are AES-256-GCM encrypted\n- Does NOT print secret values to stdout unless explicitly requested via `--get --raw`\n- Does NOT install npm packages\n- Does NOT phone home or transmit secrets anywhere\n- Does NOT log secret values\n- Does NOT require a separate key server — master key is a local file\n\n## Comparison\n\n| Approach | Encryption | Setup | Audit | Rotation | Recovery |\n|----------|-----------|-------|-------|----------|----------|\n| Environment vars | None | Medium | None | Manual | N/A |\n| .env files | None | Low | None | Manual | N/A |\n| **Secrets Manager** | **AES-256-GCM** | **None** | **Auto** | **Auto** | **With .master-key** |\n| Vault service | Various | High | Auto | Auto | Yes |\n\n**Secrets Manager gives you real encryption + rotation + audit with zero external dependencies.**\n\n## Design Principles\n\n1. **Zero setup** — Works immediately, no config needed\n2. **No dependencies** — Pure Node.js crypto, no npm packages\n3. **Safe by default** — Masked output, encrypted at rest, no plaintext-on-disk\n4. **Transparent** — Audit reports show exactly what's wrong\n5. **Recoverable** — Master key + encrypted secrets = full recovery\n\n<!-- clawhub-sync: 2026-07-22 v1.1.9 security audit remediation -->\n\nFile v1.1.15:README.md\n\n# Secrets Manager 🔐\n\n**Encrypted local secret store.** AES-256-GCM authenticated encryption, rotation\ntracking, audit, and delete. A **PURE STORE** — it encrypts, retrieves, lists,\nrotates, audits, and deletes secrets. It does **not** generate executable command\nscripts and does **not** write plaintext secrets to disk.\n\n> **Important**: If you lose `.master-key`, all stored secrets become unrecoverable. Back it up.\n\n## Security model\n\n- **AES-256-GCM** authenticated encryption (tamper → decrypt returns `null`)\n- 256-bit master key, auto-generated on first store, stored in\n  `memory/secrets/.master-key` (chmod 0600)\n- Per-secret random 96-bit IV, 128-bit GCM auth tag\n- Encrypted secrets persist in `memory/secrets/secrets.json` (chmod 0600)\n- No plaintext secrets are ever written to disk or to logs\n\n## Quick Start\n\n```bash\n# Store a secret (encrypted at rest)\nnode secrets-manager.js --store openai-key sk-abc123\n# → Stored: openai-key (masked: sk-****23)\n\n# Get a secret (masked by default)\nnode secrets-manager.js --get openai-key\n# → openai-key: sk-****23\n\n# Get the raw value (prints to stdout — use only when you must pass it onward)\nnode secrets-manager.js --get --raw openai-key > /tmp/key.txt && chmod 600 /tmp/key.txt\n\n# List secret names + metadata (never values)\nnode secrets-manager.js --list\n\n# Delete a secret (irreversible)\nnode secrets-manager.js --delete old-key\n\n# Rotate a secret (generates a new random value; old value archived as retired)\nnode secrets-manager.js --rotate openai-key\n\n# Rotate all secrets\nnode secrets-manager.js --rotate --all\n\n# Audit for exposure / rotation issues\nnode secrets-manager.js --audit\nnode secrets-manager.js --audit --expired\nnode secrets-manager.js --audit --stale\n\n# Status overview\nnode secrets-manager.js --status\n```\n\n## Features\n\n- **Encryption** — AES-256-GCM, per-secret IV, authenticated (tamper detection)\n- **Rotation tracking** — 90-day default cycle, expiration warnings, one-command rotation\n- **Audit system** — flags expired/stale secrets, weak patterns, decryption failures\n- **Masked by default** — values never printed unless explicitly requested via `--get --raw`\n- **Zero plaintext-on-disk** — secrets are encrypted at rest; no temp scripts are generated\n\n## Configuration\n\nData stored in `memory/secrets/`:\n- `secrets.json` — encrypted secrets (chmod 0600)\n- `.master-key` — 256-bit master key as hex (chmod 0600)\n- `permissions.json` — per-secret access rules (chmod 0600)\n\nOverride storage location:\n```bash\nSECRETS_DIR=/path/to/secrets node secrets-manager.js --status\n```\n\nOverride master key (ephemeral/CI only):\n```bash\nSECRETS_MASTER_KEY=<64-hex-chars> node secrets-manager.js --get openai-key\n```\n> Never set `SECRETS_MASTER_KEY` in shared, containerized, CI, or logged\n> environments — anyone who can read process env or logs can recover the key.\n> Prefer the file-based `.master-key` (chmod 0600) on a single-user host.\n\n## Agent Protocol\n\n1. **Store with encryption** — `--store <name> <value>` writes AES-256-GCM ciphertext\n2. **Default to masked output** — `--get` (not `--get --raw`) for display\n3. **Audit regularly** — `--audit` during heartbeats\n4. **Rotate proactively** — rotate secrets flagged as expiring\n5. **Back up `.master-key`** — without it, stored secrets are unrecoverable\n\n## Security Notes\n\n- AES-256-GCM authenticated encryption — secrets encrypted at rest, not base64\n- Master key in `memory/secrets/.master-key` (chmod 0600) — back it up\n- For production-grade secrets with HSM-backed keys, use a real vault\n  (HashiCorp, AWS Secrets Manager, OS keychain)\n- `SECRETS_MASTER_KEY` env var for ephemeral/CI environments\n- **No plaintext is written to disk** — the store only ever holds ciphertext\n\n## What This Skill Does NOT Do\n\n- Does NOT store secrets in plaintext or base64 — all values are AES-256-GCM encrypted\n- Does NOT print secret values to stdout unless explicitly requested via `--get --raw`\n- Does NOT generate executable command scripts (no `--inject`)\n- Does NOT install npm packages\n- Does NOT phone home or transmit secrets anywhere\n- Does NOT log secret values\n- Does NOT require a separate key server — master key is a local file\n\n## Design Principles\n\n1. **Zero setup** — Works immediately, no config needed\n2. **No dependencies** — Pure Node.js crypto, no npm packages\n3. **Safe by default** — Masked output, encrypted at rest, no plaintext-on-disk\n4. **Transparent** — Audit reports show exactly what's wrong\n5. **Recoverable** — Master key + encrypted secrets = full recovery\n\n> **Need to inject a secret into a shell command?** Use the separate\n> `secrets-inject` skill (high-privilege, clearly labeled). This store\n> deliberately does not do that.\n\nFile v1.1.15:_meta.json\n\n{\n  \"ownerId\": \"kn7b6eyf5vc7khg5fr63pjm8xd82qvw5\",\n  \"slug\": \"secrets-manager\",\n  \"version\": \"1.1.15\",\n  \"publishedAt\": 1785856940261\n}\n\nFile v1.1.15:skill-card.md\n\n## Description:\n\nEncrypted local secret store for OpenClaw agents that stores, retrieves, lists, rotates, audits, and deletes secrets using AES-256-GCM authenticated encryption with a local master key.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[jlacroix82](https://clawhub.ai/user/jlacroix82)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and agent operators use this skill to keep local agent secrets encrypted at rest, retrieve masked values by default, rotate stored secrets, and audit rotation or exposure issues.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Plaintext secrets can be exposed through command arguments, raw stdout, temp files, CI logs, or agent transcripts.\n\nMitigation: Use masked retrieval by default, avoid real secrets in command arguments or logged environments, and reserve raw output for private local piping only.\n\nRisk: Audit output may contain sensitive material until the plaintext-prefix issue is fixed.\n\nMitigation: Treat audit output as sensitive and avoid sharing it in logs, transcripts, or public issue reports.\n\nRisk: Local permissions metadata is not a complete access-control boundary.\n\nMitigation: Use the skill only in a local, single-user environment and do not rely on permissions.json for security isolation.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/jlacroix82/skills/secrets-manager)\n- [README.md](artifact/README.md)\n- [CHANGELOG.txt](artifact/CHANGELOG.txt)\n\n## Skill Output:\n\n**Output Type(s):** [text, shell commands, configuration]\n\n**Output Format:** [CLI text output with masked secret values by default and optional raw stdout for explicit retrieval]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Writes encrypted local secret data and a local master-key file under the configured secrets directory.]\n\n## Skill Version(s):\n\n1.1.15 (source: server release evidence and artifact/clawhub.yaml)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v1.1.15:clawhub.yaml\n\nslug: secrets-manager\nname: secrets-manager\nowner: jlacroix82\ndescription: \"Encrypted local secret store for OpenClaw agents. A PURE STORE: AES-256-GCM authenticated encryption with per-secret random IVs, master key in chmod 0600 .master-key file. Modes: store, get (masked; --raw prints plaintext), list (names+metadata only), delete (irreversible), rotate / rotate --all (archive old as retired), audit (--expired/--stale), status. NEVER writes plaintext secrets to disk or generates executable command scripts — command injection lives in the separate secrets-inject skill. SECRETS_DIR and SECRETS_MASTER_KEY env overrides supported. Losing .master-key makes secrets unrecoverable.\"\nversion: 1.1.15\ntype: skill\nauthor: OpenClaw\nlicense: MIT\nkeywords:\n  - secrets\n  - encryption\n  - aes-256-gcm\n  - rotation\n  - audit\n  - key-management\ncapabilities:\n  - filesystem\n  - environment\n  - crypto\nentry: SKILL.md\ndependencies: []\npermissions:\n  - name: filesystem.read-write\n    description: Read/write data files in memory/secrets/ (secrets.json chmod 0600, .master-key chmod 0600)\n  - name: environment.read\n    description: Read SECRETS_DIR and SECRETS_MASTER_KEY environment variables\n  - name: crypto.aes-256-gcm\n    description: Encrypt/decrypt secrets with AES-256-GCM authenticated encryption\ndata_retention:\n  secrets: 'AES-256-GCM encrypted, chmod 0600, persists until deleted'\n  master_key: '256-bit key in .master-key file, chmod 0600'\nsecurity_notes:\n  - 'Master key auto-generated on first store; backup is your responsibility'\n  - 'Losing .master-key = unrecoverable secrets'\n  - 'Plaintext only printed via explicit --get --raw (to stdout); no plaintext written to disk'\n  - 'SECRETS_MASTER_KEY env override: NEVER set it in shared, containerized, CI, or logged environments — anyone who can read process env or logs can recover the key. Prefer the file-based .master-key (chmod 0600) on a single-user host.'\n  - 'Command injection / secret substitution is NOT provided here; use the separate secrets-inject skill (high-privilege).'\n\nFile v1.1.15:CHANGELOG.txt\n\nSecrets Manager v1.1.15 — Documentation alignment (2026-08-04)\n\nRemoves all references to secret injection / temp-file generation from this\nskill's documentation and tests. This skill is now an explicit PURE STORE:\nit encrypts, retrieves, lists, rotates, audits, and deletes secrets, and does\nnot generate executable command scripts or write plaintext secrets to disk.\n\nThe command-injection capability was moved to the separate `secrets-inject`\nskill (high-privilege, clearly labeled). Any earlier changelog entries that\ndescribe temp injection files or \"safe command injection\" referred to prior\nversions and do not apply to v1.1.14+.\n\nNo crypto changes — still AES-256-GCM with per-secret IV and authenticated\ndecryption (tamper -> null). Master key handling unchanged.\n\nFile v1.1.15:test.txt\n\nTesting\n\nArchive v1.1.14: 12 files, 19070 bytes\n\nFiles: CHANGELOG.txt (770b), clawhub.yaml (2051b), README.md (6127b), secrets-manager.js (18133b), skill-card.md (2261b), SKILL.md (7253b), test-final.js (2802b), test.txt (8b), test/run-tests.js (2044b), test/test-secrets.js (2496b), tests/run-self-tests.js (11102b), _meta.json (135b)\n\nFile v1.1.14:SKILL.md\n\n---\nname: secrets-manager\ndescription: >-\n  Encrypted local secret store for OpenClaw agents. AES-256-GCM authenticated\n  encryption with per-secret random IVs, master key in chmod 0600 .master-key\n  file. A PURE STORE: it encrypts, retrieves, lists, rotates, audits, and deletes\n  secrets — it never writes plaintext secrets to disk or generates executable\n  command scripts. Modes: --store (encrypt+write), --get (masked; --raw prints\n  plaintext to stdout), --list (names+metadata only), --delete (irreversible),\n  --rotate and --rotate --all (generate new random values, archive old as\n  retired), --audit / --audit --expired / --audit --stale (exposure/rotation\n  checks), --status. Supports SECRETS_DIR and SECRETS_MASTER_KEY env overrides.\n  For injecting secrets into shell commands, use the separate `secrets-inject`\n  skill (high-privilege). Master key is recoverable from .master-key file;\n  losing it makes stored secrets unrecoverable.\npermissions:\n  - filesystem.read-write\n  - environment.read\n  - crypto.aes-256-gcm\n---\n\n# Secrets Manager 🔐\n\n**Encrypted local secret store.** AES-256-GCM authenticated encryption. Master key auto-generated on first store and stored in `memory/secrets/.master-key` (chmod 0600).\n\n> **Important**: If you lose `.master-key`, all stored secrets become unrecoverable. Back it up.\n\n## ⚠️ Important Warnings\n\n### Encryption: AES-256-GCM (Authenticated)\n- 256-bit master key, per-secret 96-bit random IV, 128-bit GCM auth tag\n- Tampered ciphertext returns `null` from decrypt (no partial decryption)\n- Master key stored in `memory/secrets/.master-key` with chmod 0600\n- Override via `SECRETS_MASTER_KEY=<hex>` env var\n- Losing the master key = all secrets unrecoverable\n\n### `--get --raw` Prints Plaintext to stdout\nThe secret value goes to stdout, which may be captured in:\n- Shell history / terminal scrollback\n- Process logs / journald / syslog\n- CI/CD pipeline output\n- Agent transcripts / OpenClaw session history\n\nUse only when piping to a private process:\n```bash\nnode secrets-manager.js --get --raw api-key > /tmp/api-key.txt && chmod 600 /tmp/api-key.txt\n```\n\n### Rotation: Old Values Are Archived\nRotated secrets keep the old encrypted value as `retired`. Rotate again to discard the archive. There is no `--undo` for archival.\n\n### Storage Location\n`memory/secrets/secrets.json` (chmod 0600) plus `memory/secrets/.master-key` (chmod 0600). Override via `--dir <path>` or `SECRETS_DIR=<path>`.\n\n## Quick Start\n\n### Store a secret\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --store openai-key sk-abc123\n# Output: [secrets-manager] Stored: openai-key (masked: sk-****23)\n```\n\n### Get a secret (masked by default)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --get openai-key\n# Output: [secrets-manager] openai-key: sk-****23\n```\n\n### Get raw value (when you must pass it to another tool)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --get --raw openai-key > /tmp/key.txt\n# Output: sk-abc123 (captured to file)\n```\n\n### List all secrets (names + metadata, NOT values)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --list\n```\n\n### Delete a secret\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --delete old-key\n```\n\n### Rotate a secret\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --rotate openai-key\n# New random value generated, old encrypted value archived as retired\n```\n\n### Rotate all secrets\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --rotate --all\n```\n\n### Audit for security issues\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --audit\nnode skills/secrets-manager/secrets-manager.js --audit --expired\nnode skills/secrets-manager/secrets-manager.js --audit --stale\n```\n\n### Status overview\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --status\n```\n\n## Features\n\n### Encryption\n- **AES-256-GCM** authenticated encryption\n- 256-bit master key (auto-generated on first store)\n- 96-bit per-secret random IV\n- 128-bit GCM auth tag (tamper detection)\n- Master key in `memory/secrets/.master-key` (chmod 0600)\n- `SECRETS_MASTER_KEY` env var override\n\n### Rotation Tracking\n- 90-day default rotation cycle per secret\n- Automatic expiration warnings (audit --stale at 70% of cycle)\n- One-command rotation with new random value generation\n- Old values archived as `retired` (encrypted, recoverable until next rotate)\n\n### Audit System\n- Detects expired secrets past rotation date\n- Flags secrets approaching rotation deadline (70% threshold)\n- Identifies weak patterns (common prefixes, short length <8 chars)\n- Detects decryption failures (tampered ciphertext or wrong master key)\n- Reports rotation age for each secret\n\n## Configuration\n\nData stored in: `memory/secrets/`\n- `secrets.json` — encrypted secrets (chmod 0600)\n- `.master-key` — 256-bit master key as hex (chmod 0600)\n- `permissions.json` — per-secret access rules (chmod 0600)\n\nOverride storage location:\n```bash\n--dir /path/to/secrets\n# or env var\nSECRETS_DIR=/path/to/secrets node secrets-manager.js --status\n```\n\nOverride master key:\n```bash\nSECRETS_MASTER_KEY=<64-hex-chars> node secrets-manager.js --get openai-key\n```\n\n## Agent Protocol\n\nWhen handling secrets:\n\n1. **Store with encryption** — `--store <name> <value>` writes AES-256-GCM ciphertext\n2. **Default to masked output** — `--get` (not `--get --raw`) for display\n3. **Audit regularly** — `--audit` during heartbeats\n5. **Rotate proactively** — rotate secrets flagged as expiring\n6. **Back up `.master-key`** — without it, stored secrets are unrecoverable\n\n## Security Notes\n\n- **AES-256-GCM authenticated encryption** — secrets are encrypted at rest, not base64-encoded\n- **Master key** in `memory/secrets/.master-key` (chmod 0600) — back it up\n- For production-grade secrets with HSM-backed keys, use a real vault (HashiCorp, AWS Secrets Manager, OS keychain)\n- `SECRETS_MASTER_KEY` env var for ephemeral/CI environments\n\n## What This Skill Does NOT Do\n\n- Does NOT store secrets in plaintext or base64 — all values are AES-256-GCM encrypted\n- Does NOT print secret values to stdout unless explicitly requested via `--get --raw`\n- Does NOT install npm packages\n- Does NOT phone home or transmit secrets anywhere\n- Does NOT log secret values\n- Does NOT require a separate key server — master key is a local file\n\n## Comparison\n\n| Approach | Encryption | Setup | Audit | Rotation | Recovery |\n|----------|-----------|-------|-------|----------|----------|\n| Environment vars | None | Medium | None | Manual | N/A |\n| .env files | None | Low | None | Manual | N/A |\n| **Secrets Manager** | **AES-256-GCM** | **None** | **Auto** | **Auto** | **With .master-key** |\n| Vault service | Various | High | Auto | Auto | Yes |\n\n**Secrets Manager gives you real encryption + rotation + audit with zero external dependencies.**\n\n## Design Principles\n\n1. **Zero setup** — Works immediately, no config needed\n2. **No dependencies** — Pure Node.js crypto, no npm packages\n3. **Safe by default** — Masked output, encrypted at rest, no plaintext-on-disk\n4. **Transparent** — Audit reports show exactly what's wrong\n5. **Recoverable** — Master key + encrypted secrets = full recovery\n\n<!-- clawhub-sync: 2026-07-22 v1.1.9 security audit remediation -->\n\nFile v1.1.14:README.md\n\n# Secrets Manager\n\n**Encrypted local secret storage for OpenClaw agents.** AES-256-GCM authenticated encryption, rotation tracking, audit, and safe command injection.\n\n> **TL;DR**: Secrets are encrypted at rest with AES-256-GCM. The master key is stored separately in `.master-key` (chmod 0600). If you lose `.master-key`, your secrets are unrecoverable — back it up.\n\n## Features\n\n- **AES-256-GCM Encryption** — secrets encrypted at rest with a 256-bit master key and per-secret random 96-bit IVs. Authenticated encryption (GCM auth tag) detects tampering.\n- **Secure Storage** — `store`, `get`, `list`, `delete` lifecycle\n- **Auto-Expiry & Rotation** — 90-day default rotation cycle with audit reporting\n- **Safe Command Injection** — substitutes `{{placeholder}}` and writes to a private temp file (chmod 0600) by default. NEVER prints secrets to stdout unless you opt in.\n- **Masked Output** — default output shows masked values (`sup****ue`)\n- **Status & Audit** — health checks, expired/stale secret reporting\n- **Zero External Dependencies** — pure Node.js `crypto` module\n\n## ⚠️ Security Warnings\n\n### Raw Mode (`--get --raw`) Prints Secrets to stdout\nThe secret value goes to stdout, which may be captured in:\n- Shell history / terminal scrollback\n- Process logs / journald / syslog\n- CI/CD pipeline output\n- Agent transcripts / OpenClaw session history\n- Downstream tool output\n\nUse only when piping directly to a private process or writing to a chmod-0600 file:\n```bash\nnode secrets-manager.js --get --raw api-key > /tmp/api-key.txt && chmod 600 /tmp/api-key.txt\n```\n\n### Command Injection (`--inject`) Default: Safe\nBy default, `--inject` substitutes `{{secrets}}` and writes the resolved command to a temp file (chmod 0600), then prints **only the file path** to stdout. Run the command with `sh /path/to/file`.\n\nTo print the resolved command to stdout (DANGEROUS — leaks secrets to logs), use **both** flags:\n```bash\nnode secrets-manager.js --inject-stdout --confirm-expose \"curl -H 'Authorization: Bearer {{api-key}}' https://api.example.com\"\n```\nThe skill will refuse to print the resolved command unless you pass `--confirm-expose`.\n\n### Master Key Backup\nThe master key lives in `memory/secrets/.master-key` (chmod 0600). If you lose this file, all stored secrets are unrecoverable. Back it up to a secure location (encrypted disk, password manager, OS keychain).\n\nYou can also use `SECRETS_MASTER_KEY=<hex>` env var instead of the file (useful for ephemeral environments).\n\n### Not for Production Credentials (But Better Than Plain JSON)\nThis is a local agent tool with file-based key storage. For production-grade secret management with HSM-backed keys, audit trails, and access policies, use HashiCorp Vault, AWS Secrets Manager, etc. That said, **this skill provides real AES-256-GCM encryption** — secrets are not stored in plaintext or base64.\n\n## Installation\n\n```bash\n# Auto-loaded by OpenClaw via the skill registry.\n# For standalone use:\nconst SM = require('./secrets-manager.js');\nSM.storeSecret('api-key', 'sk-abc123');\n```\n\n## Commands\n\n```\nstore <name> <value>        Store a secret (encrypted)\nget <name>                  Get secret (masked)\nget <name> --raw            Get secret (⚠️ raw value to stdout)\nlist                        List all secret names + metadata\ndelete <name>               Delete a secret\nrotate <name>               Generate new random value\nrotate --all                Rotate all secrets\ninject <command>            Substitute {{secrets}} → write to temp file (safe)\ninject-stdout --confirm-expose <command>\n                            Substitute and print (DANGEROUS)\naudit                       Check for expired/stale secrets\nstatus                      Show storage health\n```\n\n## API (require as module)\n\n```javascript\nconst SM = require('./secrets-manager.js');\n\nSM.storeSecret('api-key', 'sk-abc123');\nconst value = SM.getSecret('api-key');              // returns plaintext value\nconst masked = SM.getSecret('api-key');             // prints masked, returns value\nSM.listSecrets();                                    // prints table\nSM.deleteSecret('api-key');\nSM.rotateSecret('api-key');\nSM.auditSecrets('expired');\nSM.showStatus();\n```\n\n## Security Architecture\n\n- **AES-256-GCM** authenticated encryption (256-bit key, 96-bit IV per secret, 128-bit auth tag)\n- **Master key** auto-generated on first `store`, stored in `memory/secrets/.master-key` (chmod 0600)\n- **Per-secret IVs** — same plaintext encrypted twice produces different ciphertext\n- **Auth tag verification** — tampered ciphertext returns `null` from decrypt (no partial decryption)\n- **Atomic file writes** — temp file + rename to prevent corruption on crash\n- **chmod 0600** on all sensitive files (POSIX)\n- **No external dependencies** — pure Node.js `crypto`\n\n## Data Layout\n\n```\nmemory/secrets/\n  .master-key       # 32 random bytes as hex, chmod 0600\n  secrets.json      # { name: { iv, ct, tag, created, updated, ... } }, chmod 0600\n  permissions.json  # Per-secret access rules (optional), chmod 0600\n```\n\n## Testing\n\n```bash\n# Self-test suite (isolated temp directory)\nnode tests/run-self-tests.js\n\n# Quick smoke test\nnode test/run-tests.js\n```\n\n### Test Coverage\n\n| Suite | Tests | Status |\n|---|---|---|\n| Self-tests (isolated) | 29 | ✅ Passing |\n| Quick tests | 9 | ✅ Passing |\n\n## Examples\n\n**Store an API key:**\n```javascript\nSM.storeSecret('github-token', 'ghp_abc123...');\n```\n\n**Get for use in a script:**\n```javascript\nconst key = SM.getSecret('github-token');  // returns plaintext (handle carefully)\n```\n\n**Audit for expired secrets:**\n```javascript\nSM.auditSecrets('expired');\n```\n\n**Rotate all secrets:**\n```javascript\nSM.rotateAllSecrets();\n```\n\n**Inject into a command (safe):**\n```bash\n$ node secrets-manager.js --inject \"curl -H 'Authorization: Bearer {{api-key}}' https://api.example.com\"\n[secrets-manager] ✅ Injected 1 secret(s) into: /tmp/secrets-inject-12345-1234567890.sh\n[secrets-manager]    Run with: sh /tmp/secrets-inject-12345-1234567890.sh\n$ sh /tmp/secrets-inject-12345-1234567890.sh\n# ... command output ...\n```\n\nFile v1.1.14:_meta.json\n\n{\n  \"ownerId\": \"kn7b6eyf5vc7khg5fr63pjm8xd82qvw5\",\n  \"slug\": \"secrets-manager\",\n  \"version\": \"1.1.14\",\n  \"publishedAt\": 1785756304345\n}\n\nFile v1.1.14:skill-card.md\n\n## Description: <br>\nSecrets Manager is a local encrypted secret store for OpenClaw agents that stores, retrieves, lists, rotates, audits, and deletes secrets using AES-256-GCM with a local master key. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[jlacroix82](https://clawhub.ai/user/jlacroix82) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and agent operators use this skill to keep local agent secrets encrypted at rest, retrieve them in masked form by default, and manage rotation, deletion, and audit checks. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: Server security evidence marks the release suspicious because README, changelog, tests, manifest, and code disagree about secret-injection and temp-file behavior. <br>\nMitigation: Review before installing, do not rely on README-documented injection or cleanup commands, and use a clearly separate high-privilege injection skill when command injection is needed. <br>\nRisk: The --get --raw mode and the local .master-key are sensitive credential material that can expose stored secrets if captured or mishandled. <br>\nMitigation: Prefer masked retrieval, pipe raw output only to private processes or protected files, protect and back up .master-key, and avoid exposing SECRETS_MASTER_KEY in shared or logged environments. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill page](https://clawhub.ai/jlacroix82/skills/secrets-manager) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, files, shell commands, configuration] <br>\n**Output Format:** [CLI text output and encrypted local JSON data files] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Creates and updates local encrypted secret data and a local master-key file; raw retrieval can print plaintext to stdout.] <br>\n\n## Skill Version(s): <br>\n1.1.14 (source: server release metadata and clawhub.yaml) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nFile v1.1.14:clawhub.yaml\n\nslug: secrets-manager\nname: secrets-manager\nowner: jlacroix82\ndescription: \"Encrypted local secret store for OpenClaw agents. A PURE STORE: AES-256-GCM authenticated encryption with per-secret random IVs, master key in chmod 0600 .master-key file. Modes: store, get (masked; --raw prints plaintext), list (names+metadata only), delete (irreversible), rotate / rotate --all (archive old as retired), audit (--expired/--stale), status. NEVER writes plaintext secrets to disk or generates executable command scripts — command injection lives in the separate secrets-inject skill. SECRETS_DIR and SECRETS_MASTER_KEY env overrides supported. Losing .master-key makes secrets unrecoverable.\"\nversion: 1.1.14\ntype: skill\nauthor: OpenClaw\nlicense: MIT\nkeywords:\n  - secrets\n  - encryption\n  - aes-256-gcm\n  - rotation\n  - audit\n  - key-management\ncapabilities:\n  - filesystem\n  - environment\n  - crypto\nentry: SKILL.md\ndependencies: []\npermissions:\n  - name: filesystem.read-write\n    description: Read/write data files in memory/secrets/ (secrets.json chmod 0600, .master-key chmod 0600)\n  - name: environment.read\n    description: Read SECRETS_DIR and SECRETS_MASTER_KEY environment variables\n  - name: crypto.aes-256-gcm\n    description: Encrypt/decrypt secrets with AES-256-GCM authenticated encryption\ndata_retention:\n  secrets: 'AES-256-GCM encrypted, chmod 0600, persists until deleted'\n  master_key: '256-bit key in .master-key file, chmod 0600'\nsecurity_notes:\n  - 'Master key auto-generated on first store; backup is your responsibility'\n  - 'Losing .master-key = unrecoverable secrets'\n  - 'Plaintext only printed via explicit --get --raw (to stdout); no plaintext written to disk'\n  - 'SECRETS_MASTER_KEY env override: NEVER set it in shared, containerized, CI, or logged environments — anyone who can read process env or logs can recover the key. Prefer the file-based .master-key (chmod 0600) on a single-user host.'\n  - 'Command injection / secret substitution is NOT provided here; use the separate secrets-inject skill (high-privilege).'\n\nFile v1.1.14:CHANGELOG.txt\n\nSecrets Manager v1.1.12 — Security audit finding remediation (2026-08-02)\n\nFixes the ClawHub security-audit findings on v1.1.10:\n  - Implemented the advertised `--cleanup-tmp` command. Previously the CLI\n    told users to run `--cleanup-tmp` to remove temp injection files holding\n    plaintext secret substitutions, but no such flag was wired up (Description-\n    Behavior Mismatch / Intent-Code Divergence findings). `--cleanup-tmp` now\n    immediately deletes all tracked temp injection files.\n  - Documentation aligned: header comment and usage now state `--cleanup-tmp`\n    is implemented and that temp files are chmod 0600.\n\nNo crypto changes — still AES-256-GCM with per-secret IV and authenticated\ndecryption (tamper -> null). Master key handling unchanged.\n\nFile v1.1.14:test.txt\n\nTesting\n\nArchive v1.1.13: 12 files, 21626 bytes\n\nFiles: CHANGELOG.txt (770b), clawhub.yaml (2082b), README.md (6127b), secrets-manager.js (25698b), skill-card.md (2643b), SKILL.md (9000b), test-final.js (2802b), test.txt (8b), test/run-tests.js (2044b), test/test-secrets.js (2496b), tests/run-self-tests.js (11102b), _meta.json (135b)\n\nFile v1.1.13:SKILL.md\n\n---\nname: secrets-manager\ndescription: >-\n  Encrypted local secret store for OpenClaw agents. AES-256-GCM authenticated\n  encryption with per-secret random IVs, master key in chmod 0600 .master-key\n  file. Modes: --store (encrypt+write), --get (masked; --raw prints plaintext\n  to stdout), --list (names+metadata only), --delete (irreversible), --rotate\n  and --rotate --all (generate new random values, archive old as retired),\n  --audit / --audit --expired / --audit --stale (exposure/rotation checks),\n  --inject (substitute {{secrets}} into a command, writes to a chmod 0600 temp\n  file by default; --inject-stdout requires --confirm-expose), --cleanup-tmp\n  (delete tracked temp injection files), --status. Supports SECRETS_DIR and\n  SECRETS_MASTER_KEY env overrides. Master key is recoverable from .master-key\n  file; losing it makes stored secrets unrecoverable.\npermissions:\n  - filesystem.read-write\n  - environment.read\n  - crypto.aes-256-gcm\n---\n\n# Secrets Manager 🔐\n\n**Encrypted local secret store.** AES-256-GCM authenticated encryption. Master key auto-generated on first store and stored in `memory/secrets/.master-key` (chmod 0600).\n\n> **Important**: If you lose `.master-key`, all stored secrets become unrecoverable. Back it up.\n\n## ⚠️ Important Warnings\n\n### Encryption: AES-256-GCM (Authenticated)\n- 256-bit master key, per-secret 96-bit random IV, 128-bit GCM auth tag\n- Tampered ciphertext returns `null` from decrypt (no partial decryption)\n- Master key stored in `memory/secrets/.master-key` with chmod 0600\n- Override via `SECRETS_MASTER_KEY=<hex>` env var\n- Losing the master key = all secrets unrecoverable\n\n### `--get --raw` Prints Plaintext to stdout\nThe secret value goes to stdout, which may be captured in:\n- Shell history / terminal scrollback\n- Process logs / journald / syslog\n- CI/CD pipeline output\n- Agent transcripts / OpenClaw session history\n\nUse only when piping to a private process:\n```bash\nnode secrets-manager.js --get --raw api-key > /tmp/api-key.txt && chmod 600 /tmp/api-key.txt\n```\n\n### `--inject` Default: Safe (writes to temp file, chmod 0600)\nBy 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:\n```bash\n--inject-stdout --confirm-expose \"command {{secret}}\"\n```\nThe skill refuses to print the resolved command without `--confirm-expose`.\n\n### Rotation: Old Values Are Archived\nRotated secrets keep the old encrypted value as `retired`. Rotate again to discard the archive. There is no `--undo` for archival.\n\n### Storage Location\n`memory/secrets/secrets.json` (chmod 0600) plus `memory/secrets/.master-key` (chmod 0600). Override via `--dir <path>` or `SECRETS_DIR=<path>`.\n\n## Quick Start\n\n### Store a secret\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --store openai-key sk-abc123\n# Output: [secrets-manager] Stored: openai-key (masked: sk-****23)\n```\n\n### Get a secret (masked by default)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --get openai-key\n# Output: [secrets-manager] openai-key: sk-****23\n```\n\n### Get raw value (when needed for injection)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --get --raw openai-key > /tmp/key.txt\n# Output: sk-abc123 (captured to file)\n```\n\n### List all secrets (names + metadata, NOT values)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --list\n```\n\n### Delete a secret\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --delete old-key\n```\n\n### Rotate a secret\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --rotate openai-key\n# New random value generated, old encrypted value archived as retired\n```\n\n### Rotate all secrets\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --rotate --all\n```\n\n### Audit for security issues\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --audit\nnode skills/secrets-manager/secrets-manager.js --audit --expired\nnode skills/secrets-manager/secrets-manager.js --audit --stale\n```\n\n### Inject secrets into a command (safe default)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --inject \"curl -H 'Authorization: Bearer {{openai-key}}' https://api.openai.com/v1/chat\"\n# Output: [secrets-manager] ✅ Injected 1 secret(s) into: /tmp/secrets-inject-12345-1234567890.sh\n#         [secrets-manager]    Run with: sh /tmp/secrets-inject-12345-1234567890.sh\n```\n\n**Then run the command** (the secrets are in the temp file, chmod 0600):\n```bash\nsh /tmp/secrets-inject-12345-1234567890.sh\n```\n\n### Inject to stdout (DANGEROUS — requires explicit confirmation)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --inject-stdout --confirm-expose \"echo {{openai-key}}\"\n# Will print: [secrets-manager] ⚠️ Resolved command below contains 1 secret value(s) in plaintext:\n#              echo sk-abc123\n```\n\nThe skill **refuses** to print the resolved command without `--confirm-expose`. This is to prevent accidental secret leaks to logs.\n\n### Status overview\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --status\n```\n\n## Features\n\n### Encryption\n- **AES-256-GCM** authenticated encryption\n- 256-bit master key (auto-generated on first store)\n- 96-bit per-secret random IV\n- 128-bit GCM auth tag (tamper detection)\n- Master key in `memory/secrets/.master-key` (chmod 0600)\n- `SECRETS_MASTER_KEY` env var override\n\n### Rotation Tracking\n- 90-day default rotation cycle per secret\n- Automatic expiration warnings (audit --stale at 70% of cycle)\n- One-command rotation with new random value generation\n- Old values archived as `retired` (encrypted, recoverable until next rotate)\n\n### Audit System\n- Detects expired secrets past rotation date\n- Flags secrets approaching rotation deadline (70% threshold)\n- Identifies weak patterns (common prefixes, short length <8 chars)\n- Detects decryption failures (tampered ciphertext or wrong master key)\n- Reports rotation age for each secret\n\n### Safe Command Injection\n- `{{secret_name}}` placeholders replaced in command strings\n- **Default**: writes resolved command to chmod-0600 temp file, prints path only\n- **Opt-in stdout**: requires both `--inject-stdout` AND `--confirm-expose`\n- No secret values ever reach stdout by default\n\n## Configuration\n\nData stored in: `memory/secrets/`\n- `secrets.json` — encrypted secrets (chmod 0600)\n- `.master-key` — 256-bit master key as hex (chmod 0600)\n- `permissions.json` — per-secret access rules (chmod 0600)\n\nOverride storage location:\n```bash\n--dir /path/to/secrets\n# or env var\nSECRETS_DIR=/path/to/secrets node secrets-manager.js --status\n```\n\nOverride master key:\n```bash\nSECRETS_MASTER_KEY=<64-hex-chars> node secrets-manager.js --get openai-key\n```\n\n## Agent Protocol\n\nWhen handling secrets:\n\n1. **Store with encryption** — `--store <name> <value>` writes AES-256-GCM ciphertext\n2. **Default to masked output** — `--get` (not `--get --raw`) for display\n3. **Use safe inject by default** — `--inject` writes to temp file, doesn't leak\n4. **Audit regularly** — `--audit` during heartbeats\n5. **Rotate proactively** — rotate secrets flagged as expiring\n6. **Back up `.master-key`** — without it, stored secrets are unrecoverable\n\n## Security Notes\n\n- **AES-256-GCM authenticated encryption** — secrets are encrypted at rest, not base64-encoded\n- **Master key** in `memory/secrets/.master-key` (chmod 0600) — back it up\n- For production-grade secrets with HSM-backed keys, use a real vault (HashiCorp, AWS Secrets Manager, OS keychain)\n- `SECRETS_MASTER_KEY` env var for ephemeral/CI environments\n- Default `--inject` never prints secrets; `--inject-stdout` requires explicit confirmation\n\n## What This Skill Does NOT Do\n\n- Does NOT store secrets in plaintext or base64 — all values are AES-256-GCM encrypted\n- Does NOT print secret values to stdout unless explicitly requested via `--get --raw` or `--inject-stdout --confirm-expose`\n- Does NOT install npm packages\n- Does NOT phone home or transmit secrets anywhere\n- Does NOT log secret values\n- Does NOT require a separate key server — master key is a local file\n\n## Comparison\n\n| Approach | Encryption | Setup | Audit | Rotation | Recovery |\n|----------|-----------|-------|-------|----------|----------|\n| Environment vars | None | Medium | None | Manual | N/A |\n| .env files | None | Low | None | Manual | N/A |\n| **Secrets Manager** | **AES-256-GCM** | **None** | **Auto** | **Auto** | **With .master-key** |\n| Vault service | Various | High | Auto | Auto | Yes |\n\n**Secrets Manager gives you real encryption + rotation + audit with zero external dependencies.**\n\n## Design Principles\n\n1. **Zero setup** — Works immediately, no config needed\n2. **No dependencies** — Pure Node.js crypto, no npm packages\n3. **Safe by default** — Masked output, safe inject, encrypted at rest\n4. **Transparent** — Audit reports show exactly what's wrong\n5. **Recoverable** — Master key + encrypted secrets = full recovery\n\n<!-- clawhub-sync: 2026-07-22 v1.1.9 security audit remediation -->\n\nFile v1.1.13:README.md\n\n# Secrets Manager\n\n**Encrypted local secret storage for OpenClaw agents.** AES-256-GCM authenticated encryption, rotation tracking, audit, and safe command injection.\n\n> **TL;DR**: Secrets are encrypted at rest with AES-256-GCM. The master key is stored separately in `.master-key` (chmod 0600). If you lose `.master-key`, your secrets are unrecoverable — back it up.\n\n## Features\n\n- **AES-256-GCM Encryption** — secrets encrypted at rest with a 256-bit master key and per-secret random 96-bit IVs. Authenticated encryption (GCM auth tag) detects tampering.\n- **Secure Storage** — `store`, `get`, `list`, `delete` lifecycle\n- **Auto-Expiry & Rotation** — 90-day default rotation cycle with audit reporting\n- **Safe Command Injection** — substitutes `{{placeholder}}` and writes to a private temp file (chmod 0600) by default. NEVER prints secrets to stdout unless you opt in.\n- **Masked Output** — default output shows masked values (`sup****ue`)\n- **Status & Audit** — health checks, expired/stale secret reporting\n- **Zero External Dependencies** — pure Node.js `crypto` module\n\n## ⚠️ Security Warnings\n\n### Raw Mode (`--get --raw`) Prints Secrets to stdout\nThe secret value goes to stdout, which may be captured in:\n- Shell history / terminal scrollback\n- Process logs / journald / syslog\n- CI/CD pipeline output\n- Agent transcripts / OpenClaw session history\n- Downstream tool output\n\nUse only when piping directly to a private process or writing to a chmod-0600 file:\n```bash\nnode secrets-manager.js --get --raw api-key > /tmp/api-key.txt && chmod 600 /tmp/api-key.txt\n```\n\n### Command Injection (`--inject`) Default: Safe\nBy default, `--inject` substitutes `{{secrets}}` and writes the resolved command to a temp file (chmod 0600), then prints **only the file path** to stdout. Run the command with `sh /path/to/file`.\n\nTo print the resolved command to stdout (DANGEROUS — leaks secrets to logs), use **both** flags:\n```bash\nnode secrets-manager.js --inject-stdout --confirm-expose \"curl -H 'Authorization: Bearer {{api-key}}' https://api.example.com\"\n```\nThe skill will refuse to print the resolved command unless you pass `--confirm-expose`.\n\n### Master Key Backup\nThe master key lives in `memory/secrets/.master-key` (chmod 0600). If you lose this file, all stored secrets are unrecoverable. Back it up to a secure location (encrypted disk, password manager, OS keychain).\n\nYou can also use `SECRETS_MASTER_KEY=<hex>` env var instead of the file (useful for ephemeral environments).\n\n### Not for Production Credentials (But Better Than Plain JSON)\nThis is a local agent tool with file-based key storage. For production-grade secret management with HSM-backed keys, audit trails, and access policies, use HashiCorp Vault, AWS Secrets Manager, etc. That said, **this skill provides real AES-256-GCM encryption** — secrets are not stored in plaintext or base64.\n\n## Installation\n\n```bash\n# Auto-loaded by OpenClaw via the skill registry.\n# For standalone use:\nconst SM = require('./secrets-manager.js');\nSM.storeSecret('api-key', 'sk-abc123');\n```\n\n## Commands\n\n```\nstore <name> <value>        Store a secret (encrypted)\nget <name>                  Get secret (masked)\nget <name> --raw            Get secret (⚠️ raw value to stdout)\nlist                        List all secret names + metadata\ndelete <name>               Delete a secret\nrotate <name>               Generate new random value\nrotate --all                Rotate all secrets\ninject <command>            Substitute {{secrets}} → write to temp file (safe)\ninject-stdout --confirm-expose <command>\n                            Substitute and print (DANGEROUS)\naudit                       Check for expired/stale secrets\nstatus                      Show storage health\n```\n\n## API (require as module)\n\n```javascript\nconst SM = require('./secrets-manager.js');\n\nSM.storeSecret('api-key', 'sk-abc123');\nconst value = SM.getSecret('api-key');              // returns plaintext value\nconst masked = SM.getSecret('api-key');             // prints masked, returns value\nSM.listSecrets();                                    // prints table\nSM.deleteSecret('api-key');\nSM.rotateSecret('api-key');\nSM.auditSecrets('expired');\nSM.showStatus();\n```\n\n## Security Architecture\n\n- **AES-256-GCM** authenticated encryption (256-bit key, 96-bit IV per secret, 128-bit auth tag)\n- **Master key** auto-generated on first `store`, stored in `memory/secrets/.master-key` (chmod 0600)\n- **Per-secret IVs** — same plaintext encrypted twice produces different ciphertext\n- **Auth tag verification** — tampered ciphertext returns `null` from decrypt (no partial decryption)\n- **Atomic file writes** — temp file + rename to prevent corruption on crash\n- **chmod 0600** on all sensitive files (POSIX)\n- **No external dependencies** — pure Node.js `crypto`\n\n## Data Layout\n\n```\nmemory/secrets/\n  .master-key       # 32 random bytes as hex, chmod 0600\n  secrets.json      # { name: { iv, ct, tag, created, updated, ... } }, chmod 0600\n  permissions.json  # Per-secret access rules (optional), chmod 0600\n```\n\n## Testing\n\n```bash\n# Self-test suite (isolated temp directory)\nnode tests/run-self-tests.js\n\n# Quick smoke test\nnode test/run-tests.js\n```\n\n### Test Coverage\n\n| Suite | Tests | Status |\n|---|---|---|\n| Self-tests (isolated) | 29 | ✅ Passing |\n| Quick tests | 9 | ✅ Passing |\n\n## Examples\n\n**Store an API key:**\n```javascript\nSM.storeSecret('github-token', 'ghp_abc123...');\n```\n\n**Get for use in a script:**\n```javascript\nconst key = SM.getSecret('github-token');  // returns plaintext (handle carefully)\n```\n\n**Audit for expired secrets:**\n```javascript\nSM.auditSecrets('expired');\n```\n\n**Rotate all secrets:**\n```javascript\nSM.rotateAllSecrets();\n```\n\n**Inject into a command (safe):**\n```bash\n$ node secrets-manager.js --inject \"curl -H 'Authorization: Bearer {{api-key}}' https://api.example.com\"\n[secrets-manager] ✅ Injected 1 secret(s) into: /tmp/secrets-inject-12345-1234567890.sh\n[secrets-manager]    Run with: sh /tmp/secrets-inject-12345-1234567890.sh\n$ sh /tmp/secrets-inject-12345-1234567890.sh\n# ... command output ...\n```\n\nFile v1.1.13:_meta.json\n\n{\n  \"ownerId\": \"kn7b6eyf5vc7khg5fr63pjm8xd82qvw5\",\n  \"slug\": \"secrets-manager\",\n  \"version\": \"1.1.13\",\n  \"publishedAt\": 1785725349344\n}\n\nFile v1.1.13:skill-card.md\n\n## Description: <br>\nEncrypted local secret store for OpenClaw agents with AES-256-GCM storage, masked retrieval, rotation and audit commands, and opt-in plaintext output or command injection modes. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[jlacroix82](https://clawhub.ai/user/jlacroix82) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and agents use this skill to store, retrieve, rotate, audit, and inject local secrets for OpenClaw workflows without relying on external dependencies. It is suited for single-user local secret convenience, not production-grade shared credential management. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The security review identifies a high-risk feature that writes plaintext secrets into runnable temporary shell scripts. <br>\nMitigation: Avoid --inject for sensitive credentials unless this exposure is acceptable, run --cleanup-tmp immediately after use, and prefer a managed secret store for high-value or shared credentials. <br>\nRisk: This is a local, single-user convenience vault rather than production-grade secret management. <br>\nMitigation: Use an OS keychain, HashiCorp Vault, AWS Secrets Manager, or another managed secret store for production, shared, or high-value secrets. <br>\nRisk: Raw retrieval and stdout injection can expose plaintext credentials to logs, transcripts, shell history, or downstream tools. <br>\nMitigation: Use masked retrieval by default and reserve --get --raw or --inject-stdout --confirm-expose for tightly controlled private processes. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill page](https://clawhub.ai/jlacroix82/skills/secrets-manager) <br>\n- [Skill instructions](artifact/SKILL.md) <br>\n- [README](artifact/README.md) <br>\n- [Changelog](artifact/CHANGELOG.txt) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [Text, Files, Shell commands, Configuration] <br>\n**Output Format:** [CLI text output, encrypted JSON data files, and chmod 0600 shell scripts for injected commands] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Secret values are masked by default; plaintext output and command exposure require explicit flags.] <br>\n\n## Skill Version(s): <br>\n1.1.13 (source: server release metadata and clawhub.yaml) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nFile v1.1.13:clawhub.yaml\n\nslug: secrets-manager\nname: secrets-manager\nowner: jlacroix82\ndescription: \"Encrypted local secret store for OpenClaw agents. AES-256-GCM authenticated encryption with per-secret random IVs, master key in chmod 0600 .master-key file. Modes: store, get (masked; --raw prints plaintext), list (names+metadata only), delete (irreversible), rotate / rotate --all (archive old as retired), audit (--expired/--stale), inject (writes to chmod 0600 temp file; --inject-stdout requires --confirm-expose), cleanup-tmp, status. SECRETS_DIR and SECRETS_MASTER_KEY env overrides supported. Losing .master-key makes secrets unrecoverable.\"\nversion: 1.1.13\ntype: skill\nauthor: OpenClaw\nlicense: MIT\nkeywords:\n  - secrets\n  - encryption\n  - aes-256-gcm\n  - rotation\n  - audit\n  - key-management\ncapabilities:\n  - filesystem\n  - environment\n  - crypto\nentry: SKILL.md\ndependencies: []\npermissions:\n  - name: filesystem.read-write\n    description: Read/write data files in memory/secrets/ (secrets.json chmod 0600, .master-key chmod 0600)\n  - name: environment.read\n    description: Read SECRETS_DIR and SECRETS_MASTER_KEY environment variables\n  - name: crypto.aes-256-gcm\n    description: Encrypt/decrypt secrets with AES-256-GCM authenticated encryption\ndata_retention:\n  secrets: 'AES-256-GCM encrypted, chmod 0600, persists until deleted'\n  master_key: '256-bit key in .master-key file, chmod 0600'\n  temp_files: 'chmod 0600, /tmp/secrets-inject-*.sh, auto-cleaned on rotate/delete/cleanup; tracked in .tmp-injections.json'\nsecurity_notes:\n  - 'Master key auto-generated on first store; backup is your responsibility'\n  - 'Losing .master-key = unrecoverable secrets'\n  - 'Plaintext only printed via explicit --get --raw or --inject-stdout --confirm-expose'\n  - 'Temp injection files auto-cleaned on rotate/delete/cleanup; tracked in .tmp-injections.json'\n  - 'SECRETS_MASTER_KEY env override: NEVER set it in shared, containerized, CI, or logged environments — anyone who can read process env or logs can recover the key. Prefer the file-based .master-key (chmod 0600) on a single-user host.'\n\nFile v1.1.13:CHANGELOG.txt\n\nSecrets Manager v1.1.12 — Security audit finding remediation (2026-08-02)\n\nFixes the ClawHub security-audit findings on v1.1.10:\n  - Implemented the advertised `--cleanup-tmp` command. Previously the CLI\n    told users to run `--cleanup-tmp` to remove temp injection files holding\n    plaintext secret substitutions, but no such flag was wired up (Description-\n    Behavior Mismatch / Intent-Code Divergence findings). `--cleanup-tmp` now\n    immediately deletes all tracked temp injection files.\n  - Documentation aligned: header comment and usage now state `--cleanup-tmp`\n    is implemented and that temp files are chmod 0600.\n\nNo crypto changes — still AES-256-GCM with per-secret IV and authenticated\ndecryption (tamper -> null). Master key handling unchanged.\n\nFile v1.1.13:test.txt\n\nTesting\n\nArchive v1.1.12: 12 files, 21274 bytes\n\nFiles: CHANGELOG.txt (770b), clawhub.yaml (1762b), README.md (6127b), secrets-manager.js (25698b), skill-card.md (2789b), SKILL.md (8483b), test-final.js (2802b), test.txt (8b), test/run-tests.js (2044b), test/test-secrets.js (2496b), tests/run-self-tests.js (11102b), _meta.json (135b)\n\nFile v1.1.12:SKILL.md\n\n---\nname: secrets-manager\ndescription: Encrypted local secret store for OpenClaw agents. AES-256-GCM authenticated encryption with per-secret random IVs, master key in chmod 0600 .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.\n---\n\n# Secrets Manager 🔐\n\n**Encrypted local secret store.** AES-256-GCM authenticated encryption. Master key auto-generated on first store and stored in `memory/secrets/.master-key` (chmod 0600).\n\n> **Important**: If you lose `.master-key`, all stored secrets become unrecoverable. Back it up.\n\n## ⚠️ Important Warnings\n\n### Encryption: AES-256-GCM (Authenticated)\n- 256-bit master key, per-secret 96-bit random IV, 128-bit GCM auth tag\n- Tampered ciphertext returns `null` from decrypt (no partial decryption)\n- Master key stored in `memory/secrets/.master-key` with chmod 0600\n- Override via `SECRETS_MASTER_KEY=<hex>` env var\n- Losing the master key = all secrets unrecoverable\n\n### `--get --raw` Prints Plaintext to stdout\nThe secret value goes to stdout, which may be captured in:\n- Shell history / terminal scrollback\n- Process logs / journald / syslog\n- CI/CD pipeline output\n- Agent transcripts / OpenClaw session history\n\nUse only when piping to a private process:\n```bash\nnode secrets-manager.js --get --raw api-key > /tmp/api-key.txt && chmod 600 /tmp/api-key.txt\n```\n\n### `--inject` Default: Safe (writes to temp file, chmod 0600)\nBy 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:\n```bash\n--inject-stdout --confirm-expose \"command {{secret}}\"\n```\nThe skill refuses to print the resolved command without `--confirm-expose`.\n\n### Rotation: Old Values Are Archived\nRotated secrets keep the old encrypted value as `retired`. Rotate again to discard the archive. There is no `--undo` for archival.\n\n### Storage Location\n`memory/secrets/secrets.json` (chmod 0600) plus `memory/secrets/.master-key` (chmod 0600). Override via `--dir <path>` or `SECRETS_DIR=<path>`.\n\n## Quick Start\n\n### Store a secret\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --store openai-key sk-abc123\n# Output: [secrets-manager] Stored: openai-key (masked: sk-****23)\n```\n\n### Get a secret (masked by default)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --get openai-key\n# Output: [secrets-manager] openai-key: sk-****23\n```\n\n### Get raw value (when needed for injection)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --get --raw openai-key > /tmp/key.txt\n# Output: sk-abc123 (captured to file)\n```\n\n### List all secrets (names + metadata, NOT values)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --list\n```\n\n### Delete a secret\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --delete old-key\n```\n\n### Rotate a secret\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --rotate openai-key\n# New random value generated, old encrypted value archived as retired\n```\n\n### Rotate all secrets\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --rotate --all\n```\n\n### Audit for security issues\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --audit\nnode skills/secrets-manager/secrets-manager.js --audit --expired\nnode skills/secrets-manager/secrets-manager.js --audit --stale\n```\n\n### Inject secrets into a command (safe default)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --inject \"curl -H 'Authorization: Bearer {{openai-key}}' https://api.openai.com/v1/chat\"\n# Output: [secrets-manager] ✅ Injected 1 secret(s) into: /tmp/secrets-inject-12345-1234567890.sh\n#         [secrets-manager]    Run with: sh /tmp/secrets-inject-12345-1234567890.sh\n```\n\n**Then run the command** (the secrets are in the temp file, chmod 0600):\n```bash\nsh /tmp/secrets-inject-12345-1234567890.sh\n```\n\n### Inject to stdout (DANGEROUS — requires explicit confirmation)\n\n```bash\nnode skills/secrets-manager/secrets-manager.js --inject-stdout --confirm-expose \"echo {{openai-key}}\"\n# Will print: [secrets-manager] ⚠️ Resolved command below contains 1 secret value(s) in plaintext:\n#              echo sk-abc123\n```\n\nThe skill **refuses** to print the resolved command without `--confirm-expose`.\n\nArchive v1.1.11: 6 files, 7562 bytes\n\nFiles: clawhub.yaml (243b), secrets-manager.js (9614b), skill-card.md (2262b), SKILL.md (2360b), tests/run-self-tests.js (4074b), _meta.json (135b)\n\nArchive v1.1.10: 11 files, 20551 bytes\n\nFiles: clawhub.yaml (1762b), README.md (6127b), secrets-manager.js (25135b), skill-card.md (2662b), SKILL.md (8483b), test-final.js (2802b), test.txt (8b), test/run-tests.js (2044b), test/test-secrets.js (2496b), tests/run-self-tests.js (11102b), _meta.json (135b)","readmeExcerpt":"Skill: secrets-manager Owner: jlacroix82 Summary: Encrypted 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 i","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"node secrets-manager.js --get --raw api-key > /tmp/api-key.txt\n# Restrict file permissions after writing"},{"language":"bash","snippet":"--inject-stdout --confirm-expose \"command {{secret}}\""},{"language":"bash","snippet":"node skills/secrets-manager/secrets-manager.js --store openai-key sk-abc123\n# Output: [secrets-manager] Stored: openai-key (masked: sk-****23)"},{"language":"bash","snippet":"node skills/secrets-manager/secrets-manager.js --get openai-key\n# Output: [secrets-manager] openai-key: sk-****23"},{"language":"bash","snippet":"node skills/secrets-manager/secrets-manager.js --get --raw openai-key > /tmp/key.txt\n# Output: sk-abc123 (captured to file)"},{"language":"bash","snippet":"node skills/secrets-manager/secrets-manager.js --list"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: secrets-manager\nversion: 1.1.19\ndescription: Encrypted 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.\npermissions: [\"fs\", \"env\", \"exec\", \"shell\", \"elevated\"]\n---\n\n# Secrets Manager 🔐\n\n**Encrypted 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).\n\n> **Important**: If you lose `.master-key`, all stored secrets become unrecoverable. Back it up.\n\n## ⚠️ Important Warnings\n\n### Encryption: AES-256-GCM (Authenticated)\n- 256-bit master key, per-secret 96-bit random IV, 128-bit GCM auth tag\n- Tampered ciphertext returns `null` from decrypt (no partial decryption)\n- Master key stored in the skill's private storage directory with restricted permissions (owner-only)\n- Override via `SECRETS_MASTER_KEY=<hex>` env var\n- Losing the master key = all secrets unrecoverable\n\n### `--get --raw` Prints Plaintext to stdout\nThe secret value goes to stdout, which may be captured in:\n- Shell history / terminal scrollback\n- Process logs / journald / syslog\n- CI/CD pipeline output\n- Agent transcripts / OpenClaw session history\n\nUse only when piping to a private process:\n```bash\nnode secrets-manager.js --get --raw api-key > /tmp/api-key.txt\n# Restrict file permissions after writing\n```\n\n### `--inject` Default: Safe (writes to temp file with restricted permissions)\nBy 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:\n```bash\n--inject-stdout --confirm-expose \"command {{secret}}\"\n```\nThe skill refuses to print the resolved command without `--confirm-expose`.\n\n### Rotation: Old Values Are Archived\nRotated secrets keep the old encrypted value as `retired`. Rotate again to discard the archive. There is no `--undo` for archival.\n\n### Storage Location\nEncrypted 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>`.\n\n## Permissions\n\nThis skill requires the following capabilities:\n\n| Permission | Scope | Reason |\n|---|---|---|\n| `fs.read` | Private storage | Read encrypted secrets and master key |\n| `fs.write` | Private storage | Write encrypted secrets, master key, permission rules |\n| `run-cli` | CLI invocation | Invoke `secrets-manager.js` for store/get/rotate/audit operations |\n| `elevated` | File permissions | Set restricted permissions on secret files to ensure owner-only access |\n\nElevation is required only for restricted permission enforcement on files"},{"path":"README.md","content":"# Secrets Manager\n\n**Encrypted local secret storage for OpenClaw agents.** AES-256-GCM authenticated encryption, rotation tracking, audit, and safe command injection.\n\n> **TL;DR**: Secrets are encrypted at rest with AES-256-GCM. The master key is stored separately in `.master-key` with restricted permissions (owner-only). If you lose `.master-key`, your secrets are unrecoverable — back it up.\n\n## Features\n\n- **AES-256-GCM Encryption** — secrets encrypted at rest with a 256-bit master key and per-secret random 96-bit IVs. Authenticated encryption (GCM auth tag) detects tampering.\n- **Secure Storage** — `store`, `get`, `list`, `delete` lifecycle\n- **Auto-Expiry & Rotation** — 90-day default rotation cycle with audit reporting\n- **Safe Command Injection** — substitutes `{{placeholder}}` and writes to a private temp file with restricted permissions by default. NEVER prints secrets to stdout unless you opt in.\n- **Masked Output** — default output shows masked values (`sup****ue`)\n- **Status & Audit** — health checks, expired/stale secret reporting\n- **Zero External Dependencies** — pure Node.js `crypto` module\n\n## ⚠️ Security Warnings\n\n### Raw Mode (`--get --raw`) Prints Secrets to stdout\nThe secret value goes to stdout, which may be captured in:\n- Shell history / terminal scrollback\n- Process logs / journald / syslog\n- CI/CD pipeline output\n- Agent transcripts / OpenClaw session history\n- Downstream tool output\n\nUse only when piping directly to a private process or writing to a file with restricted permissions:\n```bash\nnode secrets-manager.js --get --raw api-key > /tmp/api-key.txt\n# Restrict file permissions after writing\n```\n\n### Command Injection (`--inject`) Default: Safe\nBy default, `--inject` substitutes `{{secrets}}` and writes the resolved command to a temp file with restricted permissions, then prints **only the file path** to stdout. Run the command with `sh /path/to/file`.\n\nTo print the resolved command to stdout (DANGEROUS — leaks secrets to logs), use **both** flags:\n```bash\nnode secrets-manager.js --inject-stdout --confirm-expose \"curl -H 'Authorization: Bearer {{api-key}}' https://api.example.com\"\n```\nThe skill will refuse to print the resolved command unless you pass `--confirm-expose`.\n\n### Master Key Backup\nThe master key is stored in a restricted-permission file within the skill's private data directory (owner-only). If you lose this file, all stored secrets are unrecoverable. Back it up to a secure location (encrypted disk, password manager, OS keychain).\n\nYou can also use `SECRETS_MASTER_KEY=<hex>` env var instead of the file (useful for ephemeral environments).\n\n### Not for Production Credentials (But Better Than Plain JSON)\nThis is a local agent tool with file-based key storage. For production-grade secret management with HSM-backed keys, audit trails, and access policies, use HashiCorp Vault, AWS Secrets Manager, etc. That said, **this skill provides real AES-256-GCM encryption** — secrets are not stored in plaintext or base64."},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7b6eyf5vc7khg5fr63pjm8xd82qvw5\",\n  \"slug\": \"secrets-manager\",\n  \"version\": \"1.1.19\",\n  \"publishedAt\": 1789302192890\n}"},{"path":"skill-card.md","content":"## Description:\n\nEncrypted 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 a restricted temp file by default and requires explicit confirmation before printing resolved commands. Losing the master key makes stored secrets unrecoverable.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[jlacroix82](https://clawhub.ai/user/jlacroix82)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and agent operators use this skill to store, retrieve, rotate, audit, and inject local secrets for OpenClaw workflows while keeping default display output masked.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Credential values may be exposed through argv, persistent temp scripts, or audit output.\n\nMitigation: Review and fix credential handling before storing high-value production credentials; prefer masked output and default temp-file injection until the release has been remediated.\n\nRisk: The release requests shell and elevated permissions that may be broader than necessary.\n\nMitigation: Limit deployment to reviewed environments, constrain the storage directory, and confirm that elevated permissions are only used for restrictive file-permission enforcement.\n\nRisk: The local master key is required to recover stored secrets.\n\nMitigation: Back up the master key to a secure location and test recovery before relying on the store for important credentials.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/jlacroix82/skills/secrets-manager)\n- [Publisher profile](https://clawhub.ai/user/jlacroix82)\n- [README](artifact/README.md)\n- [Vetting report](artifact/VET-REPORT.md)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Shell commands, Files, Configuration]\n\n**Output Format:** [CLI text output, masked secret values by default, and restricted-permission temp shell scripts for command injection]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May emit plaintext secrets only when explicitly requested through raw retrieval or confirmed stdout injection.]\n\n## Skill Version(s):\n\n1.1.19 (source: frontmatter and server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment."},{"path":"VET-REPORT.md","content":"# Vetting Report: secrets-manager\n**Date:** 2026-09-13 08:11 EDT\n**Vetter:** JARVIS (skill-vetter skill)\n**Source:** local (/home/jarvis/.openclaw/workspace)\n**Verdict:** PASS\n**Risk score:** 8/100\n\n## Findings\n\n### Critical\n- (none)\n\n### Warnings\n- 1 network URLs\n- No description in frontmatter\n\n### Notes\n- (none)\n\n## Permission footprint\n- Tools requested: exec process read write \n\n## Network footprint\nhttps://api.openai.com/v1/chat\n\n## Side effects\n- Reads: SKILL.md\n- Writes: VET-REPORT.md (this file)\n- Network: 1 distinct hosts\n\n## Verdict rationale\nScore 8/100 with 0 critical findings and 2 warnings."}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":null,"editorialQuality":{"score":100,"threshold":65,"status":"thin","wordCount":2148,"uniquenessScore":36,"reasons":["uniqueness-below-45"]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-10T06:53:23.949Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-10T06:53:23.949Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-10T10:43:37.946Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}