fix: always fresh Vault login on each key rotation (was using expired startup token)

This commit is contained in:
ZOMBIIIIIII
2026-05-12 12:37:38 +03:00
parent 8dc0855827
commit e87d178d71

View File

@@ -1,4 +1,4 @@
import { env, getVaultToken } from '../config/env'; import { env } from '../config/env';
import { vaultAppRoleLogin } from '../config/vault'; import { vaultAppRoleLogin } from '../config/vault';
import { fetchJwtKeysFromVault, swapKeyMap, getKeyMapSize } from './jwt.service'; import { fetchJwtKeysFromVault, swapKeyMap, getKeyMapSize } from './jwt.service';
import { fetchCsrfConfig, swapCsrfConfig } from './csrf.service'; import { fetchCsrfConfig, swapCsrfConfig } from './csrf.service';
@@ -33,17 +33,15 @@ async function doRefresh(): Promise<void> {
return; return;
} }
// Каждый refresh — свежий Vault token. Старый optimisation с `currentVaultToken` // КАЖДЫЙ refresh — свежий AppRole login. Vault token TTL обычно ≤1 час, а refresh-интервал
// был dead code (синхронный reset перед использованием). // тоже ~1 час → кэшировать токен между tick'ами = expired token на 2-м tick → silent fail.
let token = getVaultToken(); // Стоимость fresh login: один HTTP-запрос в час — пренебрежимо. Безопасность: гарантированно
// валидный токен для всех последующих fetches.
const token = await vaultAppRoleLogin(addr, roleId, secretId);
if (!token) { if (!token) {
const fresh = await vaultAppRoleLogin(addr, roleId, secretId);
if (!fresh) {
logger.error('Key refresh: Vault AppRole login failed'); logger.error('Key refresh: Vault AppRole login failed');
return; return;
} }
token = fresh;
}
const jwtPromise = fetchJwtKeysFromVault(addr, token, mount, jwtKidPath, jwtKidsPrefix); const jwtPromise = fetchJwtKeysFromVault(addr, token, mount, jwtKidPath, jwtKidsPrefix);
const csrfPromise = csrfPath ? fetchCsrfConfig(addr, token, mount, csrfPath) : Promise.resolve(null); const csrfPromise = csrfPath ? fetchCsrfConfig(addr, token, mount, csrfPath) : Promise.resolve(null);