Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

セキュリティポリシー

ナビゲーション: ガイド | ドキュメントルート

V0.2.1 の厳格モードの署名および暗号化ポリシーに関する運用者向けガイドです。鍵の生成、ポリシーの有効化、デプロイのシナリオ、および信頼モデルを扱います。

想定読者

バイトコードの実行を暗号的に制約しなければならない環境に keleusma-cli を配備する運用者向けです。例としては、ロックダウンされた本番サーバ、エアギャップされたワークステーション、規制対象のワークフロー実行、組み込みフリートの配備などが挙げられます。ここで説明する仕組みは任意かつ追加的なものであり、V0.2.0 の寛容な振る舞いが引き続き既定です。

4 つのポリシー状態

CLI は 2 つの独立した厳格モードを備えています。いずれの組み合わせでも有効にできます。

署名ゲート暗号化ゲートポリシーの概要
無効無効V0.2.0 の寛容な既定です。ソースファイル、未署名のバイトコード、--verifying-key を伴う署名付きバイトコード、--decryption-key を伴う暗号化されたバイトコードを受け入れます。
有効無効ソースファイルと未署名のバイトコードは拒否されます。署名付きバイトコードは、署名が登録済みの署名者に対して検証された場合にのみ許容されます。--verifying-key コマンドライン引数は拒否されます。
無効有効暗号化されていないバイトコード(署名の有無を問わず)は拒否されます。暗号化されたバイトコードは、登録済みの復号鍵が成果物の受信者識別子と一致した場合にのみ許容されます。--decryption-key コマンドライン引数は拒否されます。
有効有効厳格署名かつ厳格暗号化です。バイトコードは、登録済みの署名者によって署名され、かつ登録済みの受信者に対して暗号化されていなければなりません。

厳格署名の有効化

厳格署名を有効化するつまみは 3 つあり、優先順位順に示します。

  1. KELEUSMA_TRUSTED_KEYS_DIR 環境変数は、*.pub ファイルのディレクトリを指します。各ファイルは 32 バイトの Ed25519 検証鍵を保持します。
  2. プラットフォーム慣習のディレクトリ、Unix 系システムでは /etc/keleusma/trusted_keys、Windows では %PROGRAMDATA%\keleusma\trusted_keys です。環境変数が設定されていない場合に用いられます。
  3. KELEUSMA_REQUIRE_SIGNED=1 環境変数は、信頼ストアが空であっても厳格モードを強制します。あらゆるものに対してフェイルクローズとなります。

厳格署名は、信頼ストアが空でない場合、または強制厳格変数が設定されている場合に有効になります。

検出はフェイルクローズです。不正な鍵ファイル(サイズが誤っている、Ed25519 エンコーディングが無効)は、CLI が明確な診断とともに起動を拒否する原因となります。これにより、信頼リストが部分的になるエッジケースを防ぎます。

厳格暗号化の有効化

暗号化ゲートは並行する仕組みを用います。優先順位順に 3 つのつまみがあります。

  1. KELEUSMA_DECRYPTION_KEYS_DIR 環境変数は、*.seed ファイルのディレクトリを指します。各ファイルは 32 バイトの X25519 秘密鍵を保持します。
  2. プラットフォーム慣習のディレクトリ、Unix 系システムでは /etc/keleusma/decryption_keys、Windows では %PROGRAMDATA%\keleusma\decryption_keys です。
  3. KELEUSMA_REQUIRE_ENCRYPTED=1 環境変数は、復号鍵ストアが空であっても厳格暗号化モードを強制します。

厳格暗号化には、ランタイム上で encryption Cargo フィーチャが有効になっている必要があります。keleusma-cli バイナリはこのフィーチャを有効にして出荷されます。独自のランタイムをビルドする埋め込み側は、明示的にオプトインします。

鍵の生成

keleusma keygen コマンドは、署名 (Ed25519) または暗号化 (X25519) のいずれかに用いる 32 バイトのシードファイルと 32 バイトの公開鍵ファイルを生成します。この 2 種類の鍵は互換性がありません。

# Ed25519 署名鍵ペア(デフォルト)。
keleusma keygen --seed sign.seed --public sign.pub

# 同等の明示的な形式。
keleusma keygen --kind signing --seed sign.seed --public sign.pub

# X25519 暗号化鍵ペア。
keleusma keygen --kind encryption --seed enc.seed --public enc.pub

シードファイルは秘密の片割れであり、機密として扱わなければなりません。Unix システムでは、keygen は多層防御策としてシードファイルのパーミッションをモード 0600(所有者の読み書きのみ)に厳格化します。公開鍵ファイルは、検証者(署名の場合)や、このホスト向けの成果物を生成するコンパイラ(暗号化の場合)へ配布しても安全です。

