Configure Turso, Resend, Vercel, and GitHub for Concourse
This runbook configures the existing concourse Vercel project. It does not create a staging
environment or a custom domain.
concourse project.mail.tredis.dev verified for sending.conveyal/concourse.Keep these settings:
| Setting | Value |
|---|---|
| Project | concourse |
| Root directory | apps/concourse |
| Framework | Next.js |
| Node.js | 24.x |
| Function region | iad1 |
| Production URL | https://concourse-conveyal.vercel.app |
| Production branch | main |
Vercel Git deploys each main commit. Preview branches deploy through the same project.
Before you enable Rackspace schema operations, complete the Rackspace schema status record. The status record owns all current MySQL, firewall, account, Workflow, Blob, Connect, and GitHub evidence.
Keep all Rackspace values in the Production environment. The application keeps these operations disabled in Preview and Development environments.
Step 0 uses the permanent local probe through the approved laptop VPN. Run QA before production. The probe receives sensitive values only through masked, paste-enabled prompts. Do not put these values in command arguments, local environment files, or shell environment variables.
Store each persistent Step 0 report in a protected absolute directory outside this repository. The probe removes temporary plaintext after review, but it never removes a persistent report automatically.
Step 1 of the implementation plan cannot start while a hard gate in that runbook is incomplete.
Create one production database through the Vercel Marketplace integration. Keep its default
24-hour recovery window. Connect it only to the Production environment of the concourse project.
Vercel stores and injects its TURSO_DATABASE_URL and TURSO_AUTH_TOKEN values.
Keep the Turso Marketplace installation on its free Starter plan. Record its Vercel installation ID
as VERCEL_TURSO_INSTALLATION_ID. Preview workflows use the Vercel Marketplace API to create and
remove resources. They do not need a Turso account or Platform API token.
Set these GitHub variables:
| Scope | Variable |
|---|---|
| Repository | VERCEL_PROJECT_ID, VERCEL_TEAM_ID, VERCEL_TURSO_INSTALLATION_ID |
Set these GitHub secrets:
| Scope | Secret |
|---|---|
| Repository | VERCEL_TOKEN, AUTH_AUDIT_FINGERPRINT_SECRET, BETTER_AUTH_SECRETS, PREVIEW_ADMIN_EMAIL, PREVIEW_ADMIN_NAME, PREVIEW_ADMIN_PASSWORD |
| Production environment | Optional VERCEL_AUTOMATION_BYPASS_SECRET |
The Vercel token must manage Marketplace resources, environment variables, and preview redeployments for the Conveyal team. Store it only in GitHub. No database credential is stored in GitHub.
Use preview-only values for the repository authentication secrets. Configure the same two values in Vercel's Preview environment. Do not reuse the production authentication secrets.
Use the existing Resend account. Add mail.tredis.dev to that account and use Resend's Vercel DNS
setup to verify it. Create a sending-only API key restricted to mail.tredis.dev. Store the key as
the sensitive Vercel variable RESEND_API_KEY in the Production and Preview environments.
Configure production with:
EMAIL_PROVIDER=resend
AUTH_EMAIL_FROM=concourse@mail.tredis.dev
RESEND_TEST_RECIPIENT=<approved test address>The application rejects every To, CC, and BCC recipient that does not match
RESEND_TEST_RECIPIENT. Keep general-user email disabled until this allowlist policy is
deliberately replaced.
Local development and browser tests continue to use Maildev.
Configure the production Vercel environment with the Turso Marketplace URL and token, the Resend key and values above, and these application values:
AUTH_BASE_URL=https://concourse-conveyal.vercel.app
AUTH_TRUSTED_PROXY_IP_HEADERS=x-forwarded-forAlso configure strong values for AUTH_AUDIT_FINGERPRINT_SECRET and BETTER_AUTH_SECRETS. Never
copy production secrets into a preview, log, issue, pull request, or local environment file.
Configure the Preview environment with separate strong values for those two secrets, the Resend
settings, and AUTH_TRUSTED_PROXY_IP_HEADERS=x-forwarded-for. Enable Vercel system environment
variables. The application uses VERCEL_BRANCH_URL as Better Auth's stable preview origin. The
preview database workflow adds only the branch-specific Turso values.
.github/workflows/preview-database.yml accepts only pull requests whose head repository is
conveyal/concourse. It creates the free Marketplace resource concourse-pr-<number>. The workflow
temporarily connects that resource to Vercel's Development environment with a unique prefix, pulls
the credentials into an isolated temporary file, and disconnects the resource before any preview
deployment uses it. It then applies migrations, seeds fixtures, bootstraps the preview system
administrator, stores branch-specific Turso values in Vercel, and redeploys the first preview. Later
pushes reuse the same database.
The database token is sensitive after it becomes a branch variable. When the pull request closes,
the workflow removes the branch values and Marketplace resource. The daily preview-orphans.yml
workflow removes any missed resources. Fork pull requests never receive these credentials or
databases.
Add these two GitHub results as Vercel Deployment Checks that block production alias assignment:
CI / verify job.Concourse production migration commit status.Keep automatic production aliasing enabled. Vercel sends vercel.deployment.ready to GitHub. The
production workflow validates the repository, project, branch, and exact commit. It pulls the
integration-managed production database values into an isolated temporary file, deletes the file,
serializes migrations, checks the migration ledger and database, and calls the deployment readiness
endpoint. Vercel can assign the production alias only after both checks pass.
The Marketplace integration does not provide Turso Platform API access. The migration therefore uses the same database credential that Vercel manages for the application instead of a short-lived credential. Rotate that credential through the Marketplace resource when required.
After the first production migration succeeds, run the interactive administrator command with the production environment loaded:
pnpm auth:create-adminCreate the first systemAdmin. Do not put its password on a command line or in a workflow.
Use the Turso dashboard opened through Vercel Marketplace to perform recovery operations. The Marketplace workflow cannot automate point-in-time restores without Turso Platform API access. When the dashboard permits a temporary restore, apply no writes to the active production database, verify the restored schema and administrator record, and delete only the temporary restore database.
For later releases, use expand-contract migrations. Do not combine a destructive schema change with application code that still needs the old schema.
pnpm install --frozen-lockfile && pnpm verify passes on Linux CI.Configure Turso, Resend, Vercel, and GitHub for Concourse
This runbook configures the existing concourse Vercel project. It does not create a staging
environment or a custom domain.
concourse project.mail.tredis.dev verified for sending.conveyal/concourse.Keep these settings:
| Setting | Value |
|---|---|
| Project | concourse |
| Root directory | apps/concourse |
| Framework | Next.js |
| Node.js | 24.x |
| Function region | iad1 |
| Production URL | https://concourse-conveyal.vercel.app |
| Production branch | main |
Vercel Git deploys each main commit. Preview branches deploy through the same project.
Before you enable Rackspace schema operations, complete the Rackspace schema status record. The status record owns all current MySQL, firewall, account, Workflow, Blob, Connect, and GitHub evidence.
Keep all Rackspace values in the Production environment. The application keeps these operations disabled in Preview and Development environments.
Step 0 uses the permanent local probe through the approved laptop VPN. Run QA before production. The probe receives sensitive values only through masked, paste-enabled prompts. Do not put these values in command arguments, local environment files, or shell environment variables.
Store each persistent Step 0 report in a protected absolute directory outside this repository. The probe removes temporary plaintext after review, but it never removes a persistent report automatically.
Step 1 of the implementation plan cannot start while a hard gate in that runbook is incomplete.
Create one production database through the Vercel Marketplace integration. Keep its default
24-hour recovery window. Connect it only to the Production environment of the concourse project.
Vercel stores and injects its TURSO_DATABASE_URL and TURSO_AUTH_TOKEN values.
Keep the Turso Marketplace installation on its free Starter plan. Record its Vercel installation ID
as VERCEL_TURSO_INSTALLATION_ID. Preview workflows use the Vercel Marketplace API to create and
remove resources. They do not need a Turso account or Platform API token.
Set these GitHub variables:
| Scope | Variable |
|---|---|
| Repository | VERCEL_PROJECT_ID, VERCEL_TEAM_ID, VERCEL_TURSO_INSTALLATION_ID |
Set these GitHub secrets:
| Scope | Secret |
|---|---|
| Repository | VERCEL_TOKEN, AUTH_AUDIT_FINGERPRINT_SECRET, BETTER_AUTH_SECRETS, PREVIEW_ADMIN_EMAIL, PREVIEW_ADMIN_NAME, PREVIEW_ADMIN_PASSWORD |
| Production environment | Optional VERCEL_AUTOMATION_BYPASS_SECRET |
The Vercel token must manage Marketplace resources, environment variables, and preview redeployments for the Conveyal team. Store it only in GitHub. No database credential is stored in GitHub.
Use preview-only values for the repository authentication secrets. Configure the same two values in Vercel's Preview environment. Do not reuse the production authentication secrets.
Use the existing Resend account. Add mail.tredis.dev to that account and use Resend's Vercel DNS
setup to verify it. Create a sending-only API key restricted to mail.tredis.dev. Store the key as
the sensitive Vercel variable RESEND_API_KEY in the Production and Preview environments.
Configure production with:
EMAIL_PROVIDER=resend
AUTH_EMAIL_FROM=concourse@mail.tredis.dev
RESEND_TEST_RECIPIENT=<approved test address>The application rejects every To, CC, and BCC recipient that does not match
RESEND_TEST_RECIPIENT. Keep general-user email disabled until this allowlist policy is
deliberately replaced.
Local development and browser tests continue to use Maildev.
Configure the production Vercel environment with the Turso Marketplace URL and token, the Resend key and values above, and these application values:
AUTH_BASE_URL=https://concourse-conveyal.vercel.app
AUTH_TRUSTED_PROXY_IP_HEADERS=x-forwarded-forAlso configure strong values for AUTH_AUDIT_FINGERPRINT_SECRET and BETTER_AUTH_SECRETS. Never
copy production secrets into a preview, log, issue, pull request, or local environment file.
Configure the Preview environment with separate strong values for those two secrets, the Resend
settings, and AUTH_TRUSTED_PROXY_IP_HEADERS=x-forwarded-for. Enable Vercel system environment
variables. The application uses VERCEL_BRANCH_URL as Better Auth's stable preview origin. The
preview database workflow adds only the branch-specific Turso values.
.github/workflows/preview-database.yml accepts only pull requests whose head repository is
conveyal/concourse. It creates the free Marketplace resource concourse-pr-<number>. The workflow
temporarily connects that resource to Vercel's Development environment with a unique prefix, pulls
the credentials into an isolated temporary file, and disconnects the resource before any preview
deployment uses it. It then applies migrations, seeds fixtures, bootstraps the preview system
administrator, stores branch-specific Turso values in Vercel, and redeploys the first preview. Later
pushes reuse the same database.
The database token is sensitive after it becomes a branch variable. When the pull request closes,
the workflow removes the branch values and Marketplace resource. The daily preview-orphans.yml
workflow removes any missed resources. Fork pull requests never receive these credentials or
databases.
Add these two GitHub results as Vercel Deployment Checks that block production alias assignment:
CI / verify job.Concourse production migration commit status.Keep automatic production aliasing enabled. Vercel sends vercel.deployment.ready to GitHub. The
production workflow validates the repository, project, branch, and exact commit. It pulls the
integration-managed production database values into an isolated temporary file, deletes the file,
serializes migrations, checks the migration ledger and database, and calls the deployment readiness
endpoint. Vercel can assign the production alias only after both checks pass.
The Marketplace integration does not provide Turso Platform API access. The migration therefore uses the same database credential that Vercel manages for the application instead of a short-lived credential. Rotate that credential through the Marketplace resource when required.
After the first production migration succeeds, run the interactive administrator command with the production environment loaded:
pnpm auth:create-adminCreate the first systemAdmin. Do not put its password on a command line or in a workflow.
Use the Turso dashboard opened through Vercel Marketplace to perform recovery operations. The Marketplace workflow cannot automate point-in-time restores without Turso Platform API access. When the dashboard permits a temporary restore, apply no writes to the active production database, verify the restored schema and administrator record, and delete only the temporary restore database.
For later releases, use expand-contract migrations. Do not combine a destructive schema change with application code that still needs the old schema.
pnpm install --frozen-lockfile && pnpm verify passes on Linux CI.