NAC_Blockchain/ops/nac-admin/server/secrets.ts

130 lines
3.4 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* NAC知识引擎管理后台 - 密钥安全管理模块
*
* 安全原则:
* 1. 所有密钥必须来自环境变量,绝不硬编码
* 2. 任何必要密钥缺失时,服务拒绝启动
* 3. 密钥值永远不出现在日志、错误信息或代码中
* 4. 所有密钥通过此模块统一访问,不直接读取 process.env
*/
type SecretKey =
| "NAC_MYSQL_URL"
| "NAC_MONGO_URL"
| "NAC_JWT_SECRET"
| "NAC_ADMIN_TOKEN"
| "DATABASE_URL"
| "JWT_SECRET";
// 必须存在的密钥列表(缺失则服务拒绝启动)
const REQUIRED_SECRETS: SecretKey[] = [
"NAC_MYSQL_URL",
"NAC_MONGO_URL",
"NAC_JWT_SECRET",
];
// 可选密钥列表(缺失时记录警告但不阻止启动)
const OPTIONAL_SECRETS: SecretKey[] = [
"NAC_ADMIN_TOKEN",
"DATABASE_URL",
"JWT_SECRET",
];
/**
* 安全读取单个密钥
* 密钥值不会出现在任何错误消息中
*/
function readSecret(key: SecretKey): string | undefined {
return process.env[key];
}
/**
* 验证所有必要密钥是否已配置
* 在服务启动时调用,任何缺失则抛出错误阻止启动
*/
export function validateSecrets(): void {
const missing: string[] = [];
for (const key of REQUIRED_SECRETS) {
const value = readSecret(key);
if (!value || value.trim() === "") {
missing.push(key);
}
}
if (missing.length > 0) {
// 只记录缺失的密钥名称,绝不记录任何密钥值
console.error(`[Secrets] 启动失败:以下必要密钥未配置: ${missing.join(", ")}`);
console.error("[Secrets] 请通过环境变量配置所有必要密钥,绝不要在代码中硬编码密钥值");
throw new Error(`缺少必要的安全密钥配置: ${missing.join(", ")}`);
}
for (const key of OPTIONAL_SECRETS) {
const value = readSecret(key);
if (!value || value.trim() === "") {
console.warn(`[Secrets] 可选密钥未配置: ${key}`);
}
}
console.log("[Secrets] 所有必要密钥验证通过");
}
/**
* 获取NAC MySQL连接字符串
* 仅用于建立数据库连接,不得用于日志输出
*/
export function getNacMysqlUrl(): string {
const val = readSecret("NAC_MYSQL_URL");
if (!val) throw new Error("[Secrets] NAC_MYSQL_URL 未配置");
return val;
}
/**
* 获取NAC MongoDB连接字符串
* 仅用于建立数据库连接,不得用于日志输出
*/
export function getNacMongoUrl(): string {
const val = readSecret("NAC_MONGO_URL");
if (!val) throw new Error("[Secrets] NAC_MONGO_URL 未配置");
return val;
}
/**
* 获取NAC JWT签名密钥
* 仅用于JWT签名和验证不得用于日志输出
*/
export function getNacJwtSecret(): string {
const val = readSecret("NAC_JWT_SECRET");
if (!val) throw new Error("[Secrets] NAC_JWT_SECRET 未配置");
return val;
}
/**
* 获取NAC管理员Token
* 仅用于CIB服务调用不得用于日志输出
*/
export function getNacAdminToken(): string {
const val = readSecret("NAC_ADMIN_TOKEN");
if (!val) {
console.warn("[Secrets] NAC_ADMIN_TOKEN 未配置CIB管理功能将不可用");
return "";
}
return val;
}
/**
* 获取系统数据库连接字符串MySQL/TiDB
*/
export function getDatabaseUrl(): string {
const val = readSecret("DATABASE_URL");
if (!val) throw new Error("[Secrets] DATABASE_URL 未配置");
return val;
}
/**
* 获取系统JWT密钥用于Manus会话可选
*/
export function getJwtSecret(): string {
return readSecret("JWT_SECRET") ?? "";
}