keygen は既存のシードファイルや公開鍵ファイルの上書きを拒否します。ローテーションを行うには、まず古いファイルを明示的に削除する必要があります。

成果物のコンパイル

keleusma compile コマンドは、未署名、署名付き、または署名付きかつ暗号化された成果物を生成します。

# 未署名。厳格な署名モードでは実行されません。
keleusma compile script.kel -o script.kel.bin

# 署名付き。ソースはエントリ関数を `signed` 修飾子付きで宣言する必要があります。
keleusma compile script.kel --signing-key sign.seed -o script.kel.bin

# 特定の受信者向けに署名かつ暗号化されたもの。
keleusma compile script.kel \
    --signing-key sign.seed \
    --encryption-key recipient.pub \
    -o script.kel.bin

暗号化には署名が必要です。署名が暗号化された本体を対象とするため、ワイヤーフォーマットは両者を結び付けています。攻撃者は署名を無効化することなく暗号化レイヤーを剥がして平文に差し替えることはできません。

成果物の実行

keleusma run コマンドはコンパイル済みの成果物を実行します。CLI はフレーミングヘッダーからバイトコードの形状を自動検出します。

許容モード(鍵が登録されておらず、強制厳格フラグもない場合)では次のようになります。

# 未署名のバイトコードは無条件に実行されます。
keleusma run script.kel.bin

# 署名付きのバイトコードは、署名が --verifying-key に対して検証された場合に実行されます。
keleusma run script.kel.bin --verifying-key sign.pub

# 暗号化されたバイトコードは、署名が検証され、かつ復号鍵が一致した場合に実行されます。
keleusma run script.kel.bin --verifying-key sign.pub --decryption-key host.seed

厳格モードでは、コマンドラインの鍵フラグは拒否されます。CLI はシステム管理下のトラストストアに登録された鍵のみを使用します。

デプロイのシナリオ

エアギャップされたオフィス配布

本社が、エアギャップされたワークステーションを使用する遠隔地の従業員へ運用スクリプトを配布します。

初期プロビジョニング(信頼できる担当者による、現地作業):

  1. 本社で従業員ごとの X25519 鍵ペアを生成します。各従業員の秘密鍵を、信頼できる担当者を通じて当該従業員のワークステーションへ届けます。
  2. 本社の Ed25519 署名鍵ペアを生成します。シードは本社に保管します。公開鍵を各ワークステーションへ配布します。
  3. 各ワークステーションに keleusma-cli バイナリをインストールします。
  4. 本社の検証鍵を各ワークステーションの /etc/keleusma/trusted_keys/ ディレクトリに登録します。
  5. そのワークステーション固有の X25519 秘密鍵を /etc/keleusma/decryption_keys/ に登録します。

これで各ワークステーションにおいて両方の厳格モードが有効になります。

スクリプトごとの配布(本社):

keleusma compile script.kel \
    --signing-key head_office.seed \
    --encryption-key workstation_42.pub \
    -o script_for_42.kel.bin

この成果物はワークステーション 42 専用に暗号化されています。通信経路上で傍受されたとしても、他のいかなるワークステーションでも復号されません。

配送:宅配便で配送されるストレージメディア(USB メモリ、リムーバブルドライブ)。shebang を備えた成果物は、オペレーティングシステムのシェルを通じて直接実行可能です。

実行(ワークステーション 42):

./script_for_42.kel.bin

CLI は両方の厳格モードを自動的に強制します。スクリプトは、本社によって署名され、かつワークステーション 42 の登録済み鍵で復号可能な場合に実行されます。それ以外の場合は拒否されます。

傍受された成果物:配送経路上で盗まれた成果物は不透明な暗号文です。攻撃者はその内容を読み取ることができません。

侵害されたワークステーション:侵害されたワークステーションは自身の秘密鍵のみを露呈します。他のワークステーション向けの成果物は機密のまま保たれます。

本番サーバーフリート

本番環境ではリリースチームが署名したビルドのみを実行します。

# 各本番サーバーで、ビルドサーバーの検証鍵をインストールします。
sudo cp /tmp/release_key.pub /etc/keleusma/trusted_keys/release.pub

# これで CLI は厳格な署名を強制します。
keleusma run /opt/keleusma/scripts/job.kel.bin

本番サーバー上のローカルオペレーターは、認可されていないスクリプトを実行できません。厳格な署名ポリシーがそれらを拒否します。--verifying-key コマンドライン引数は拒否され、ローカルでの緩和を防ぎます。

