@zincapp/zn-vault-agent 1.4.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +153 -6
- package/dist/commands/exec.d.ts.map +1 -1
- package/dist/commands/exec.js +11 -0
- package/dist/commands/exec.js.map +1 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +41 -4
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/start.d.ts.map +1 -1
- package/dist/commands/start.js +15 -1
- package/dist/commands/start.js.map +1 -1
- package/dist/lib/api.d.ts +47 -0
- package/dist/lib/api.d.ts.map +1 -1
- package/dist/lib/api.js +24 -0
- package/dist/lib/api.js.map +1 -1
- package/dist/lib/config.d.ts +31 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +31 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/secret-env.d.ts +11 -2
- package/dist/lib/secret-env.d.ts.map +1 -1
- package/dist/lib/secret-env.js +44 -4
- package/dist/lib/secret-env.js.map +1 -1
- package/dist/lib/websocket.d.ts.map +1 -1
- package/dist/lib/websocket.js +33 -3
- package/dist/lib/websocket.js.map +1 -1
- package/dist/services/managed-key-renewal.d.ts +31 -0
- package/dist/services/managed-key-renewal.d.ts.map +1 -0
- package/dist/services/managed-key-renewal.js +212 -0
- package/dist/services/managed-key-renewal.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
// Path: src/services/managed-key-renewal.ts
|
|
2
|
+
// Automatic managed API key renewal service
|
|
3
|
+
// Schedules key refresh based on rotation metadata from the vault server
|
|
4
|
+
import { loadConfig, updateManagedKey, isManagedKeyMode } from '../lib/config.js';
|
|
5
|
+
import { bindManagedApiKey } from '../lib/api.js';
|
|
6
|
+
import { createLogger } from '../lib/logger.js';
|
|
7
|
+
const log = createLogger({ module: 'managed-key-renewal' });
|
|
8
|
+
// How early before rotation to refresh (30 seconds default)
|
|
9
|
+
const DEFAULT_REFRESH_BEFORE_MS = 30 * 1000;
|
|
10
|
+
// Minimum refresh interval (don't refresh more than once per minute)
|
|
11
|
+
const MIN_REFRESH_INTERVAL_MS = 60 * 1000;
|
|
12
|
+
// Fallback interval if no rotation time is known (5 minutes)
|
|
13
|
+
const FALLBACK_REFRESH_INTERVAL_MS = 5 * 60 * 1000;
|
|
14
|
+
let refreshTimer = null;
|
|
15
|
+
let isRunning = false;
|
|
16
|
+
let currentKey = null;
|
|
17
|
+
// Callback for when key changes (used to notify other parts of the system)
|
|
18
|
+
let onKeyChangedCallback = null;
|
|
19
|
+
/**
|
|
20
|
+
* Set callback for when the API key changes
|
|
21
|
+
* This allows other parts of the system (e.g., WebSocket) to be notified
|
|
22
|
+
*/
|
|
23
|
+
export function onKeyChanged(callback) {
|
|
24
|
+
onKeyChangedCallback = callback;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Perform a managed key bind and update config
|
|
28
|
+
*/
|
|
29
|
+
async function refreshManagedKey() {
|
|
30
|
+
const config = loadConfig();
|
|
31
|
+
if (!config.managedKey?.name) {
|
|
32
|
+
log.debug('No managed key configured, skipping refresh');
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
if (!config.auth.apiKey) {
|
|
36
|
+
log.error('No API key available to perform bind');
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
log.debug({ name: config.managedKey.name }, 'Binding to managed key');
|
|
41
|
+
const bindResponse = await bindManagedApiKey(config.managedKey.name);
|
|
42
|
+
const oldKey = currentKey;
|
|
43
|
+
currentKey = bindResponse.key;
|
|
44
|
+
// Update config with new key and metadata
|
|
45
|
+
updateManagedKey(bindResponse.key, {
|
|
46
|
+
nextRotationAt: bindResponse.nextRotationAt,
|
|
47
|
+
graceExpiresAt: bindResponse.graceExpiresAt,
|
|
48
|
+
rotationMode: bindResponse.rotationMode,
|
|
49
|
+
});
|
|
50
|
+
// Notify if key changed
|
|
51
|
+
if (oldKey && oldKey !== bindResponse.key) {
|
|
52
|
+
log.info({
|
|
53
|
+
oldPrefix: oldKey.substring(0, 8),
|
|
54
|
+
newPrefix: bindResponse.key.substring(0, 8),
|
|
55
|
+
nextRotationAt: bindResponse.nextRotationAt,
|
|
56
|
+
}, 'Managed key rotated');
|
|
57
|
+
if (onKeyChangedCallback) {
|
|
58
|
+
onKeyChangedCallback(bindResponse.key);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
log.debug({
|
|
63
|
+
prefix: bindResponse.key.substring(0, 8),
|
|
64
|
+
nextRotationAt: bindResponse.nextRotationAt,
|
|
65
|
+
}, 'Managed key refreshed (no change)');
|
|
66
|
+
}
|
|
67
|
+
return bindResponse;
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
log.error({ err, name: config.managedKey.name }, 'Failed to bind managed key');
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Calculate when to next refresh the key
|
|
76
|
+
*/
|
|
77
|
+
function calculateNextRefreshMs(bindResponse) {
|
|
78
|
+
const config = loadConfig();
|
|
79
|
+
const now = Date.now();
|
|
80
|
+
// Priority 1: Use nextRotationAt from bind response or config
|
|
81
|
+
const nextRotationAt = bindResponse?.nextRotationAt || config.managedKey?.nextRotationAt;
|
|
82
|
+
if (nextRotationAt) {
|
|
83
|
+
const rotationTime = new Date(nextRotationAt).getTime();
|
|
84
|
+
const refreshTime = rotationTime - DEFAULT_REFRESH_BEFORE_MS;
|
|
85
|
+
const delay = Math.max(refreshTime - now, MIN_REFRESH_INTERVAL_MS);
|
|
86
|
+
log.debug({
|
|
87
|
+
nextRotationAt,
|
|
88
|
+
refreshInMs: delay,
|
|
89
|
+
refreshInMinutes: Math.round(delay / 60000),
|
|
90
|
+
}, 'Scheduled refresh based on nextRotationAt');
|
|
91
|
+
return delay;
|
|
92
|
+
}
|
|
93
|
+
// Priority 2: Use graceExpiresAt (refresh well before grace ends)
|
|
94
|
+
const graceExpiresAt = bindResponse?.graceExpiresAt || config.managedKey?.graceExpiresAt;
|
|
95
|
+
if (graceExpiresAt) {
|
|
96
|
+
const graceEndTime = new Date(graceExpiresAt).getTime();
|
|
97
|
+
// Refresh at 50% of remaining grace period
|
|
98
|
+
const refreshTime = now + (graceEndTime - now) / 2;
|
|
99
|
+
const delay = Math.max(refreshTime - now, MIN_REFRESH_INTERVAL_MS);
|
|
100
|
+
log.debug({
|
|
101
|
+
graceExpiresAt,
|
|
102
|
+
refreshInMs: delay,
|
|
103
|
+
refreshInMinutes: Math.round(delay / 60000),
|
|
104
|
+
}, 'Scheduled refresh based on graceExpiresAt');
|
|
105
|
+
return delay;
|
|
106
|
+
}
|
|
107
|
+
// Fallback: use default interval
|
|
108
|
+
log.debug({
|
|
109
|
+
refreshInMs: FALLBACK_REFRESH_INTERVAL_MS,
|
|
110
|
+
refreshInMinutes: FALLBACK_REFRESH_INTERVAL_MS / 60000,
|
|
111
|
+
}, 'Using fallback refresh interval (no rotation time available)');
|
|
112
|
+
return FALLBACK_REFRESH_INTERVAL_MS;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Schedule the next key refresh
|
|
116
|
+
*/
|
|
117
|
+
function scheduleNextRefresh(bindResponse) {
|
|
118
|
+
// Clear any existing timer
|
|
119
|
+
if (refreshTimer) {
|
|
120
|
+
clearTimeout(refreshTimer);
|
|
121
|
+
refreshTimer = null;
|
|
122
|
+
}
|
|
123
|
+
if (!isRunning) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const delay = calculateNextRefreshMs(bindResponse);
|
|
127
|
+
refreshTimer = setTimeout(async () => {
|
|
128
|
+
if (!isRunning)
|
|
129
|
+
return;
|
|
130
|
+
try {
|
|
131
|
+
const response = await refreshManagedKey();
|
|
132
|
+
scheduleNextRefresh(response);
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
log.error({ err }, 'Managed key refresh failed, retrying in 1 minute');
|
|
136
|
+
// On error, retry in 1 minute
|
|
137
|
+
scheduleNextRefresh(null);
|
|
138
|
+
}
|
|
139
|
+
}, delay);
|
|
140
|
+
log.info({
|
|
141
|
+
refreshInMinutes: Math.round(delay / 60000),
|
|
142
|
+
refreshAt: new Date(Date.now() + delay).toISOString(),
|
|
143
|
+
}, 'Managed key refresh scheduled');
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Start the managed key renewal service
|
|
147
|
+
* Returns the initial bind response or null if not in managed key mode
|
|
148
|
+
*/
|
|
149
|
+
export async function startManagedKeyRenewal() {
|
|
150
|
+
if (isRunning) {
|
|
151
|
+
log.warn('Managed key renewal service already running');
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
if (!isManagedKeyMode()) {
|
|
155
|
+
log.debug('Not in managed key mode, service not started');
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
const config = loadConfig();
|
|
159
|
+
isRunning = true;
|
|
160
|
+
currentKey = config.auth.apiKey || null;
|
|
161
|
+
log.info({
|
|
162
|
+
managedKeyName: config.managedKey?.name,
|
|
163
|
+
rotationMode: config.managedKey?.rotationMode,
|
|
164
|
+
}, 'Starting managed key renewal service');
|
|
165
|
+
// Perform initial bind
|
|
166
|
+
const bindResponse = await refreshManagedKey();
|
|
167
|
+
// Schedule next refresh
|
|
168
|
+
scheduleNextRefresh(bindResponse);
|
|
169
|
+
return bindResponse;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Stop the managed key renewal service
|
|
173
|
+
*/
|
|
174
|
+
export function stopManagedKeyRenewal() {
|
|
175
|
+
if (refreshTimer) {
|
|
176
|
+
clearTimeout(refreshTimer);
|
|
177
|
+
refreshTimer = null;
|
|
178
|
+
}
|
|
179
|
+
isRunning = false;
|
|
180
|
+
currentKey = null;
|
|
181
|
+
onKeyChangedCallback = null;
|
|
182
|
+
log.debug('Managed key renewal service stopped');
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Force an immediate key refresh
|
|
186
|
+
*/
|
|
187
|
+
export async function forceRefresh() {
|
|
188
|
+
if (!isManagedKeyMode()) {
|
|
189
|
+
log.warn('Cannot force refresh - not in managed key mode');
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
const response = await refreshManagedKey();
|
|
193
|
+
if (isRunning) {
|
|
194
|
+
scheduleNextRefresh(response);
|
|
195
|
+
}
|
|
196
|
+
return response;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Get current managed key status
|
|
200
|
+
*/
|
|
201
|
+
export function getManagedKeyStatus() {
|
|
202
|
+
const config = loadConfig();
|
|
203
|
+
return {
|
|
204
|
+
isRunning,
|
|
205
|
+
isManagedMode: isManagedKeyMode(),
|
|
206
|
+
managedKeyName: config.managedKey?.name,
|
|
207
|
+
currentKeyPrefix: currentKey ? currentKey.substring(0, 8) + '...' : undefined,
|
|
208
|
+
nextRotationAt: config.managedKey?.nextRotationAt,
|
|
209
|
+
graceExpiresAt: config.managedKey?.graceExpiresAt,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=managed-key-renewal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"managed-key-renewal.js","sourceRoot":"","sources":["../../src/services/managed-key-renewal.ts"],"names":[],"mappings":"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"}
|