시크릿 관리
OpenClaw는 지원되는 인증 정보가 설정에 평문으로 저장될 필요가 없도록 추가적인 SecretRef를 지원합니다.
평문도 여전히 작동합니다. SecretRef는 인증 정보별로 선택적으로 사용합니다.
목표 및 런타임 모델
시크릿은 인메모리 런타임 스냅샷으로 확인됩니다.
- 확인은 활성화 시 즉시(eager) 수행되며, 요청 경로에서 지연(lazy) 수행되지 않습니다.
- 효과적으로 활성 상태인 SecretRef를 확인할 수 없으면 시작 시 즉시 실패합니다.
- 리로드는 원자적 교체를 사용합니다: 완전히 성공하거나, 마지막으로 알려진 정상 스냅샷을 유지합니다.
- 런타임 요청은 활성 인메모리 스냅샷에서만 읽습니다.
- 아웃바운드 전달 경로도 해당 활성 스냅샷에서 읽습니다 (예: Discord 응답/스레드 전달, Telegram 액션 전송). 각 전송마다 SecretRef를 다시 확인하지 않습니다.
이렇게 하면 시크릿 프로바이더 장애가 핫 요청 경로에 영향을 미치지 않습니다.
활성 표면 필터링
SecretRef는 효과적으로 활성인 표면에서만 유효성을 검사합니다.
- 활성화된 표면: 확인되지 않은 ref가 시작/리로드를 차단합니다.
- 비활성 표면: 확인되지 않은 ref가 시작/리로드를 차단하지 않습니다.
- 비활성 ref는 코드
SECRETS_REF_IGNORED_INACTIVE_SURFACE와 함께 비치명적 진단을 생성합니다.
비활성 표면 예시:
- 비활성화된 채널/계정 항목.
- 활성화된 계정이 상속하지 않는 최상위 채널 인증 정보.
- 비활성화된 도구/기능 표면.
tools.web.search.provider에 의해 선택되지 않은 웹 검색 프로바이더별 키. 자동 모드(프로바이더 미설정)에서는 프로바이더 자동 감지를 위해 우선순위별로 키가 참조됩니다. 선택 후 선택되지 않은 프로바이더 키는 선택될 때까지 비활성으로 처리됩니다.gateway.remote.token/gateway.remote.passwordSecretRef는 다음 중 하나가 참이면 활성입니다:gateway.mode=remotegateway.remote.url이 설정됨gateway.tailscale.mode가serve또는funnel- 해당 원격 표면 없이 로컬 모드에서:
gateway.remote.token은 토큰 인증이 우선할 수 있고 env/auth 토큰이 설정되지 않았을 때 활성입니다.gateway.remote.password는 비밀번호 인증이 우선할 수 있고 env/auth 비밀번호가 설정되지 않았을 때만 활성입니다.
gateway.auth.tokenSecretRef는OPENCLAW_GATEWAY_TOKEN(또는CLAWDBOT_GATEWAY_TOKEN)이 설정된 경우 시작 인증 확인에서 비활성입니다. env 토큰 입력이 해당 런타임에서 우선하기 때문입니다.
게이트웨이 인증 표면 진단
gateway.auth.token, gateway.auth.password, gateway.remote.token, gateway.remote.password에 SecretRef가 설정된 경우, 게이트웨이 시작/리로드 시 표면 상태를 명시적으로 로그합니다:
active: SecretRef가 유효한 인증 표면의 일부이며 반드시 확인되어야 합니다.inactive: 다른 인증 표면이 우선하거나 원격 인증이 비활성/미활성이므로 해당 런타임에서 SecretRef가 무시됩니다.
이 항목들은 SECRETS_GATEWAY_AUTH_SURFACE와 함께 로그되며, 활성 표면 정책이 사용한 이유를 포함하여 인증 정보가 활성 또는 비활성으로 처리된 이유를 확인할 수 있습니다.
온보딩 참조 사전 검증
온보딩이 대화형 모드에서 실행되고 SecretRef 저장소를 선택하면, OpenClaw는 저장 전에 사전 유효성 검사를 실행합니다:
- Env ref: 환경 변수 이름을 유효성 검사하고 온보딩 중 비어 있지 않은 값이 표시되는지 확인합니다.
- 프로바이더 ref (
file또는exec): 프로바이더 선택을 유효성 검사하고,id를 확인하며, 확인된 값 유형을 검사합니다. - 빠른 시작 재사용 경로:
gateway.auth.token이 이미 SecretRef인 경우, 온보딩은 probe/대시보드 부트스트랩 전에 동일한 즉시 실패 게이트를 사용하여 확인합니다 (env,file,execref용).
유효성 검사에 실패하면, 온보딩이 오류를 표시하고 재시도할 수 있게 합니다.
SecretRef 규약
모든 곳에서 하나의 객체 형태를 사용하세요:
{ source: "env" | "file" | "exec", provider: "default", id: "..." }
source: "env"
{ source: "env", provider: "default", id: "OPENAI_API_KEY" }
유효성 검사:
provider는^[a-z][a-z0-9_-]{0,63}$와 일치해야 합니다id는^[A-Z][A-Z0-9_]{0,127}$와 일치해야 합니다
source: "file"
{ source: "file", provider: "filemain", id: "/providers/openai/apiKey" }
유효성 검사:
provider는^[a-z][a-z0-9_-]{0,63}$와 일치해야 합니다id는 절대 JSON 포인터(/...)여야 합니다- RFC6901 이스케이핑:
~=>~0,/=>~1
source: "exec"
{ source: "exec", provider: "vault", id: "providers/openai/apiKey" }
유효성 검사:
provider는^[a-z][a-z0-9_-]{0,63}$와 일치해야 합니다id는^[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}$와 일치해야 합니다id에 슬래시 구분 경로 세그먼트로.또는..가 포함되면 안 됩니다 (예:a/../b는 거부됨)
프로바이더 설정
secrets.providers에 프로바이더를 정의하세요:
{
secrets: {
providers: {
default: { source: "env" },
filemain: {
source: "file",
path: "~/.openclaw/secrets.json",
mode: "json", // 또는 "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,
},
},
}
Env 프로바이더
allowlist를 통한 선택적 허용 목록.- 누락되거나 빈 환경 변수 값은 확인 실패.
File 프로바이더
path에서 로컬 파일을 읽습니다.mode: "json"은 JSON 객체 페이로드를 기대하고id를 포인터로 확인합니다.mode: "singleValue"는 ref id"value"를 기대하고 파일 내용을 반환합니다.- 경로는 소유권/권한 검사를 통과해야 합니다.
- Windows 폐쇄적 실패 참고: 경로에 대한 ACL 검증이 불가능하면 확인이 실패합니다. 신뢰할 수 있는 경로에만 해당 프로바이더에
allowInsecurePath: true를 설정하여 경로 보안 검사를 우회하세요.
Exec 프로바이더
- 설정된 절대 바이너리 경로를 실행하며, 셸을 사용하지 않습니다.
- 기본적으로
command는 심볼릭 링크가 아닌 일반 파일을 가리켜야 합니다. - 심볼릭 링크 명령 경로를 허용하려면
allowSymlinkCommand: true를 설정하세요 (예: Homebrew 심). OpenClaw가 확인된 대상 경로를 유효성 검사합니다. allowSymlinkCommand를 패키지 관리자 경로(예:["/opt/homebrew"])에 대한trustedDirs와 함께 사용하세요.- 타임아웃, 무출력 타임아웃, 출력 바이트 제한, 환경 허용 목록, 신뢰할 수 있는 디렉터리를 지원합니다.
- Windows 폐쇄적 실패 참고: 명령 경로에 대한 ACL 검증이 불가능하면 확인이 실패합니다. 신뢰할 수 있는 경로에만 해당 프로바이더에
allowInsecurePath: true를 설정하여 경로 보안 검사를 우회하세요.
요청 페이로드 (stdin):
{ "protocolVersion": 1, "provider": "vault", "ids": ["providers/openai/apiKey"] }
응답 페이로드 (stdout):
{ "protocolVersion": 1, "values": { "providers/openai/apiKey": "<openai-api-key>" } } // pragma: allowlist secret
ID별 선택적 오류:
{
"protocolVersion": 1,
"values": {},
"errors": { "providers/openai/apiKey": { "message": "not found" } }
}
Exec 통합 예시
1Password CLI
{
secrets: {
providers: {
onepassword_openai: {
source: "exec",
command: "/opt/homebrew/bin/op",
allowSymlinkCommand: true, // 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, // 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, // 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" },
},
},
},
}
지원되는 인증 정보 표면
정규 지원 및 미지원 인증 정보는 다음에 나열되어 있습니다:
런타임 생성 또는 순환 인증 정보와 OAuth 갱신 자료는 읽기 전용 SecretRef 확인에서 의도적으로 제외됩니다.
필수 동작 및 우선순위
- ref가 없는 필드: 변경 없음.
- ref가 있는 필드: 활성화 시 활성 표면에서 필수.
- 평문과 ref가 모두 있으면, 지원되는 우선순위 경로에서 ref가 우선합니다.
경고 및 감사 신호:
SECRETS_REF_OVERRIDES_PLAINTEXT(런타임 경고)REF_SHADOWED(auth-profiles.json인증 정보가openclaw.jsonref보다 우선할 때의 감사 발견)
Google Chat 호환성 동작:
serviceAccountRef가 평문serviceAccount보다 우선합니다.- 형제 ref가 설정되면 평문 값은 무시됩니다.
활성화 트리거
시크릿 활성화는 다음에서 실행됩니다:
- 시작 (사전 검증 + 최종 활성화)
- 설정 리로드 핫 적용 경로
- 설정 리로드 재시작 확인 경로
secrets.reload를 통한 수동 리로드
활성화 규약:
- 성공하면 스냅샷을 원자적으로 교체합니다.
- 시작 실패 시 게이트웨이 시작을 중단합니다.
- 런타임 리로드 실패 시 마지막으로 알려진 정상 스냅샷을 유지합니다.
- 아웃바운드 헬퍼/도구 호출에 명시적 채널별 토큰을 제공하는 것은 SecretRef 활성화를 트리거하지 않습니다. 활성화 지점은 시작, 리로드, 명시적
secrets.reload입니다.
저하 및 복구 신호
정상 상태 후 리로드 시 활성화가 실패하면, OpenClaw는 저하된 시크릿 상태에 진입합니다.
일회성 시스템 이벤트 및 로그 코드:
SECRETS_RELOADER_DEGRADEDSECRETS_RELOADER_RECOVERED
동작:
- 저하: 런타임이 마지막으로 알려진 정상 스냅샷을 유지합니다.
- 복구: 다음 성공적인 활성화 후 한 번 발생합니다.
- 이미 저하 상태에서 반복 실패 시 경고를 로그하지만 이벤트를 스팸하지 않습니다.
- 시작 시 즉시 실패는 런타임이 활성화된 적이 없으므로 저하 이벤트를 발생시키지 않습니다.
명령 경로 확인
명령 경로는 게이트웨이 스냅샷 RPC를 통해 지원되는 SecretRef 확인에 참여할 수 있습니다.
두 가지 넓은 동작이 있습니다:
- 엄격한 명령 경로(예:
openclaw memory원격 메모리 경로,openclaw qr --remote)는 활성 스냅샷에서 읽고 필수 SecretRef를 사용할 수 없으면 즉시 실패합니다. - 읽기 전용 명령 경로(예:
openclaw status,openclaw status --all,openclaw channels status,openclaw channels resolve, 읽기 전용 doctor/설정 복구 흐름)도 활성 스냅샷을 선호하지만, 대상 SecretRef가 해당 명령 경로에서 사용 불가능하면 중단 대신 저하됩니다.
읽기 전용 동작:
- 게이트웨이가 실행 중이면, 이 명령들은 먼저 활성 스냅샷에서 읽습니다.
- 게이트웨이 확인이 불완전하거나 게이트웨이를 사용할 수 없으면, 특정 명령 표면에 대한 대상 로컬 대체를 시도합니다.
- 대상 SecretRef가 여전히 사용 불가능하면, 명령은 저하된 읽기 전용 출력과 “configured but unavailable in this command path”와 같은 명시적 진단으로 계속됩니다.
- 이 저하 동작은 명령 로컬 전용입니다. 런타임 시작, 리로드, 전송/인증 경로를 약화시키지 않습니다.
기타 참고:
- 백엔드 시크릿 순환 후 스냅샷 갱신은
openclaw secrets reload로 처리됩니다. - 이 명령 경로에서 사용하는 게이트웨이 RPC 메서드:
secrets.resolve.
감사 및 설정 워크플로우
기본 운영자 흐름:
openclaw secrets audit --check
openclaw secrets configure
openclaw secrets audit --check
secrets audit
발견 항목:
- 저장된 평문 값 (
openclaw.json,auth-profiles.json,.env, 생성된agents/*/agent/models.json) - 생성된
models.json항목의 평문 민감 프로바이더 헤더 잔여물 - 확인되지 않은 ref
- 우선순위 섀도잉 (
auth-profiles.json이openclaw.jsonref보다 우선) - 레거시 잔여물 (
auth.json, OAuth 알림)
헤더 잔여물 참고:
- 민감한 프로바이더 헤더 감지는 이름 휴리스틱 기반입니다 (일반적인 인증/인증 정보 헤더 이름 및
authorization,x-api-key,token,secret,password,credential과 같은 단편).
secrets configure
다음을 수행하는 대화형 도우미:
- 먼저
secrets.providers설정 (env/file/exec, 추가/편집/제거) openclaw.json및 하나의 에이전트 범위의auth-profiles.json에서 지원되는 시크릿 포함 필드 선택- 대상 선택기에서 새
auth-profiles.json매핑을 직접 생성 가능 - SecretRef 세부 정보 캡처 (
source,provider,id) - 사전 확인 실행
- 즉시 적용 가능
유용한 모드:
openclaw secrets configure --providers-onlyopenclaw secrets configure --skip-provider-setupopenclaw secrets configure --agent <id>
configure 적용 기본값:
- 대상 프로바이더에 대해
auth-profiles.json에서 일치하는 정적 인증 정보 스크럽 auth.json에서 레거시 정적api_key항목 스크럽<config-dir>/.env에서 일치하는 알려진 시크릿 줄 스크럽
secrets apply
저장된 계획 적용:
openclaw secrets apply --from /tmp/openclaw-secrets-plan.json
openclaw secrets apply --from /tmp/openclaw-secrets-plan.json --dry-run
엄격한 대상/경로 규약 세부 정보 및 정확한 거부 규칙은 다음을 참고하세요:
단방향 안전 정책
OpenClaw는 과거 평문 시크릿 값을 포함하는 롤백 백업을 의도적으로 작성하지 않습니다.
안전 모델:
- 쓰기 모드 전에 사전 검증 성공 필요
- 커밋 전에 런타임 활성화 유효성 검사
- 적용은 원자적 파일 교체를 사용하며 실패 시 최선 노력으로 복원
레거시 인증 호환성 참고
정적 인증 정보의 경우, 런타임은 더 이상 평문 레거시 인증 저장소에 의존하지 않습니다.
- 런타임 인증 정보 소스는 확인된 인메모리 스냅샷입니다.
- 레거시 정적
api_key항목은 발견 시 스크럽됩니다. - OAuth 관련 호환성 동작은 별도로 유지됩니다.
웹 UI 참고
일부 SecretInput 유니언은 폼 모드보다 원시 편집기 모드에서 설정하기 더 쉽습니다.
관련 문서
- CLI 명령: secrets
- 계획 규약 세부 정보: 시크릿 적용 계획 규약
- 인증 정보 표면: SecretRef 인증 정보 표면
- 인증 설정: 인증
- 보안 태세: 보안
- 환경 우선순위: 환경 변수