Gateway

비밀 정보 관리

OpenClaw는 지원되는 자격 증명을 구성에 평문으로 저장하지 않아도 되도록 추가 방식의 SecretRef를 지원합니다.

런타임 모델

  • 비밀은 요청 경로에서 지연 방식으로 확인되는 것이 아니라 활성화 중에 즉시 메모리 내 런타임 스냅샷으로 확인됩니다.
  • 실질적으로 활성 상태인 SecretRef를 확인할 수 없으면 시작이 즉시 실패합니다.
  • 다시 로드는 원자적 교체 방식입니다. 완전히 성공하거나 마지막으로 정상 작동한 스냅샷을 유지합니다.
  • 정책 위반(예: OAuth 모드 인증 프로필과 SecretRef 입력의 조합)이 있으면 런타임을 교체하기 전에 활성화가 실패합니다.
  • 런타임 요청은 활성화된 메모리 내 스냅샷만 읽습니다. 모델 공급자의 SecretRef 자격 증명은 외부 전송 시점까지 프로세스 로컬 센티널 형태로 인증 저장소와 스트림 옵션을 통과합니다. 아웃바운드 전달 경로(Discord 답장/스레드 전달, Telegram 작업 전송)도 이 스냅샷을 읽으며 전송할 때마다 참조를 다시 확인하지 않습니다.

이 방식은 비밀 공급자의 장애가 빈번한 요청 경로에 영향을 주지 않도록 합니다.

외부 전송 시점 주입(센티널)

SecretRef를 기반으로 하는 모델 공급자 자격 증명의 경우 OpenClaw는 모델 인증 확인 중에 불투명한 프로세스 로컬 센티널을 발급합니다. 따라서 인증 저장소, 스트림 옵션, SDK 구성, 로그, 오류 객체 및 대부분의 런타임 검사는 공급자 자격 증명 대신 oc-sent-v1-... 같은 값을 확인합니다. 보호되는 모델 가져오기와 관리형 로컬 공급자 상태 프로브는 각 요청이 프로세스를 벗어나기 직전에 URL 및 헤더 값에서 알려진 센티널을 교체합니다.

알 수 없는 센티널 형태의 값은 네트워크 활동 전에 안전하게 실패합니다. OpenClaw는 확인되지 않은 센티널을 공급자에게 전달하는 대신 요청 전송을 거부합니다. 또한 심층 방어 수단으로 확인된 비밀 값을 정확한 값 기준 로그 마스킹 대상으로 등록합니다.

공급자 어댑터는 SDK가 지원하는 가장 마지막 주입 지점을 사용합니다.

  • 사용자 지정 가져오기 옵션이 있는 SDK에는 OpenClaw의 보호된 가져오기가 전달되므로 SDK가 센티널을 유지합니다.
  • 사용자 지정 가져오기 옵션이 없는 SDK는 클라이언트를 생성하기 직전에 센티널을 해제합니다. Plugin 소유의 공급자 스트림과 에이전트 하네스는 해당 전송 계층이 OpenClaw의 보호된 가져오기를 공유하지 않으므로 코어가 소유하는 최종 전달 지점에서 센티널을 해제합니다.

센티널은 모델 호출 체인 전반에서 평문 노출을 줄이지만 프로세스 격리를 제공하지는 않습니다. 실제 값은 여전히 동일한 프로세스의 메모리에 존재하며 최종 어댑터 경계에 나타납니다. SecretRef를 통해 구성하지 않은 평문 환경 자격 증명은 평문 상태로 유지되며 이 메커니즘의 적용 대상이 아닙니다.

사고 대응 또는 호환성 문제 해결 중 센티널 발급을 비활성화하려면 OPENCLAW_SECRET_SENTINELS=off을 설정하십시오(0 또는 false도 대소문자 구분 없이 허용됩니다). 이 비상 중단 스위치는 정확한 값 기준 마스킹 등록을 비활성화하지 않습니다.

에이전트 접근 경계

SecretRef는 자격 증명이 구성 및 생성된 모델 파일에 영구 저장되지 않도록 하지만 프로세스 격리 경계는 아닙니다. 에이전트가 읽을 수 있는 디스크 경로에 평문 자격 증명이 남아 있으면 파일 또는 셸 도구를 통해 여전히 읽을 수 있으며 API 수준 마스킹을 우회합니다.

