#23000: Secrets: add migrate rollback and skill ref support
cli
agents
maintainer
size: XL
Cluster:
Model Authentication Enhancements
## Summary
- add `openclaw secrets migrate` with dry-run/write modes and `--rollback <backup-id>` support
- implement migration of plaintext static secrets into file-backed refs (`sops`) for:
- `models.providers.*.apiKey`
- `skills.entries.*.apiKey`
- `channels.googlechat(.accounts.*).serviceAccount`
- `auth-profiles.json` `api_key.key` / `token.token`
- add backup manifest + restore flow and automatic rollback on migration apply failure
- add optional `.env` scrub by matching migrated plaintext values
- add runtime SecretRef resolution for `skills.entries.*.apiKey`
- scrub legacy static `api_key` entries from `auth.json` in pi auth discovery path
## Validation
- `pnpm check`
- `pnpm vitest src/secrets/migrate.test.ts src/cli/secrets-cli.test.ts src/secrets/runtime.test.ts src/config/config.secrets-schema.test.ts src/agents/pi-model-discovery.auth.test.ts`
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
This PR adds a comprehensive secrets migration system that migrates plaintext secrets to file-backed `SecretRef` objects encrypted with SOPS. The migration covers model provider API keys, skill entry API keys, Google Chat service accounts, and auth profile credentials.
Key changes:
- Added `openclaw secrets migrate` CLI command with dry-run (default) and `--write` modes
- Implemented `--rollback <backup-id>` to restore from automatic backups
- Added optional `.env` scrubbing to remove migrated plaintext values
- Extended `SecretRef` support to `skills.entries.*.apiKey` in config schema and runtime resolution
- Added automatic cleanup of legacy static `api_key` entries from `auth.json` files in pi auth discovery
The implementation includes automatic rollback on migration failure, backup retention (last 20 backups), and comprehensive test coverage for migration, rollback, and runtime resolution.
<h3>Confidence Score: 4/5</h3>
- This PR is safe to merge with minor considerations
- The PR implements a critical security feature with thorough error handling, automatic rollback on failure, and comprehensive test coverage. The code follows consistent patterns and includes backup/restore mechanisms. One minor edge case exists in the env parsing logic that could theoretically mishandle a single quote character, but this is extremely unlikely in practice and wouldn't cause data loss.
- Pay close attention to `src/secrets/migrate.ts` parseEnvValue function (line 205-214) for the edge case handling
<sub>Last reviewed commit: a4119ac</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#22846: Config: add secret ref schema and redaction foundations
by joshavant · 2026-02-21
77.9%
#16663: feat: GCP Secret Manager integration for external secrets management
by amor71 · 2026-02-15
75.7%
#19538: security: migrate sensitive Docker env vars to Docker secrets
by Mozzzaic · 2026-02-17
74.9%
#23009: Onboard: persist env-backed API keys as secret refs
by joshavant · 2026-02-21
73.4%
#22858: Gateway: add eager secrets runtime snapshot activation
by joshavant · 2026-02-21
72.2%
#23165: fix(security): detect plaintext credentials in security audit
by ihsanmokhlisse · 2026-02-22
71.6%
#22744: feat: masked secrets — prevent agents from accessing raw API keys
by theMachineClay · 2026-02-21
71.0%
#9747: feat(config): add pass (password-store) secret backend support
by evilbuck · 2026-02-05
70.9%
#21053: security(infra): OS keychain storage for device private keys
by richvincent · 2026-02-19
70.7%
#10258: fix(config): preserve ${ENV_VAR} references when writing config (#9...
by nu-gui · 2026-02-06
70.4%