60 lines
2.0 KiB
JavaScript
Executable File
60 lines
2.0 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
// =====================================================================
|
|
// Erzeugt die Schlüssel für eine self-gehostete Supabase-Instanz:
|
|
// - JWT_SECRET (zufällig, >= 40 Zeichen)
|
|
// - ANON_KEY (HS256-JWT, role=anon, 10 Jahre gültig)
|
|
// - SERVICE_ROLE_KEY (HS256-JWT, role=service_role, 10 Jahre gültig)
|
|
//
|
|
// anon/service-Key sind KEINE Passwörter, sondern JWTs, die mit dem
|
|
// JWT_SECRET signiert sind — exakt wie bei Supabase Cloud. PostgREST und
|
|
// Storage validieren sie lokal gegen das Secret (kein GoTrue nötig).
|
|
//
|
|
// Nutzung:
|
|
// node gen-keys.mjs # neues Secret + passende Keys
|
|
// node gen-keys.mjs <bestehendes-JWT_SECRET> # Keys zu vorhandenem Secret
|
|
//
|
|
// Ausgabe ist direkt in die Supabase-.env kopierbar.
|
|
// Pure Node-crypto, keine Abhängigkeiten.
|
|
// =====================================================================
|
|
|
|
import { createHmac, randomBytes } from "node:crypto";
|
|
|
|
function b64url(input) {
|
|
return Buffer.from(input)
|
|
.toString("base64")
|
|
.replace(/=/g, "")
|
|
.replace(/\+/g, "-")
|
|
.replace(/\//g, "_");
|
|
}
|
|
|
|
function signJwt(payload, secret) {
|
|
const header = { alg: "HS256", typ: "JWT" };
|
|
const head = b64url(JSON.stringify(header));
|
|
const body = b64url(JSON.stringify(payload));
|
|
const data = `${head}.${body}`;
|
|
const sig = createHmac("sha256", secret).update(data).digest("base64")
|
|
.replace(/=/g, "")
|
|
.replace(/\+/g, "-")
|
|
.replace(/\//g, "_");
|
|
return `${data}.${sig}`;
|
|
}
|
|
|
|
const secret = process.argv[2] || randomBytes(48).toString("base64url");
|
|
if (secret.length < 32) {
|
|
console.error("JWT_SECRET muss mindestens 32 Zeichen lang sein.");
|
|
process.exit(1);
|
|
}
|
|
|
|
const iat = Math.floor(Date.now() / 1000);
|
|
const exp = iat + 60 * 60 * 24 * 365 * 10; // 10 Jahre
|
|
|
|
const anon = signJwt({ role: "anon", iss: "supabase", iat, exp }, secret);
|
|
const service = signJwt(
|
|
{ role: "service_role", iss: "supabase", iat, exp },
|
|
secret,
|
|
);
|
|
|
|
console.log(`JWT_SECRET=${secret}`);
|
|
console.log(`ANON_KEY=${anon}`);
|
|
console.log(`SERVICE_ROLE_KEY=${service}`);
|