feat(BOXP-120): lolice cluster メンバーポータルのセルフサービス化#11314
Open
boxp wants to merge 21 commits into
Open
Conversation
…ber-portal CI失敗の原因: aqua/ディレクトリが存在せずterraformバイナリが見つからなかった。 moltworkerと同じv1.15.8のterraform、v0.63.1のtflint、v0.72.0のtrivyを設定。 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
- GET /api/approve now returns a confirmation HTML page; POST /api/approve performs the actual approval, preventing link-preview bots from approving requests without admin intent - Validate payload is a non-null object in POST /api/request before accessing payload.email, returning 400 instead of 500 for null/non-object bodies - Wrap read-modify-write in addEmailToAccessPolicy with a 3-attempt retry loop to handle concurrent approval race conditions Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
acquirePolicyLock/releasePolicyLockを追加し、addEmailToAccessPolicy内の read-modify-write全体をKVベースのアドバイザリーロックで保護する。 KVはアトミックCASを持たないためベストエフォートだが、既存のPUT後の 検証(verify)ループと組み合わせることで、並行承認による上書きを 検出・再試行し、全メールアドレスが最終的にポリシーに含まれることを保証する。 maxRetriesも5→8に増加。 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
…limiting - Replace KV-based advisory lock (non-atomic, racy) with a singleton PolicyUpdater Durable Object. The DO runtime serializes concurrent requests, eliminating the read-modify-write race on Access Policy PUT. - Add IP-based rate limiting (3 req/hour) to POST /api/request to prevent admin email spam from bots. - Remove dead KV lock code (acquirePolicyLock, releasePolicyLock). - Add durable_object_namespace_binding to worker.tf. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
…om worker.tf cloudflare/cloudflare v4.52 does not support durable_object_namespace_binding in cloudflare_workers_script. Replace PolicyUpdater Durable Object with inline read-modify-write+verify retry loop (3 attempts) in addEmailToAccessPolicy. Manual approvals are sequential in practice so the retry handles the edge case. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
…e Object Replace the retry-based read-modify-write in addEmailToAccessPolicy with a singleton PolicyUpdateDO Durable Object. The DO's single-threaded event loop queues concurrent approval requests, so each GET→PUT sees the fully committed result of the previous write and no email addition can be silently overwritten. Also add durable_object_namespace_binding and migrations block to worker.tf.
Contributor
❌ terraform/cloudflare/b0xp.io/lolice-member-portal: terraform validateDetails |
…pdates Cloudflare provider v4.52 does not support durable_object_namespace_binding or migrations blocks in cloudflare_workers_script, causing terraform validate to fail. Replace the DO-based serialization with an addEmailToAccessPolicy function that performs a read-modify-write loop and verifies the email was persisted after each PUT. If a concurrent PUT overwrote the write, the verify step detects the missing entry and retries with backoff (up to 5 attempts), ensuring eventual consistency without requiring Durable Objects. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
Replace read-modify-write retry loop with PolicyUpdater Durable Object so concurrent approvals are queued and executed serially Replace non-atomic KV rate limiting with atomic DO storage counters Remove default="" from cf_api_token/resend_api_key to prevent deploying with blank secrets
Contributor
❌ terraform/cloudflare/b0xp.io/lolice-member-portal: terraform validateDetails |
DO storage does not support expirationTtl option (unlike KV).
Store {count, windowStart} record and reset when window expires.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Contributor
❌ terraform/cloudflare/b0xp.io/lolice-member-portal: terraform validateDetails |
Cloudflare TF provider v4.52.8 does not support durable_object_namespace_binding or migrations blocks in cloudflare_workers_script, causing CI failures. Replace the DO approach with a KV-sourced strategy: - Add APPROVED_EMAILS KV namespace as durable source of truth for approvals - On each policy update: write email to KV first, then merge ALL KV emails into the policy (deduplicating with existing include rules) - Verify email appears after PUT; retry with fresh GET if absent (handles the rare case where a concurrent PUT overwrote our addition) - Rate limiting uses PENDING_REQUESTS KV with expirationTtl Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
Replace secret_text_binding (which required Terraform variables for secret values) with separate cloudflare_workers_secret resources. Secrets are initialized with a dummy placeholder and lifecycle.ignore_changes prevents Terraform from overwriting values set manually via Cloudflare Dashboard. This eliminates the need for cf_api_token and resend_api_key variables, so terraform plan in CI succeeds without secret values. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
Contributor
❌ terraform/cloudflare/b0xp.io/lolice-member-portal: terraform validateDetails |
…ET verification - Remove PolicyUpdater Durable Object (unsupported in cloudflare provider v4.52) - Restore APPROVED_EMAILS KV namespace as durable source of truth - Rewrite addEmailToAccessPolicy to merge ALL KV emails on every PUT attempt - Verify with a separate fresh GET (not PUT response) that ALL KV emails exist - Retry up to 5 times with exponential backoff on concurrent-overwrite detection
This comment has been minimized.
This comment has been minimized.
addEmailToAccessPolicy でKV list()の1ページ目(最大1,000件)しか 処理していなかった問題を修正。list_complete/cursorによるページネーション ループで全メールアドレスを取得するように変更。 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
…rrent approvals The verification step was checking kvEmails from the start of the loop iteration. If a concurrent approval was persisted to KV after that snapshot was taken, our PUT could overwrite their addition and the stale-snapshot check would still pass (missing their email). Fix: re-scan APPROVED_EMAILS KV in step 6 to get the current complete set, then verify the live policy contains all of them. If any are absent, the loop retries the full read-modify-write cycle. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
…and SSM for secrets - Replace APPROVED_EMAILS KV namespace with Cloudflare D1 database so that the retry+verify loop in addEmailToAccessPolicy always sees a consistent view of approved emails. KV's eventual consistency meant concurrent approvals could miss each other's writes even during the verify re-read; D1 (SQLite, ACID) eliminates this gap. - Remove dummy secret values and lifecycle ignore_changes from cloudflare_workers_secret. Secrets are now read from AWS SSM Parameter Store via data sources, ensuring terraform apply always deploys the real credentials and no dummy placeholder can be accidentally left in place. - Add AWS provider (hashicorp/aws ~> 5.0) to backend.tf and provider.tf. - SSM prerequisites: aws ssm put-parameter --name /lolice-member-portal/CF_API_TOKEN and /lolice-member-portal/RESEND_API_KEY must be created before first apply. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…sion constraint - Bump aws provider constraint from ~> 5.0 to ~> 6.0 to match other directories in this repo - Add hashicorp/aws 6.54.0 entry to .terraform.lock.hcl (copied from bastion which uses same version) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Contributor
|
❌ Details |
Remove the manually-added 6.54.0 entry and keep only the CI-generated 5.100.0 entry from update-aqua-checksums. Align backend.tf constraint to ~> 5.0. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Contributor
❌ Plan Failed (terraform/cloudflare/b0xp.io/lolice-member-portal)
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
lolice cluster(PalWorldゲームサーバー)への参加をセルフサービス化するメンバーポータルを実装します。
実装内容
フロー
並行承認の安全性
addEmailToAccessPolicyでCloudflare Access PolicyのRead-Modify-Writeを行う際:これにより、複数の承認が並行した場合でも最終的にすべての承認済みメールがポリシーに反映される。
デプロイ前に必要な設定(terraform apply 前)
シークレットをAWS SSM Parameter Storeに設定する必要があります:
設定後、通常通り
terraform applyを実行するとSSMからシークレットが自動で読み込まれます。tfaction
terraform/cloudflare/b0xp.io/lolice-member-portal/ディレクトリが追加されます。PRマージ後に tfaction が terraform plan → apply を実行します。