Skip to content
Merged
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
18 changes: 18 additions & 0 deletions apps/server/src/auth/EnvironmentAuthPolicy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,24 @@ it.layer(NodeServices.layer)("EnvironmentAuthPolicy.layer", (it) => {
),
);

it.effect("uses remote-reachable policy when Tailscale Serve exposes a loopback host", () =>
Effect.gen(function* () {
const policy = yield* EnvironmentAuthPolicy.EnvironmentAuthPolicy;
const descriptor = yield* policy.getDescriptor();

expect(descriptor.policy).toBe("remote-reachable");
expect(descriptor.bootstrapMethods).toEqual(["one-time-token"]);
}).pipe(
Effect.provide(
makeEnvironmentAuthPolicyLayer({
mode: "web",
host: "127.0.0.1",
tailscaleServeEnabled: true,
}),
),
),
);

it.effect("uses remote-reachable policy for non-loopback web hosts", () =>
Effect.gen(function* () {
const policy = yield* EnvironmentAuthPolicy.EnvironmentAuthPolicy;
Expand Down
5 changes: 4 additions & 1 deletion apps/server/src/auth/EnvironmentAuthPolicy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ export class EnvironmentAuthPolicy extends Context.Service<

export const make = Effect.gen(function* () {
const config = yield* ServerConfig.ServerConfig;
const isRemoteReachable = isWildcardHost(config.host) || !isLoopbackHost(config.host);
// Tailscale Serve proxies the loopback-bound backend onto the tailnet, so the
// server is remotely reachable even though config.host stays on 127.0.0.1.
const isRemoteReachable =
config.tailscaleServeEnabled || isWildcardHost(config.host) || !isLoopbackHost(config.host);

const policy =
config.mode === "desktop"
Expand Down
Loading