規制されたワークフローの実行

医療情報学のパイプラインは、検証済みのワークフロースクリプトのみが患者データ上で実行されたことを監査人に証明しなければなりません。

  1. 各ワークフローバージョンは承認チームによって署名されます。
  2. 本番処理ノードは、そのトラストストアに承認チームの検証鍵のみを保持します。
  3. 監査ログ(ホスト側、スクリプトの外部)は、どの署名付きバイトコードのハッシュがどの入力を実行したかを記録します。

厳格な署名ゲートにより、不正なスクリプトが承認プロセスを迂回できないことが保証されます。

キオスクまたは隔離デプロイ

特定の事前インストール済みスクリプトのみを実行し、それ以外はすべて拒否すべきキオスクの例です。

export KELEUSMA_REQUIRE_SIGNED=1
export KELEUSMA_REQUIRE_ENCRYPTED=1
# 鍵が登録されていません。実行可能なバイトコードはありません。キオスクはロックされています。

登録済みの鍵ストアと組み合わせることで、厳格モードの姿勢を維持しながら、特定の署名付きかつ暗号化されたバイトコードを許可できます。

デーモンのデプロイとティック間隔のケイデンス

CLI の生産的発散ループランナーは、長期稼働する署名付きかつ暗号化されたデーモンワークロードの主要な経路です。--tick-interval <duration> フラグはループのレートを制限します。フラグのリファレンスと、スクリプト側のネイティブ関数 shell::set_tick_interval および shell::tick_interval については CLI README を参照してください。

フェイルファストな構成

セッターのネイティブ関数は、与えられた文字列が有効な人間可読の期間でない場合、実行時に失敗することがあります。不正な引数が最初のイテレーションで表面化し、運用状態が構築される前にデーモンが終了するよう、ループ本体の先頭で shell::set_tick_interval を呼び出してください。推奨されるパターンは次のとおりです。

loop main(tick: Word) -> Word {
    let _ = shell::set_tick_interval("1s");
    // Operational logic from here.
    ...
}

実行時の判断に基づいてループの途中でセッターを呼び出すデーモンは、構成エラーを長期間にわたって隠蔽するおそれがあります。オペレーターは、この間隔を静的な構成つまみとして扱うべきです。

機能としてのメモリ常駐

Keleusma のループデーモンを意図的にメモリ上に常駐させることは、割り当て失敗が予期される一連の運用シナリオに対処します。ホストが、新しいプロセスの起動が失敗するほどのメモリ圧迫下にある場合でも、すでに常駐しているデーモンはマッピング済みのページを保持し、実行を継続します。これは CLI のループランナーについて文書化されたユースケースです。

パターン:小さなフットプリント(1 桁のメガバイト単位の常駐セットサイズ。METRICS.md を参照)と長いティック間隔で Keleusma のループデーモンを実行します。このデーモンは、システムが新しいプロセスを起動できない場合でもスケジュールされ続け、すでにロード済みのコードを必要とする診断や復旧作業に利用できます。

デフォルトのゼロ間隔の動作は、スクリプトが yield する限り高速に回転します。これはバッチ処理には適していますが、メモリ常駐でオンコールとなるデプロイには適していません。メモリ常駐デーモンとして実行する場合は、明示的な間隔(--tick-interval 30s--tick-interval 5m など、ケイデンスの必要性に応じて)を設定してください。

メモリ圧迫下でのクリーンな失敗

ランナーは、ホストがプログラムのメモリを真に満たせない場合にもクリーンに失敗します。検証済みプログラムの最悪ケースのアリーナは境界が定まり既知であるため、CLI はアリーナをその境界に合わせてサイズ設定し、失敗可能な形で割り当てます。それを提供できないホストは、SIGABRT でアボートするのではなく、out of memory: this program needs an N-byte arena という診断メッセージと非ゼロのステータスで終了するため、スーパーバイザーやオーケストレーターが観測して対応できます。事前にホストをプロビジョニングまたは適格性判定するには、keleusma run <file> --print-memory がプログラムの最悪ケースのアリーナフットプリント、すなわち永続部分と一時部分を含む合計を報告し、実行せずに終了します。

4 週間を超えるケイデンス

--tick-interval フラグは、4 週間を超える間隔を拒否します。月次または四半期のケイデンスを扱うオペレーターには 2 つの選択肢があります。

外部スケジューラ。デプロイプラットフォーム上の cron、systemd タイマー、またはそれに相当するものを使用して、所望のケイデンスでワンショットの Keleusma スクリプトを起動します。この手法は、要件がタイミングのみである場合に適しています。

