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 サービス構成と各コンポーネント間の通信フローを解説します。

本システムは 5 つの論理レイヤ(Web、API、Data、Prover、Storage)で構成され、各レイヤは明確な責務を持ちます。

レイヤ別トポロジー

Web レイヤ

Amplify Hosting が Next.js アプリケーションのビルドとホスティングを担当します。GitHub リポジトリのブランチ(develop / main)と Amplify の環境が 1 対 1 で対応し、プッシュをトリガーとする自動デプロイが行われます。

API レイヤ

API Gateway(HTTP API)が /api/* パスパターンのリクエストを受け取り、単一の Lambda 関数(hono-api)にプロキシします。hono-api は Hono フレームワーク上に構築されており、ルーティング、セッション管理、Turnstile 検証、レート制限を処理します。

flowchart LR
  Client["クライアント"] --> APIGW["API Gateway<br/>(HTTP API)"]
  APIGW --> HONO["hono-api<br/>Lambda"]
  HONO --> APPSYNC["AppSync<br/>(Data)"]
  HONO --> SQS["SQS<br/>(非同期証明)"]
  HONO --> S3["S3<br/>(バンドル取得)"]

  subgraph "リクエストパイプライン"
    direction TB
    SESS["セッション検証"]
    TURN["Turnstile 検証"]
    RATE["レート制限"]
    HAND["ハンドラー実行"]
    SESS --> TURN --> RATE --> HAND
  end

CORS 設定では X-Session-ID ヘッダーを許可し、セッションスコープのリクエスト制御を実現しています。

Data レイヤ

AppSync(GraphQL API)と DynamoDB が、セッション・投票・集計結果のデータ永続化を担当します。認証は Cognito Identity Pool によるゲスト認証(IAM SigV4)で行われます。

主要なデータモデルは以下の 2 つです(集計結果は VotingSession.finalizationResultJson に格納)。

モデルキー/識別子主要フィールドTTL
VotingSessionidelectionId, botCount, finalized, userVoteIndex, finalizationResultJsonttl
Vote識別子: sessionId + voteIndexchoice, random, commitment, rootAtCast, isUserVote

レート制限用に 2 つの追加テーブル(RateLimitEvents、RateLimitCounters)が PAY_PER_REQUEST モードで運用されています。

Prover レイヤ

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

flowchart LR
  SQS["SQS<br/>ワークキュー"] --> DP["prover-dispatch-proxy<br/>Lambda"]
  DP --> SFN["Step Functions<br/>ディスパッチャー"]
  SFN --> SIG["check-image-signature<br/>Lambda"]
  SFN --> ECS["ECS Fargate<br/>16 vCPU / 32 GB"]
  SFN --> CB["finalize-callback-runner<br/>Lambda"]
  ECS --> S3["S3<br/>証明バンドル"]

ECS タスクは ARM64 アーキテクチャの Fargate で実行され、専用の VPC(10.0.0.0/16)内のパブリックサブネットに配置されます。セキュリティグループは HTTPS エグレスのみを許可し、インバウンドトラフィックは一切受け付けません。

Storage レイヤ

S3 バケットが証明バンドル(レシート、ジャーナル、公開入力)の保存を担当します。

項目設定
バケット命名stark-ballot-simulator-proof-bundles-{環境名}
暗号化AES256(サーバーサイド暗号化)
パブリックアクセス全ブロック
ライフサイクルdevelop: 7 日、main: 30 日で自動削除
バージョニング無効(PoC では不要)

オブジェクトのパスは sessions/{sessionId}/{executionId}/ 配下に構造化されています。

ファイル公開可否説明
input.json非公開zkVM への完全な入力(プライベートウィットネス)
*-receipt.json非公開zkVM host の生出力(レシート)
*-output.json非公開zkVM host の生出力(集計結果)
public-input.json公開zkVM への入力の公開部分
bundle.zip公開receipt.json + journal.json + public-input.json
verification.json非公開検証サービスの出力(検証実行後に生成)

receipt.jsonjournal.json は S3 直下には保存されず、bundle.zip の内部エントリとして配布されます。

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

投票から検証までの全データフローを、レイヤ間の通信として示します。

sequenceDiagram
  participant C as クライアント
  participant W as Web レイヤ<br/>(Amplify Hosting)
  participant A as API レイヤ<br/>(API GW + Lambda)
  participant D as Data レイヤ<br/>(AppSync + DDB)
  participant P as Prover レイヤ<br/>(SQS → SFN → ECS)
  participant S as Storage レイヤ<br/>(S3)

  Note over C,D: 投票フェーズ
  C->>W: ページ読み込み
  C->>A: POST /api/session
  A->>D: セッション作成
  C->>A: POST /api/vote
  A->>D: 投票 + コミットメント保存
  A-->>C: レシート返却
  Note over A,D: ボット投票を自動追加

  Note over C,P: 集計フェーズ
  C->>A: POST /api/finalize
  alt FINALIZE_ASYNC_MODE=true
    A->>P: SQS メッセージ送信
    A-->>C: 202 Accepted
    P->>P: イメージ署名検証
    P->>P: ECS タスクで証明生成
    P->>S: input.json + 実行成果物 + bundle.zip 保存
    P->>D: コールバックで結果書き込み
  else FINALIZE_ASYNC_MODE=false
    A->>A: 同期で zkVM 実行
    A-->>C: 200 OK(集計結果)
  end

  Note over C,S: 検証フェーズ
  C->>A: GET /api/verify
  A->>D: セッション + 集計結果取得
  A-->>C: 検証ペイロード返却
  C->>A: POST /api/verification/run
  A->>S: バンドル取得
  A->>A: STARK レシート検証
  A-->>C: 検証結果返却

ネットワーク構成

VPC

Terraform が管理する VPC は、ECS Fargate タスク専用です。Amplify 管理のリソース(Lambda、AppSync)は VPC 外で動作します。

flowchart TD
  subgraph VPC["VPC (10.0.0.0/16)"]
    subgraph AZ1["ap-northeast-1a"]
      S1["パブリックサブネット<br/>10.0.1.0/24"]
    end
    subgraph AZ2["ap-northeast-1c"]
      S2["パブリックサブネット<br/>10.0.2.0/24"]
    end
    SG["セキュリティグループ<br/>Egress: 443 のみ"]
  end

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

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

ECS タスクはパブリック IP を持ちますが、セキュリティグループがインバウンドを全拒否するため、外部からのアクセスはできません。アウトバウンドは HTTPS(ポート 443)のみ許可され、ECR からのイメージ取得と S3 へのアップロードに使用されます。

監視とロギング

CloudWatch ログ群

ログ群対象保持期間
/aws/ecs/{project}-prover-{env}ECS Fargate タスクdevelop: 7 日 / main: 14 日
/aws/stepfunctions/{project}-prover-{env}Step Functions 実行develop: 7 日 / main: 14 日
/aws/codebuild/{project}-fargate-prover-{env}CodeBuild ビルドdevelop: 7 日 / main: 14 日
/aws/lambda/{project}-check-image-signature-{env}イメージ署名検証 Lambdadevelop: 7 日 / main: 14 日
/aws/apigateway/{project}-hono-api-{env}API Gateway アクセスログAmplify 管理

CloudTrail(main 環境のみ)

main 環境では CloudTrail による全リージョン監査ログが有効です。

項目設定
対象リージョン全リージョン
ログ検証有効
保存先専用 S3 バケット + CloudWatch Logs
保持期間90 日