トポロジー
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 |
|---|---|---|---|
| VotingSession | id | electionId, botCount, finalized, userVoteIndex, finalizationResultJson | ttl |
| Vote | 識別子: sessionId + voteIndex | choice, 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.json と journal.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} | イメージ署名検証 Lambda | develop: 7 日 / main: 14 日 |
/aws/apigateway/{project}-hono-api-{env} | API Gateway アクセスログ | Amplify 管理 |
CloudTrail(main 環境のみ)
main 環境では CloudTrail による全リージョン監査ログが有効です。
| 項目 | 設定 |
|---|---|
| 対象リージョン | 全リージョン |
| ログ検証 | 有効 |
| 保存先 | 専用 S3 バケット + CloudWatch Logs |
| 保持期間 | 90 日 |