Skip to content

Commit

Permalink
Move proxy shared secret to where it is needed
Browse files Browse the repository at this point in the history
This avoids prop drilling.
  • Loading branch information
petebacondarwin committed Dec 20, 2023
1 parent 97b4851 commit 86029d3
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 22 deletions.
8 changes: 0 additions & 8 deletions packages/wrangler/src/dev.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { randomUUID } from "node:crypto";
import path from "node:path";
import { isWebContainer } from "@webcontainer/env";
import { watch } from "chokidar";
Expand Down Expand Up @@ -39,11 +38,6 @@ import type {
} from "./yargs-types";
import type { Json } from "miniflare";

// This is a shared secret between the Proxy Worker and the User Worker
// so that the User Worker can trust the MF-Original-Url header and set the Host
// header accordingly.
const unsafeProxySharedSecret = randomUUID();

export function devOptions(yargs: CommonYargsArgv) {
return (
yargs
Expand Down Expand Up @@ -489,7 +483,6 @@ export async function startDev(args: StartDevOptions) {
sendMetrics={configParam.send_metrics}
testScheduled={args.testScheduled}
projectRoot={projectRoot}
unsafeProxySharedSecret={unsafeProxySharedSecret}
/>
);
}
Expand Down Expand Up @@ -632,7 +625,6 @@ export async function startApiDev(args: StartDevOptions) {
testScheduled: args.testScheduled,
disableDevRegistry: args.disableDevRegistry ?? false,
projectRoot,
unsafeProxySharedSecret: unsafeProxySharedSecret,
});
}

Expand Down
2 changes: 0 additions & 2 deletions packages/wrangler/src/dev/dev.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,6 @@ export type DevProps = {
sendMetrics: boolean | undefined;
testScheduled: boolean | undefined;
projectRoot: string | undefined;
unsafeProxySharedSecret: string;
};

