Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

`bootstrap_keys()` auto-bootstrap path does not write `bootstrap-info.json`

オープン
#539 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
3/5
見積もり時間
1〜2日
初心者へのやさしさ
45/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
停滞
技術スタック
rust
領域
api, backend, security

調査の方向性

onboard_service.rs の bootstrap_keys() から始め、手動の bootstrap() パスと比較します。次に、config.rs の bootstrap_info() と main_service.rs の GetMeta を調べます。TDX 対応のセットアップで自動ブートストラップのフローを検証し、quote_enabled の動作も確認します。また、GetMeta が後続の kms:set-info 登録向けに設定済みの bootstrap 情報を公開していることを確認します。

索引モデルが issue の本文から書いたものです。

説明

When KMS is configured with auto_bootstrap_domain (non-empty string in kms.toml), the auto-bootstrap code path in onboard_service.rs:bootstrap_keys() generates keys and stores them via keys.store(cfg), but never writes bootstrap-info.json.

This causes GetMeta to return bootstrap_info: null, which blocks the kms:set-info hardhat task from registering the KMS on-chain.

Steps to Reproduce

  1. Deploy KMS CVM with auto_bootstrap_domain set in kms.toml:

    [onboard]
    auto_bootstrap_domain = "kms.example.com"
    quote_enabled = true
    
  2. KMS starts, auto-bootstrap runs successfully (keys generated, certs created)

  3. Query GetMeta:

    curl -sk https://localhost:9100/prpc/KMS.GetMeta?json | jq .bootstrap_info
    
  4. Result: null

Root Cause

Auto-bootstrap (onboard_service.rs:330-339):

pub(crate) async fn bootstrap_keys(cfg: &KmsConfig) -> Result<()> {
    let keys = Keys::generate(
        &cfg.onboard.auto_bootstrap_domain,
        cfg.onboard.quote_enabled,
    )
    .await
    .context("Failed to generate keys")?;
    keys.store(cfg)?;  // Stores 8 files (keys, certs, rpc-domain) — NOT bootstrap-info.json
    Ok(())
}

Manual bootstrap (onboard_service.rs:54-78):

async fn bootstrap(self, request: BootstrapRequest) -> Result<BootstrapResponse> {
    let quote_enabled = self.state.config.onboard.quote_enabled;
    let keys = Keys::generate(&request.domain, quote_enabled)
        .await
        .context("Failed to generate keys")?;

    let k256_pubkey = keys.k256_key.verifying_key().to_sec1_bytes().to_vec();
    let ca_pubkey = keys.ca_key.public_key_der();
    let attestation = if quote_enabled {
        Some(attest_keys(&ca_pubkey, &k256_pubkey).await?)
    } else {
        None
    };

    let cfg = &self.state.config;
    let response = BootstrapResponse {
        ca_pubkey,
        k256_pubkey,
        attestation: attestation.unwrap_or_default(),
    };
    // Store the bootstrap info
    safe_write(cfg.bootstrap_info(), serde_json::to_vec(&response)?)?;  // ← Writes the file
    keys.store(cfg)?;
    Ok(response)
}

The manual path extracts public keys, optionally generates an attestation quote via attest_keys(), constructs a BootstrapResponse, and writes it to {cert_dir}/bootstrap-info.json (defined in config.rs:88-90 as self.cert_dir.join("bootstrap-info.json")). The auto-bootstrap path does none of this.

GetMeta (main_service.rs:323-326) silently returns None when the file is missing:

let bootstrap_info = fs::read_to_string(self.state.config.bootstrap_info())
    .ok()
    .and_then(|s| serde_json::from_str(&s).ok());

Impact

  • GetMeta returns bootstrap_info: null
  • kms:set-info hardhat task fails (cannot read/parse null bootstrap info)
  • KMS public keys and TDX attestation quote are never registered on-chain
  • Applications cannot verify KMS attestation through the smart contract
  • The entire on-chain trust anchor is missing

No workaround exists — bootstrap-info.json is only written in one place in the codebase (the manual bootstrap() RPC handler at line 75). No other service or background task populates it.

History

  • ae75c86e (2025-01-12): Added bootstrap_keys() — no bootstrap-info.json write
  • 6900f54e (2025-01-15): Added bootstrap-info.json write to the manual bootstrap() path only

The auto path has never written this file since it was introduced.

Suggested Fix

Add public key extraction, attestation quote generation, and bootstrap-info.json writing to bootstrap_keys(), mirroring the manual bootstrap() path:

pub(crate) async fn bootstrap_keys(cfg: &KmsConfig) -> Result<()> {
    let keys = Keys::generate(
        &cfg.onboard.auto_bootstrap_domain,
        cfg.onboard.quote_enabled,
    )
    .await
    .context("Failed to generate keys")?;
    keys.store(cfg)?;

    // Write bootstrap-info.json (same as manual bootstrap path)
    let k256_pubkey = keys.k256_key.verifying_key().to_sec1_bytes().to_vec();
    let ca_pubkey = keys.ca_key.public_key_der();
    let attestation = if cfg.onboard.quote_enabled {
        Some(attest_keys(&ca_pubkey, &k256_pubkey).await?)
    } else {
        None
    };
    let response = BootstrapResponse {
        ca_pubkey,
        k256_pubkey,
        attestation: attestation.unwrap_or_default(),
    };
    safe_write(cfg.bootstrap_info(), serde_json::to_vec(&response)?)?;

    Ok(())
}

Note: The attest_keys() function (line 351) generates a TDX attestation quote binding both the P256 CA public key and the secp256k1 key. This is needed for on-chain registration to include a valid attestation.

Also affected: feat/auto-onboard-kms branch

The auto_onboard_keys() function on the unmerged feat/auto-onboard-kms feature branch has the same gap — it generates keys and stores them but does not write bootstrap-info.json.

Environment

  • dstack version: v0.5.7
  • Platform: TDX-enabled server (Intel Xeon with TDX support)
  • Ubuntu 24.04 LTS
主要言語
Rust
スター
551
フォーク
97
平均マージ
19時間 22分
マージ済み PR(30日)
109

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

Dstack-TEE/dstack のほかの issue

Dstack-TEE/dstack の issue をすべて見る

似ている issue

Rust の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。