log-llm-config 1.3.34 → 1.3.35
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/dist/log_config_files/auth/auth_flow.js +14 -68
- package/dist/log_config_files/auth/auth_key_store.js +4 -19
- package/dist/log_config_files/sender/endpoint_config.js +7 -61
- package/dist/log_config_files/sender/signing.js +1 -15
- package/dist/log_uuid/startup_sender.js +3 -3
- package/package.json +3 -2
|
@@ -1,76 +1,22 @@
|
|
|
1
|
-
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
2
1
|
import path from 'node:path';
|
|
3
2
|
import { postStartupPayload } from '../../endpoint_client/index.js';
|
|
4
|
-
import {
|
|
3
|
+
import { ensureAuthentication as ensureTofuAuthentication } from 'optimus-tofu';
|
|
5
4
|
import { loadEndpointBase } from '../sender/endpoint_config.js';
|
|
6
|
-
import {
|
|
5
|
+
import { OPT_AI_SEC_MANAGEMENT_REL } from '../../bootstrap_constants.js';
|
|
7
6
|
import { hookRunLog } from '../runtime/hook_logger.js';
|
|
8
|
-
|
|
9
|
-
try {
|
|
10
|
-
return new URL(endpoint).origin;
|
|
11
|
-
}
|
|
12
|
-
catch {
|
|
13
|
-
return endpoint.replace(/\/+$/, '');
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
function persistAuthKey(key, keyId, hardwareUuid) {
|
|
17
|
-
const authPath = getAuthKeyPath();
|
|
18
|
-
if (!authPath)
|
|
19
|
-
return;
|
|
20
|
-
mkdirSync(path.dirname(authPath), { recursive: true, mode: 0o700 });
|
|
21
|
-
writeFileSync(authPath, JSON.stringify({ key, key_id: keyId ?? null, hardware_uuid: hardwareUuid, stored_at: new Date().toISOString() }, null, 2), { encoding: 'utf8', mode: 0o600 });
|
|
22
|
-
}
|
|
23
|
-
async function verifyStoredKey(hardwareUuid, storedKey, authUrl) {
|
|
24
|
-
const verifyPayload = { hardware_uuid: hardwareUuid };
|
|
25
|
-
const signature = createSignature(verifyPayload, storedKey.key);
|
|
26
|
-
const requestBody = { hardware_uuid: hardwareUuid, signature, key_id: storedKey.key_id || '' };
|
|
27
|
-
try {
|
|
28
|
-
const response = await postStartupPayload(authUrl, requestBody);
|
|
29
|
-
if (response.status === 'authenticated') {
|
|
30
|
-
console.log('Auth key verified successfully.');
|
|
31
|
-
hookRunLog(`auth: verified key_id_suffix=${(storedKey.key_id || '').slice(-8) || '(none)'}`);
|
|
32
|
-
return storedKey;
|
|
33
|
-
}
|
|
34
|
-
if (response.status === 'key_issued' && response.key) {
|
|
35
|
-
console.log('Stored key was invalid, received new key from server.');
|
|
36
|
-
hookRunLog('auth: new_key_issued (stored key was invalid)');
|
|
37
|
-
persistAuthKey(response.key, response.key_id, hardwareUuid);
|
|
38
|
-
return { key: response.key, key_id: response.key_id, hardware_uuid: hardwareUuid };
|
|
39
|
-
}
|
|
40
|
-
console.warn('Key verification failed, will request new key.');
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
catch (error) {
|
|
44
|
-
console.warn(`Failed to verify key: ${error instanceof Error ? error.message : String(error)}, will request new key.`);
|
|
45
|
-
return null;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
async function requestNewKey(hardwareUuid, authUrl) {
|
|
49
|
-
console.log('No valid auth key found, performing authentication handshake...');
|
|
50
|
-
try {
|
|
51
|
-
const response = await postStartupPayload(authUrl, { hardware_uuid: hardwareUuid });
|
|
52
|
-
if (response.status === 'key_issued' && response.key) {
|
|
53
|
-
hookRunLog('auth: handshake_new_key');
|
|
54
|
-
persistAuthKey(response.key, response.key_id, hardwareUuid);
|
|
55
|
-
console.log(`Stored new auth key at ${getAuthKeyPath()}`);
|
|
56
|
-
return { key: response.key, key_id: response.key_id, hardware_uuid: hardwareUuid };
|
|
57
|
-
}
|
|
58
|
-
throw new Error(`Authentication failed: ${response.error || response.message || 'Unknown error'}`);
|
|
59
|
-
}
|
|
60
|
-
catch (error) {
|
|
61
|
-
throw new Error(`Failed to authenticate: ${error instanceof Error ? error.message : String(error)}`);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
7
|
+
const AUTH_KEY_RELATIVE_PATH = path.join(OPT_AI_SEC_MANAGEMENT_REL, 'auth_key.txt');
|
|
64
8
|
/** Ensure authentication — verify stored key or request new one via handshake. */
|
|
65
9
|
async function ensureAuthentication(hardwareUuid) {
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
10
|
+
const key = await ensureTofuAuthentication({
|
|
11
|
+
hardwareUuid,
|
|
12
|
+
endpointBase: loadEndpointBase(),
|
|
13
|
+
authRelativePath: AUTH_KEY_RELATIVE_PATH,
|
|
14
|
+
postJson: (endpointUrl, body) => postStartupPayload(endpointUrl, body),
|
|
15
|
+
onLog: (message) => {
|
|
16
|
+
if (message.startsWith('auth:'))
|
|
17
|
+
hookRunLog(message);
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
return key;
|
|
75
21
|
}
|
|
76
22
|
export { ensureAuthentication };
|
|
@@ -1,29 +1,14 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
2
1
|
import path from 'node:path';
|
|
2
|
+
import { getAuthKeyPath as getSharedAuthKeyPath, readStoredAuthKey as readSharedStoredAuthKey, } from 'optimus-tofu';
|
|
3
3
|
import { OPT_AI_SEC_MANAGEMENT_REL } from '../../bootstrap_constants.js';
|
|
4
4
|
const AUTH_KEY_RELATIVE_PATH = path.join(OPT_AI_SEC_MANAGEMENT_REL, 'auth_key.txt');
|
|
5
|
+
const AUTH_KEY_OPTIONS = { authRelativePath: AUTH_KEY_RELATIVE_PATH };
|
|
5
6
|
/** Return absolute path to auth_key.txt, or null if home dir is unavailable. */
|
|
6
7
|
function getAuthKeyPath() {
|
|
7
|
-
|
|
8
|
-
if (!homeDir)
|
|
9
|
-
return null;
|
|
10
|
-
return path.join(homeDir, AUTH_KEY_RELATIVE_PATH);
|
|
8
|
+
return getSharedAuthKeyPath(AUTH_KEY_OPTIONS);
|
|
11
9
|
}
|
|
12
10
|
/** Read and parse the stored auth key, or return null if absent/unreadable. */
|
|
13
11
|
function readStoredAuthKey() {
|
|
14
|
-
|
|
15
|
-
if (!authPath || !existsSync(authPath))
|
|
16
|
-
return null;
|
|
17
|
-
try {
|
|
18
|
-
const raw = readFileSync(authPath, 'utf8');
|
|
19
|
-
const parsed = JSON.parse(raw);
|
|
20
|
-
if (parsed?.key && parsed?.hardware_uuid) {
|
|
21
|
-
return parsed;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
catch (error) {
|
|
25
|
-
console.warn(`Unable to read stored auth key: ${error instanceof Error ? error.message : String(error)}`);
|
|
26
|
-
}
|
|
27
|
-
return null;
|
|
12
|
+
return readSharedStoredAuthKey(AUTH_KEY_OPTIONS);
|
|
28
13
|
}
|
|
29
14
|
export { getAuthKeyPath, readStoredAuthKey };
|
|
@@ -1,65 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
const DEFAULT_ENDPOINT = 'https://demo.optimuslabs.io/';
|
|
4
|
-
/**
|
|
5
|
-
* Walk up from `dir` looking for `optimus_dev.env`, stopping at the filesystem
|
|
6
|
-
* root. Returns the first path found, or null. Mirrors how git finds .git.
|
|
7
|
-
*/
|
|
8
|
-
function findEnvFileUpward(dir) {
|
|
9
|
-
let current = dir;
|
|
10
|
-
while (true) {
|
|
11
|
-
const candidate = path.join(current, 'optimus_dev.env');
|
|
12
|
-
if (existsSync(candidate))
|
|
13
|
-
return candidate;
|
|
14
|
-
const parent = path.dirname(current);
|
|
15
|
-
if (parent === current)
|
|
16
|
-
return null; // filesystem root
|
|
17
|
-
current = parent;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
function parseEndpointFromFile(filePath) {
|
|
21
|
-
try {
|
|
22
|
-
const envContent = readFileSync(filePath, 'utf8');
|
|
23
|
-
for (const line of envContent.split(/\r?\n/)) {
|
|
24
|
-
const trimmed = line.trim();
|
|
25
|
-
if (!trimmed || trimmed.startsWith('#'))
|
|
26
|
-
continue;
|
|
27
|
-
const [key, ...rest] = trimmed.split('=');
|
|
28
|
-
if (key === 'OPTIMUS_ENDPOINT') {
|
|
29
|
-
const value = rest.join('=').trim();
|
|
30
|
-
if (value)
|
|
31
|
-
return value.replace(/\/+$/, '') + '/';
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
catch {
|
|
36
|
-
// ignore
|
|
37
|
-
}
|
|
38
|
-
return null;
|
|
39
|
-
}
|
|
1
|
+
import { getEndpointSource as getSharedEndpointSource, loadEndpointBase, } from "optimus-tofu";
|
|
40
2
|
/** Where endpoint came from (for logging). */
|
|
41
3
|
function getEndpointSource() {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
if (
|
|
46
|
-
return
|
|
47
|
-
return
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Load OPTIMUS_ENDPOINT: env var wins, then walk up from cwd looking for
|
|
51
|
-
* optimus_dev.env, then default (https://demo.optimuslabs.io/).
|
|
52
|
-
*/
|
|
53
|
-
function loadEndpointBase() {
|
|
54
|
-
const fromEnv = process.env.OPTIMUS_ENDPOINT?.trim();
|
|
55
|
-
if (fromEnv)
|
|
56
|
-
return fromEnv.replace(/\/+$/, '') + '/';
|
|
57
|
-
const found = findEnvFileUpward(process.cwd());
|
|
58
|
-
if (found) {
|
|
59
|
-
const value = parseEndpointFromFile(found);
|
|
60
|
-
if (value)
|
|
61
|
-
return value;
|
|
62
|
-
}
|
|
63
|
-
return DEFAULT_ENDPOINT;
|
|
4
|
+
const source = getSharedEndpointSource();
|
|
5
|
+
if (source === "file")
|
|
6
|
+
return "file";
|
|
7
|
+
if (source === "default")
|
|
8
|
+
return "default";
|
|
9
|
+
return "env";
|
|
64
10
|
}
|
|
65
11
|
export { loadEndpointBase, getEndpointSource };
|
|
@@ -1,15 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { createRequire } from 'node:module';
|
|
3
|
-
const canonicalize = createRequire(import.meta.url)('canonicalize');
|
|
4
|
-
/** RFC 8785 canonical JSON — must match server's rfc8785.dumps() exactly. */
|
|
5
|
-
function canonicalizePayload(payload) {
|
|
6
|
-
const out = canonicalize(payload);
|
|
7
|
-
return out ?? '{}';
|
|
8
|
-
}
|
|
9
|
-
/** Create HMAC-SHA256 signature for a payload (canonicalize then sign). */
|
|
10
|
-
function createSignature(payload, keyHex) {
|
|
11
|
-
const canonicalPayload = canonicalizePayload(payload);
|
|
12
|
-
const keyBuffer = Buffer.from(keyHex, 'hex');
|
|
13
|
-
return crypto.createHmac('sha256', keyBuffer).update(canonicalPayload).digest('hex');
|
|
14
|
-
}
|
|
15
|
-
export { canonicalizePayload, createSignature };
|
|
1
|
+
export { canonicalizePayload, createSignature } from 'optimus-tofu';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { createSignature as createSharedSignature } from 'optimus-tofu';
|
|
2
2
|
import { classifyEndpointResponse, postStartupPayload } from '../endpoint_client/index.js';
|
|
3
3
|
import { resolveHardwareUuid } from './hardware_uuid.js';
|
|
4
4
|
import { writeAuthKey, readStoredAuthKey, loadEndpointBase, buildStartupEndpointUrl } from './auth_key_store.js';
|
|
@@ -16,8 +16,8 @@ const canonicalizeValue = (value) => {
|
|
|
16
16
|
};
|
|
17
17
|
const canonicalStringify = (value) => JSON.stringify(canonicalizeValue(value));
|
|
18
18
|
const createSignature = (payloadSummary, keyHex) => {
|
|
19
|
-
|
|
20
|
-
return
|
|
19
|
+
// Keep this adapter for backward compatibility of public exports in log_uuid.
|
|
20
|
+
return createSharedSignature(payloadSummary, keyHex);
|
|
21
21
|
};
|
|
22
22
|
const getMetadata = () => ({
|
|
23
23
|
github_username: process.env.GITHUB_USER || process.env.GH_USER || '',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "log-llm-config",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.35",
|
|
4
4
|
"description": "CLI helpers for logging hardware UUIDs and posting startup payloads to Optimus Security.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"axios": "^1.15.0",
|
|
59
|
-
"canonicalize": "^2.1.0"
|
|
59
|
+
"canonicalize": "^2.1.0",
|
|
60
|
+
"optimus-tofu": "^0.1.0"
|
|
60
61
|
}
|
|
61
62
|
}
|