export function DevImplementation(props: DevProps): JSX.Element {
Expand Down Expand Up @@ -442,7 +441,6 @@ function DevSession(props: DevSessionProps) {
onReady={announceAndOnReady}
enablePagesAssetsServiceBinding={props.enablePagesAssetsServiceBinding}
sourceMapPath={bundle?.sourceMapPath}
unsafeProxySharedSecret={props.unsafeProxySharedSecret}
/>
) : (
<Remote
Expand Down
5 changes: 2 additions & 3 deletions packages/wrangler/src/dev/local.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ export interface LocalProps {
enablePagesAssetsServiceBinding?: EnablePagesAssetsServiceBindingOptions;
testScheduled?: boolean;
sourceMapPath: string | undefined;
unsafeProxySharedSecret: string;
}

// TODO(soon): we should be able to remove this function when we fully migrate
Expand Down Expand Up @@ -93,7 +92,6 @@ export async function localPropsToConfigBundle(
localUpstream: props.localUpstream,
inspect: props.inspect,
serviceBindings,
unsafeProxySharedSecret: props.unsafeProxySharedSecret,
};
}

Expand Down Expand Up @@ -180,7 +178,8 @@ function useLocalWorker(props: LocalProps) {
},
headers: {
// Passing this signature from Proxy Worker allows the User Worker to trust the request.
"MF-Proxy-Shared-Secret": props.unsafeProxySharedSecret,
"MF-Proxy-Shared-Secret":
event.proxyToUserWorkerAuthenticationSecret,
},
liveReload: props.liveReload,
// in local mode, the logs are already being printed to the console by workerd but only for workers written in "module" format
Expand Down
23 changes: 16 additions & 7 deletions packages/wrangler/src/dev/miniflare.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import assert from "node:assert";
import { type UUID, randomUUID } from "node:crypto";
import { realpathSync } from "node:fs";
import path from "node:path";
import { Log, LogLevel, TypedEventTarget, Mutex, Miniflare } from "miniflare";
Expand Down Expand Up @@ -112,10 +113,6 @@ export interface ConfigBundle {
localUpstream: string | undefined;
inspect: boolean;
serviceBindings: Record<string, (_request: Request) => Promise<Response>>;
// The unsafeProxySharedSecret is given as a shared secret to the Proxy and User workers
// so that the User Worker can trust aspects of HTTP requests from the Proxy Worker
// if it provides the secret in a `MF-Proxy-Shared-Secret` header.
unsafeProxySharedSecret: string;
}

export class WranglerLog extends Log {
Expand Down Expand Up @@ -513,7 +510,8 @@ export function handleRuntimeStdio(stdout: Readable, stderr: Readable) {

async function buildMiniflareOptions(
log: Log,
config: ConfigBundle
config: ConfigBundle,
proxyToUserWorkerAuthenticationSecret: UUID
): Promise<{ options: MiniflareOptions; internalObjects: CfDurableObject[] }> {
if (config.crons.length > 0) {
logger.warn("Miniflare 3 does not support CRON triggers yet, ignoring...");
Expand Down Expand Up @@ -558,7 +556,7 @@ async function buildMiniflareOptions(
inspectorPort: config.inspect ? config.inspectorPort : undefined,
liveReload: config.liveReload,
upstream,
unsafeProxySharedSecret: config.unsafeProxySharedSecret,
unsafeProxySharedSecret: proxyToUserWorkerAuthenticationSecret,

log,
verbose: logger.loggerLevel === "debug",
Expand All @@ -585,15 +583,19 @@ async function buildMiniflareOptions(
export interface ReloadedEventOptions {
url: URL;
internalDurableObjects: CfDurableObject[];
proxyToUserWorkerAuthenticationSecret: UUID;
}
export class ReloadedEvent extends Event implements ReloadedEventOptions {
readonly url: URL;
readonly internalDurableObjects: CfDurableObject[];
readonly proxyToUserWorkerAuthenticationSecret: UUID;

constructor(type: "reloaded", options: ReloadedEventOptions) {
super(type);
this.url = options.url;
this.internalDurableObjects = options.internalDurableObjects;
this.proxyToUserWorkerAuthenticationSecret =
options.proxyToUserWorkerAuthenticationSecret;
}
}

Expand All @@ -616,6 +618,10 @@ export type MiniflareServerEventMap = {
export class MiniflareServer extends TypedEventTarget<MiniflareServerEventMap> {
#log = buildLog();
#mf?: Miniflare;
// This is given as a shared secret to the Proxy and User workers
// so that the User Worker can trust aspects of HTTP requests from the Proxy Worker
// if it provides the secret in a `MF-Proxy-Shared-Secret` header.
#proxyToUserWorkerAuthenticationSecret = randomUUID();

// `buildMiniflareOptions()` is asynchronous, meaning if multiple bundle
// updates were submitted, the second may apply before the first. Therefore,
Expand All @@ -627,7 +633,8 @@ export class MiniflareServer extends TypedEventTarget<MiniflareServerEventMap> {
try {
const { options, internalObjects } = await buildMiniflareOptions(
this.#log,
config
config,
this.#proxyToUserWorkerAuthenticationSecret
);
if (opts?.signal?.aborted) return;
if (this.#mf === undefined) {
Expand All @@ -640,6 +647,8 @@ export class MiniflareServer extends TypedEventTarget<MiniflareServerEventMap> {
const event = new ReloadedEvent("reloaded", {
url,
internalDurableObjects: internalObjects,
proxyToUserWorkerAuthenticationSecret:
this.#proxyToUserWorkerAuthenticationSecret,
});
this.dispatchEvent(event);
} catch (error: unknown) {
Expand Down
3 changes: 1 addition & 2 deletions packages/wrangler/src/dev/start-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,6 @@ export async function startDevServer(
usageModel: props.usageModel,
workerDefinitions,
sourceMapPath: bundle?.sourceMapPath,
unsafeProxySharedSecret: props.unsafeProxySharedSecret,
});

return {
Expand Down Expand Up @@ -415,7 +414,7 @@ export async function startLocalServer(
},
headers: {
// Passing this signature from Proxy Worker allows the User Worker to trust the request.
"MF-Proxy-Shared-Secret": props.unsafeProxySharedSecret,
"MF-Proxy-Shared-Secret": event.proxyToUserWorkerAuthenticationSecret,
},
liveReload: props.liveReload,
// in local mode, the logs are already being printed to the console by workerd but only for workers written in "module" format
Expand Down

0 comments on commit 86029d3

Please sign in to comment.