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

トポロジー

AWS 上のサービス配置とコンポーネント間の通信経路を示します。 このページは runtime の責務分担を説明します(個別環境の導入進捗は扱いません)。

本システムは次の 6 つの論理レイヤで構成されます。

レイヤ別トポロジー

Web レイヤ

CloudFront が private S3 origin の Vite/React 静的アセットを配信します。 /api/* は同じ CloudFront distribution から API Gateway origin に routing されます。 extensionless browser route は viewer-request fallback で index.html に解決します。

develop で operator gate が有効な場合、static frontend、browser route、/api/api/* の viewer access は CloudFront signed cookie を要求します。 信頼する public key group は、追跡対象 keyset に従って Terraform が管理する非対称 KMS signing key から public key を導出して構成します。 KMS の private signing material は CloudFront、app runtime role、Terraform state には渡しません。 この gate は develop 固有の条件付き境界であり、すべての環境に一律適用されるものではありません。

API レイヤ

API Gateway(HTTP API)が /api/* パスパターンのリクエストを受け取り、単一の Lambda 関数(public-api)にプロキシします。 public-api は Hono route inventory を実行する runtime adapter で、ルーティング、セッション管理、Turnstile 検証、レート制限を処理します。 下図の「主なリクエスト制御」は、public-api がルートごとに適用有無と順序を切り替える代表的な要素を示します。 固定順のパイプラインではありません。

flowchart LR
  Client["クライアント"] --> CF["CloudFront"]
  KMS["KMS<br/>(develop signing keys)"] --> KG["CloudFront trusted key group<br/>(public keys only)"]
  KG -. develop signed-cookie gate .-> CF
  CF --> FRONT["S3<br/>(static frontend)"]
  CF --> APIGW["API Gateway<br/>(HTTP API)"]
  APIGW --> API["public-api<br/>Lambda"]
  API --> DDB["DynamoDB<br/>(sessions / votes / rate limits)"]
  API --> SQS["SQS<br/>(非同期証明)"]
  API --> VQS["SQS<br/>(検証 work queue)"]
  API --> S3["S3<br/>(bundle / report delivery)"]
  VQS --> VW["verification-worker<br/>Lambda"]
  VW --> S3
  VW --> DDB

  subgraph "主なリクエスト制御(ルートごとに適用)"
    direction TB
    RATE["IP / zkVM レート制限"]
    SESS["セッション / capability 検証"]
    TURN["Turnstile 検証"]
    BODY["入力検証"]
    HAND["ハンドラー実行"]
    RATE -.-> HAND
    SESS -.-> HAND
    TURN -.-> HAND
    BODY -.-> HAND
  end

CORS 設定で X-Session-Capability ヘッダーを許可し、session-scoped route は path の sessionId と capability トークンを照合します(契約は API リファレンス > セッション capability)。 POST /api/sessions/{sessionId}/finalizations/{finalizationId}/verification は、target runtime では検証 work を verification-work キューへ登録し、HTTP 応答では verificationStatus=runningfinalizationId、推定所要時間、idempotent 判定を返します。 実際の STARK レシート検証と protected report の保存は verification-worker の責務です。 後述のエンドツーエンドのデータフローも参照してください。

Data レイヤ

DynamoDB が、セッション、投票、集計結果、レート制限状態の永続化を担当します。 データプレーンは target Lambda IAM role ごとの最小権限で制限され、ブラウザから DynamoDB へ直接アクセスする経路はありません。

通常時は Terraform-owned primary sessions / votes table pair を参照します。 DynamoDB recovery の 4 phase 定義と切替契約は Terraform を参照してください(quiesced phase の図への影響は エンドツーエンドのデータフロー に注記)。

sessions table は string partition key sessionId を使いますが、単一の aggregate session row は保存しません。 identity、voting、finalization、verification、artifact delivery を、責務ごとの record family と prefixed key に分離します。 votes table は引き続き (sessionId, voteIndex) の複合キーを使います。

record familysessions table のキー例主な authority / field
Session identity{sessionId}SESSION_IDENTITY; identity に election config、electionIdlogId、作成時刻を固定
Session votingVOTING#{sessionId}SESSION_VOTING; bulletin root history、bot count、user participation、last activity、revision
Finalization lifecycleFINALIZATION_CURRENT#{sessionId} / FINALIZATION#...current pointer と finalization ごとの lifecycle record
Verification / evidenceVERIFICATION#... / OBSERVATION#... / BITMAP#...verification result、browser observation、finalization bitmap を別々に所有
AWS runtime / artifact deliveryFINALIZATION_RUNTIME#... / VERIFICATION_DELIVERY#...Step Functions / bundle metadata と s3BundleKey / s3ReportKey delivery metadata を semantic state から分離
Votevotes table の {sessionId} + {voteIndex}voteId、encrypted vote / randcommittimestamprootAtCastisUserVoteexpiresAt

session-owned record には用途に応じた expiresAt を持たせます。 receipt board の global counter は sessions table 上の独立した非 TTL record です。

レート制限用に 2 つの追加テーブル(RateLimitEvents、RateLimitCounters)が PAY_PER_REQUEST モードで運用されています。 これとは別に、同時実行数を制御する prover semaphore table も DynamoDB 上で管理します。

Prover レイヤ

STARK 証明の生成を担当するレイヤです。 SQS キュー、Step Functions ステートマシン、ECS Fargate タスクで構成されます。 詳細は 非同期プローバー を参照してください。

flowchart LR
  CODEBUILD["CodeBuild<br/>プローバー候補イメージ"] --> META["S3<br/>候補 metadata / promotion evidence"]
  CODEBUILD -. legacy / optional<br/>非 authority .-> SSM["SSM Parameter<br/>current metadata"]
  META --> RECORD["Prover release record<br/>accepted pointer"]
  RECORD --> PREFLIGHT["image-signature-verifier<br/>preflight alias"]
  PREFLIGHT -. VERIFIED evidence .-> APP["App deployment record"]
  SQS["SQS<br/>ワークキュー"] --> DP["proof-dispatcher<br/>Lambda"]
  DP --> SFN["Step Functions<br/>ディスパッチャー"]
  APP -. digest / verifier authority .-> SFN
  SFN --> SIG["image-signature-verifier<br/>runtime alias"]
  SIG -. VERIFIED .-> SFN
  SFN <--> SEM["DynamoDB<br/>prover semaphore"]
  JANITOR["semaphore-janitor<br/>Lambda"] --> SEM
  SFN --> ECS["ECS Fargate<br/>ARM64 Linux / CPU-only"]
  SFN --> CALLBACK["finalization-writer<br/>Lambda"]
  ECS --> S3["S3<br/>証明バンドル"]

normal App deployment は、選択した digest 固定 Prover image を immutable verifier version の preflight alias で検証し、その evidence と verifier authority を App deployment record に固定します。 runtime では Step Functions の最初の state が同じ authority の runtime alias を呼び、暗号学的検証に成功した場合だけ semaphore の取得と ECS 起動へ進みます。

ECS タスクは ARM64 アーキテクチャの Fargate で実行され、Foundation-owned VPC(10.42.0.0/20)内のパブリックサブネットに配置されます(セキュリティグループの設定は ネットワーク構成 を参照)。 Step Functions は DynamoDB の semaphore row で prover slot を取得・解放し、semaphore-janitor は terminal execution event と定期 sweep から stale slot を回収します。

Verification レイヤ

STARK レシート検証を担当するレイヤです。 public-api は session capability、finalization state、bundle locator、Image ID を確認したうえで検証 work を SQS に登録します。 verification-worker は work item に含まれる sessionIdfinalizationIdbundleKey、expected Image ID を使って private S3 bucket から bundle.zip を取得します。 その後、verifier-serviceReceipt::verify(expected_image_id) を実行します。

検証結果は protected report artifact(verification.json)として保存されます(扱いは 公開境界 と後述の Storage レイヤ)。

Storage レイヤ

S3 バケットが、証明バンドルに含まれる配布対象アーティファクトと非公開ワーク入力の保存を担当します。 Target Terraform はこれに加えて、プローバーイメージ候補の metadata、promotion evidence、release record / accepted pointer 用の非公開 S3 storage を管理します。 実行対象は選択された app deployment record から渡される digest 固定 prover image URI で決まります。

項目設定
バケット命名stark-ballot-simulator-{account-alias}-{environment}-proof-artifacts
暗号化AES256(サーバーサイド暗号化)
パブリックアクセス全ブロック
ライフサイクルproof_artifact_lifecycle_days 日(既定 7 日)で current / noncurrent object を自動削除
バージョニングEnabled

プローバー release metadata / evidence は foundation 側の versioned manifest storage に保存します。 CodeBuild からの publish 仕様、legacy/optional SSM current pointer の非 authority 境界、digest 固定 runtime input の関係は イメージ署名 > ビルドと署名の概念 を参照してください。

証明バンドル側のオブジェクトパスは既定で sessions/{sessionId}/{finalizationId}/ 配下です。 target runtime では S3_PROOF_PREFIX=sessions/ が Terraform と runtime validation の契約です。 この prefix を変更するには、public-apiverification-workerproof-dispatcherfinalization-writer、CLI/report delivery の S3 policy と artifact lookup を同時に変更する必要があります。 影響範囲は 非同期プローバー > Dispatch 処理 を参照してください。

配布対象(bundle.zip とその同梱物)と保護対象(input.json、bitmap sibling object など)の区分は 公開境界 を、bundle member と S3 レイアウトの詳細は バンドル構造 を参照してください。 このレイヤに固有のファイルは次のとおりです。

ファイル区分説明
*-receipt.json中間データzkVM host の生出力。bundle.zip 内の receipt.json の元データ
*-output.json中間データzkVM host の生出力(集計結果)。bundle.zip 内の journal.json の元データ
verification.json保護検証サービスの出力。target runtime では protected report artifact として保存を要求し、bundle.zip には含めない

エンドツーエンドのデータフロー

投票から検証までのデータフローを、レイヤ間の通信として示します。 以下は primary_active または replacement_active の非 quiesced phase における処理です。 *_quiesced phase では、この図に含まれる新規 session admission と prover / verification queue consumption は利用できません。 図では API request ごとの CloudFront hop を省略していますが、develop operator gate が有効な場合は frontend と API の両方で viewer request の signed cookie を検証します。

sequenceDiagram
  participant C as クライアント
  participant W as Web レイヤ<br/>(CloudFront + S3)
  participant A as API レイヤ<br/>(API GW + Lambda)
  participant Q as 検証キュー<br/>(verification-work)
  participant V as 検証レイヤ<br/>(verification-worker)
  participant D as Data レイヤ<br/>(DynamoDB)
  participant P as Prover レイヤ<br/>(SQS → SFN → ECS)
  participant S as Storage レイヤ<br/>(S3)

  Note over C,D: 投票フェーズ
  C->>W: ページ読み込み
  opt develop operator gate enabled
    W->>W: CloudFront signed-cookie 検証
  end
  C->>A: POST /api/sessions
  A->>D: セッション作成
  C->>A: POST /api/sessions/{sessionId}/votes
  A->>D: 投票 + コミットメント保存
  A-->>C: 投票レシート返却
  Note over A,D: ボット投票を自動追加

  Note over C,P: 集計フェーズ
  C->>A: POST /api/sessions/{sessionId}/finalizations
  A->>P: SQS メッセージ送信
  A-->>C: 202 Accepted
  P->>S: input.json 保存(SFN 起動前)
  P->>P: イメージ署名検証
  P->>P: ECS タスクで証明生成
  P->>S: 実行成果物 + 公開監査アーティファクト + bundle.zip 保存
  P->>D: コールバックで結果書き込み

  Note over C,S: 検証フェーズ
  C->>A: GET /api/sessions/{sessionId}/finalizations/{finalizationId}/verification
  A->>D: identity + voting + finalization + verification record 取得
  A-->>C: 検証ペイロード返却
  C->>A: POST /api/sessions/{sessionId}/finalizations/{finalizationId}/verification
  A->>Q: 検証 work を登録
  A->>D: VERIFICATION_RESULT に running を記録
  A-->>C: verificationStatus=running + finalizationId 返却
  Q->>V: work item 配信
  V->>S: bundle.zip 取得
  V->>V: verifier-service 実行
  V->>S: verification.json を protected report として保存
  V->>D: verification result と delivery metadata を別 record に記録
  C->>A: GET /api/sessions/{sessionId}/finalizations/{finalizationId}/verification
  A->>D: 最新の検証状態取得
  A-->>C: 検証結果を含むペイロード返却

verification-workerbundle.zip を検証入力として読み取り、target AWS runtime では verification.json が存在しない場合や S3 upload に失敗した場合に fail-closed に失敗します。 保存に成功した report locator は VERIFICATION_DELIVERY record に、検証結果は VERIFICATION_RESULT record に保存し、pure finalization state には混在させません。 report 保存に失敗しても delivery metadata の既存 s3BundleKey は維持されますが、verification run 自体は成功扱いになりません(report と bitmap sibling object の扱いは バンドル構造)。

ネットワーク構成

VPC

Foundation Terraform が管理する VPC は、ECS Fargate タスク専用です。 API Gateway、target Lambdas、DynamoDB、S3、CloudFront は VPC 外の managed service boundary で動作します。 VPC は 10.42.0.0/20 で、最初の 2 つの available AZ に /24 public subnet を 1 つずつ配置します。 AZ 名は Terraform が実行時に取得するため、特定の AZ suffix には固定しません。

flowchart TD
  subgraph VPC["Foundation-owned VPC (10.42.0.0/20)"]
    subgraph AZ1["available AZ 1"]
      S1["パブリックサブネット<br/>10.42.0.0/24"]
    end
    subgraph AZ2["available AZ 2"]
      S2["パブリックサブネット<br/>10.42.1.0/24"]
    end
    SG["セキュリティグループ<br/>Ingress: なし<br/>Egress: all protocols / ports"]
  end

  IGW["インターネット<br/>ゲートウェイ"]
  ECR["ECR<br/>(イメージ取得)"]
  S3["S3<br/>(バンドル保存)"]

  VPC --> IGW
  IGW --> ECR
  IGW --> S3

ECS タスクはパブリック IP を持ちますが、セキュリティグループがインバウンドを全拒否するため、外部からのアクセスはできません。 アウトバウンドは 0.0.0.0/0 に対する全 protocol / port を許可します。 この egress 全許可は、public subnet から ECR、S3、CloudWatch Logs などへ到達するための develop prover の割り切りです。

監視とロギング

この節はログの物理配置と保持期間を示します。 ログ、メトリクス、alarm、operations ledger の authority と読み方は 可観測性設計 を参照してください。

主な CloudWatch ログ群

runtime のログ群(ECS Fargate タスク、Step Functions 実行、public-api / proof-dispatcher / finalization-writer / verification-worker / image-signature-verifier / semaphore-janitor の各 Lambda、API Gateway アクセスログ)の保持期間は develop 90 日 / main 180 日で統一しています。 例外は次の 2 つです。

ログ群対象developmain
/aws/ecs/containerinsights/{project}-{account-alias}-{environment}-prover/performanceECS Container Insights7 日30 日
/aws/events/{project}-{account-alias}-{environment}-ops-ledgernormalized operations ledger365 日731 日

ロググループ名は Terraform-managed physical names と component suffix に揃えます(image-signature-verifier の log group だけは stark-ballot-sim- を name prefix に使います)。 deployment pipeline の CodeBuild log group は bootstrap root の管理対象です。 develop / main の保持期間は、bootstrap pipeline が 30 / 365 日、App pipeline が 180 / 365 日、Foundation と image release pipeline が 365 / 365 日です。

CloudTrail

CloudTrail は current target app/bootstrap/foundation Terraform runtime の構成要素ではなく、account-plane または organization-level の監査証跡として別途管理される場合があります。 旧構成の残存ロググループ、旧 standalone prover/toolchain CodeBuild log group、旧 Terraform の multi-region CloudTrail(main 環境のみ、90 日保持)は、この topology の runtime authority に含めません。

関連する章