Skip to content

sec(iac): flip dev/staging/prod to AWS_IAM + enable CloudFront OAC (closes #575) - #797

Closed
cristim wants to merge 1 commit into
feat/multicloud-web-frontendfrom
sec/575-aws-iam-cdn-oac
Closed

cristim wants to merge 1 commit into
feat/multicloud-web-frontendfrom
sec/575-aws-iam-cdn-oac

Conversation

@cristim

@cristim cristim commented May 28, 2026

Copy link
Copy Markdown
Member

Summary

What flips, in what order

A single enable_cdn = true in each tfvars activates three resources atomically in one terraform apply:

  1. aws_cloudfront_origin_access_control.lambda -- OAC of type lambda, SigV4 always-sign, created by the frontend module when enable_oac = true (set automatically from enable_cdn && compute_platform == "lambda" in frontend.tf).
  2. aws_cloudfront_distribution.frontend -- CloudFront distribution with the OAC attached to the Lambda Function URL origin.
  3. aws_lambda_permission.function_url_cloudfront -- permission scoping lambda:InvokeFunctionUrl to the distribution ARN (environment layer, compute.tf).
  4. aws_lambda_function_url.main auth_type: NONE -> AWS_IAM (derived from local.lambda_function_url_auth_type = var.enable_cdn ? "AWS_IAM" : "NONE" in compute.tf).

Deploy order: dev first. Staging and prod are not provisioned yet (.invalid placeholder origins); their enable_cdn = true is committed here so they go straight to OAC-enabled when provisioned, but no apply risk until a real environment exists.

File-by-file changes

File Change
terraform/environments/aws/github-dev.tfvars enable_cdn = true; remove raw Lambda URL from lambda_allowed_origins; add post-apply note to add CF domain
terraform/environments/aws/github-staging.tfvars enable_cdn = true; replace TODO with pre-apply checklist (staging not provisioned)
terraform/environments/aws/github-prod.tfvars enable_cdn = true; replace TODO with pre-apply checklist (prod not provisioned)

No module changes -- the scaffolding (OAC resource, enable_oac variable, aws_lambda_permission, auth_type local) was fully landed in PR #574.

Verified outputs

terraform fmt -check (all envs, single config root)

$ terraform fmt -check   # exit 0, no output
PASS

terraform validate (all envs, single config root)

$ terraform validate
Success! The configuration is valid.

terraform plan (DEV only -- account 909626172446, profile cristi-cloudprowess-prd)

Plan: 7 to add, 3 to change, 4 to destroy

Resources added (OAC chain):

  • aws_lambda_permission.function_url_cloudfront[0]
  • module.frontend[0].aws_cloudfront_distribution.frontend
  • module.frontend[0].aws_cloudfront_function.security_headers
  • module.frontend[0].aws_cloudfront_origin_access_control.lambda[0]
  • module.frontend[0].aws_cloudwatch_metric_alarm.cloudfront_5xx

Resources changed:

  • module.compute_lambda[0].aws_lambda_function.main -- CORS origins update, env var changes
  • module.compute_lambda[0].aws_lambda_function_url.main -- auth_type: NONE -> AWS_IAM
  • module.build[0].terraform_data.image_tag -- placeholder image URI triggers tag recalculation (expected; CI provides real URI)

Resources destroyed (4 = 2 replacements x destroy+create): module.build[0].terraform_data.docker_build[0] and module.build[0].terraform_data.docker_cleanup[0] -- these are terraform_data build triggers that replace when image URI changes; unrelated to OAC and expected when running plan with a placeholder URI outside CI.

No unexpected resource churn. The Lambda URL itself is an in-place update (auth_type change), not a replacement.

Risk callouts

  • Dev cuts over on first merge+apply. The raw Lambda Function URL (https://33pz7pombdqwu3bdlxp4lqxyra0bsriy.lambda-url.us-east-1.on.aws) will return HTTP 403 for direct requests after apply -- this is the intended security posture. All traffic must go through CloudFront.
  • Staging and prod are gate-protected. Their lambda_allowed_origins uses .invalid TLD placeholders; any accidental terraform apply will fail fast on hostname resolution before touching live resources. Update to real CF domains before provisioning these envs.
  • CloudFront distribution takes 5-15 minutes to deploy. The terraform apply will block until the distribution is Deployed. Plan for this in maintenance windows.
  • lambda_allowed_origins for dev is now ["http://localhost:3000"] only. After apply, run terraform output cloudfront_domain_name and add that value to lambda_allowed_origins, then re-apply so CORS allows the CF origin. Without this second apply, browser requests from the CF domain will be rejected by Lambda's CORS policy (CORS is enforced at the app layer, separate from the IAM gate).

Roll-back plan

If the cut-over breaks something post-merge:

  1. In github-dev.tfvars, set enable_cdn = false and restore the Lambda Function URL in lambda_allowed_origins.
  2. Run terraform apply -- this destroys the CloudFront distribution and OAC, and flips auth_type back to NONE.
  3. The Lambda Function URL becomes directly accessible again within seconds.

No data migrations involved; roll-back is safe at any time.

Manual verification steps (post-deploy)

  1. terraform apply -var-file=github-dev.tfvars completes successfully.
  2. terraform output cloudfront_domain_name -- note the *.cloudfront.net domain.
  3. curl -I https://<cloudfront-domain>/health -- expect HTTP/2 200.
  4. curl -I https://33pz7pombdqwu3bdlxp4lqxyra0bsriy.lambda-url.us-east-1.on.aws/health -- expect HTTP/2 403 (Lambda URL now IAM-gated).
  5. Open the CloudFront URL in a browser, log in, confirm the dashboard loads.
  6. Add the CF domain to lambda_allowed_origins in github-dev.tfvars and re-apply to fix CORS for browser fetch calls.

Closes LeanerCloud/cloud-commitments-platform#16
Refs #424

Flip enable_cdn = true in all three env tfvars (dev, staging, prod).
The compute.tf local already derives lambda_function_url_auth_type =
"AWS_IAM" when enable_cdn = true, and frontend.tf sets enable_oac =
true for the Lambda compute path, so a single flag flip activates:
  - aws_cloudfront_origin_access_control.lambda (sigv4, always-sign)
  - aws_lambda_function_url.main auth_type NONE -> AWS_IAM
  - aws_lambda_permission.function_url_cloudfront scoped to the
    distribution ARN

Dev: remove raw Lambda Function URL from lambda_allowed_origins (now
behind CloudFront); add post-apply note to set the CF domain.
Staging/prod: keep .invalid placeholders (envs not provisioned yet);
replace TODO with explicit pre-apply checklist.

terraform validate: Success. terraform fmt -check: clean (all envs).
terraform plan (dev only): 7 to add, 3 to change, 4 to destroy
(the 4 destroys are docker_build/cleanup terraform_data replaces
triggered by the placeholder image URI, unrelated to OAC).

Closes #575
@cristim cristim added triaged Item has been triaged priority/p1 Next up; this sprint severity/high Significant harm urgency/this-sprint Within the current sprint impact/all-users Affects every user effort/m Days type/security Security finding labels May 28, 2026
@coderabbitai

coderabbitai Bot commented May 28, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@cristim, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 47 minutes and 44 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3415e453-542a-4a90-b0af-67c402355d13

📥 Commits

Reviewing files that changed from the base of the PR and between 4956d66 and ce088a3.

📒 Files selected for processing (3)
  • terraform/environments/aws/github-dev.tfvars
  • terraform/environments/aws/github-prod.tfvars
  • terraform/environments/aws/github-staging.tfvars
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sec/575-aws-iam-cdn-oac

Comment @coderabbitai help to get the list of available commands and usage tips.

@cristim

cristim commented May 28, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cristim

cristim commented May 30, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented May 30, 2026

Copy link
Copy Markdown
Contributor

Rate Limit Exceeded

@cristim have exceeded the limit for the number of chat messages per hour. Please wait 54 minutes and 23 seconds before sending another message.

@cristim cristim closed this May 31, 2026
@cristim
cristim deleted the sec/575-aws-iam-cdn-oac branch June 3, 2026 21:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/m Days impact/all-users Affects every user priority/p1 Next up; this sprint severity/high Significant harm triaged Item has been triaged type/security Security finding urgency/this-sprint Within the current sprint

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant