diff --git a/apps/alerting/alchemy.run.ts b/apps/alerting/alchemy.run.ts index 295badc21..d4f11fce2 100644 --- a/apps/alerting/alchemy.run.ts +++ b/apps/alerting/alchemy.run.ts @@ -100,7 +100,13 @@ export const createAlertingWorker = ({ stage, mapleDb, chatFlue }: CreateAlertin MAPLE_APP_BASE_URL: process.env.MAPLE_APP_BASE_URL?.trim() || "https://app.maple.dev", EMAIL_FROM: process.env.EMAIL_FROM?.trim() || "Maple ", ...optionalPlain("MAPLE_ENDPOINT"), - ...optionalPlain("MAPLE_ENVIRONMENT", resolveDeploymentEnvironment(stage)), + // Derived from the stage, deliberately NOT `optionalPlain` — that helper + // lets `process.env` win over the fallback, so a stray + // MAPLE_ENVIRONMENT=production in a pr-N deploy environment would open + // both email gates at once (the worker's scheduled() early-return and + // EmailService.emailAllowed both derive from this one value), leaving + // the prd-only EMAIL binding as the sole guard. + MAPLE_ENVIRONMENT: resolveDeploymentEnvironment(stage), // Non-prod stages skip all crons (they share live org data via the prod // DB); set to "1" on a stage to deliberately exercise crons there. ...optionalPlain("MAPLE_ALERTING_ALLOW_NONPROD"), diff --git a/apps/api/alchemy.run.ts b/apps/api/alchemy.run.ts index 6c49cc87c..50e985d0c 100644 --- a/apps/api/alchemy.run.ts +++ b/apps/api/alchemy.run.ts @@ -208,7 +208,11 @@ export const createMapleApi = ({ stage, domains }: CreateMapleApiOptions) => SERVICE_OPERATIONS_ROLLUP_ENABLED: process.env.SERVICE_OPERATIONS_ROLLUP_ENABLED?.trim() || "false", ...optionalPlain("MAPLE_ENDPOINT"), - ...optionalPlain("MAPLE_ENVIRONMENT", resolveDeploymentEnvironment(stage)), + // Derived from the stage, deliberately NOT `optionalPlain` — that helper + // lets `process.env` win over the fallback, so a stray + // MAPLE_ENVIRONMENT=production in a pr-N deploy environment would open + // EmailService.emailAllowed on a stage that shares live org data. + MAPLE_ENVIRONMENT: resolveDeploymentEnvironment(stage), ...optionalPlain("COMMIT_SHA"), MAPLE_INGEST_KEY: Redacted.make(requireEnv("MAPLE_OTEL_INGEST_KEY")), ...optionalSecret("MAPLE_ROOT_PASSWORD"),