mirror of
https://github.com/andwati/zitadel.git
synced 2026-10-18 05:52:51 +00:00
feat(login): Support private key file with env (#10575)
# Which Problems Are Solved Instead of encoding the private key as base64 and setting it in the env as SYSTEM_USER_PRIVATE_KEY it is sometimes easier to write it to disk and use a file path. This is for example also possible when setting up system users in zitadel core. # How the Problems Are Solved Added SYSTEM_USER_PRIVATE_KEY_FILE which is preferred over SYSTEM_USER_PRIVATE_KEY and expects a file path to a private key in PEM format (like SYSTEM_USER_PRIVATE_KEY but not base64 encoded). To prevent loading the private key too often it is cached. --------- Co-authored-by: Ramon <[email protected]>
This commit is contained in:
Vendored
+2
@@ -4,10 +4,12 @@ declare namespace NodeJS {
|
||||
[key: `${string}_AUDIENCE`]: string; // The system api url
|
||||
[key: `${string}_SYSTEM_USER_ID`]: string; // The service account id
|
||||
[key: `${string}_SYSTEM_USER_PRIVATE_KEY`]: string; // The service account private key
|
||||
[key: `${string}_SYSTEM_USER_PRIVATE_KEY_FILE`]: string; // The service account private key file path
|
||||
|
||||
AUDIENCE: string; // The fallback system api url
|
||||
SYSTEM_USER_ID: string; // The fallback service account id
|
||||
SYSTEM_USER_PRIVATE_KEY: string; // The fallback service account private key
|
||||
SYSTEM_USER_PRIVATE_KEY_FILE: string; // The fallback service account private key file path
|
||||
|
||||
/**
|
||||
* The Zitadel API url
|
||||
|
||||
+21
-10
@@ -1,7 +1,20 @@
|
||||
import { newSystemToken } from "@zitadel/client/node";
|
||||
import { readFileSync } from "fs";
|
||||
import { readFile } from "fs/promises";
|
||||
import { getLoginSystemUserId } from "./deployment";
|
||||
|
||||
// The key token is only loaded once from disk per process.
|
||||
// If the file was loaded you need to restart the process to switch the key.
|
||||
let keyToken: string | undefined;
|
||||
|
||||
async function getTokenFromFile(): Promise<string> {
|
||||
if (keyToken) {
|
||||
return keyToken;
|
||||
}
|
||||
|
||||
keyToken = await readFile(process.env.SYSTEM_USER_PRIVATE_KEY_FILE, "binary");
|
||||
return keyToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a signed JWT token using system user credentials from environment
|
||||
* variables. The SYSTEM_USER_PRIVATE_KEY is expected to be base64-encoded and
|
||||
@@ -12,16 +25,14 @@ import { getLoginSystemUserId } from "./deployment";
|
||||
* @throws If the underlying token signing fails.
|
||||
*/
|
||||
export async function systemAPIToken() {
|
||||
const token = {
|
||||
audience: process.env.AUDIENCE,
|
||||
userID: process.env.SYSTEM_USER_ID,
|
||||
token: Buffer.from(process.env.SYSTEM_USER_PRIVATE_KEY, "base64").toString("utf-8"),
|
||||
};
|
||||
const key = process.env.SYSTEM_USER_PRIVATE_KEY_FILE
|
||||
? await getTokenFromFile()
|
||||
: Buffer.from(process.env.SYSTEM_USER_PRIVATE_KEY, "base64").toString("utf-8");
|
||||
|
||||
return newSystemToken({
|
||||
audience: token.audience,
|
||||
subject: token.userID,
|
||||
key: token.token,
|
||||
audience: process.env.AUDIENCE,
|
||||
subject: process.env.SYSTEM_USER_ID,
|
||||
key,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -38,7 +49,7 @@ export async function loginServiceKeyToken() {
|
||||
const keyFile = process.env.ZITADEL_LOGIN_SERVICE_KEY_FILE!;
|
||||
|
||||
try {
|
||||
const key = readFileSync(keyFile, "utf-8");
|
||||
const key = await readFile(keyFile, "utf-8");
|
||||
|
||||
return newSystemToken({
|
||||
audience: process.env.AUDIENCE || process.env.ZITADEL_API_URL,
|
||||
|
||||
@@ -5,13 +5,18 @@
|
||||
* - AUDIENCE: The API audience for JWT authentication
|
||||
* - SYSTEM_USER_ID: The system user's ID
|
||||
* - SYSTEM_USER_PRIVATE_KEY: The private key for JWT signing
|
||||
* - SYSTEM_USER_PRIVATE_KEY_FILE: The private key file path for JWT signing
|
||||
*
|
||||
* Both multi-tenant and self-hosted deployments can use system user authentication.
|
||||
*
|
||||
* @returns true if system user credentials are present, false otherwise
|
||||
*/
|
||||
export function hasSystemUserCredentials(): boolean {
|
||||
return !!process.env.AUDIENCE && !!process.env.SYSTEM_USER_ID && !!process.env.SYSTEM_USER_PRIVATE_KEY;
|
||||
return (
|
||||
!!process.env.AUDIENCE &&
|
||||
!!process.env.SYSTEM_USER_ID &&
|
||||
(!!process.env.SYSTEM_USER_PRIVATE_KEY || !!process.env.SYSTEM_USER_PRIVATE_KEY_FILE)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user