Public, free to read, reuse, and adapt — Kirk Patrick Miller's notice for this edition. Not a patent grant.
Public work excerpts — privacy boundaries marked · c06
569a78c8f4 · words 1572 · characters 47075–59525
Previous section · Next section
Exact section text · Full source · Source index
function runBridgeCli(argv) {
var cmd = argv[0];
if (!cmd || cmd.indexOf('--') !== 0) return false;
bridgeEphemeral = false; // the command line always edits the trust file itself
var st = trustState();
var arg = argv[1];
function say(s) { console.log(' ' + s); }
function fail(s) { console.error(' ! ' + s); process.exitCode = 1; return true; }
function findMind(id) { return st.minds.filter(function (m) { return m.id === String(id || ''); })[0] || null; }
switch (cmd) {
case '--list-minds': {
say('Trusted minds (' + st.minds.length + '). Tokens are never shown; only their hashes are kept.');
st.minds.forEach(function (m) {
say(m.id + ' ' + m.kind + ' ' + m.name + (m.origin ? ' ' + m.origin : '') +
' scopes=' + m.scopes.join(',') + ' paired=' + (m.createdAt || '?') +
' last=' + (m.lastUsedAt || 'never') + (m.kind === 'cli' && !st.localTools ? ' (off)' : ''));
});
say('Local tools: ' + (st.localTools ? 'trusted (token file ' + TOKEN_FILE + ')' : 'off'));
say('Extra trusted origins: ' + (st.trustedOrigins.length ? st.trustedOrigins.join(', ') : 'none'));
say('Project folders: ' + rootList().map(function (r) { return r.name + '=' + r.path; }).join(', '));
return true;
}
case '--revoke': {
var m = findMind(arg);
if (!m) return fail('No trusted mind with id ' + String(arg || '(missing)') + '. Try --list-minds.');
st.minds = st.minds.filter(function (x) { return x.id !== m.id; });
if (m.kind === 'cli') { st.localTools = false; try { fs.unlinkSync(TOKEN_FILE); } catch (e) {} }
if (!saveTrust()) return fail('Could not save.');
ledgerAppend({ kind: 'pair', route: 'cli:--revoke', device: m.id, result: 'revoked' });
say('Revoked ' + m.name + ' (' + m.id + '). Its next request will be asked to pair.');
return true;
}
case '--revoke-all': {
var before = st.minds.length;
st.minds = st.minds.filter(function (x) { return x.kind === 'cli'; });
if (!saveTrust()) return fail('Could not save.');
ledgerAppend({ kind: 'pair', route: 'cli:--revoke-all', result: 'revoked-all' });
say('Revoked ' + (before - st.minds.length) + ' paired device(s). Local tools stay trusted.');
return true;
}
case '--allow-secrets':
case '--deny-secrets': {
var sm = findMind(arg);
if (!sm) return fail('No trusted mind with id ' + String(arg || '(missing)') + '.');
sm.scopes = sm.scopes.filter(function (s) { return s !== 'secrets'; });
if (cmd === '--allow-secrets') sm.scopes.push('secrets');
if (!saveTrust()) return fail('Could not save.');
ledgerAppend({ kind: 'pair', route: 'cli:' + cmd, device: sm.id, result: 'scopes' });
say(sm.name + ' scopes: ' + sm.scopes.join(','));
return true;
}
case '--trust-origin':
case '--untrust-origin': {
var o = exactOrigin(arg);
if (!o) return fail('Exact origins only, like https://example.dev or http://192.168.1.20:8000. Never *.');
st.trustedOrigins = st.trustedOrigins.filter(function (x) { return x !== o; });
if (cmd === '--trust-origin') st.trustedOrigins.push(o);
if (!saveTrust()) return fail('Could not save.');
ledgerAppend({ kind: 'trust', route: 'cli:' + cmd, origin: o, result: 'ok' });
say((cmd === '--trust-origin' ? 'Trusted ' : 'Removed ') + o + '. It still has to pair before it can change anything.');
return true;
}
case '--add-root': {
var name = String(arg || '');
var dir = argv[2] ? path.resolve(argv[2]) : '';
if (!/^[a-z0-9][a-z0-9_-]{0,31}$/i.test(name) || name === 'project') return fail('Name: letters, digits, - or _, up to 32, not "project".');
var isDir = false;
try { isDir = fs.statSync(dir).isDirectory(); } catch (e) {}
if (!dir || !isDir) return fail('Folder not found: ' + String(argv[2] || '(missing)'));
st.roots[name] = fs.realpathSync(dir);
if (!saveTrust()) return fail('Could not save.');
ledgerAppend({ kind: 'trust', route: 'cli:--add-root', result: 'ok' });
say('Trusted project folder "' + name + '" = ' + st.roots[name]);
return true;
}
case '--remove-root': {
if (!Object.prototype.hasOwnProperty.call(st.roots, String(arg || ''))) return fail('No project folder named ' + String(arg || '(missing)') + '.');
delete st.roots[arg];
if (!saveTrust()) return fail('Could not save.');
ledgerAppend({ kind: 'trust', route: 'cli:--remove-root', result: 'ok' });
say('Removed project folder "' + arg + '".');
return true;
}
case '--trust-local-tools': {
st.localTools = true;
if (!saveTrust()) return fail('Could not save.');
ensureLocalToolsToken();
ledgerAppend({ kind: 'pair', route: 'cli:--trust-local-tools', result: 'local-tools-on' });
say('Local tools on this computer are trusted. Token file: ' + TOKEN_FILE);
return true;
}
case '--untrust-local-tools': {
st.localTools = false;
st.minds = st.minds.filter(function (x) { return x.kind !== 'cli'; });
try { fs.unlinkSync(TOKEN_FILE); } catch (e) {}
if (!saveTrust()) return fail('Could not save.');
ledgerAppend({ kind: 'pair', route: 'cli:--untrust-local-tools', result: 'local-tools-off' });
say('Local tools now need to pair like any other device.');
return true;
}
default:
bridgeLockUsage();
return fail('Unknown option ' + cmd);
}
}
## Exact source excerpt, characters 48734–48859
function bridgeLockInit() {
trustState();
ensureLocalToolsToken();
}
// ── end LAYER bridge-lock-v0 · v0.1 helpers ──
```
## Exact source excerpt, characters 48861–48909
### Block B: `handleRequest` (replaces L111-129)
## Exact source excerpt, characters 48911–49277
```js
function handleRequest(req, res) {
// LAYER bridge-lock-v0: the old `Access-Control-Allow-Origin: *` is superseded here.
var origin = req.headers.origin || '';
var pathname = String(req.url || '/').split('?')[0];
res.setHeader('Content-Type', 'application/json');
res.setHeader('Vary', 'Origin');
res.setHeader('X-Content-Type-Options', 'nosniff');
## Exact source excerpt, characters 49279–49498
// 1. Host guard (DNS rebinding): only 127.0.0.1 / localhost.
if (!hostAllowed(req.headers.host)) {
req.resume();
return respond(res, 403, { error: 'Host not allowed', bridgeLock: BRIDGE_LOCK_VERSION });
}
## Exact source excerpt, characters 49500–50465
// 2. Origin guard. Browsers always send Origin on cross-origin fetches and
// preflights. No Origin = local CLI or same-machine tool (still needs
// a trusted token for anything that changes state).
if (origin && !originAllowed(origin)) {
if (pathname === '/code/git/commit') {
ledgerAppend({ route: pathname, origin: origin, result: 'refused:origin' });
}
req.resume();
return respond(res, 403, { error: 'Origin not on the FreeLattice allowlist', bridgeLock: BRIDGE_LOCK_VERSION });
}
if (origin) {
res.setHeader('Access-Control-Allow-Origin', origin);
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, X-Agent-Id, X-FL-Bridge-Token');
res.setHeader('Access-Control-Max-Age', '600');
if (req.headers['access-control-request-private-network']) {
res.setHeader('Access-Control-Allow-Private-Network', 'true');
}
}
## Exact source excerpt, characters 50467–50555
if (req.method === 'OPTIONS') { req.resume(); res.writeHead(204); res.end(); return; }
## Exact source excerpt, characters 50557–51059
// 3. Trusted-mind guard: which paired device (or local tool) is this?
var gated = needsToken(req.method, pathname);
var mind = gated ? requestMind(req) : null;
if (gated && !mind) {
if (pathname === '/code/git/commit') {
ledgerAppend({ route: pathname, origin: origin, result: 'refused:token' });
}
req.resume();
return respond(res, 401, { error: 'Pair with the Agent Bridge first (token missing, stale or revoked).', pair: 'code', bridgeLock: BRIDGE_LOCK_VERSION });
}
## Exact source excerpt, characters 51061–51618
// 4. Scope guard. A new mind has every scope except 'secrets' (.env files).
var need = mind ? scopeFor(req.method, pathname) : '';
if (need && mind.scopes.indexOf(need) === -1) {
if (pathname === '/code/git/commit') {
ledgerAppend({ route: pathname, origin: origin, device: mind.id, result: 'refused:scope' });
}
req.resume();
return respond(res, 403, { error: 'This mind has not been given "' + need + '" here. Kirk can add it in Paired minds.', scope: need, bridgeLock: BRIDGE_LOCK_VERSION });
}
if (mind) touchMind(mind);
## Exact source excerpt, characters 51620–51757
// Allow requests to act as a different agent via X-Agent-Id header
var requestAgentId = req.headers['x-agent-id'] || agentId.meshId;
## Exact source excerpt, characters 51759–52650
// 5. Body cap. Drain the rest so the client sees the 413 cleanly.
var chunks = [];
var size = 0;
var tooBig = false;
req.on('data', function(chunk) {
size += chunk.length;
if (size > MAX_BODY_BYTES) { tooBig = true; chunks = []; return; }
if (!tooBig) chunks.push(chunk);
});
req.on('end', function() {
if (tooBig) return respond(res, 413, { error: 'Body too large (max ' + MAX_BODY_BYTES + ' bytes)' });
var body = Buffer.concat(chunks).toString('utf8');
var data = {};
if (body) {
try { data = JSON.parse(body); }
catch (e) { return respond(res, 400, { error: 'Body is not valid JSON' }); }
if (!data || typeof data !== 'object' || Array.isArray(data)) return respond(res, 400, { error: 'Body must be a JSON object' });
}
route(req.url, req.method, data, res, requestAgentId, { origin: origin, mind: mind });
});
}
```
## Exact source excerpt, characters 52652–52717
### Block C: pairing and trusted-minds routes (insert after L133)
## Exact source excerpt, characters 52719–55008
```js
// ── LAYER bridge-lock-v0 · v0.1: pairing and trusted minds ──
if (url === '/pair' && method === 'POST') {
var now = Date.now();
if (!pairState.code || now > pairState.expires) newPairCode('expired');
if (now < pairState.coolUntil) return respond(res, 429, { error: 'Resting for a moment. Try again in 30 seconds.' });
var given = normalizePairCode(data.code);
var good = given.length === 6 &&
crypto.timingSafeEqual(Buffer.from(given, 'utf8'), Buffer.from(pairState.code, 'utf8'));
var pairOrigin = (meta && meta.origin) || '';
if (!good) {
pairState.tries += 1;
if (pairState.tries >= PAIR_MAX_TRIES) {
ledgerAppend({ kind: 'pair', route: '/pair', origin: pairOrigin, result: 'refused:lockout' });
newPairCode('lockout');
return respond(res, 429, { error: 'Too many tries. The bridge window shows a new code.' });
}
return respond(res, 403, { error: 'That code does not match. Check the bridge window.', triesLeft: PAIR_MAX_TRIES - pairState.tries });
}
var st = trustState();
var tok = newToken();
var mind = {
id: newMindId(),
name: cleanName(data.name) || (pairOrigin ? 'A browser at ' + pairOrigin : 'A local tool'),
origin: pairOrigin,
kind: pairOrigin ? 'browser' : 'tool',
scopes: DEFAULT_SCOPES.slice(),
tokenSha256: sha256Hex(tok),
createdAt: new Date().toISOString(),
lastUsedAt: '',
expiresAt: null
};
st.minds.push(mind);
if (!saveTrust()) {
st.minds = st.minds.filter(function (m) { return m.id !== mind.id; });
return respond(res, 500, { error: 'The bridge could not save this pairing. Check ~/.freelattice.' });
}
ledgerAppend({ kind: 'pair', route: '/pair', origin: pairOrigin, device: mind.id, result: 'ok' });
console.log(' \u2726 Paired "' + mind.name + '" (' + mind.id + '). ' +
(bridgeEphemeral ? 'Ephemeral mode: forgotten when the bridge stops.' : 'It stays paired until you revoke it.'));
newPairCode('used'); // single use: the next device gets a fresh code
return respond(res, 200, { token: tok, id: mind.id, name: mind.name, scopes: mind.scopes,
persistent: !bridgeEphemeral, bridgeLock: BRIDGE_LOCK_VERSION });
}
## Exact source excerpt, characters 55010–55274