feat: establish core identity foundation
CI / verify (pull_request) Successful in 25s
CI / infrastructure-smoke (pull_request) Successful in 12s
CI / migration-smoke (pull_request) Successful in 22s

Adds Core-owned identity contracts, a Core-owned Better Auth database schema
(ekklesia_core_user/session/account/verification), a first-class Core-owned
migration source that coexists with module-owned migrations under the exact
existing migration system, and an explicit Better Auth construction boundary.
No authentication endpoint or sign-in UI is exposed yet (ADR 0010).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
ekklesia
2026-07-21 16:39:15 -05:00
co-authored by Claude Sonnet 5
parent df0f20d8af
commit 679a5d225c
43 changed files with 4259 additions and 64 deletions
+70
View File
@@ -200,6 +200,7 @@ describe("Ekklesia Doctor diagnostics", () => {
"migrations.discovery",
"postgresql.connection",
"postgresql.plan",
"identity.configuration",
"object-storage.integration",
]);
expect(check(report, "modules.discovery").details).toEqual(["people 0.1.0", "calendar 0.2.0"]);
@@ -438,4 +439,73 @@ describe("Ekklesia Doctor diagnostics", () => {
expect(services.discoverSchemas).toHaveBeenCalledOnce();
expect(services.discoverMigrations).toHaveBeenCalledOnce();
});
it("skips identity configuration (not a failure) when none of it is set", async () => {
const report = await diagnoseEkklesia(options(), dependencies());
const identity = check(report, "identity.configuration");
expect(identity.status).toBe("skipped");
expect(identity.details[0]).toContain("Core identity schema defines 4 tables");
expect(report.result).toBe("ready-with-warnings");
expect(doctorExitCode(report)).toBe(0);
});
it("passes identity configuration when a valid secret, base URL, and trusted origins are provided", async () => {
const report = await diagnoseEkklesia(
{
...options(),
identityConfiguration: {
baseUrl: "https://identity.example.test",
environment: "production",
secret: "correct-horse-battery-staple-0123456789",
trustedOrigins: ["https://identity.example.test"],
},
},
dependencies(),
);
const identity = check(report, "identity.configuration");
expect(identity.status).toBe("pass");
expect(report.result).toBe("ready-with-warnings"); // PostgreSQL is still skipped in this fixture
});
it("fails identity configuration for an invalid secret without leaking it", async () => {
const hostileSecret = "s3cr3t-do-not-log";
const report = await diagnoseEkklesia(
{
...options(),
identityConfiguration: {
baseUrl: "https://identity.example.test",
environment: "production",
secret: hostileSecret,
trustedOrigins: ["https://identity.example.test"],
},
},
dependencies(),
);
const identity = check(report, "identity.configuration");
expect(identity.status).toBe("failure");
expect(identity.details.some((detail) => detail.includes("SECRET_TOO_SHORT"))).toBe(true);
expect(report.result).toBe("not-ready");
expect(doctorExitCode(report)).toBe(1);
expect(JSON.stringify(report)).not.toContain(hostileSecret);
});
it("never constructs a migration database or Better Auth merely to check identity configuration", async () => {
const services = dependencies();
await diagnoseEkklesia(
{
...options(),
identityConfiguration: {
baseUrl: "https://identity.example.test",
secret: "correct-horse-battery-staple-0123456789",
trustedOrigins: ["https://identity.example.test"],
},
},
services,
);
expect(services.createMigrationDatabase).not.toHaveBeenCalled();
});
});