Repository navigation
feat(website): add the email sign-in settings and ONE's SES roles - #48
Merged
Merged
Conversation
The website's sign-in by emailed code reads five settings. The stack now sets AUTH_EMAIL_FROM, mounts TURNSTILE_SECRET_KEY from a new secret whose placeholder version is a single space, and passes SES_ROLE_ARN, SES_REGION and TURNSTILE_SITE_KEY from variables that stay null until the values exist. Email sign-in stays off until all five are set. The revision waits for the placeholder version through readiness_dependencies, so the first apply cannot start a revision that mounts a secret with no version.
ONE's AWS account (961128127831, us-east-1) has one SES sender role per environment, and each trusts only that environment's runtime service account with its own token audience. The website stack's ses object sets SES_ROLE_ARN, SES_REGION and SES_TOKEN_AUDIENCE together, and both env.auto.tfvars files now set it to their role.
The widgets "DFO website staging" and "DFO website production" exist in the ONE Campaign Cloudflare account. Email sign-in turns on once each secret key is added as a version of its turnstile-secret-key secret.
Terraform Apply —
|
| Init | Validate | Apply |
|---|---|---|
| pass | pass | pass |
Show apply output
ephemeral.random_password.website_better_auth_secret: Opening...
ephemeral.random_password.website_caller_hmac_key: Opening...
ephemeral.random_password.website_caller_hmac_key: Opening complete after 0s
ephemeral.random_password.website_better_auth_secret: Opening complete after 0s
google_secret_manager_secret.website_turnstile_secret_key: Creating...
google_secret_manager_secret.website_turnstile_secret_key: Creation complete after 0s [id=projects/dev-fin-observatory/secrets/dfo-dev-website-staging-turnstile-secret-key]
google_secret_manager_secret_version.website_turnstile_secret_key_placeholder: Creating...
module.website_service.google_secret_manager_secret_iam_member.runtime_secret_access["dfo-dev-website-staging-turnstile-secret-key"]: Creating...
google_secret_manager_secret_version.website_turnstile_secret_key_placeholder: Creation complete after 1s [id=projects/41292283861/secrets/dfo-dev-website-staging-turnstile-secret-key/versions/1]
module.website_service.google_secret_manager_secret_iam_member.runtime_secret_access["dfo-dev-website-staging-turnstile-secret-key"]: Creation complete after 4s [id=projects/dev-fin-observatory/secrets/dfo-dev-website-staging-turnstile-secret-key/roles/secretmanager.secretAccessor/serviceAccount:dfo-dev-website-staging-run@dev-fin-observatory.iam.gserviceaccount.com]
module.website_service.google_cloud_run_v2_service.this: Modifying... [id=projects/dev-fin-observatory/locations/northamerica-northeast1/services/dfo-dev-website-staging]
module.website_service.google_cloud_run_v2_service.this: Still modifying... [id=projects/dev-fin-observatory/locations/...east1/services/dfo-dev-website-staging, 00m10s elapsed]
module.website_service.google_cloud_run_v2_service.this: Modifications complete after 12s [id=projects/dev-fin-observatory/locations/northamerica-northeast1/services/dfo-dev-website-staging]
ephemeral.random_password.website_better_auth_secret: Closing...
ephemeral.random_password.website_caller_hmac_key: Closing...
ephemeral.random_password.website_caller_hmac_key: Closing complete after 0s
ephemeral.random_password.website_better_auth_secret: Closing complete after 0s
Apply complete! Resources: 3 added, 1 changed, 0 destroyed.
Outputs:
database_endpoint_ip = "10.100.1.2"
database_host = "bbd723248b19.3niso0mm9bket.northamerica-northeast1.sql.goog"
database_name = "website-staging"
database_runtime_user = "dfo-dev-website-staging-run@dev-fin-observatory.iam"
migrate_job_name = "dfo-dev-website-staging-migrate"
migrator_database_user = "dfo-dev-website-stg-migrator@dev-fin-observatory.iam"
migrator_service_account = "dfo-dev-website-stg-migrator@dev-fin-observatory.iam.gserviceaccount.com"
runtime_service_account = "dfo-dev-website-staging-run@dev-fin-observatory.iam.gserviceaccount.com"
service_name = "dfo-dev-website-staging"
service_url = "https://dfo-dev-website-staging-zms5lj4zhq-nn.a.run.app"
website_url = "https://dfo-dev-website-staging-zms5lj4zhq-nn.a.run.app"Stack website · f04a835 · @jm-rivera · run
This branch was successfully deployed
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.
Adds the settings that the website's sign-in by emailed code reads (DevelopmentFinanceObservatory/website#28) to the website stack in dev and prod, and points each environment at its SES sender role in ONE's AWS account (
961128127831,us-east-1).AUTH_EMAIL_FROMis fixed atDFO Studio <studio@developmentfinance.org>, the one address the roles may send as. The newsesobject setsSES_ROLE_ARN,SES_REGIONandSES_TOKEN_AUDIENCEtogether, and a validation refuses one whose ARN, region or audience is malformed or blank. Each role trusts only its environment's runtime service account, and only with that environment's audience:dfo-dev-website-staging-runwithdevelopment-finance-observatory-staging, anddfo-prod-website-runwithdevelopment-finance-observatory-production. Bothenv.auto.tfvarsfiles set their role.TURNSTILE_SITE_KEYcomes fromturnstile_site_key, which defaults to null and leaves the env var out. Both tfvars files set it to the site key of their widget in the ONE Campaign Cloudflare account, "DFO website staging" for the run.app host and "DFO website production" fordevelopmentfinance.org.TURNSTILE_SECRET_KEYmountslatestfrom a new secret,<website name>-turnstile-secret-key, ininfra/stacks/website/email_sign_in.tf. Its placeholder first version is a single space, which the app trims to blank and reads as unset, so email sign-in stays off whatever else is set until the real key is added as a new version. The service'sreadiness_dependenciesnames that placeholder version, so the first apply cannot start a revision before the secret has a version to read.Email sign-in stays off after this merges, until each widget's secret key is added as a version of
<website name>-turnstile-secret-keyand the service rolls onto a new revision. Each environment's README "Email sign-in" section has the command that adds the Turnstile secret key, the role and audience each service uses, and when a revision needs a manual roll. The deployed website ignores all six settings, so this can merge before website#28. The DKIM and DMARC records for the sending domain are in #57.Testing:
terraform fmt -checkpasses, andterraform validatepasses in both environments. Aterraform plan -lock=falseagainst dev state shows 3 to add (the secret, its placeholder version and the runtime account's accessor grant) and 1 in-place change to the service, which gainsAUTH_EMAIL_FROM,SES_ROLE_ARN,SES_REGION,SES_TOKEN_AUDIENCE,TURNSTILE_SITE_KEY,TURNSTILE_SECRET_KEYand the readiness annotation. Plans with a malformed ARN, an empty region, a blank audience or a missing attribute are refused. No token has been exchanged at AWS STS against either role yet.