Fail closed for public tenant DB startup

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-05-19 14:25:05 -05:00
1 parent bb076c6e93
commit 059051649a
2 files changed
+55

No files matched your search

@@ -216,6 +216,35 @@ describe("startServer feedback export wiring", () => {
serverPort: 3210,
});
});
it("refuses authenticated public startup without an external database URL", async () => {
loadConfigMock.mockReturnValue(buildTestConfig({
deploymentExposure: "public",
authBaseUrlMode: "explicit",
authPublicBaseUrl: "https://tenant.example.com",
databaseMode: "embedded-postgres",
databaseUrl: undefined,
}));
await expect(startServer()).rejects.toThrow(
"authenticated public deployments require DATABASE_URL or config.database.connectionString",
);
expect(createDbMock).not.toHaveBeenCalled();
});
it("refuses authenticated public startup when DATABASE_URL is not a postgres URL", async () => {
loadConfigMock.mockReturnValue(buildTestConfig({
deploymentExposure: "public",
authBaseUrlMode: "explicit",
authPublicBaseUrl: "https://tenant.example.com",
databaseUrl: "secret://paperclip-cloud/stacks/alpha/database/runtime-url",
}));
await expect(startServer()).rejects.toThrow(
"authenticated public deployments require DATABASE_URL to be a postgres/postgresql connection string",
);
expect(createDbMock).not.toHaveBeenCalled();
});
});
describe("startServer authenticated auth origin setup", () => {
+26
View File
@@ -187,6 +187,31 @@ export async function startServer(): Promise<StartedServer> {
return normalized === "127.0.0.1" || normalized === "localhost" || normalized === "::1";
}
function isPostgresConnectionString(connectionString: string): boolean {
try {
const parsed = new URL(connectionString);
return parsed.protocol === "postgres:" || parsed.protocol === "postgresql:";
} catch {
return false;
}
}
function assertCloudDatabaseContract(): void {
if (config.deploymentMode !== "authenticated" || config.deploymentExposure !== "public") {
return;
}
if (!config.databaseUrl) {
throw new Error(
"authenticated public deployments require DATABASE_URL or config.database.connectionString; refusing embedded PostgreSQL fallback",
);
}
if (!isPostgresConnectionString(config.databaseUrl)) {
throw new Error(
"authenticated public deployments require DATABASE_URL to be a postgres/postgresql connection string",
);
}
}
function rewriteLocalUrlPort(rawUrl: string | undefined, port: number): string | undefined {
if (!rawUrl) return undefined;
try {
@@ -270,6 +295,7 @@ export async function startServer(): Promise<StartedServer> {
let startupDbInfo:
| { mode: "external-postgres"; connectionString: string }
| { mode: "embedded-postgres"; dataDir: string; port: number };
assertCloudDatabaseContract();
if (config.databaseUrl) {
const migrationUrl = config.databaseMigrationUrl ?? config.databaseUrl;
migrationSummary = await ensureMigrations(migrationUrl, "PostgreSQL");