secret reference server usage

This commit is contained in:
Jakub Trávník 2025-12-15 10:50:13 +01:00
parent 605fb1c27c
commit 58b1a0574e
7 changed files with 50 additions and 50 deletions

View file

@ -34,7 +34,7 @@ const mount = async (config: BackendConfig, path: string) => {
const run = async () => { const run = async () => {
await fs.mkdir(path, { recursive: true }); await fs.mkdir(path, { recursive: true });
const password = await cryptoUtils.decrypt(config.password); const password = await cryptoUtils.resolveSecret(config.password);
const source = `//${config.server}/${config.share}`; const source = `//${config.server}/${config.share}`;
const options = [ const options = [

View file

@ -50,7 +50,7 @@ const mount = async (config: BackendConfig, path: string) => {
: ["uid=1000", "gid=1000", "file_mode=0664", "dir_mode=0775"]; : ["uid=1000", "gid=1000", "file_mode=0664", "dir_mode=0775"];
if (config.username && config.password) { if (config.username && config.password) {
const password = await cryptoUtils.decrypt(config.password); const password = await cryptoUtils.resolveSecret(config.password);
const secretsFile = "/etc/davfs2/secrets"; const secretsFile = "/etc/davfs2/secrets";
const secretsContent = `${source} ${config.username} ${password}\n`; const secretsContent = `${source} ${config.username} ${password}\n`;
await fs.appendFile(secretsFile, secretsContent, { mode: 0o600 }); await fs.appendFile(secretsFile, secretsContent, { mode: 0o600 });

View file

@ -38,42 +38,42 @@ async function encryptSensitiveFields(config: NotificationConfig): Promise<Notif
case "email": case "email":
return { return {
...config, ...config,
password: config.password ? await cryptoUtils.encrypt(config.password) : undefined, password: config.password ? await cryptoUtils.sealSecret(config.password) : undefined,
}; };
case "slack": case "slack":
return { return {
...config, ...config,
webhookUrl: await cryptoUtils.encrypt(config.webhookUrl), webhookUrl: await cryptoUtils.sealSecret(config.webhookUrl),
}; };
case "discord": case "discord":
return { return {
...config, ...config,
webhookUrl: await cryptoUtils.encrypt(config.webhookUrl), webhookUrl: await cryptoUtils.sealSecret(config.webhookUrl),
}; };
case "gotify": case "gotify":
return { return {
...config, ...config,
token: await cryptoUtils.encrypt(config.token), token: await cryptoUtils.sealSecret(config.token),
}; };
case "ntfy": case "ntfy":
return { return {
...config, ...config,
password: config.password ? await cryptoUtils.encrypt(config.password) : undefined, password: config.password ? await cryptoUtils.sealSecret(config.password) : undefined,
}; };
case "pushover": case "pushover":
return { return {
...config, ...config,
apiToken: await cryptoUtils.encrypt(config.apiToken), apiToken: await cryptoUtils.sealSecret(config.apiToken),
}; };
case "telegram": case "telegram":
return { return {
...config, ...config,
botToken: await cryptoUtils.encrypt(config.botToken), botToken: await cryptoUtils.sealSecret(config.botToken),
}; };
case "custom": case "custom":
return { return {
...config, ...config,
shoutrrrUrl: await cryptoUtils.encrypt(config.shoutrrrUrl), shoutrrrUrl: await cryptoUtils.sealSecret(config.shoutrrrUrl),
}; };
default: default:
return config; return config;
@ -85,42 +85,42 @@ async function decryptSensitiveFields(config: NotificationConfig): Promise<Notif
case "email": case "email":
return { return {
...config, ...config,
password: config.password ? await cryptoUtils.decrypt(config.password) : undefined, password: config.password ? await cryptoUtils.resolveSecret(config.password) : undefined,
}; };
case "slack": case "slack":
return { return {
...config, ...config,
webhookUrl: await cryptoUtils.decrypt(config.webhookUrl), webhookUrl: await cryptoUtils.resolveSecret(config.webhookUrl),
}; };
case "discord": case "discord":
return { return {
...config, ...config,
webhookUrl: await cryptoUtils.decrypt(config.webhookUrl), webhookUrl: await cryptoUtils.resolveSecret(config.webhookUrl),
}; };
case "gotify": case "gotify":
return { return {
...config, ...config,
token: await cryptoUtils.decrypt(config.token), token: await cryptoUtils.resolveSecret(config.token),
}; };
case "ntfy": case "ntfy":
return { return {
...config, ...config,
password: config.password ? await cryptoUtils.decrypt(config.password) : undefined, password: config.password ? await cryptoUtils.resolveSecret(config.password) : undefined,
}; };
case "pushover": case "pushover":
return { return {
...config, ...config,
apiToken: await cryptoUtils.decrypt(config.apiToken), apiToken: await cryptoUtils.resolveSecret(config.apiToken),
}; };
case "telegram": case "telegram":
return { return {
...config, ...config,
botToken: await cryptoUtils.decrypt(config.botToken), botToken: await cryptoUtils.resolveSecret(config.botToken),
}; };
case "custom": case "custom":
return { return {
...config, ...config,
shoutrrrUrl: await cryptoUtils.decrypt(config.shoutrrrUrl), shoutrrrUrl: await cryptoUtils.resolveSecret(config.shoutrrrUrl),
}; };
default: default:
return config; return config;

View file

@ -20,31 +20,31 @@ const encryptConfig = async (config: RepositoryConfig): Promise<RepositoryConfig
const encryptedConfig: Record<string, string | boolean | number> = { ...config }; const encryptedConfig: Record<string, string | boolean | number> = { ...config };
if (config.customPassword) { if (config.customPassword) {
encryptedConfig.customPassword = await cryptoUtils.encrypt(config.customPassword); encryptedConfig.customPassword = await cryptoUtils.sealSecret(config.customPassword);
} }
switch (config.backend) { switch (config.backend) {
case "s3": case "s3":
case "r2": case "r2":
encryptedConfig.accessKeyId = await cryptoUtils.encrypt(config.accessKeyId); encryptedConfig.accessKeyId = await cryptoUtils.sealSecret(config.accessKeyId);
encryptedConfig.secretAccessKey = await cryptoUtils.encrypt(config.secretAccessKey); encryptedConfig.secretAccessKey = await cryptoUtils.sealSecret(config.secretAccessKey);
break; break;
case "gcs": case "gcs":
encryptedConfig.credentialsJson = await cryptoUtils.encrypt(config.credentialsJson); encryptedConfig.credentialsJson = await cryptoUtils.sealSecret(config.credentialsJson);
break; break;
case "azure": case "azure":
encryptedConfig.accountKey = await cryptoUtils.encrypt(config.accountKey); encryptedConfig.accountKey = await cryptoUtils.sealSecret(config.accountKey);
break; break;
case "rest": case "rest":
if (config.username) { if (config.username) {
encryptedConfig.username = await cryptoUtils.encrypt(config.username); encryptedConfig.username = await cryptoUtils.sealSecret(config.username);
} }
if (config.password) { if (config.password) {
encryptedConfig.password = await cryptoUtils.encrypt(config.password); encryptedConfig.password = await cryptoUtils.sealSecret(config.password);
} }
break; break;
case "sftp": case "sftp":
encryptedConfig.privateKey = await cryptoUtils.encrypt(config.privateKey); encryptedConfig.privateKey = await cryptoUtils.sealSecret(config.privateKey);
break; break;
} }

View file

@ -25,12 +25,12 @@ async function encryptSensitiveFields(config: BackendConfig): Promise<BackendCon
case "smb": case "smb":
return { return {
...config, ...config,
password: await cryptoUtils.encrypt(config.password), password: await cryptoUtils.sealSecret(config.password),
}; };
case "webdav": case "webdav":
return { return {
...config, ...config,
password: config.password ? await cryptoUtils.encrypt(config.password) : undefined, password: config.password ? await cryptoUtils.sealSecret(config.password) : undefined,
}; };
default: default:
return config; return config;

View file

@ -41,11 +41,11 @@ export const hasCompatibleCredentials = async (
(config1.backend === "s3" || config1.backend === "r2") && (config1.backend === "s3" || config1.backend === "r2") &&
(config2.backend === "s3" || config2.backend === "r2") (config2.backend === "s3" || config2.backend === "r2")
) { ) {
const accessKey1 = await cryptoUtils.decrypt(config1.accessKeyId); const accessKey1 = await cryptoUtils.resolveSecret(config1.accessKeyId);
const secretKey1 = await cryptoUtils.decrypt(config1.secretAccessKey); const secretKey1 = await cryptoUtils.resolveSecret(config1.secretAccessKey);
const accessKey2 = await cryptoUtils.decrypt(config2.accessKeyId); const accessKey2 = await cryptoUtils.resolveSecret(config2.accessKeyId);
const secretKey2 = await cryptoUtils.decrypt(config2.secretAccessKey); const secretKey2 = await cryptoUtils.resolveSecret(config2.secretAccessKey);
return accessKey1 === accessKey2 && secretKey1 === secretKey2; return accessKey1 === accessKey2 && secretKey1 === secretKey2;
} }
@ -53,8 +53,8 @@ export const hasCompatibleCredentials = async (
} }
case "gcs": { case "gcs": {
if (config1.backend === "gcs" && config2.backend === "gcs") { if (config1.backend === "gcs" && config2.backend === "gcs") {
const credentials1 = await cryptoUtils.decrypt(config1.credentialsJson); const credentials1 = await cryptoUtils.resolveSecret(config1.credentialsJson);
const credentials2 = await cryptoUtils.decrypt(config2.credentialsJson); const credentials2 = await cryptoUtils.resolveSecret(config2.credentialsJson);
return credentials1 === credentials2 && config1.projectId === config2.projectId; return credentials1 === credentials2 && config1.projectId === config2.projectId;
} }
@ -62,8 +62,8 @@ export const hasCompatibleCredentials = async (
} }
case "azure": { case "azure": {
if (config1.backend === "azure" && config2.backend === "azure") { if (config1.backend === "azure" && config2.backend === "azure") {
const config1Accountkey = await cryptoUtils.decrypt(config1.accountKey); const config1Accountkey = await cryptoUtils.resolveSecret(config1.accountKey);
const config2Accountkey = await cryptoUtils.decrypt(config2.accountKey); const config2Accountkey = await cryptoUtils.resolveSecret(config2.accountKey);
return config1.accountName === config2.accountName && config1Accountkey === config2Accountkey; return config1.accountName === config2.accountName && config1Accountkey === config2Accountkey;
} }
@ -75,10 +75,10 @@ export const hasCompatibleCredentials = async (
return true; return true;
} }
const config1Username = await cryptoUtils.decrypt(config1.username || ""); const config1Username = await cryptoUtils.resolveSecret(config1.username || "");
const config1Password = await cryptoUtils.decrypt(config1.password || ""); const config1Password = await cryptoUtils.resolveSecret(config1.password || "");
const config2Username = await cryptoUtils.decrypt(config2.username || ""); const config2Username = await cryptoUtils.resolveSecret(config2.username || "");
const config2Password = await cryptoUtils.decrypt(config2.password || ""); const config2Password = await cryptoUtils.resolveSecret(config2.password || "");
return config1Username === config2Username && config1Password === config2Password; return config1Username === config2Username && config1Password === config2Password;
} }

View file

@ -106,7 +106,7 @@ const buildEnv = async (config: RepositoryConfig) => {
}; };
if (config.isExistingRepository && config.customPassword) { if (config.isExistingRepository && config.customPassword) {
const decryptedPassword = await cryptoUtils.decrypt(config.customPassword); const decryptedPassword = await cryptoUtils.resolveSecret(config.customPassword);
const passwordFilePath = path.join("/tmp", `zerobyte-pass-${crypto.randomBytes(8).toString("hex")}.txt`); const passwordFilePath = path.join("/tmp", `zerobyte-pass-${crypto.randomBytes(8).toString("hex")}.txt`);
await fs.writeFile(passwordFilePath, decryptedPassword, { mode: 0o600 }); await fs.writeFile(passwordFilePath, decryptedPassword, { mode: 0o600 });
@ -117,17 +117,17 @@ const buildEnv = async (config: RepositoryConfig) => {
switch (config.backend) { switch (config.backend) {
case "s3": case "s3":
env.AWS_ACCESS_KEY_ID = await cryptoUtils.decrypt(config.accessKeyId); env.AWS_ACCESS_KEY_ID = await cryptoUtils.resolveSecret(config.accessKeyId);
env.AWS_SECRET_ACCESS_KEY = await cryptoUtils.decrypt(config.secretAccessKey); env.AWS_SECRET_ACCESS_KEY = await cryptoUtils.resolveSecret(config.secretAccessKey);
break; break;
case "r2": case "r2":
env.AWS_ACCESS_KEY_ID = await cryptoUtils.decrypt(config.accessKeyId); env.AWS_ACCESS_KEY_ID = await cryptoUtils.resolveSecret(config.accessKeyId);
env.AWS_SECRET_ACCESS_KEY = await cryptoUtils.decrypt(config.secretAccessKey); env.AWS_SECRET_ACCESS_KEY = await cryptoUtils.resolveSecret(config.secretAccessKey);
env.AWS_REGION = "auto"; env.AWS_REGION = "auto";
env.AWS_S3_FORCE_PATH_STYLE = "true"; env.AWS_S3_FORCE_PATH_STYLE = "true";
break; break;
case "gcs": { case "gcs": {
const decryptedCredentials = await cryptoUtils.decrypt(config.credentialsJson); const decryptedCredentials = await cryptoUtils.resolveSecret(config.credentialsJson);
const credentialsPath = path.join("/tmp", `zerobyte-gcs-${crypto.randomBytes(8).toString("hex")}.json`); const credentialsPath = path.join("/tmp", `zerobyte-gcs-${crypto.randomBytes(8).toString("hex")}.json`);
await fs.writeFile(credentialsPath, decryptedCredentials, { mode: 0o600 }); await fs.writeFile(credentialsPath, decryptedCredentials, { mode: 0o600 });
env.GOOGLE_PROJECT_ID = config.projectId; env.GOOGLE_PROJECT_ID = config.projectId;
@ -136,7 +136,7 @@ const buildEnv = async (config: RepositoryConfig) => {
} }
case "azure": { case "azure": {
env.AZURE_ACCOUNT_NAME = config.accountName; env.AZURE_ACCOUNT_NAME = config.accountName;
env.AZURE_ACCOUNT_KEY = await cryptoUtils.decrypt(config.accountKey); env.AZURE_ACCOUNT_KEY = await cryptoUtils.resolveSecret(config.accountKey);
if (config.endpointSuffix) { if (config.endpointSuffix) {
env.AZURE_ENDPOINT_SUFFIX = config.endpointSuffix; env.AZURE_ENDPOINT_SUFFIX = config.endpointSuffix;
} }
@ -144,15 +144,15 @@ const buildEnv = async (config: RepositoryConfig) => {
} }
case "rest": { case "rest": {
if (config.username) { if (config.username) {
env.RESTIC_REST_USERNAME = await cryptoUtils.decrypt(config.username); env.RESTIC_REST_USERNAME = await cryptoUtils.resolveSecret(config.username);
} }
if (config.password) { if (config.password) {
env.RESTIC_REST_PASSWORD = await cryptoUtils.decrypt(config.password); env.RESTIC_REST_PASSWORD = await cryptoUtils.resolveSecret(config.password);
} }
break; break;
} }
case "sftp": { case "sftp": {
const decryptedKey = await cryptoUtils.decrypt(config.privateKey); const decryptedKey = await cryptoUtils.resolveSecret(config.privateKey);
const keyPath = path.join("/tmp", `ironmount-ssh-${crypto.randomBytes(8).toString("hex")}`); const keyPath = path.join("/tmp", `ironmount-ssh-${crypto.randomBytes(8).toString("hex")}`);
let normalizedKey = decryptedKey.replace(/\r\n/g, "\n"); let normalizedKey = decryptedKey.replace(/\r\n/g, "\n");