Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/wise-pandas-warn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@cloudflare/workers-utils": patch
"wrangler": patch
---

Warn when `CLOUDFLARE_COMPLIANCE_REGION` overrides a conflicting configured compliance region

Wrangler now explains that the environment variable takes precedence and continues using its value instead of rejecting the command.
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import path from "node:path";
import { dedent } from "ts-dedent";
import { UserError } from "../errors";
import { getGlobalConfigPath } from "../global-wrangler-config-path";
import {
getBooleanEnvironmentVariableFactory,
Expand Down Expand Up @@ -101,20 +99,6 @@ export const getCloudflareComplianceRegion = (
complianceConfig: ComplianceConfig
) => {
const complianceRegionFromEnv = getCloudflareComplianceRegionFromEnv();
if (
complianceRegionFromEnv !== undefined &&
complianceConfig?.compliance_region !== undefined &&
complianceRegionFromEnv !== complianceConfig.compliance_region
) {
throw new UserError(
dedent`
The compliance region has been set to different values in two places:
- \`CLOUDFLARE_COMPLIANCE_REGION\` environment variable: \`${complianceRegionFromEnv}\`
- \`compliance_region\` configuration property: \`${complianceConfig.compliance_region}\`
`,
{ telemetryMessage: false }
);
}
return (
complianceRegionFromEnv || complianceConfig?.compliance_region || "public"
);
Comment thread
edmundhung marked this conversation as resolved.
Comment on lines 102 to 104

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Commands that only work in the public region can now silently talk to the FedRAMP endpoint

Commands that declare they only support the public region now have that declaration silently overridden by the environment variable (complianceRegionFromEnv || complianceConfig?.compliance_region at packages/workers-utils/src/environment-variables/misc-variables.ts:102-104) with no error or warning, so those commands quietly send their requests to the FedRAMP High servers instead.
Impact: Users with the FedRAMP environment variable set will see Pages, tail and similar commands fail or behave unexpectedly against the wrong servers, with no message explaining why.

Why the public-only marker is no longer honoured

Many call sites pass the COMPLIANCE_REGION_CONFIG_PUBLIC sentinel (packages/workers-utils/src/environment-variables/misc-variables.ts:75-79), documented as "Used for commands that explicitly do not support compliance regions other than 'public'" — e.g. packages/wrangler/src/tail/createTail.ts:86, packages/wrangler/src/pages/upload.ts:116, packages/wrangler/src/api/pages/deploy.ts:158.

Previously, when CLOUDFLARE_COMPLIANCE_REGION=fedramp_high was set, the removed conflict check threw a UserError, so the user was told the command could not run in that region. After this PR the env value simply wins, and getComplianceRegionSubdomain returns .fed, so requests go to api.fed.cloudflare.com for commands that explicitly do not support it.

The new warning added in packages/wrangler/src/config/index.ts:72-89 only fires when config.compliance_region is set in the user's config file during readConfig/readPagesConfig; it never covers the sentinel path, so the override is completely silent here.

Prompt for agents
Removing the conflict check in getCloudflareComplianceRegion means the CLOUDFLARE_COMPLIANCE_REGION environment variable now silently overrides COMPLIANCE_REGION_CONFIG_PUBLIC, the sentinel used by commands (Pages commands, tail, etc.) that explicitly do not support any region other than "public". Those commands will now issue requests against api.fed.cloudflare.com with no error or warning. Consider distinguishing the explicit "public-only" sentinel from a user-configured compliance_region: either keep erroring (or at least warn) when the env var conflicts with the public-only sentinel, or have those call sites bypass env resolution entirely so they always resolve to "public".
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread
devin-ai-integration[bot] marked this conversation as resolved.
Comment on lines 100 to 104

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Account info command reports the wrong source for the compliance region

The compliance region source shown by the account info output is chosen purely from the configured value (complianceConfig?.compliance_region at packages/wrangler/src/user/whoami.ts:98) even though the environment variable now wins, so users are told the region came from their configuration file when it actually came from the environment.
Impact: Someone checking which compliance region they are operating in sees a misleading explanation of where that region came from, making a misconfigured environment variable hard to spot.

How removing the conflict error exposes the mislabelling in printComplianceRegion

Before this PR, getCloudflareComplianceRegion threw a UserError whenever CLOUDFLARE_COMPLIANCE_REGION and compliance_region disagreed, so printComplianceRegion (packages/wrangler/src/user/whoami.ts:95-105) could never be reached with conflicting values. Now the env var silently wins (packages/workers-utils/src/environment-variables/misc-variables.ts:100-105). With compliance_region: "public" in config and CLOUDFLARE_COMPLIANCE_REGION=fedramp_high, complianceRegion resolves to fedramp_high, but since complianceConfig.compliance_region is truthy the message says the region is set "via the Wrangler configuration".

A fix would be to compare the resolved region against the configured one (as logWarningsIfComplianceRegionIsOverridden in packages/wrangler/src/config/index.ts:72-89 does) and attribute the source to the environment variable when they differ.

(Refers to lines 100-105)

Prompt for agents
In packages/wrangler/src/user/whoami.ts, printComplianceRegion determines the "source" of the compliance region by checking whether complianceConfig.compliance_region is set. Previously a conflict between CLOUDFLARE_COMPLIANCE_REGION and the configured compliance_region threw a UserError, so a conflicting state was unreachable. After this PR the environment variable silently takes precedence, so when the config sets one region and the env var another, whoami reports the resolved (env-var) region but attributes it to the Wrangler configuration. Update the source attribution so it reflects which value actually won — e.g. attribute to the environment variable whenever the resolved region differs from the configured one, or when the env var is set.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines 100 to 104

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟨 Conflicting compliance region settings no longer block the command, allowing FedRAMP-configured projects to target the public region

The hard error that previously stopped Wrangler when CLOUDFLARE_COMPLIANCE_REGION disagreed with the configured compliance_region was removed (packages/workers-utils/src/environment-variables/misc-variables.ts:100-105), so a project explicitly configured for fedramp_high will now silently deploy against the public API endpoints whenever a stray or attacker-influenced environment variable sets public, downgraded to only a warning emitted at config-read time (packages/wrangler/src/config/index.ts:72-89).

(Refers to lines 100-105)

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Expand Down
18 changes: 11 additions & 7 deletions packages/wrangler/src/__tests__/deploy/environments.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -451,19 +451,23 @@ describe("deploy", () => {
await runWrangler("deploy ./index.js");
});

it("should error if the region is set in both env var and configured, and they conflict", async ({
it("should warn and use the env var if it conflicts with the configured region", async ({
expect,
}) => {
vi.stubEnv("CLOUDFLARE_COMPLIANCE_REGION", "public");
writeWranglerConfig({ compliance_region: "fedramp_high" });
writeWorkerSource();
mockUploadWorkerRequest({
expectedBaseUrl: "api.cloudflare.com",
});
mockSubDomainRequest();
mockGetWorkerSubdomain({ enabled: true });

await expect(runWrangler("deploy ./index.js")).rejects
.toThrowErrorMatchingInlineSnapshot(`
[Error: The compliance region has been set to different values in two places:
- \`CLOUDFLARE_COMPLIANCE_REGION\` environment variable: \`public\`
- \`compliance_region\` configuration property: \`fedramp_high\`]
`);
await runWrangler("deploy ./index.js");

expect(std.warn).toContain(
'The compliance region was resolved to "public" from the `CLOUDFLARE_COMPLIANCE_REGION` environment variable, which takes precedence over the configured value "fedramp_high".'
);
});

it("should not error if the region is set in both env var and configured, and they are the same", async () => {
Expand Down
23 changes: 23 additions & 0 deletions packages/wrangler/src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
configFileName,
experimental_readRawConfig,
FatalError,
getCloudflareComplianceRegion,
isPagesConfig,
normalizeAndValidateConfig,
UserError,
Expand Down Expand Up @@ -68,6 +69,25 @@ async function logWarningsWithUpgradeHint(
}
}

function logWarningsIfComplianceRegionIsOverridden(
config: Config,
hideWarnings: boolean | undefined
): void {
const configuredRegion = config.compliance_region;
if (hideWarnings || configuredRegion === undefined) {
return;
}

const resolvedRegion = getCloudflareComplianceRegion(config);
if (resolvedRegion === configuredRegion) {
return;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: readConfig is invoked multiple times within some commands (e.g. ConfigController re-reads on file changes during wrangler dev), so this warning may be emitted repeatedly in a single session. This matches the existing behaviour of logWarningsWithUpgradeHint, so it may be acceptable, but if you want it shown once, consider de-duplicating.


logger.once.warn(
`The compliance region was resolved to "${resolvedRegion}" from the \`CLOUDFLARE_COMPLIANCE_REGION\` environment variable, which takes precedence over the configured value "${configuredRegion}".`
);
}

/**
* Carries the validated `Config` alongside the
* watcher dependency set and the normalised type-generation settings.
Expand Down Expand Up @@ -123,6 +143,7 @@ export async function readNewConfig(
);

void logWarningsWithUpgradeHint(diagnostics, options.hideWarnings);
logWarningsIfComplianceRegionIsOverridden(config, options.hideWarnings);
if (diagnostics.hasErrors()) {
throw new UserError(diagnostics.renderErrors(), {
telemetryMessage: "new-config worker validation failed",
Expand Down Expand Up @@ -175,6 +196,7 @@ export function readConfig(
);

void logWarningsWithUpgradeHint(diagnostics, options?.hideWarnings);
logWarningsIfComplianceRegionIsOverridden(config, options.hideWarnings);
if (diagnostics.hasErrors()) {
throw new UserError(diagnostics.renderErrors(), {
telemetryMessage: "config wrangler validation failed",
Expand Down Expand Up @@ -238,6 +260,7 @@ export function readPagesConfig(
);

void logWarningsWithUpgradeHint(diagnostics, options.hideWarnings);
logWarningsIfComplianceRegionIsOverridden(config, options.hideWarnings);
if (diagnostics.hasErrors()) {
throw new UserError(diagnostics.renderErrors(), {
telemetryMessage: "config pages validation failed",
Expand Down
Loading