Noop な yield サイクル。より短い間隔(1 時間、1 日)で Keleusma のループデーモンを実行し、内部ティックを所望のケイデンスに対してカウントします。ほとんどのイテレーションは何もせず yield するだけです。周期的なイテレーションが実際の作業を実行します。

loop main(tick: Word) -> Word {
    let _ = shell::set_tick_interval("1d");
    // Tick counts days. Real work runs every thirtieth day.
    let _ = if tick % 30 == 0 {
        // Operational logic.
        ...;
    };
    let _ = yield tick;
    tick
}

この手法は、メモリ常駐が要件の一部である場合(上記参照)に適しています。また、署名付きかつ暗号化された配送モデルをエンドツーエンドで維持します。スクリプトは決して終了せず、決して再起動されません。

鍵の侵害、失効、およびローテーション

このモデルは、侵害された場合の結果が大きく異なる 2 つの秘密鍵に依拠しています。オペレーターはこの非対称性を理解し、各鍵をそれに応じて保護すべきです。

2 つの秘密鍵とそれぞれの影響範囲

  • 署名シード(sign.seed、生成者が保持)は最重要の機密です。 対応する検証鍵を登録したすべてのホストは、それによって署名されたあらゆるものを信頼します。署名シードが漏洩すると、攻撃者はフリート全体で厳格な署名検証を通過する成果物を偽造でき、鍵を登録したすべてのデプロイにわたって真正性が完全に失われます。これを最も厳重に保護してください。オフラインまたはエアギャップされた署名ホストに保管し、アクセスを可能な限り最小のオペレーター集合に制限し、脅威モデルが正当化する場合はハードウェアセキュリティモジュールまたは同等のものを優先してください。これはシステム内で最も影響の大きい単一の機密であり、署名鍵漏洩のケースはモデル全体を掘り崩すものです。
  • 復号シード(dest.seed、受信者が保持)の影響範囲は限定的です。 復号シードが漏洩すると、攻撃者はその 1 つの受信者向けに暗号化された成果物のみを読み取れます。他の受信者向けの成果物は、前述のエアギャップシナリオで述べたとおり機密のまま保たれます。受信者鍵のレベルでは前方秘匿性がないため、復号シードが漏洩すると、攻撃者が保持していた過去の暗号化成果物も、将来のものだけでなく露呈します。各受信者の鍵ペアは受信者ホスト上で生成し、シードが送信されないようにするとともに、keygen が Unix 上で設定するモード 0600 のパーミッションに依拠してください。

有効期限はなく、失効は手動です

登録された鍵は、有効期間が埋め込まれていない生の Ed25519 鍵および X25519 鍵であるため、登録された鍵はオペレーターが削除するまで信頼されます。証明書失効リストもオンライン失効チェックもありません。これはエアギャップされた登録鍵モデルに内在するものです。したがって鍵を失効させるとは、影響を受けるすべてのホストのトラストストアまたは復号鍵ストアから、1 ホストずつそのファイルを削除することを意味し、失効はそのホストが更新された時点で初めて有効になります。この遅延を見込んでください。フリート全体の失効は、デプロイ作業であって即時のブロードキャストではありません。

ローテーション手順

ポリシーとして定期的に、そして侵害の疑いがある場合には直ちにローテーションを行ってください。署名鍵のローテーションは次のとおりです。

  1. 署名ホスト上で新しい署名鍵ペアを生成します(keleusma keygen --seed sign.v2.seed --public sign.v2.pub)。
  2. 新しい検証鍵を配布し、帯域外で認証したうえで(登録の真正性に関する残余リスクの注記を参照)すべてのホストのトラストストアに登録します。移行期間中は古い鍵を登録したままにしておきます。
  3. 実行可能なまま維持しなければならない成果物を、新しい鍵で再署名します。
  4. すべてのホストが新しい鍵を保持し、稼働中のすべての成果物が再署名されたら、すべてのトラストストアから古い検証鍵を削除します。古い署名シードはその時点で無力となり、破棄すべきです。

復号鍵のローテーションは対称的です。受信者ホスト上で新しい受信者鍵ペアを生成し、新しい公開鍵を生成者へ配布し、その受信者が依然として必要とする成果物を再暗号化し、それに向けて暗号化された流通中のものがなくなった時点で古い復号シードを削除します。

信頼モデル

