Gateway
シークレット管理
OpenClaw は加算的な SecretRef をサポートしているため、サポート対象の認証情報を設定内に平文で保存する必要はありません。
ランタイムモデル
- Secrets は、リクエストパスで遅延的にではなく、アクティベーション中に即時解決され、メモリ内のランタイムスナップショットに格納されます。
- Gateway のコールドスタートでは、既知の非 Gateway オーナーが分離をサポートしている場合、再試行可能な SecretRef の失敗をそのオーナーに分離します。マッピング対象のオーナークラスには、モデルプロバイダーと Skills、メディア/TTS/cron プロバイダー、対象となる認証プロファイル、エージェントごとのメモリ、サンドボックス SSH、チャネルアカウント、マニフェストで宣言された Plugin ルートが含まれます。Gateway は起動し、そのオーナーを「設定済みだが利用不可」として記録し、機密情報を除去した機能低下警告を出力します。Gateway の受信認証、構造的に無効な参照または解決値、フェイルクローズのオーナー、およびランタイムオーナーがマッピングされていない参照では、引き続き起動に失敗します。
- リロードでは、マッピング対象の各オーナーを個別に検証した後、1 つのアトミックなスナップショットを公開します。正常なオーナーは更新されます。対象となる失敗したオーナーは、参照 ID、プロバイダー定義、およびシークレット以外の完全なオーナー契約が変更されていない場合に限り、最後に正常だった値を維持して stale 状態になります。変更された、または新規の失敗したオーナーは cold 状態になります。厳格な失敗ではリロードを拒否し、アクティブなスナップショットを維持します。
- ポリシー違反(たとえば、OAuth モードの認証プロファイルと SecretRef 入力の組み合わせ)は、ランタイムの切り替え前にアクティベーションを失敗させます。
- ランタイムリクエストは、アクティブなメモリ内スナップショットのみを読み取ります。モデルプロバイダーの SecretRef 認証情報は、外部送信時までプロセスローカルなセンチネルとして認証ストレージとストリームオプションを通過します。外部配信パス(Discord の返信/スレッド配信、Telegram のアクション送信)もそのスナップショットを読み取り、送信ごとに参照を再解決しません。
これにより、シークレットプロバイダーの障害がホットなリクエストパスから排除されます。
Gateway の受信保護、構造的に無効な設定または解決値、ポリシー違反、不明な所有関係では、引き続きフェイルクローズします。分離されたオーナーが優先順位の低い認証情報ソースへフォールスルーすることはありません。
外部送信時の注入(センチネル)
SecretRef によって提供されるモデルプロバイダー認証情報について、OpenClaw はモデル認証の解決中に不透明なプロセスローカルのセンチネルを生成します。そのため、認証ストレージ、ストリームオプション、SDK 設定、ログ、エラーオブジェクト、および大半のランタイムイントロスペクションからは、プロバイダー認証情報ではなく oc-sent-v1-... のような値が見えます。保護されたモデル fetch と、管理対象のローカルプロバイダーのヘルスプローブは、各リクエストがプロセスを離れる直前に、URL とヘッダーの値に含まれる既知のセンチネルを置き換えます。
不明なセンチネル形式の値は、ネットワーク処理の前にフェイルクローズします。OpenClaw は、未解決のセンチネルをプロバイダーへ転送せず、リクエストの送信を拒否します。多層防御として、解決済みのシークレット値も完全一致によるログ秘匿化の対象として登録されます。
プロバイダーアダプターは、SDK がサポートする最も遅い注入ポイントを使用します。
- カスタム fetch オプションを備えた SDK には OpenClaw の保護された fetch が渡されるため、SDK 内ではセンチネルが維持されます。
- カスタム fetch オプションがない SDK では、クライアントを構築する直前にセンチネルを展開します。Plugin が所有するプロバイダーストリームとエージェントハーネスは、これらのトランスポートが OpenClaw の保護された fetch を共有しないため、コアが所有する最終ハンドオフ時にセンチネルを展開します。
センチネルはモデル呼び出しチェーン全体での平文露出を減らしますが、プロセス分離ではありません。実際の値は同一プロセスのメモリ内に引き続き存在し、最終的なアダプター境界に現れます。SecretRef を介さずに設定された平文の環境認証情報は平文のままであり、この仕組みの対象外です。
インシデント対応または互換性のトラブルシューティング中にセンチネルの生成を無効にするには、OPENCLAW_SECRET_SENTINELS=off(0 または false も大文字と小文字を区別せず受け付けます)を設定します。このキルスイッチでは、完全一致による秘匿化登録は無効になりません。
エージェントアクセス境界
SecretRef は認証情報が設定や生成済みモデルファイルに永続化されることを防ぎますが、プロセス分離の境界ではありません。エージェントが読み取れるディスク上のパスに残された平文の認証情報は、API レベルの秘匿化を迂回し、ファイルツールまたはシェルツールで引き続き読み取れます。
エージェントからアクセス可能なファイルが対象範囲に含まれる本番環境では、次のすべてを満たす場合に限り、移行が完了したものとして扱ってください。
- サポート対象の認証情報で、平文値ではなく SecretRef を使用している。
openclaw.json、auth-profiles.json、.env、および生成されたmodels.jsonファイルから、従来の平文の残存が除去されている。- 移行後の
openclaw secrets audit --checkがクリーンである。 - 残っている未サポートまたはローテーション対象の認証情報が、OS 分離、コンテナ分離、または外部認証情報プロキシによって保護されている。
このため、監査/設定/適用ワークフローは単なる利便性のためのヘルパーではなく、セキュリティ移行のゲートです。
アクティブサーフェスのフィルタリング
SecretRef は、実質的にアクティブなサーフェスでのみ検証されます。
- 有効なサーフェス:マッピング済みで分離可能なオーナーにおける再試行可能な失敗は、cold または stale の機能低下状態になります。厳格、フェイルクローズ、Gateway に必須、またはマッピングされていない失敗は、起動/リロードを阻止します。
- 非アクティブなサーフェス:未解決の参照は起動/リロードを阻止せず、致命的でない
SECRETS_REF_IGNORED_INACTIVE_SURFACE診断を出力します。
非アクティブなサーフェスの例
- 無効化されたチャネル/アカウントエントリ。
- 有効なアカウントに継承されないトップレベルのチャネル認証情報。
- 無効化されたツール/機能サーフェス。
tools.web.search.providerで選択されていない Web 検索プロバイダー固有のキー。自動モード(プロバイダー未設定)では、いずれか 1 つが解決されるまで、優先順位に従って自動検出用のキーを参照します。選択後、選択されなかったプロバイダーのキーは非アクティブになります。- サンドボックス SSH 認証情報(
agents.defaults.sandbox.ssh.identityData、certificateData、knownHostsData、およびエージェントごとのオーバーライド)は、デフォルトエージェントまたは有効なエージェントについて、有効なサンドボックスバックエンドがsshであり、かつサンドボックスモードがoffではない場合にのみアクティブです。 gateway.remote.token/gateway.remote.passwordSecretRef は、次のいずれかを満たす場合にアクティブです。gateway.mode=remotegateway.remote.urlが設定されているgateway.tailscale.modeがserveまたはfunnelである- これらのリモートサーフェスがないローカルモードでは、トークン認証が優先される可能性があり、かつ環境/認証トークンが設定されていない場合に
gateway.remote.tokenがアクティブになります。パスワード認証が優先される可能性があり、かつ環境/認証パスワードが設定されていない場合にのみgateway.remote.passwordがアクティブになります。 OPENCLAW_GATEWAY_TOKENが設定されている場合、そのランタイムでは環境トークン入力が優先されるため、起動時の認証解決ではgateway.auth.tokenSecretRef は非アクティブです。
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、file、およびexec参照について)解決します。
検証に失敗するとエラーが表示され、再試行できます。
SecretRef の契約
すべての場所で使用するオブジェクト形式は 1 つです。
{ source: "env" | "file" | "exec", provider: "default", id: "..." }env
{ source: "env", provider: "default", id: "OPENAI_API_KEY" }SecretInput フィールドでは短縮文字列も使用できます。
"${OPENAI_API_KEY}""$OPENAI_API_KEY"検証:
providerは^[a-z][a-z0-9_-]{0,63}$に一致する必要がありますidは^[A-Z][A-Z0-9_]{0,127}$に一致する必要があります
file
{ 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
{ 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 の下にプロバイダーを定義します。
{ 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, }, "team-secrets": { source: "exec", pluginIntegration: { pluginId: "acme-secrets", integrationId: "secret-store", }, }, }, defaults: { env: "default", file: "filemain", exec: "vault", }, },}環境プロバイダー
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 が 1 つだけの場合、JSON ではないプレーンな stdout がその id の値として受け入れられます。- Windows ではフェイルクローズします。コマンドパスの ACL 検証を利用できない場合、解決は失敗します。信頼できるパスに限り、そのプロバイダーに
allowInsecurePath: trueを設定してチェックを回避できます。 - Plugin が管理する Exec プロバイダーでは、コピーした
command/argsの代わりにpluginIntegrationを使用できます。OpenClaw は起動時または再読み込み時に、インストール済み Plugin のマニフェストから現在のコマンド詳細を解決します。Plugin が無効化、削除、信頼解除された場合、または統合を宣言しなくなった場合、そのプロバイダー上のアクティブな SecretRef はフェイルクローズします。
リクエストペイロード(stdin):
{ "protocolVersion": 1, "provider": "vault", "ids": ["providers/openai/apiKey"] }レスポンスペイロード(stdout):
{ "protocolVersion": 1, "values": { "providers/openai/apiKey": "<openai-api-key>" } } // pragma: allowlist secretid ごとの省略可能なエラー:
{"protocolVersion": 1,"values": {},"errors": { "providers/openai/apiKey": { "code": "NOT_FOUND" } }}code は省略可能な機械可読診断情報です。OpenClaw は認識される
コード NOT_FOUND および AMBIGUOUS_DUPLICATE_KEY を、プロバイダーと参照 id とともに表示します。その他の
コードや message などの自由形式フィールドは、protocol-v1 との互換性のために受け入れられますが、
リゾルバーの出力に認証情報が含まれる可能性があるため表示されません。
ファイルベースの API キー
設定の env ブロックに file:... 文字列を配置しないでください。このブロックはリテラルであり上書きされないため、そこで file:... が解決されることはありません。
代わりに、サポートされている認証情報フィールドでファイル SecretRef を使用してください。
{ 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 統合の例
サービスアカウント、同梱のエージェント Skills、トラブルシューティングを扱う 1Password 専用ガイドについては、1Passwordを参照してください。
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" }, }, }, },}Bitwarden Secrets Manager (`bws`)
リゾルバーラッパーを使用して、SecretRef の id を Bitwarden Secrets Manager の項目キーにマッピングします。リポジトリには scripts/secrets/openclaw-bws-resolver.mjs が含まれています。Gateway を実行するホスト上の信頼できる絶対パスにインストールまたはコピーしてください。
要件:
- Bitwarden Secrets Manager CLI(
bws)が Gateway ホストにインストールされていること。 BWS_ACCESS_TOKENが Gateway サービスから利用できること。PATHがリゾルバーに渡されていること、またはBWS_BINにbwsバイナリの絶対パスが設定されていること。- セルフホスト型 Bitwarden インスタンスを使用する場合、環境に
BWS_SERVER_URLが設定されていること。
{ 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 を曖昧として失敗させます。設定を更新した後、リゾルバーのパスを検証してください。
openclaw secrets audit --allow-execHashiCorp 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" }, }, }, },}password-store (`pass`)
小さなリゾルバーラッパーを使用して、SecretRef の id を pass エントリに直接マッピングします。Exec プロバイダーのパスチェックを通過する絶対パス(/usr/local/bin/openclaw-pass-resolver など)に、実行可能ファイルとして保存してください。#!/usr/bin/env node シバンは、リゾルバープロセスの PATH から node を解決するため、passEnv に PATH を含めてください。pass がその PATH 上にない場合は、親環境に PASS_BIN を設定し、passEnv にも含めてください。
#!/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 エントリのパスを指すようにします。
{ 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 エントリの 1 行目に保持するか、代わりに pass show の出力全体を返すようにラッパーをカスタマイズしてください。設定を更新した後、静的監査と Exec リゾルバーのパスの両方を検証してください。
openclaw secrets audit --checkopenclaw secrets audit --allow-execsops
{ 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 キーやトークンがプレーンテキスト設定に含まれないようにします。
{ 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 もサポートします。
{ 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 の serviceAccount は、インライン JSON または SecretRef を受け付けます。このフィールドが未設定の場合、Doctor は廃止された同階層の serviceAccountRef をこの正式なフィールドへ移動します。
有効化のトリガー
シークレットの有効化は、次の場合に実行されます:
- 起動時(事前検証と最終有効化)
- 設定リロードのホット適用パス
- 設定リロードの再起動チェックパス
secrets.reloadによる手動リロード- Gateway 設定書き込み RPC の事前検証(
config.set/config.apply/config.patch)。編集を永続化する前に、送信された設定ペイロード内のアクティブ対象の SecretRef を検証します
有効化の契約:
- 成功すると、スナップショットがアトミックに置き換えられます。
- 厳格な起動失敗が発生すると、Gateway の起動は中止されます。
- コールドスタート中に、マッピング済みで分離可能な Gateway 以外の所有者について再試行可能な解決失敗が発生した場合、その所有者のみを設定済み利用不可としてスナップショットを公開することがあります。その所有者へのリクエストは
SECRET_SURFACE_UNAVAILABLEで失敗します。明示的な参照が失敗した後、モデルプロバイダーの所有者が環境変数や認証プロファイルの認証情報へフォールバックすることはありません。 - リロードと再起動チェックでは、対象となるマッピング済み所有者を分離します。参照 ID、プロバイダー定義、および完全な非シークレット所有者契約がいずれも変更されていない場合、その所有者は最新の正常値を stale 状態としてそのまま保持します。変更された参照や新たに設定された未解決の参照は、その所有者のみを cold 状態で公開します。厳格なリロード失敗の場合、以前のアクティブなスナップショットが保持されます。
config.set、config.apply、およびconfig.patchは、分離可能な所有者について構文的に有効な未解決の参照を受け付け、秘匿化されたdegradedSecretOwnersレポートを返します。Gateway の受信認証、構造的に無効な設定や解決値、ポリシー違反、および不明な所有者は、引き続きディスク変更前に拒否されます。- 別の所有者が cold または stale 状態でも、正常な同階層の所有者は通常どおり解決され、公開されます。
- 送信ヘルパーやツールの呼び出しに、呼び出し単位の明示的なチャンネルトークンを指定しても、SecretRef の有効化はトリガーされません。有効化ポイントは、起動、リロード、および明示的な
secrets.reloadのままです。
機能低下と復旧のシグナル
正常な状態の後にリロード時の有効化が失敗すると、OpenClaw はシークレットの機能低下状態に入り、1 回限りのシステムイベントとログコードを出力します:
SECRETS_RELOADER_DEGRADEDSECRETS_RELOADER_RECOVERED
動作:
- 機能低下: 正常な所有者は更新され、stale 状態の所有者は最新の正常値を維持し、cold 状態の所有者は引き続き利用できません。
- 復旧: 次回の有効化が成功した後に 1 回だけ出力されます。
- すでに機能低下状態にある間に失敗が繰り返された場合、警告はログに記録されますが、イベントは再出力されません。
- 厳格な起動失敗ではランタイムが一度もアクティブにならないため、機能低下イベントは出力されません。cold 状態の所有者を伴って起動に成功した場合は、所有者の機能低下がログに記録されますが、リローダーイベントは出力されません。
- 参照単位の起動およびリロード失敗では、影響を受ける所有者ごとに構造化された
SECRETS_DEGRADED警告が出力されます。プロバイダー単位の障害では、所有者ごとにプロバイダー障害を繰り返す代わりに、プロバイダーと影響を受ける所有者の完全な一覧を含むSECRETS_PROVIDER_DEGRADED警告が 1 つ出力されます。警告には、秘匿化された理由、所有者の状態を示すcoldまたはstale、およびopenclaw secrets reloadの再試行ヒントが含まれます。解決された値や SecretRef ID が含まれることはありません。 openclaw doctorは、cold および stale 状態の所有者について、影響を受ける設定パス、秘匿化された理由、および再試行ガイダンスを一覧表示します。
コマンドパスでの解決
コマンドパスは、Gateway スナップショット RPC を介して、サポートされる SecretRef 解決を使用できます。大きく分けて 2 つの動作があります:
厳格なコマンドパス
たとえば、openclaw memory のリモートメモリパスや、リモート共有シークレット参照が必要な場合の openclaw qr --remote です。これらはアクティブなスナップショットから読み取り、必要な SecretRef が利用できない場合は即座に失敗します。
読み取り専用コマンドパス
たとえば、openclaw status、openclaw status --all、openclaw channels status、openclaw channels resolve、openclaw security audit、および読み取り専用の Doctor/設定修復フローです。これらもアクティブなスナップショットを優先しますが、対象の SecretRef が利用できない場合は中止せず、機能低下状態で処理を継続します。
読み取り専用の動作:
- Gateway が実行中の場合、これらのコマンドはまずアクティブなスナップショットから読み取ります。
- Gateway での解決が不完全な場合、または Gateway が利用できない場合、そのコマンドの対象に限定したローカルフォールバックを試みます。
- 対象の SecretRef が引き続き利用できない場合、コマンドは機能低下した読み取り専用出力と、その参照は設定済みだがこのコマンドパスでは利用できないことを示す明示的な診断を出力して処理を継続します。
- この機能低下時の動作はそのコマンド内に限定され、ランタイムの起動、リロード、送信、または認証パスの要件を緩和するものではありません。
その他の注意事項:
- バックエンドのシークレットローテーション後のスナップショット更新は、
openclaw secrets reloadによって処理されます。 - これらのコマンドパスで使用される Gateway RPC メソッド:
secrets.resolve。
監査と設定のワークフロー
オペレーターのデフォルトフロー:
現在の状態を監査
openclaw secrets audit --checkSecretRef を設定して適用
openclaw secrets configure --apply再監査
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.jsonがopenclaw.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、追加/編集/削除)。 - 1 つのエージェントスコープについて、
openclaw.json内のサポート対象のシークレット保持フィールドとauth-profiles.jsonを選択できます。 - 対象選択画面から新しい
auth-profiles.jsonマッピングを直接作成できます。 - SecretRef の詳細(
source、provider、id)を取得します。 - 事前解決を実行し、すぐに適用することもできます。
exec に関する注意: --allow-exec が設定されていない限り、事前検証では exec SecretRef のチェックを省略します。configure --apply から直接適用し、プランに exec 参照またはプロバイダーが含まれる場合は、適用手順でも --allow-exec を設定したままにしてください。
便利なモード:
openclaw secrets configure --providers-onlyopenclaw secrets configure --skip-provider-setupopenclaw secrets configure --agent <id>
configure 適用時のデフォルト:
- 対象のプロバイダーについて、
auth-profiles.jsonから一致する静的認証情報を削除します。 auth.jsonからレガシーな静的api_keyエントリを削除します。- 有効な状態およびアクティブな設定の
.envファイルから、一致する既知のシークレット行を削除します(両方のパスが一致する場合は重複を排除します)。
secrets apply
保存済みプランを適用します:
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-execexec に関する注意: --allow-exec が設定されていない限り、ドライランでは exec チェックを省略します。書き込みモードでは、--allow-exec が設定されていない場合、exec SecretRef またはプロバイダーを含むプランを拒否します。
厳格な対象/パス契約の詳細と正確な拒否規則については、シークレット適用プランの契約を参照してください。
一方向の安全ポリシー
安全モデル:
- 書き込みモードの前に事前検証が成功する必要があります。
- コミット前にランタイムの有効化が検証されます。
- 適用処理では、アトミックなファイル置換を使用してファイルを更新し、失敗時にはベストエフォートで復元します。
レガシー認証の互換性に関する注意事項
静的認証情報について、ランタイムは平文のレガシー認証ストレージに依存しなくなりました。
- ランタイムの認証情報ソースは、解決済みのメモリ内スナップショットです。
- レガシーな静的
api_keyエントリは、検出時に削除されます。 - OAuth 関連の互換動作は別に維持されます。
Web UI に関する注意
一部の SecretInput ユニオンは、フォームモードよりも raw エディターモードの方が簡単に設定できます。
関連項目
- 認証 - 認証のセットアップ
- CLI:シークレット - CLI コマンド
- Vault SecretRefs - HashiCorp Vault プロバイダーのセットアップ
- 環境変数 - 環境変数の優先順位
- SecretRef 認証情報サーフェス - 認証情報サーフェス
- シークレット適用プランの契約 - プラン契約の詳細
- セキュリティ - セキュリティ体制