에이전트가 접근할 수 있는 파일이 범위에 포함되는 프로덕션 배포에서는 다음 조건을 모두 충족하는 경우에만 마이그레이션이 완료된 것으로 간주하십시오.

  • 지원되는 자격 증명은 평문 값 대신 SecretRef를 사용합니다.
  • 기존 평문 잔여물을 openclaw.json, auth-profiles.json, .env 및 생성된 models.json 파일에서 제거합니다.
  • 마이그레이션 후 openclaw secrets audit --check에 문제가 없어야 합니다.
  • 지원되지 않거나 순환되는 나머지 자격 증명은 OS 격리, 컨테이너 격리 또는 외부 자격 증명 프록시로 보호합니다.

이러한 이유로 감사/구성/적용 워크플로는 단순한 편의 도우미가 아니라 보안 마이그레이션 게이트입니다.

활성 표면 필터링

SecretRef는 실질적으로 활성화된 표면에서만 검증됩니다.

  • 활성화된 표면: 확인되지 않은 참조는 시작/다시 로드를 차단합니다.
  • 비활성 표면: 확인되지 않은 참조는 시작/다시 로드를 차단하지 않으며, 치명적이지 않은 SECRETS_REF_IGNORED_INACTIVE_SURFACE 진단을 내보냅니다.
비활성 표면의 예
  • 비활성화된 채널/계정 항목입니다.
  • 활성화된 계정이 상속하지 않는 최상위 채널 자격 증명입니다.
  • 비활성화된 도구/기능 표면입니다.
  • tools.web.search.provider에서 선택하지 않은 웹 검색 공급자별 키입니다. 자동 모드(공급자 미설정)에서는 하나가 확인될 때까지 우선순위에 따라 자동 감지를 위한 키를 확인하며, 선택 후에는 선택되지 않은 공급자의 키가 비활성 상태가 됩니다.
  • 샌드박스 SSH 인증 자료(agents.defaults.sandbox.ssh.identityData, certificateData, knownHostsData 및 에이전트별 재정의)는 기본 에이전트 또는 활성화된 에이전트에 대해 유효 샌드박스 백엔드가 ssh이고 샌드박스 모드가 off이 아닐 때만 활성 상태입니다.
  • 다음 중 하나라도 충족하면 gateway.remote.token / gateway.remote.password SecretRef가 활성 상태입니다.
  • gateway.mode=remote
  • gateway.remote.url이 구성되어 있습니다.
  • gateway.tailscale.modeserve 또는 funnel입니다.
  • 이러한 원격 표면이 없는 로컬 모드에서는 토큰 인증이 우선할 수 있고 환경/인증 토큰이 구성되지 않은 경우 gateway.remote.token이 활성 상태이며, 비밀번호 인증이 우선할 수 있고 환경/인증 비밀번호가 구성되지 않은 경우에만 gateway.remote.password가 활성 상태입니다.
  • OPENCLAW_GATEWAY_TOKEN이 설정된 경우 환경 토큰 입력이 해당 런타임에서 우선하므로 시작 인증 확인 시 gateway.auth.token SecretRef는 비활성 상태입니다.

Gateway 인증 표면 진단

gateway.auth.token, gateway.auth.password, gateway.remote.token 또는 gateway.remote.password에 SecretRef가 설정되면 Gateway 시작/다시 로드 시 코드 SECRETS_GATEWAY_AUTH_SURFACE 아래에 표면 상태가 기록됩니다.

  • active: SecretRef가 유효 인증 표면의 일부이므로 반드시 확인되어야 합니다.
  • inactive: 다른 인증 표면이 우선하거나 원격 인증이 비활성화되었거나 활성 상태가 아닙니다.

로그 항목에는 활성 표면 정책이 사용한 이유가 포함됩니다.

온보딩 참조 사전 점검

대화형 온보딩에서 SecretRef 저장소를 선택하면 저장하기 전에 사전 검증을 실행합니다.

  • 환경 참조: 환경 변수 이름을 검증하고 설정 중 비어 있지 않은 값이 표시되는지 확인합니다.
  • 공급자 참조(file 또는 exec): 공급자 선택을 검증하고 id을 확인한 후 확인된 값의 유형을 검사합니다.
  • 빠른 시작 흐름: gateway.auth.token이 이미 SecretRef인 경우 온보딩은 동일한 즉시 실패 게이트를 사용하여 프로브/대시보드 부트스트랩 전에 해당 참조(env, fileexec 참조)를 확인합니다.

