Problem
We currently store API keys and credentials as plaintext strings across multiple config files and potentially source code. OpenClaw now has a built-in external secrets manager (openclaw secrets) that supports SecretRef objects with exec-based providers, including native 1Password CLI (op) integration.
Current State
~/.openclaw/openclaw.json — at least 4 plaintext apiKey values (model providers, skills)
~/.openclaw/.env — environment variables with secret values
~/.openclaw/agents/*/agent/auth-profiles.json — potential plaintext credentials
- Source code — any hardcoded secrets, tokens, or credentials in NOVA repos (nova-memory, nova-cognition, nova-relationships, nova-openclaw fork)
- 1Password CLI — already installed (
op v2.32.0) but not integrated
Desired State
All secrets replaced with SecretRef objects pointing to 1Password:
{
"source": "exec",
"provider": "onepassword",
"id": "value"
}
With a provider config like:
{
"secrets": {
"providers": {
"onepassword": {
"source": "exec",
"command": "/home/linuxbrew/.linuxbrew/bin/op",
"args": ["read", "op://VAULT/ITEM/FIELD"],
"passEnv": ["HOME"],
"jsonOnly": false
}
}
}
}
Scope
Phase 1: Audit
- Run
openclaw secrets audit --check to identify all plaintext secrets in OpenClaw config
- Grep all NOVA repos for hardcoded secrets, tokens, API keys, passwords
- Check
.env files, auth-profiles.json, any legacy auth.json
- Document every secret location and what it's used for
Phase 2: 1Password Setup
- Ensure all secrets exist in 1Password vault(s) with consistent naming
- Verify
op CLI can read each secret non-interactively (service account or biometric)
- Test exec provider connectivity from the OpenClaw gateway process
Phase 3: Migration
- Run
openclaw secrets configure to set up the exec provider
- Map each plaintext field to its 1Password SecretRef
- Run preflight validation
- Apply migration (one-way scrub of plaintext)
- Run
openclaw secrets audit --check to confirm clean state
Phase 4: Source Code Scan
- Scan all NOVA repos for any remaining hardcoded secrets
- Replace with env var references or SecretRef patterns as appropriate
- Add
.gitignore / pre-commit hooks to prevent future secret commits
Acceptance Criteria
Technical Notes
- OpenClaw docs:
docs/gateway/secrets.md, docs/cli/secrets.md
- 1Password exec example in upstream docs
op binary path: /home/linuxbrew/.linuxbrew/bin/op
- May need
allowSymlinkCommand: true + trustedDirs if op is symlinked
- SecretRef in-scope fields (v1):
models.providers.*.apiKey, skills.entries.*.apiKey, channels.googlechat.serviceAccount, auth-profiles keyRef/tokenRef
Priority
High — plaintext secrets on disk is a security exposure.
Problem
We currently store API keys and credentials as plaintext strings across multiple config files and potentially source code. OpenClaw now has a built-in external secrets manager (
openclaw secrets) that supports SecretRef objects with exec-based providers, including native 1Password CLI (op) integration.Current State
~/.openclaw/openclaw.json— at least 4 plaintextapiKeyvalues (model providers, skills)~/.openclaw/.env— environment variables with secret values~/.openclaw/agents/*/agent/auth-profiles.json— potential plaintext credentialsopv2.32.0) but not integratedDesired State
All secrets replaced with SecretRef objects pointing to 1Password:
{ "source": "exec", "provider": "onepassword", "id": "value" }With a provider config like:
{ "secrets": { "providers": { "onepassword": { "source": "exec", "command": "/home/linuxbrew/.linuxbrew/bin/op", "args": ["read", "op://VAULT/ITEM/FIELD"], "passEnv": ["HOME"], "jsonOnly": false } } } }Scope
Phase 1: Audit
openclaw secrets audit --checkto identify all plaintext secrets in OpenClaw config.envfiles,auth-profiles.json, any legacyauth.jsonPhase 2: 1Password Setup
opCLI can read each secret non-interactively (service account or biometric)Phase 3: Migration
openclaw secrets configureto set up the exec provideropenclaw secrets audit --checkto confirm clean statePhase 4: Source Code Scan
.gitignore/ pre-commit hooks to prevent future secret commitsAcceptance Criteria
openclaw secrets audit --checkreturns clean (exit 0)openclaw.json.env(migrated to SecretRef)keyRef/tokenRefinstead of plaintextopenclaw secrets reloadworks without restartTechnical Notes
docs/gateway/secrets.md,docs/cli/secrets.mdopbinary path:/home/linuxbrew/.linuxbrew/bin/opallowSymlinkCommand: true+trustedDirsif op is symlinkedmodels.providers.*.apiKey,skills.entries.*.apiKey,channels.googlechat.serviceAccount, auth-profileskeyRef/tokenRefPriority
High — plaintext secrets on disk is a security exposure.