信頼されるコンポーネント

  • keleusma-cli バイナリ自体。バイナリを差し替えた攻撃者はすべてのポリシーを無効化します。バイナリの完全性はオペレーターの責任です(ファイルシステムのパーミッション、OS レイヤーでの実行ファイル署名、完全性監視ツール)。
  • トラストストアのディレクトリ。登録済み鍵ファイルを改変した攻撃者は信頼リストを拡張できます。非特権の改ざんを防ぐため、ファイルシステムのパーミッション(root 所有、鍵ファイルはモード 0644、ディレクトリはモード 0755)を使用してください。
  • ホストのオペレーティングシステム。root またはカーネルレベルのアクセスを持つ攻撃者は、あらゆるユーザー空間の仕組みを無効化できます。

信頼されないコンポーネント

  • 配送経路(ネットワーク、USB、宅配便)。通信中のバイトコードは、検査可能かつ差し替え可能なものと想定されます。
  • ディスク上のバイトコードファイル。バイトコードファイルを差し替えた攻撃者は、その差し替え物もアクティブなポリシーを通過しない限り、それを実行させることはできません。
  • デプロイホスト上のローカルオペレーター。非特権ユーザーはポリシーを緩和できません。システム管理下のトラストストアがコマンドライン引数を上書きします。

既知の残余リスク

  • 実行中のランタイムに対してメモリアクセス権を持つ攻撃者は、復号ステップの後に RAM から復号された平文を復元できます。このギャップを塞ぐにはハードウェア分離(Cortex-M55 上の TrustZone-M、その他のプラットフォーム上の同等物)が必要です。この作業は docs/decisions/BACKLOG.md の B24 として追跡されています。
  • 暗号処理に対するサイドチャネル攻撃(タイミング、電力解析)は、現在の実装では対象外です。純粋な Rust の暗号クレート(ed25519-dalekx25519-dalekaes-gcm)はコアプリミティブの定数時間実装を提供しますが、より広範なホスト環境は他の経路を通じて漏洩する可能性があります。
  • リプレイ防止や鮮度の束縛はありません。署名は起源と完全性を証明しますが、新しさは証明しません。成果物には、ホストが検査するタイムスタンプ、シーケンス番号、ノンスが付いておらず、ホストはすでに実行した成果物の記録を保持しないため、過去に有効であった成果物を保持していた攻撃者はそれを再配送でき、ホストはそれを検証して実行します。置き換えられたが一度は有効であった成果物、例えば古いワークフロースクリプトを実行することが有害である場合は、モデルの外部で鮮度を強制してください。完全性が管理された経路で配送する、置き換えの間に署名鍵をローテーションして古い成果物が検証されなくなるようにする、あるいは成果物のハッシュをホスト側で追跡する、といった方法があります。
  • 耐量子ではなく古典的な暗号です。Ed25519 と X25519 は耐量子ではありません。今日暗号化された成果物を記録した攻撃者は、暗号学的に意味のある量子コンピュータが存在すれば、それを復号できます。これはハーベスト・ナウ・デクリプト・レイターの脅威であり、長期的に機密なペイロードにとって重要です。ワイヤーフォーマットは ABI の破壊なしに耐量子スキームへ移行するために scheme_id バイトを予約していますが、そのようなスキームは今日実装されていません。
  • 登録の真正性はオペレーターの責任です。トラストストアは登録後の改ざんから保護しますが、初回の公開鍵交換は帯域外で認証されなければなりません。攻撃者が差し替えた検証鍵を登録すると、フリートは攻撃者の署名を信頼するようになり、攻撃者が差し替えた受信者公開鍵に向けて暗号化すると、ペイロードが攻撃者に開示されます。登録の前に、別の経路によるフィンガープリント比較、信頼できる宅配便、または既存の信頼アンカーによって、鍵の由来を検証してください。
  • メタデータは秘匿されません。成果物のサイズ、配送のタイミング、および暗号化された成果物のヘッダーに含まれる recipient_key_id は、経路を観測する者に見えます。内容は保護されますが、配送の事実と形状は保護されません。これは物理的なエアギャップ転送では軽微ですが、観測可能なネットワーク上ではより関連性が高くなります。

相互参照

  • 厳格モード署名ゲートの設計記録については RESOLVED.md の R49 を参照してください。
  • 暗号化レイヤーの設計記録については RESOLVED.md の R50 を参照してください。
  • 基盤となる Ed25519 署名インフラストラクチャについては RESOLVED.md の R42 を参照してください。
  • 署名済みおよび暗号化された成果物のワイヤーフォーマットの詳細については WIRE_FORMAT.md を参照してください。
  • 復号ステップを含むロード時のパイプラインについては EXECUTION_MODEL.md を参照してください。
  • 将来のハードウェア分離作業については BACKLOG.md の B24 を参照してください。