// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0 // The deployment contract per process (decision AT-D20): which Postgres role each process may // hold, and what happens when it is handed one it may not. import { describe, expect, it } from "vitest" import { loadAppEnv, roleOf } from "../config/src/env.js" import { assertBoundByRowLevelSecurity, assertOwnsSchema } from "../config/src/postgres.js" const base = { CONUSAI_API_URL: "https://api.example.test/api", CONUSAI_API_TOKEN: "token", CONUSAI_PROJECT_ID: "42", CONUSAI_ORG_ID: "9", CONUSAI_ORG_SLUG: "acme", POSTGRES_URL: "postgresql://app_app:secret@db:5432/app", POSTGRES_READER_URL: "postgresql://app_reader:secret@db:5432/app", } describe("the deployment contract", () => { it("gives web and worker the runtime role and the global reader", () => { for (const service of ["web", "worker"] as const) { const env = loadAppEnv(service, { ...base }) expect(env.postgres?.runtime).toContain("app_app") expect(env.postgres?.reader).toContain("app_reader") expect(env.postgres?.owner).toBeUndefined() } }) it("refuses to start web or worker with the owner's URL", () => { for (const service of ["web", "worker"] as const) { expect(() => loadAppEnv(service, { ...base, POSTGRES_MIGRATE_URL: "postgresql://app_owner:s@db:5432/app" }), ).toThrow(/POSTGRES_MIGRATE_URL is set for the \w+ process/) } }) it("requires the platform organization slug for production web and worker usage billing, but not migrate", () => { const { CONUSAI_ORG_SLUG: _slug, ...withoutSlug } = base for (const service of ["web", "worker"] as const) { expect(() => loadAppEnv(service, { ...withoutSlug })).toThrow(/CONUSAI_ORG_SLUG/) } expect(() => loadAppEnv("migrate", { ...withoutSlug, POSTGRES_MIGRATE_URL: "postgresql://app_owner:secret@db:5432/app", }), ).not.toThrow() }) it("refuses the migrate job without the owner's URL, naming postgres.migrate", () => { expect(() => loadAppEnv("migrate", { ...base })).toThrow(/declares postgres\.migrate/) }) it("refuses the migrate job when two of the three URLs name one role", () => { expect(() => loadAppEnv("migrate", { ...base, POSTGRES_MIGRATE_URL: base.POSTGRES_URL })).toThrow( /three separate logins/, ) }) it("names the Postgres service to link when a URL is missing", () => { const { POSTGRES_URL: _dropped, ...without } = base expect(() => loadAppEnv("web", without)).toThrow(/link a Postgres service/) }) it("refuses a runtime URL and a reader URL that name one login", () => { expect(() => loadAppEnv("web", { ...base, POSTGRES_READER_URL: base.POSTGRES_URL })).toThrow(/name the same role/) }) it("refuses a role name that is not a plain identifier", () => { expect(roleOf("postgresql://app_reader:s@db:5432/app")).toBe("app_reader") expect(() => roleOf("postgresql://app%2Dreader:s@db:5432/app")).toThrow(/not a plain identifier/) }) it("loads Convex server credentials and refuses missing or misplaced credentials", () => { const convex = { ...base, CONVEX_SELF_HOSTED_URL: "http://convex:3210", CONVEX_SELF_HOSTED_ADMIN_KEY: "server-only-test-key", } const loaded = loadAppEnv("web", convex, "convex") expect(loaded.convex).toEqual({ url: "http://convex:3210", adminKey: "server-only-test-key" }) expect(loaded).not.toHaveProperty("postgres") const { CONVEX_SELF_HOSTED_ADMIN_KEY: _key, ...missingKey } = convex expect(() => loadAppEnv("web", missingKey, "convex")).toThrow(/CONVEX_SELF_HOSTED_ADMIN_KEY/) expect(() => loadAppEnv("migrate", convex, "convex")).toThrow(/not supported by the Convex app runtime/) }) }) describe("the role the database answers with", () => { const facts = { role: "app_app", ownedTables: 0, bypassesRowLevelSecurity: false, isSuperuser: false, ownsSchema: false, } it("accepts a role that owns nothing and bypasses nothing", () => { expect(assertBoundByRowLevelSecurity(facts, "POSTGRES_URL")).toBe(facts) }) it("refuses a connection that owns a table, bypasses row-level security or is a superuser", () => { expect(() => assertBoundByRowLevelSecurity({ ...facts, ownedTables: 3 }, "POSTGRES_URL")).toThrow(/owns 3 table/) expect(() => assertBoundByRowLevelSecurity({ ...facts, bypassesRowLevelSecurity: true }, "POSTGRES_URL")).toThrow( /BYPASSRLS/, ) expect(() => assertBoundByRowLevelSecurity({ ...facts, isSuperuser: true }, "POSTGRES_READER_URL")).toThrow( /superuser/, ) }) it("refuses a migrate job that does not own schema public", () => { expect(() => assertOwnsSchema(facts, "POSTGRES_MIGRATE_URL")).toThrow(/does not own schema public/) expect(assertOwnsSchema({ ...facts, role: "app_owner", ownsSchema: true }, "POSTGRES_MIGRATE_URL").ownsSchema).toBe( true, ) }) it("names the variable whose connection is wrong", () => { expect(() => assertBoundByRowLevelSecurity({ ...facts, ownedTables: 1 }, "POSTGRES_READER_URL")).toThrow( /POSTGRES_READER_URL/, ) }) })