Gestión de secretos
OpenClaw soporta SecretRefs aditivos para que las credenciales soportadas no necesiten almacenarse en texto plano en la configuración.
El texto plano sigue funcionando. Los SecretRefs son opcionales por credencial.
Objetivos y modelo de runtime
Los secretos se resuelven en un snapshot de runtime en memoria.
- La resolución es eager durante la activación, no lazy en las rutas de solicitud.
- El inicio falla rápido cuando un SecretRef efectivamente activo no puede resolverse.
- La recarga usa intercambio atómico: éxito completo, o mantiene el último snapshot conocido como bueno.
- Las solicitudes de runtime leen solo del snapshot activo en memoria.
- Las rutas de entrega saliente también leen de ese snapshot activo (por ejemplo, entrega de respuesta/hilo de Discord y envíos de acción de Telegram); no vuelven a resolver SecretRefs en cada envío.
Esto mantiene las interrupciones del proveedor de secretos fuera de las rutas de solicitud activas.
Filtrado de superficie activa
Los SecretRefs se validan solo en superficies efectivamente activas.
- Superficies habilitadas: las refs no resueltas bloquean inicio/recarga.
- Superficies inactivas: las refs no resueltas no bloquean inicio/recarga.
- Las refs inactivas emiten diagnósticos no fatales con código
SECRETS_REF_IGNORED_INACTIVE_SURFACE.
Ejemplos de superficies inactivas:
- Entradas de canal/cuenta deshabilitadas.
- Credenciales de canal de nivel superior que ninguna cuenta habilitada hereda.
- Superficies de herramienta/característica deshabilitadas.
- Claves específicas del proveedor de búsqueda web que no están seleccionadas por
tools.web.search.provider. En modo automático (proveedor no establecido), las claves se consultan por precedencia para auto-detección del proveedor hasta que una se resuelve. Después de la selección, las claves de proveedores no seleccionados se tratan como inactivas hasta ser seleccionadas. - Los SecretRefs de
gateway.remote.token/gateway.remote.passwordestán activos si se cumple una de estas condiciones:gateway.mode=remotegateway.remote.urlestá configuradogateway.tailscale.modeesserveofunnel- En modo local sin esas superficies remotas:
gateway.remote.tokenestá activo cuando la autenticación por token puede ganar y no hay token de env/auth configurado.gateway.remote.passwordestá activo solo cuando la autenticación por password puede ganar y no hay password de env/auth configurado.
- El SecretRef de
gateway.auth.tokenestá inactivo para la resolución de autenticación de inicio cuandoOPENCLAW_GATEWAY_TOKEN(oCLAWDBOT_GATEWAY_TOKEN) está establecido, porque la entrada de token de env gana para ese runtime.
Diagnósticos de superficie de autenticación del Gateway
Cuando un SecretRef está configurado en gateway.auth.token, gateway.auth.password,
gateway.remote.token o gateway.remote.password, el inicio/recarga del gateway registra el
estado de la superficie explícitamente:
active: el SecretRef es parte de la superficie de autenticación efectiva y debe resolverse.inactive: el SecretRef se ignora para este runtime porque otra superficie de autenticación gana, o porque la autenticación remota está deshabilitada/no activa.
Estas entradas se registran con SECRETS_GATEWAY_AUTH_SURFACE e incluyen la razón usada por la
política de superficie activa, para que puedas ver por qué una credencial fue tratada como activa o inactiva.
Verificación previa de referencia en onboarding
Cuando el onboarding se ejecuta en modo interactivo y eliges almacenamiento SecretRef, OpenClaw ejecuta validación previa antes de guardar:
- Refs de env: valida el nombre de la variable de entorno y confirma que un valor no vacío es visible durante el onboarding.
- Refs de proveedor (
fileoexec): valida la selección del proveedor, resuelveidy verifica el tipo de valor resuelto. - Ruta de reutilización del quickstart: cuando
gateway.auth.tokenya es un SecretRef, el onboarding lo resuelve antes del probe/bootstrap del dashboard (para refsenv,fileyexec) usando la misma compuerta de fallo rápido.
Si la validación falla, el onboarding muestra el error y te permite reintentar.
Contrato SecretRef
Usa una forma de objeto en todas partes:
{ source: "env" | "file" | "exec", provider: "default", id: "..." }
source: "env"
{ source: "env", provider: "default", id: "OPENAI_API_KEY" }
Validación:
providerdebe coincidir con^[a-z][a-z0-9_-]{0,63}$iddebe coincidir con^[A-Z][A-Z0-9_]{0,127}$
source: "file"
{ source: "file", provider: "filemain", id: "/providers/openai/apiKey" }
Validación:
providerdebe coincidir con^[a-z][a-z0-9_-]{0,63}$iddebe ser un puntero JSON absoluto (/...)- Escape RFC6901 en segmentos:
~=>~0,/=>~1
source: "exec"
{ source: "exec", provider: "vault", id: "providers/openai/apiKey" }
Validación:
providerdebe coincidir con^[a-z][a-z0-9_-]{0,63}$iddebe coincidir con^[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}$idno debe contener.o..como segmentos de ruta delimitados por barra (por ejemploa/../bse rechaza)
Configuración de proveedores
Define proveedores en secrets.providers:
{
secrets: {
providers: {
default: { source: "env" },
filemain: {
source: "file",
path: "~/.openclaw/secrets.json",
mode: "json", // o "singleValue"
},
vault: {
source: "exec",
command: "/usr/local/bin/openclaw-vault-resolver",
args: ["--profile", "prod"],
passEnv: ["PATH", "VAULT_ADDR"],
jsonOnly: true,
},
},
defaults: {
env: "default",
file: "filemain",
exec: "vault",
},
resolution: {
maxProviderConcurrency: 4,
maxRefsPerProvider: 512,
maxBatchBytes: 262144,
},
},
}
Proveedor env
- Lista de permitidos opcional vía
allowlist. - Los valores de env faltantes/vacíos fallan en la resolución.
Proveedor file
- Lee un archivo local desde
path. mode: "json"espera un payload de objeto JSON y resuelveidcomo puntero.mode: "singleValue"espera el id de ref"value"y devuelve el contenido del archivo.- La ruta debe pasar verificaciones de propiedad/permisos.
- Nota de fallo cerrado en Windows: si la verificación de ACL no está disponible para una ruta, la resolución falla. Para rutas de confianza únicamente, establece
allowInsecurePath: trueen ese proveedor para omitir las verificaciones de seguridad de ruta.
Proveedor exec
- Ejecuta la ruta binaria absoluta configurada, sin shell.
- Por defecto,
commanddebe apuntar a un archivo regular (no un enlace simbólico). - Establece
allowSymlinkCommand: truepara permitir rutas de comando con enlaces simbólicos (por ejemplo, shims de Homebrew). OpenClaw valida la ruta de destino resuelta. - Combina
allowSymlinkCommandcontrustedDirspara rutas de gestores de paquetes (por ejemplo["/opt/homebrew"]). - Soporta timeout, timeout sin salida, límites de bytes de salida, lista de env permitidas y directorios de confianza.
- Nota de fallo cerrado en Windows: si la verificación de ACL no está disponible para la ruta del comando, la resolución falla. Para rutas de confianza únicamente, establece
allowInsecurePath: trueen ese proveedor para omitir las verificaciones de seguridad de ruta.
Payload de solicitud (stdin):
{ "protocolVersion": 1, "provider": "vault", "ids": ["providers/openai/apiKey"] }
Payload de respuesta (stdout):
{ "protocolVersion": 1, "values": { "providers/openai/apiKey": "<openai-api-key>" } } // pragma: allowlist secret
Errores opcionales por id:
{
"protocolVersion": 1,
"values": {},
"errors": { "providers/openai/apiKey": { "message": "not found" } }
}
Ejemplos de integración exec
1Password CLI
{
secrets: {
providers: {
onepassword_openai: {
source: "exec",
command: "/opt/homebrew/bin/op",
allowSymlinkCommand: true, // requerido para binarios con enlace simbólico de Homebrew
trustedDirs: ["/opt/homebrew"],
args: ["read", "op://Personal/OpenClaw QA API Key/password"],
passEnv: ["HOME"],
jsonOnly: false,
},
},
},
models: {
providers: {
openai: {
baseUrl: "https://api.openai.com/v1",
models: [{ id: "gpt-5", name: "gpt-5" }],
apiKey: { source: "exec", provider: "onepassword_openai", id: "value" },
},
},
},
}
HashiCorp Vault CLI
{
secrets: {
providers: {
vault_openai: {
source: "exec",
command: "/opt/homebrew/bin/vault",
allowSymlinkCommand: true, // requerido para binarios con enlace simbólico de Homebrew
trustedDirs: ["/opt/homebrew"],
args: ["kv", "get", "-field=OPENAI_API_KEY", "secret/openclaw"],
passEnv: ["VAULT_ADDR", "VAULT_TOKEN"],
jsonOnly: false,
},
},
},
models: {
providers: {
openai: {
baseUrl: "https://api.openai.com/v1",
models: [{ id: "gpt-5", name: "gpt-5" }],
apiKey: { source: "exec", provider: "vault_openai", id: "value" },
},
},
},
}
sops
{
secrets: {
providers: {
sops_openai: {
source: "exec",
command: "/opt/homebrew/bin/sops",
allowSymlinkCommand: true, // requerido para binarios con enlace simbólico de Homebrew
trustedDirs: ["/opt/homebrew"],
args: ["-d", "--extract", '["providers"]["openai"]["apiKey"]', "/path/to/secrets.enc.json"],
passEnv: ["SOPS_AGE_KEY_FILE"],
jsonOnly: false,
},
},
},
models: {
providers: {
openai: {
baseUrl: "https://api.openai.com/v1",
models: [{ id: "gpt-5", name: "gpt-5" }],
apiKey: { source: "exec", provider: "sops_openai", id: "value" },
},
},
},
}
Superficie de credenciales soportada
Las credenciales soportadas y no soportadas canónicas se listan en:
Las credenciales generadas en runtime o rotativas y el material de actualización OAuth están intencionalmente excluidos de la resolución SecretRef de solo lectura.
Comportamiento requerido y precedencia
- Campo sin ref: sin cambios.
- Campo con ref: obligatorio en superficies activas durante la activación.
- Si están presentes tanto texto plano como ref, la ref tiene precedencia en las rutas de precedencia soportadas.
Señales de advertencia y auditoría:
SECRETS_REF_OVERRIDES_PLAINTEXT(advertencia de runtime)REF_SHADOWED(hallazgo de auditoría cuando las credenciales deauth-profiles.jsontienen precedencia sobre las refs deopenclaw.json)
Comportamiento de compatibilidad de Google Chat:
serviceAccountReftiene precedencia sobreserviceAccounten texto plano.- El valor en texto plano se ignora cuando la ref hermana está establecida.
Disparadores de activación
La activación de secretos se ejecuta en:
- Inicio (verificación previa más activación final)
- Ruta de hot-apply en recarga de configuración
- Ruta de verificación de reinicio en recarga de configuración
- Recarga manual vía
secrets.reload
Contrato de activación:
- El éxito intercambia el snapshot atómicamente.
- El fallo en el inicio aborta el inicio del gateway.
- El fallo en recarga de runtime mantiene el último snapshot conocido como bueno.
- Proporcionar un token de canal explícito por llamada a un helper/tool call saliente no dispara la activación de SecretRef; los puntos de activación permanecen en inicio, recarga y
secrets.reloadexplícito.
Señales de degradación y recuperación
Cuando la activación en tiempo de recarga falla después de un estado saludable, OpenClaw entra en estado de secretos degradado.
Evento de sistema y códigos de log de disparo único:
SECRETS_RELOADER_DEGRADEDSECRETS_RELOADER_RECOVERED
Comportamiento:
- Degradado: el runtime mantiene el último snapshot conocido como bueno.
- Recuperado: se emite una vez después de la siguiente activación exitosa.
- Los fallos repetidos mientras ya está degradado registran advertencias pero no generan spam de eventos.
- El fallo rápido de inicio no emite eventos de degradación porque el runtime nunca se activó.
Resolución de rutas de comando
Las rutas de comando pueden optar por la resolución SecretRef soportada vía RPC de snapshot del gateway.
Hay dos comportamientos generales:
- Rutas de comando estrictas (por ejemplo, rutas de memoria remota de
openclaw memoryyopenclaw qr --remote) leen del snapshot activo y fallan rápido cuando un SecretRef requerido no está disponible. - Rutas de comando de solo lectura (por ejemplo,
openclaw status,openclaw status --all,openclaw channels status,openclaw channels resolvey flujos de doctor/reparación de config de solo lectura) también prefieren el snapshot activo, pero degradan en lugar de abortar cuando un SecretRef objetivo no está disponible en esa ruta de comando.
Comportamiento de solo lectura:
- Cuando el gateway está ejecutándose, estos comandos leen primero del snapshot activo.
- Si la resolución del gateway está incompleta o el gateway no está disponible, intentan un respaldo local dirigido para la superficie del comando específico.
- Si un SecretRef objetivo sigue sin estar disponible, el comando continúa con salida degradada de solo lectura y diagnósticos explícitos como “configured but unavailable in this command path”.
- Este comportamiento degradado es solo local al comando. No debilita las rutas de inicio, recarga o envío/autenticación del runtime.
Otras notas:
- La actualización del snapshot después de la rotación de secretos del backend se maneja con
openclaw secrets reload. - Método RPC del Gateway usado por estas rutas de comando:
secrets.resolve.
Flujo de trabajo de auditoría y configuración
Flujo por defecto del operador:
openclaw secrets audit --check
openclaw secrets configure
openclaw secrets audit --check
secrets audit
Los hallazgos incluyen:
- valores en texto plano en reposo (
openclaw.json,auth-profiles.json,.envyagents/*/agent/models.jsongenerados) - residuos de headers sensibles de proveedores en texto plano en entradas
models.jsongeneradas - refs no resueltas
- sombreado de precedencia (
auth-profiles.jsonteniendo prioridad sobre refs deopenclaw.json) - residuos heredados (
auth.json, recordatorios OAuth)
Nota sobre residuos de headers:
- La detección de headers sensibles de proveedores se basa en heurísticas de nombre (nombres comunes de headers de autenticación/credenciales y fragmentos como
authorization,x-api-key,token,secret,passwordycredential).
secrets configure
Asistente interactivo que:
- configura
secrets.providersprimero (env/file/exec, agregar/editar/eliminar) - te permite seleccionar campos soportados que contienen secretos en
openclaw.jsonmásauth-profiles.jsonpara un alcance de agente - puede crear un nuevo mapeo en
auth-profiles.jsondirectamente en el selector de destinos - captura detalles del SecretRef (
source,provider,id) - ejecuta resolución previa
- puede aplicar inmediatamente
Modos útiles:
openclaw secrets configure --providers-onlyopenclaw secrets configure --skip-provider-setupopenclaw secrets configure --agent <id>
Valores por defecto de apply en configure:
- limpia credenciales estáticas coincidentes de
auth-profiles.jsonpara los proveedores objetivo - limpia entradas estáticas heredadas de
api_keydeauth.json - limpia líneas de secretos conocidos coincidentes de
<config-dir>/.env
secrets apply
Aplica un plan guardado:
openclaw secrets apply --from /tmp/openclaw-secrets-plan.json
openclaw secrets apply --from /tmp/openclaw-secrets-plan.json --dry-run
Para detalles estrictos del contrato de destino/ruta y reglas exactas de rechazo, consulta:
Política de seguridad unidireccional
OpenClaw intencionalmente no escribe copias de respaldo de rollback que contengan valores históricos de secretos en texto plano.
Modelo de seguridad:
- la verificación previa debe tener éxito antes del modo de escritura
- la activación de runtime se valida antes del commit
- apply actualiza archivos usando reemplazo atómico de archivos y restauración en base a mejor esfuerzo en caso de fallo
Notas de compatibilidad de autenticación heredada
Para credenciales estáticas, el runtime ya no depende del almacenamiento heredado de autenticación en texto plano.
- La fuente de credenciales de runtime es el snapshot resuelto en memoria.
- Las entradas estáticas heredadas de
api_keyse limpian cuando se descubren. - El comportamiento de compatibilidad relacionado con OAuth permanece separado.
Nota sobre la Web UI
Algunas uniones SecretInput son más fáciles de configurar en modo de editor raw que en modo formulario.
Documentación relacionada
- Comandos CLI: secrets
- Detalles del contrato del plan: Contrato del plan de Secrets Apply
- Superficie de credenciales: Superficie de credenciales SecretRef
- Configuración de autenticación: Autenticación
- Postura de seguridad: Seguridad
- Precedencia de entorno: Variables de entorno