@agent-beam/beam 0.2.20 → 0.2.22
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 +19 -0
- package/dist/account.js +1 -1
- package/dist/account.js.map +1 -1
- package/dist/agents.d.ts +8 -2
- package/dist/agents.js +7 -7
- package/dist/agents.js.map +1 -1
- package/dist/cli.js +289 -41
- package/dist/cli.js.map +1 -1
- package/dist/client.js +23 -6
- package/dist/client.js.map +1 -1
- package/dist/connect.js +1 -1
- package/dist/connect.js.map +1 -1
- package/dist/enroll.d.ts +0 -4
- package/dist/enroll.js +2 -60
- package/dist/enroll.js.map +1 -1
- package/dist/forward.d.ts +2 -0
- package/dist/forward.js +19 -0
- package/dist/forward.js.map +1 -1
- package/dist/hook-adapters.js +14 -1
- package/dist/hook-adapters.js.map +1 -1
- package/dist/install.d.ts +2 -0
- package/dist/install.js +58 -6
- package/dist/install.js.map +1 -1
- package/dist/policy.d.ts +1 -0
- package/dist/policy.js +11 -3
- package/dist/policy.js.map +1 -1
- package/dist/serve.d.ts +2 -0
- package/dist/serve.js +47 -2
- package/dist/serve.js.map +1 -1
- package/dist/setup.js +33 -2
- package/dist/setup.js.map +1 -1
- package/dist/skill-context.d.ts +11 -0
- package/dist/skill-context.js +78 -0
- package/dist/skill-context.js.map +1 -0
- package/dist/skill-gate.d.ts +21 -0
- package/dist/skill-gate.js +180 -0
- package/dist/skill-gate.js.map +1 -0
- package/dist/skill-inventory.d.ts +81 -0
- package/dist/skill-inventory.js +167 -0
- package/dist/skill-inventory.js.map +1 -0
- package/dist/skill-risk-rules.d.ts +17 -0
- package/dist/skill-risk-rules.js +61 -0
- package/dist/skill-risk-rules.js.map +1 -0
- package/dist/skill-scan.d.ts +27 -0
- package/dist/skill-scan.js +157 -0
- package/dist/skill-scan.js.map +1 -0
- package/dist/skill-setup.d.ts +11 -0
- package/dist/skill-setup.js +26 -0
- package/dist/skill-setup.js.map +1 -0
- package/dist/skill-sync.d.ts +40 -0
- package/dist/skill-sync.js +79 -0
- package/dist/skill-sync.js.map +1 -0
- package/dist/skill-watch.d.ts +16 -0
- package/dist/skill-watch.js +41 -0
- package/dist/skill-watch.js.map +1 -0
- package/dist/skills.d.ts +33 -0
- package/dist/skills.js +139 -0
- package/dist/skills.js.map +1 -0
- package/dist/tamper.d.ts +9 -0
- package/dist/tamper.js +116 -0
- package/dist/tamper.js.map +1 -0
- package/dist/trusted-skills.d.ts +9 -0
- package/dist/trusted-skills.js +31 -0
- package/dist/trusted-skills.js.map +1 -0
- package/dist/tty-prompt.js +3 -1
- package/dist/tty-prompt.js.map +1 -1
- package/package.json +2 -2
package/dist/tamper.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// Tamper detection: beam's hook install/service can be removed two ways -- through beam itself
|
|
2
|
+
// ('beam uninstall', 'beam agent install-all', ...), which is authorized and already tells the
|
|
3
|
+
// workspace via revokeDevice()/reportControlEvent() below, or by hand (editing an agent's config
|
|
4
|
+
// file directly, deleting it, unloading the launchd/systemd job) -- which today leaves no record
|
|
5
|
+
// anywhere. This module gives the collector a baseline of what *should* be installed and reports
|
|
6
|
+
// the difference as a critical finding the moment it notices something vanished outside beam's
|
|
7
|
+
// own code path. It cannot detect the collector process itself being killed -- a dead process
|
|
8
|
+
// can't self-report -- that has to be inferred workspace-side from a heartbeat/last-seen gap;
|
|
9
|
+
// this module only covers "the collector is still alive but something under it was tampered with."
|
|
10
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
11
|
+
import { homedir, hostname } from "node:os";
|
|
12
|
+
import { dirname, join } from "node:path";
|
|
13
|
+
import { getDataDirectory } from "./config.js";
|
|
14
|
+
import { findAgent } from "./agents.js";
|
|
15
|
+
import { installedHookAgentIds } from "./install.js";
|
|
16
|
+
import { normalize } from "./core.js";
|
|
17
|
+
import { forwardEvents } from "./forward.js";
|
|
18
|
+
function tamperStatePath() {
|
|
19
|
+
return join(getDataDirectory(), "tamper-state.json");
|
|
20
|
+
}
|
|
21
|
+
export async function readTamperState() {
|
|
22
|
+
try {
|
|
23
|
+
return JSON.parse(await readFile(tamperStatePath(), "utf8"));
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async function writeTamperState(state) {
|
|
30
|
+
const path = tamperStatePath();
|
|
31
|
+
await mkdir(dirname(path), { recursive: true, mode: 0o700 });
|
|
32
|
+
await writeFile(path, `${JSON.stringify(state, null, 2)}\n`, { mode: 0o600 });
|
|
33
|
+
}
|
|
34
|
+
// Snapshots which agents currently have beam's hook installed and remembers it as the expected
|
|
35
|
+
// baseline. Call this right after any *authorized* change to hook state (installHook,
|
|
36
|
+
// uninstallHook, installAllDetectedHooks, uninstallAllHooks, and every 'beam start') so the
|
|
37
|
+
// baseline always reflects the last state a beam command itself produced. checkForTampering()
|
|
38
|
+
// below then only flags a gap between that baseline and reality -- i.e. a change nobody made
|
|
39
|
+
// through beam.
|
|
40
|
+
export async function recordExpectedHooks(home = homedir()) {
|
|
41
|
+
const expectedHooks = await installedHookAgentIds(home);
|
|
42
|
+
await writeTamperState({ expectedHooks, updatedAt: new Date().toISOString() });
|
|
43
|
+
}
|
|
44
|
+
function selfMonitorRecord(fields, severity) {
|
|
45
|
+
return {
|
|
46
|
+
record_type: "finding",
|
|
47
|
+
source_agent: "beam",
|
|
48
|
+
source_type: "self-monitor",
|
|
49
|
+
severity,
|
|
50
|
+
hostname: hostname(),
|
|
51
|
+
timestamp: new Date().toISOString(),
|
|
52
|
+
...fields,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function tamperFindingRecord(agentId) {
|
|
56
|
+
const name = findAgent(agentId)?.name ?? agentId;
|
|
57
|
+
return selfMonitorRecord({
|
|
58
|
+
event_type: "beam.tamper",
|
|
59
|
+
rule_id: "beam.tamper.hook_removed",
|
|
60
|
+
title: `Beam monitoring hook removed from ${name}`,
|
|
61
|
+
summary: `${name}'s beam hook disappeared from its config on ${hostname()} outside of any 'beam uninstall' or 'beam agent' command. This agent is no longer being observed or policy-enforced by beam.`,
|
|
62
|
+
}, "critical");
|
|
63
|
+
}
|
|
64
|
+
// Compares the live on-disk hook set against the last known-good baseline and returns one
|
|
65
|
+
// critical finding Event per hook that vanished without going through beam. The caller (serve.ts)
|
|
66
|
+
// stores these locally and forwards them to the workspace exactly like any other captured event,
|
|
67
|
+
// so they land on the dashboard's existing Activity/Security risks views with no new backend
|
|
68
|
+
// route required. Never throws -- a failure here must not take down the collector's poll loop.
|
|
69
|
+
export async function checkForTampering(home = homedir()) {
|
|
70
|
+
try {
|
|
71
|
+
const state = await readTamperState();
|
|
72
|
+
const current = await installedHookAgentIds(home);
|
|
73
|
+
if (!state) {
|
|
74
|
+
await recordExpectedHooks(home);
|
|
75
|
+
return [];
|
|
76
|
+
}
|
|
77
|
+
const missing = state.expectedHooks.filter(id => !current.includes(id));
|
|
78
|
+
const changed = missing.length > 0
|
|
79
|
+
|| current.length !== state.expectedHooks.length
|
|
80
|
+
|| current.some(id => !state.expectedHooks.includes(id));
|
|
81
|
+
if (changed)
|
|
82
|
+
await writeTamperState({ expectedHooks: current, updatedAt: new Date().toISOString() });
|
|
83
|
+
if (!missing.length)
|
|
84
|
+
return [];
|
|
85
|
+
const events = [];
|
|
86
|
+
for (const agentId of missing) {
|
|
87
|
+
try {
|
|
88
|
+
events.push(normalize(tamperFindingRecord(agentId)));
|
|
89
|
+
}
|
|
90
|
+
catch { /* skip a record normalize() can't accept */ }
|
|
91
|
+
}
|
|
92
|
+
return events;
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Explicit, non-tamper notice for an authorized stop/uninstall/logout, so the dashboard can tell
|
|
99
|
+
// "an admin or device owner deliberately turned this off" apart from the silent disappearance
|
|
100
|
+
// checkForTampering() exists to catch. Sent directly (not through the local collector, which may
|
|
101
|
+
// already be shutting down as part of the same command) using whatever identity is still on disk
|
|
102
|
+
// at the moment the caller invokes this -- callers must call it *before* clearing that identity.
|
|
103
|
+
// Best-effort: never blocks the command that calls it.
|
|
104
|
+
export async function reportControlEvent(ruleSuffix, title, detail) {
|
|
105
|
+
try {
|
|
106
|
+
const event = normalize(selfMonitorRecord({
|
|
107
|
+
event_type: "beam.control",
|
|
108
|
+
rule_id: `beam.control.${ruleSuffix}`,
|
|
109
|
+
title,
|
|
110
|
+
summary: detail,
|
|
111
|
+
}, "info"));
|
|
112
|
+
await forwardEvents(event);
|
|
113
|
+
}
|
|
114
|
+
catch { /* best-effort only */ }
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=tamper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tamper.js","sourceRoot":"","sources":["../src/tamper.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type TrustedSkill = {
|
|
2
|
+
name: string;
|
|
3
|
+
hash: string;
|
|
4
|
+
trustedAt: string;
|
|
5
|
+
};
|
|
6
|
+
export declare const trustedSkillsFile: () => string;
|
|
7
|
+
export declare function readTrustedSkills(): Promise<TrustedSkill[]>;
|
|
8
|
+
export declare function trustSkill(name: string, hash: string): Promise<void>;
|
|
9
|
+
export declare function untrustSkill(nameOrHash: string): Promise<number>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { getDataDirectory } from "./config.js";
|
|
4
|
+
export const trustedSkillsFile = () => join(getDataDirectory(), "trusted-skills.json");
|
|
5
|
+
export async function readTrustedSkills() {
|
|
6
|
+
try {
|
|
7
|
+
const parsed = JSON.parse(await readFile(trustedSkillsFile(), "utf8"));
|
|
8
|
+
return Array.isArray(parsed) ? parsed.filter((t) => typeof t?.hash === "string" && typeof t?.name === "string") : [];
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return [];
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
async function write(list) {
|
|
15
|
+
await mkdir(getDataDirectory(), { recursive: true, mode: 0o700 });
|
|
16
|
+
const file = trustedSkillsFile();
|
|
17
|
+
const temp = `${file}.tmp`;
|
|
18
|
+
await writeFile(temp, JSON.stringify(list, null, 2) + "\n", { mode: 0o600 });
|
|
19
|
+
await rename(temp, file);
|
|
20
|
+
}
|
|
21
|
+
export async function trustSkill(name, hash) {
|
|
22
|
+
const list = (await readTrustedSkills()).filter(t => t.hash !== hash);
|
|
23
|
+
await write([...list, { name, hash, trustedAt: new Date().toISOString() }]);
|
|
24
|
+
}
|
|
25
|
+
export async function untrustSkill(nameOrHash) {
|
|
26
|
+
const list = await readTrustedSkills();
|
|
27
|
+
const next = list.filter(t => t.name !== nameOrHash && t.hash !== nameOrHash);
|
|
28
|
+
await write(next);
|
|
29
|
+
return list.length - next.length;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=trusted-skills.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trusted-skills.js","sourceRoot":"","sources":["../src/trusted-skills.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAO/C,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,qBAAqB,CAAC,CAAC;AAEvF,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,iBAAiB,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;QACvE,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAqB,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,KAAK,QAAQ,IAAI,OAAO,CAAC,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1I,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,EAAE,CAAC;IAAC,CAAC;AACxB,CAAC;AAED,KAAK,UAAU,KAAK,CAAC,IAAoB;IACvC,MAAM,KAAK,CAAC,gBAAgB,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAClE,MAAM,IAAI,GAAG,iBAAiB,EAAE,CAAC;IAAC,MAAM,IAAI,GAAG,GAAG,IAAI,MAAM,CAAC;IAC7D,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7E,MAAM,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY,EAAE,IAAY;IACzD,MAAM,IAAI,GAAG,CAAC,MAAM,iBAAiB,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IACtE,MAAM,KAAK,CAAC,CAAC,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC;AAC9E,CAAC;AACD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,UAAkB;IACnD,MAAM,IAAI,GAAG,MAAM,iBAAiB,EAAE,CAAC;IACvC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,IAAI,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;IAC9E,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;IAClB,OAAO,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;AACnC,CAAC"}
|
package/dist/tty-prompt.js
CHANGED
|
@@ -35,7 +35,9 @@ export async function promptTty(message, choices) {
|
|
|
35
35
|
clearTimeout(timer);
|
|
36
36
|
rl.close();
|
|
37
37
|
input.destroy();
|
|
38
|
-
|
|
38
|
+
// Flush the prompt before closing the terminal stream. Destroying it immediately can
|
|
39
|
+
// interrupt an in-flight write and emit ERR_STREAM_DESTROYED after the choice is read.
|
|
40
|
+
output.end();
|
|
39
41
|
resolvePromise(value);
|
|
40
42
|
};
|
|
41
43
|
const timer = setTimeout(() => finish(null), PROMPT_TIMEOUT_MS);
|
package/dist/tty-prompt.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tty-prompt.js","sourceRoot":"","sources":["../src/tty-prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAIhD,MAAM,iBAAiB,GAAG,OAAO,CAAC;AAElC,8FAA8F;AAC9F,8FAA8F;AAC9F,4FAA4F;AAC5F,6FAA6F;AAC7F,0DAA0D;AAC1D,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAe,EAAE,OAAoB;IACnE,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC;IAC9C,IAAI,CAAC;QAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;IAErE,OAAO,IAAI,OAAO,CAAC,cAAc,CAAC,EAAE;QAClC,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,IAAI,KAA0C,CAAC;QAC/C,IAAI,MAA4C,CAAC;QACjD,IAAI,CAAC;YACH,KAAK,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;YACrC,MAAM,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC;YACP,cAAc,CAAC,IAAI,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9D,MAAM,MAAM,GAAG,CAAC,KAAoB,EAAE,EAAE;YACtC,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,KAAK,CAAC,OAAO,EAAE,CAAC;YAChB,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"tty-prompt.js","sourceRoot":"","sources":["../src/tty-prompt.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-beam/beam",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.22",
|
|
4
4
|
"description": "Local-first observation and heuristic risk scanning for AI coding agents (Claude Code, Codex, Cursor, Copilot CLI, Gemini). Redacts secrets, flags risky tool calls, scans skills and MCP configs offline.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai agent security",
|
|
@@ -75,4 +75,4 @@
|
|
|
75
75
|
"tsx": "^4.19.2",
|
|
76
76
|
"typescript": "^5.7.2"
|
|
77
77
|
}
|
|
78
|
-
}
|
|
78
|
+
}
|