검증에 실패하면 오류를 표시하고 다시 시도할 수 있습니다.

SecretRef 계약

모든 곳에서 하나의 객체 형태를 사용합니다.

json5
{ source: "env" | "file" | "exec", provider: "default", id: "..." }

env

json5
{ source: "env", provider: "default", id: "OPENAI_API_KEY" }

SecretInput 필드에서는 단축 문자열도 허용됩니다.

json5
"${OPENAI_API_KEY}""$OPENAI_API_KEY"

검증:

  • provider^[a-z][a-z0-9_-]{0,63}$과 일치해야 합니다.
  • id^[A-Z][A-Z0-9_]{0,127}$와 일치해야 합니다.

file

json5
{ source: "file", provider: "filemain", id: "/providers/openai/apiKey" }

검증:

  • provider^[a-z][a-z0-9_-]{0,63}$와 일치해야 합니다.
  • id는 절대 JSON 포인터(/...)이거나 singleValue 공급자의 경우 리터럴 value이어야 합니다.
  • 세그먼트의 RFC 6901 이스케이프: ~~0이 되고, /~1가 됩니다.

exec

json5
{ source: "exec", provider: "vault", id: "providers/openai/apiKey#value" }

검증:

  • provider^[a-z][a-z0-9_-]{0,63}$와 일치해야 합니다.
  • id^[A-Za-z0-9][A-Za-z0-9._:/#-]{0,255}$과 일치해야 합니다(secret#json_key 같은 선택자를 지원합니다).
  • id에는 슬래시로 구분된 경로 세그먼트로 . 또는 ..이 포함되어서는 안 됩니다(예: a/../b은 거부됩니다).

공급자 구성

secrets.providers 아래에 공급자를 정의합니다.

json5
{  secrets: {    providers: {      default: { source: "env" },      filemain: {        source: "file",        path: "~/.openclaw/secrets.json",        mode: "json", // or "singleValue"      },      vault: {        source: "exec",        command: "/usr/local/bin/openclaw-vault-resolver",        args: ["--profile", "prod"],        passEnv: ["PATH", "VAULT_ADDR"],        jsonOnly: true,      },      "team-secrets": {        source: "exec",        pluginIntegration: {          pluginId: "acme-secrets",          integrationId: "secret-store",        },      },    },    defaults: {      env: "default",      file: "filemain",      exec: "vault",    },    resolution: {      maxProviderConcurrency: 4,      maxRefsPerProvider: 512,      maxBatchBytes: 262144,    },  },}
환경 공급자
  • allowlist을 통한 정확한 이름 기준 허용 목록은 선택 사항입니다.
  • 환경 값이 없거나 비어 있으면 확인에 실패합니다.
파일 공급자
  • path에 있는 로컬 파일을 읽습니다.
  • mode: "json"(기본값)는 JSON 객체 페이로드를 요구하며 id을 JSON 포인터로 확인합니다.
  • mode: "singleValue"은 참조 ID "value"을 요구하며 원시 파일 내용(후행 줄 바꿈 제거)을 반환합니다.
  • 경로는 소유권/권한 검사를 통과해야 하며, timeoutMs(기본값 5000) 및 maxBytes(기본값 1 MiB)이 읽기 범위를 제한합니다.
  • Windows 안전 실패: 해당 경로에서 ACL 검증을 사용할 수 없으면 확인에 실패합니다. 신뢰할 수 있는 경로에서만 검사를 우회하도록 해당 공급자에 allowInsecurePath: true을 설정하십시오.
Exec 제공자
  • 구성된 절대 바이너리 경로를 셸 없이 직접 실행합니다.
  • 기본적으로 command은(는) 심볼릭 링크가 아닌 일반 파일이어야 합니다. 심볼릭 링크 명령 경로(예: Homebrew shim)를 허용하려면 allowSymlinkCommand: true을(를) 설정하고, 패키지 관리자 경로만 허용되도록 trustedDirs(예: ["/opt/homebrew"])와 함께 사용하십시오.
  • timeoutMs(기본값 5000), noOutputTimeoutMs(기본값은 timeoutMs과 동일), maxOutputBytes(기본값 1 MiB), env/passEnv 허용 목록 및 trustedDirs을(를) 지원합니다.
  • jsonOnly의 기본값은 true입니다. jsonOnly: false이(가) 설정되고 단일 id가 요청된 경우, JSON이 아닌 일반 stdout을 해당 id의 값으로 허용합니다.
  • Windows에서는 안전하게 실패합니다. 명령 경로의 ACL을 확인할 수 없으면 경로 확인이 실패합니다. 신뢰할 수 있는 경로에만 검사를 우회하도록 해당 제공자에 allowInsecurePath: true을(를) 설정하십시오.
  • Plugin에서 관리하는 Exec 제공자는 복사한 command/args 대신 pluginIntegration을(를) 사용할 수 있습니다. OpenClaw는 시작/다시 로드 중 설치된 Plugin 매니페스트에서 현재 명령 세부 정보를 확인합니다. Plugin이 비활성화 또는 제거되었거나 신뢰할 수 없거나 더 이상 통합을 선언하지 않으면 해당 제공자의 활성 SecretRef는 안전하게 실패합니다.

요청 페이로드(stdin):

json
{ "protocolVersion": 1, "provider": "vault", "ids": ["providers/openai/apiKey"] }

응답 페이로드(stdout):

jsonc
{ "protocolVersion": 1, "values": { "providers/openai/apiKey": "<openai-api-key>" } } // pragma: 허용 목록 시크릿

선택적 id별 오류:

json
{"protocolVersion": 1,"values": {},"errors": { "providers/openai/apiKey": { "code": "NOT_FOUND" } }}

code은(는) 선택적인 머신 판독 가능 진단 정보입니다. OpenClaw는 인식된 코드 NOT_FOUNDAMBIGUOUS_DUPLICATE_KEY을(를) 제공자와 참조 id와 함께 표시합니다. message 같은 기타 코드와 자유 형식 필드는 프로토콜 v1 호환성을 위해 허용되지만, 리졸버 출력에 자격 증명 자료가 포함될 수 있으므로 표시하지 않습니다.

파일 기반 API 키

구성의 env 블록에 file:... 문자열을 넣지 마십시오. 해당 블록은 리터럴이며 재정의되지 않으므로 그곳에서는 file:...이(가) 확인되지 않습니다.

대신 지원되는 자격 증명 필드에서 파일 SecretRef를 사용하십시오.

json5
{  secrets: {    providers: {      xai_key_file: {        source: "file",        path: "~/.openclaw/secrets/xai-api-key.txt",        mode: "singleValue",      },    },  },  models: {    providers: {      xai: {        apiKey: { source: "file", provider: "xai_key_file", id: "value" },      },    },  },}

mode: "singleValue"의 경우 SecretRef id은(는) "value"입니다. mode: "json"의 경우 "/providers/xai/apiKey" 같은 절대 JSON 포인터를 사용하십시오.

SecretRef를 허용하는 필드는 SecretRef 자격 증명 표면을 참조하십시오.

Exec 통합 예시

서비스 계정, 번들 에이전트 Skill 및 문제 해결을 다루는 전용 1Password 가이드는 1Password를 참조하십시오.

1Password CLI
json5
{  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" },      },    },  },}
Bitwarden Secrets Manager (`bws`)

리졸버 래퍼를 사용하여 SecretRef id를 Bitwarden Secrets Manager 항목 키에 매핑하십시오. 저장소에는 scripts/secrets/openclaw-bws-resolver.mjs이(가) 포함되어 있습니다. Gateway를 실행하는 호스트의 신뢰할 수 있는 절대 경로에 이를 설치하거나 복사하십시오.

요구 사항:

  • Gateway 호스트에 Bitwarden Secrets Manager CLI(bws)가 설치되어 있어야 합니다.
  • BWS_ACCESS_TOKEN을(를) Gateway 서비스에서 사용할 수 있어야 합니다.
  • PATH을(를) 리졸버에 전달하거나 BWS_BIN을(를) bws 바이너리의 절대 경로로 설정해야 합니다.
  • 자체 호스팅 Bitwarden 인스턴스를 사용하는 경우 환경에 BWS_SERVER_URL을(를) 설정해야 합니다.
json5
{  secrets: {    providers: {      bws: {        source: "exec",        command: "/usr/local/bin/openclaw-bws-resolver.mjs",        passEnv: ["BWS_ACCESS_TOKEN", "BWS_SERVER_URL", "PATH", "BWS_BIN"],        jsonOnly: true,      },    },  },  models: {    providers: {      openai: {        baseUrl: "https://api.openai.com/v1",        models: [{ id: "gpt-5", name: "gpt-5" }],        apiKey: {          source: "exec",          provider: "bws",          id: "openclaw/providers/openai/apiKey",        },      },    },  },}

리졸버는 요청된 id를 일괄 처리하고 bws secret list을(를) 실행한 다음 일치하는 시크릿의 key 필드 값을 반환합니다. openclaw/providers/openai/apiKey처럼 Exec SecretRef id 계약을 충족하는 키를 사용하십시오. 밑줄이 포함된 환경 변수 형식의 키는 리졸버가 실행되기 전에 거부됩니다. 표시되는 Bitwarden 시크릿이 둘 이상 동일한 요청 키를 공유하면 리졸버는 값을 추측하지 않고 해당 id를 모호한 것으로 처리하여 실패합니다. 구성을 업데이트한 후 리졸버 경로를 확인하십시오.

bash
openclaw secrets audit --allow-exec
HashiCorp Vault CLI
json5
{  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" },      },    },  },}
password-store (`pass`)

작은 리졸버 래퍼를 사용하여 SecretRef id를 pass 항목에 직접 매핑하십시오. 이를 Exec 제공자 경로 검사를 통과하는 절대 경로(예: /usr/local/bin/openclaw-pass-resolver)에 실행 파일로 저장하십시오. #!/usr/bin/env node shebang은 리졸버 프로세스의 PATH에서 node을(를) 확인하므로 passEnvPATH을(를) 포함하십시오. 해당 PATHpass이(가) 없으면 상위 환경에서 PASS_BIN을(를) 설정하고 passEnv에도 포함하십시오.

js
#!/usr/bin/env nodeconst { spawnSync } = require("node:child_process"); let stdin = "";process.stdin.setEncoding("utf8");process.stdin.on("data", (chunk) => {  stdin += chunk;});process.stdin.on("error", (err) => {  process.stderr.write(`${err.message}\n`);  process.exit(1);});process.stdin.on("end", () => {  let request;  try {    request = JSON.parse(stdin || "{}");  } catch (err) {    process.stderr.write(`요청을 구문 분석하지 못했습니다: ${err.message}\n`);    process.exit(1);  }   const passBin = process.env.PASS_BIN || "pass";  const values = {};  const errors = {};   for (const id of request.ids ?? []) {    const result = spawnSync(passBin, ["show", id], { encoding: "utf8" });    if (result.status === 0) {      values[id] = result.stdout.split(/\r?\n/, 1)[0] ?? "";    } else {      errors[id] = { message: (result.stderr || `pass가 상태 ${result.status}(으)로 종료되었습니다`).trim() };    }  }   process.stdout.write(JSON.stringify({ protocolVersion: 1, values, errors }));});

그런 다음 Exec 제공자를 구성하고 apiKey이(가) pass 항목 경로를 가리키도록 설정하십시오.

json5
{  secrets: {    providers: {      pass_store: {        source: "exec",        command: "/usr/local/bin/openclaw-pass-resolver",        passEnv: ["PATH", "HOME", "GNUPGHOME", "GPG_TTY", "PASSWORD_STORE_DIR", "PASS_BIN"],        jsonOnly: true,      },    },  },  models: {    providers: {      openai: {        baseUrl: "https://api.openai.com/v1",        models: [{ id: "gpt-5", name: "gpt-5" }],        apiKey: {          source: "exec",          provider: "pass_store",          id: "openclaw/providers/openai/apiKey",        },      },    },  },}

시크릿을 pass 항목의 첫 번째 줄에 유지하거나, 대신 전체 pass show 출력을 반환하도록 래퍼를 사용자 지정하십시오. 구성을 업데이트한 후 정적 감사와 Exec 리졸버 경로를 모두 확인하십시오.

bash
openclaw secrets audit --checkopenclaw secrets audit --allow-exec
sops
json5
{  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" },      },    },  },}

MCP 서버 환경 변수

plugins.entries.acpx.config.mcpServers을(를) 통해 구성된 MCP 서버 환경 변수는 SecretInput을 허용하므로 API 키와 토큰을 일반 텍스트 구성에 저장하지 않아도 됩니다.

json5
{  plugins: {    entries: {      acpx: {        enabled: true,        config: {          mcpServers: {            github: {              command: "npx",              args: ["-y", "@modelcontextprotocol/server-github"],              env: {                GITHUB_PERSONAL_ACCESS_TOKEN: {                  source: "env",                  provider: "default",                  id: "MCP_GITHUB_PAT",                },              },            },          },        },      },    },  },}

일반 텍스트 문자열 값도 계속 작동합니다. ${MCP_SERVER_API_KEY} 같은 환경 템플릿 참조와 SecretRef 객체는 MCP 서버 프로세스가 생성되기 전 Gateway 활성화 중에 확인됩니다. 다른 SecretRef 표면과 마찬가지로 확인되지 않은 참조는 acpx Plugin이 실제로 활성 상태일 때만 활성화를 차단합니다.

샌드박스 SSH 인증 자료

핵심 ssh 샌드박스 백엔드도 SSH 인증 자료에 SecretRef를 지원합니다.

json5
{  agents: {    defaults: {      sandbox: {        mode: "all",        backend: "ssh",        ssh: {          target: "user@gateway-host:22",          identityData: { source: "env", provider: "default", id: "SSH_IDENTITY" },          certificateData: { source: "env", provider: "default", id: "SSH_CERTIFICATE" },          knownHostsData: { source: "env", provider: "default", id: "SSH_KNOWN_HOSTS" },        },      },    },  },}

런타임 동작:

  • OpenClaw는 각 SSH 호출 시 지연 방식으로 처리하지 않고 샌드박스 활성화 중에 이러한 참조를 확인합니다.
  • 확인된 값은 제한적인 파일 권한(0o600)으로 임시 디렉터리에 기록되며 생성된 SSH 구성에서 사용됩니다.
  • 유효한 샌드박스 백엔드가 ssh이 아니거나 샌드박스 모드가 off인 경우, 이러한 참조는 비활성 상태를 유지하며 시작을 차단하지 않습니다.

지원되는 자격 증명 범위

공식적으로 지원되거나 지원되지 않는 자격 증명은 SecretRef 자격 증명 범위에 나열되어 있습니다.

필수 동작 및 우선순위

  • 참조가 없는 필드: 변경되지 않습니다.
  • 참조가 있는 필드: 활성화 중 활성 범위에서 필수입니다.
  • 일반 텍스트와 참조가 모두 있는 경우, 지원되는 우선순위 경로에서는 참조가 우선합니다.
  • 수정 마커 __OPENCLAW_REDACTED__은 내부 구성 수정/복원용으로 예약되어 있으며, 제출된 리터럴 구성 데이터로 사용하면 거부됩니다.

경고 및 감사 신호:

  • SECRETS_REF_OVERRIDES_PLAINTEXT(런타임 경고)
  • REF_SHADOWED(auth-profiles.json 자격 증명이 openclaw.json 참조보다 우선할 때의 감사 결과)

Google Chat 호환성: serviceAccountRef은 일반 텍스트 serviceAccount보다 우선하며, 동일 계층의 참조가 설정되면 일반 텍스트 값은 무시됩니다.

활성화 트리거

Secret 활성화는 다음 경우에 실행됩니다.

  • 시작(사전 점검 및 최종 활성화)
  • 구성 다시 로드의 핫 적용 경로
  • 구성 다시 로드의 재시작 확인 경로
  • secrets.reload을 통한 수동 다시 로드
  • Gateway 구성 쓰기 RPC 사전 점검(config.set / config.apply / config.patch)으로, 편집 내용을 유지하기 전에 제출된 구성 페이로드 내 활성 범위 SecretRef를 확인할 수 있는지 검사합니다.

활성화 계약:

  • 성공하면 스냅샷을 원자적으로 교체합니다.
  • 시작 실패 시 Gateway 시작이 중단됩니다.
  • 런타임 다시 로드 실패 시 마지막으로 정상 작동한 스냅샷을 유지합니다.
  • 쓰기 RPC 사전 점검이 실패하면 제출된 구성을 거부하며, 디스크 구성과 활성 런타임 스냅샷은 모두 변경되지 않습니다.
  • 아웃바운드 헬퍼/도구 호출에 호출별 채널 토큰을 명시적으로 제공해도 SecretRef 활성화가 트리거되지 않습니다. 활성화 지점은 시작, 다시 로드 및 명시적 secrets.reload으로 유지됩니다.

성능 저하 및 복구 신호

정상 상태 이후 다시 로드 시 활성화가 실패하면 OpenClaw는 Secret 성능 저하 상태로 전환되며, 일회성 시스템 이벤트와 로그 코드를 발생시킵니다.

  • SECRETS_RELOADER_DEGRADED
  • SECRETS_RELOADER_RECOVERED

동작:

  • 성능 저하: 런타임은 마지막으로 정상 작동한 스냅샷을 유지합니다.
  • 복구: 다음 활성화 성공 후 한 번 발생합니다.
  • 이미 성능 저하 상태일 때 실패가 반복되면 경고를 기록하지만 이벤트를 다시 발생시키지는 않습니다.
  • 시작 시 빠른 실패는 런타임이 활성 상태가 된 적이 없으므로 성능 저하 이벤트를 발생시키지 않습니다.

명령 경로 확인

명령 경로는 Gateway 스냅샷 RPC를 통해 지원되는 SecretRef 확인을 사용하도록 선택할 수 있습니다. 크게 두 가지 동작이 적용됩니다.

엄격한 명령 경로

예를 들어 openclaw memory 원격 메모리 경로와 원격 공유 Secret 참조가 필요할 때의 openclaw qr --remote입니다. 활성 스냅샷에서 읽으며, 필수 SecretRef를 사용할 수 없으면 빠르게 실패합니다.

읽기 전용 명령 경로

예를 들어 openclaw status, openclaw status --all, openclaw channels status, openclaw channels resolve, openclaw security audit 및 읽기 전용 doctor/구성 복구 흐름입니다. 이 경로도 활성 스냅샷을 우선하지만, 대상 SecretRef를 사용할 수 없을 때 중단하는 대신 성능 저하 상태로 동작합니다.

읽기 전용 동작:

  • Gateway가 실행 중이면 이러한 명령은 먼저 활성 스냅샷에서 읽습니다.
  • Gateway 확인이 불완전하거나 Gateway를 사용할 수 없으면 해당 명령 범위에 대한 대상 지정 로컬 폴백을 시도합니다.
  • 대상 SecretRef를 여전히 사용할 수 없으면 참조가 구성되어 있지만 이 명령 경로에서는 사용할 수 없다는 명시적 진단과 함께 성능이 저하된 읽기 전용 출력을 계속 제공합니다.
  • 이 성능 저하 동작은 해당 명령에만 적용되며 런타임 시작, 다시 로드 또는 전송/인증 경로를 완화하지 않습니다.

기타 참고 사항:

  • 백엔드 Secret 순환 후 스냅샷 갱신은 openclaw secrets reload에서 처리합니다.
  • 이러한 명령 경로에서 사용하는 Gateway RPC 메서드: secrets.resolve.

감사 및 구성 워크플로

기본 운영자 흐름:

  • 현재 상태 감사

    bash
    openclaw secrets audit --check
  • SecretRef 구성 및 적용

    bash
    openclaw secrets configure --apply
  • 재감사

    bash
    openclaw secrets audit --check
  • 재감사 결과가 깨끗해질 때까지 마이그레이션이 완료된 것으로 간주하지 마십시오. 감사에서 저장된 일반 텍스트 값을 계속 보고하는 경우, 런타임 API가 수정된 값을 반환하더라도 에이전트 접근 위험은 남아 있습니다.

    configure 중 적용하지 않고 계획을 저장한 경우, 재감사 전에 openclaw secrets apply --from <plan-path>을 사용하여 저장된 계획을 적용하십시오.

    secrets audit

    결과에는 다음이 포함됩니다.

    • 저장된 일반 텍스트 값(openclaw.json, auth-profiles.json, .env 및 생성된 agents/*/agent/models.json).
    • 생성된 models.json 항목에 남아 있는 일반 텍스트 민감 공급자 헤더.
    • 확인되지 않은 참조.
    • 우선순위 가림(auth-profiles.jsonopenclaw.json 참조보다 우선함).
    • 레거시 잔여 항목(auth.json, OAuth 알림).

    Exec 참고: 기본적으로 감사는 명령의 부작용을 방지하기 위해 exec SecretRef 확인 가능성 검사를 건너뜁니다. 감사 중 exec 공급자를 실행하려면 openclaw secrets audit --allow-exec을 사용하십시오.

    헤더 잔여 항목 참고: 민감한 공급자 헤더 감지는 이름 휴리스틱을 기반으로 합니다(일반적인 인증/자격 증명 헤더 이름과 authorization, x-api-key, token, secret, password, credential 등의 문자열 조각).

    secrets configure

    다음을 수행하는 대화형 헬퍼입니다.

    • 먼저 secrets.providers을 구성합니다(env/file/exec, 추가/편집/제거).
    • 하나의 에이전트 범위에서 openclaw.jsonauth-profiles.json의 지원되는 Secret 포함 필드를 선택할 수 있습니다.
    • 대상 선택기에서 직접 새 auth-profiles.json 매핑을 생성할 수 있습니다.
    • SecretRef 세부 정보(source, provider, id)를 수집합니다.
    • 사전 점검 확인을 실행하고 즉시 적용할 수 있습니다.

    Exec 참고: --allow-exec이 설정되지 않으면 사전 점검에서 exec SecretRef 검사를 건너뜁니다. configure --apply에서 직접 적용하며 계획에 exec 참조/공급자가 포함된 경우, 적용 단계에서도 --allow-exec을 설정된 상태로 유지하십시오.

    유용한 모드:

    • openclaw secrets configure --providers-only
    • openclaw secrets configure --skip-provider-setup
    • openclaw secrets configure --agent <id>

    configure 적용 기본값:

    • 대상 공급자의 auth-profiles.json에서 일치하는 정적 자격 증명을 제거합니다.
    • auth.json에서 레거시 정적 api_key 항목을 제거합니다.
    • <config-dir>/.env에서 일치하는 알려진 Secret 행을 제거합니다.
    secrets apply

    저장된 계획을 적용합니다.

    bash
    openclaw secrets apply --from /tmp/openclaw-secrets-plan.jsonopenclaw secrets apply --from /tmp/openclaw-secrets-plan.json --allow-execopenclaw secrets apply --from /tmp/openclaw-secrets-plan.json --dry-runopenclaw secrets apply --from /tmp/openclaw-secrets-plan.json --dry-run --allow-exec

    Exec 참고: --allow-exec이 설정되지 않으면 시험 실행에서 exec 검사를 건너뛰며, --allow-exec이 설정되지 않으면 쓰기 모드에서 exec SecretRef/공급자가 포함된 계획을 거부합니다.

    엄격한 대상/경로 계약 세부 정보와 정확한 거부 규칙은 Secret 적용 계획 계약을 참조하십시오.

    단방향 안전 정책

    안전 모델:

    • 쓰기 모드 전에 사전 점검이 성공해야 합니다.
    • 커밋 전에 런타임 활성화의 유효성을 검사합니다.
    • 적용 시 원자적 파일 교체를 사용하여 파일을 업데이트하며 실패 시 최선의 방식으로 복원합니다.

    레거시 인증 호환성 참고 사항

    정적 자격 증명의 경우 런타임은 더 이상 일반 텍스트 레거시 인증 저장소에 의존하지 않습니다.

    • 런타임 자격 증명 소스는 확인된 인메모리 스냅샷입니다.
    • 레거시 정적 api_key 항목은 발견 시 제거됩니다.
    • OAuth 관련 호환성 동작은 별도로 유지됩니다.

    웹 UI 참고 사항

    일부 SecretInput 유니온은 양식 모드보다 원시 편집기 모드에서 더 쉽게 구성할 수 있습니다.

    관련 항목

    Was this useful?
    On this page

    On this page