@botlearn-course/daemon 0.0.20-beta.11 → 0.0.20-beta.13
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 +3 -3
- package/dist/agent-service-sandbox.js +2 -1
- package/dist/agent-service-ws-protocol.d.ts +1 -0
- package/dist/agent-service-ws-protocol.js +1 -0
- package/dist/redaction.js +2 -0
- package/dist/runtime-env.d.ts +1 -1
- package/dist/runtime-env.js +1 -1
- package/dist/sandbox-supervisor.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -36,13 +36,13 @@ npx --yes --package @botlearn-course/daemon@latest botlearn-course-daemon course
|
|
|
36
36
|
| `course doctor` | 打印 Auth 状态(不含 token)与 runtime 探测表(安装路径 / 版本 / 登录状态 / 安装提示)。 |
|
|
37
37
|
| `--help` / `--version` | 帮助与版本。 |
|
|
38
38
|
|
|
39
|
-
包内还包含供 BotLearn 托管
|
|
39
|
+
包内还包含供 BotLearn 托管 sandbox 使用的内部命令
|
|
40
40
|
`botlearn-sandbox-supervisor agent-service session`。它不是 BYOA 用户入口:生产环境只允许由
|
|
41
|
-
Agent Service 以固定 argv 启动,通过 stdin 接收一次性 bootstrap。
|
|
41
|
+
Agent Service 以固定 argv 启动,通过 stdin 接收一次性 bootstrap。sandbox 中 daemon/runtime 分别
|
|
42
42
|
降权到 `botlearn-control`/`user` UID;继承 `NoNewPrivs=1`、无法使用 sudo 的平台保留 root control
|
|
43
43
|
daemon,由 root-owned 固定 launcher 清空附加组后直接降权为 `user`。两条路径都为 DeepSeek
|
|
44
44
|
设置 `no_new_privs`,runtime 用户本身没有 sudo 权限。托管启动链只执行
|
|
45
|
-
`/opt` 下的固定 Node、supervisor、daemon、launcher 与 DeepSeek 文件,不信任
|
|
45
|
+
`/opt` 下的固定 Node、supervisor、daemon、launcher 与 DeepSeek 文件,不信任 provider 会开放给 runtime
|
|
46
46
|
写入的 `/usr/local/bin`。
|
|
47
47
|
`agent-service session --bootstrap-stdin` 同样属于受 supervisor 保护的内部协议,不应直接暴露给
|
|
48
48
|
课程任务或 workspace shell。
|
|
@@ -4,7 +4,7 @@ import { Readable } from "node:stream";
|
|
|
4
4
|
import { pipeline } from "node:stream/promises";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { ensureDaemonHome } from "./auth-store.js";
|
|
7
|
-
import { AGENT_SERVICE_WS_SCHEMA, AGENT_SERVICE_WS_SUBPROTOCOL, createSandboxFrame, createWorkspaceFileChunk, parseSandboxFrame, UnsupportedSandboxProtocolError, WORKSPACE_FILE_READ_BINARY_CAPABILITY, } from "./agent-service-ws-protocol.js";
|
|
7
|
+
import { AGENT_SERVICE_WS_SCHEMA, AGENT_SERVICE_WS_SUBPROTOCOL, createSandboxFrame, createWorkspaceFileChunk, parseSandboxFrame, UnsupportedSandboxProtocolError, WORKSPACE_FILE_READ_BINARY_CAPABILITY, WORKSPACE_SNAPSHOT_ATTESTATION_CAPABILITY, } from "./agent-service-ws-protocol.js";
|
|
8
8
|
import { log as defaultLog, setOperationalLogSink, } from "./log.js";
|
|
9
9
|
import { availableRunCapabilities, runtimeSupportsCourseSkills, } from "./runtime-capabilities.js";
|
|
10
10
|
import { activationRuntimeEnv, runtimeChildEnv } from "./runtime-env.js";
|
|
@@ -875,6 +875,7 @@ export class AgentServiceSandboxClient {
|
|
|
875
875
|
"workspace_writer_freeze_v1",
|
|
876
876
|
"workspace_snapshot_v2",
|
|
877
877
|
"workspace_restore_v1",
|
|
878
|
+
WORKSPACE_SNAPSHOT_ATTESTATION_CAPABILITY,
|
|
878
879
|
...(nasWorkspaceEnabled() ? ["workspace_nas_v1"] : []),
|
|
879
880
|
...(workspaceCopyV1Supported() ? ["workspace_copy_v1"] : []),
|
|
880
881
|
],
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export declare const AGENT_SERVICE_WS_SCHEMA: "botlearn-agent-sandbox-ws/0.4";
|
|
2
2
|
export declare const AGENT_SERVICE_WS_SUBPROTOCOL: "botlearn-agent-sandbox.v4";
|
|
3
3
|
export declare const WORKSPACE_FILE_READ_BINARY_CAPABILITY: "workspace_file_read_binary_v1";
|
|
4
|
+
export declare const WORKSPACE_SNAPSHOT_ATTESTATION_CAPABILITY: "workspace_snapshot_attestation_v1";
|
|
4
5
|
export declare const WORKSPACE_FILE_CHUNK_BYTES: number;
|
|
5
6
|
export declare const WORKSPACE_FILE_CHUNK_HEADER_BYTES = 29;
|
|
6
7
|
export type SandboxFrameType = "sandbox.hello" | "sandbox.sync" | "session.open" | "session.activate" | "turn.start" | "turn.cancel" | "session.close" | "sandbox.drain" | "sandbox.shutdown" | "event.ack" | "auth.rotate" | "workspace.file.read" | "workspace.checkpoint" | "workspace.thaw" | "ping" | "sandbox.ready" | "sandbox.heartbeat" | "command.ack" | "session.opened" | "session.open_failed" | "session.closed" | "turn.event" | "turn.file.report" | "workspace.file.result" | "sandbox.drained" | "sandbox.log" | "pong" | "protocol.error";
|
|
@@ -2,6 +2,7 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
export const AGENT_SERVICE_WS_SCHEMA = "botlearn-agent-sandbox-ws/0.4";
|
|
3
3
|
export const AGENT_SERVICE_WS_SUBPROTOCOL = "botlearn-agent-sandbox.v4";
|
|
4
4
|
export const WORKSPACE_FILE_READ_BINARY_CAPABILITY = "workspace_file_read_binary_v1";
|
|
5
|
+
export const WORKSPACE_SNAPSHOT_ATTESTATION_CAPABILITY = "workspace_snapshot_attestation_v1";
|
|
5
6
|
export const WORKSPACE_FILE_CHUNK_BYTES = 64 * 1024;
|
|
6
7
|
export const WORKSPACE_FILE_CHUNK_HEADER_BYTES = 29;
|
|
7
8
|
const WORKSPACE_FILE_CHUNK_MAGIC = Buffer.from("BLWF", "ascii");
|
package/dist/redaction.js
CHANGED
|
@@ -25,6 +25,7 @@ const QUOTED_JSON_SECRET_PATTERN = new RegExp(`(["'])(${SECRET_KEY_NAME_SOURCE})
|
|
|
25
25
|
const QUOTED_ARGV_SECRET_PATTERN = new RegExp(`(["'])(${SECRET_FLAG_SOURCE})\\1(\\s*,\\s*)(["'])([^"'\\\\]*(?:\\\\.[^"'\\\\]*)*)\\4`, "gi");
|
|
26
26
|
// blic_ 是课程 install code 前缀,与 runtime token 前缀一并脱敏。
|
|
27
27
|
const SECRET_PREFIX_PATTERN = /\b(blic_|drt_|dit_|gho_|ghp_|sk-)[A-Za-z0-9_-]+/g;
|
|
28
|
+
const SIGNED_OBJECT_URL_PATTERN = /https?:\/\/[^\s"'<>]*[?&](?:X-Amz-Algorithm|X-Amz-Credential|X-Amz-Signature|X-Amz-Security-Token)=[^\s"'<>]*/gi;
|
|
28
29
|
const SECRET_VALUE_PATTERNS = [
|
|
29
30
|
[/\b(Bearer\s+)[^\s"']+/gi, `$1${REDACTED}`],
|
|
30
31
|
[new RegExp(`(^|[\\s])(${SECRET_FLAG_SOURCE})=([^\\s"']+)`, "gi"), `$1$2=${REDACTED}`],
|
|
@@ -83,6 +84,7 @@ export function assertNoInjectedCredentials(data, additionalSecrets = []) {
|
|
|
83
84
|
}
|
|
84
85
|
export function redactSecretString(text, additionalSecrets = []) {
|
|
85
86
|
return redactInjectedCredentials(text, additionalSecrets)
|
|
87
|
+
.replace(SIGNED_OBJECT_URL_PATTERN, REDACTED)
|
|
86
88
|
.replace(/\b(Bearer\s+)[^\s"']+/gi, `$1${REDACTED}`)
|
|
87
89
|
.replace(new RegExp(`(^|[\\s])(${SECRET_FLAG_SOURCE})=([^\\s"']+)`, "gi"), `$1$2=${REDACTED}`)
|
|
88
90
|
.replace(new RegExp(`(^|[\\s])(${SECRET_FLAG_SOURCE})(\\s+)([^\\s"']+)`, "gi"), `$1$2$3${REDACTED}`)
|
package/dist/runtime-env.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export declare function runtimeChildIdentity(env?: NodeJS.ProcessEnv): {
|
|
|
16
16
|
/**
|
|
17
17
|
* Build the fixed control-to-runtime privilege boundary used by managed sandboxes.
|
|
18
18
|
*
|
|
19
|
-
*
|
|
19
|
+
* The legacy image boundary may grant botlearn-control one fixed sudoers command.
|
|
20
20
|
* Platforms that inherit no_new_privs cannot use sudo, so their root supervisor daemon
|
|
21
21
|
* invokes the same immutable launcher directly; the launcher clears supplementary groups
|
|
22
22
|
* and performs the one-way uid/gid drop. BYOA retains direct-spawn behavior.
|
package/dist/runtime-env.js
CHANGED
|
@@ -96,7 +96,7 @@ export function runtimeChildIdentity(env = process.env) {
|
|
|
96
96
|
/**
|
|
97
97
|
* Build the fixed control-to-runtime privilege boundary used by managed sandboxes.
|
|
98
98
|
*
|
|
99
|
-
*
|
|
99
|
+
* The legacy image boundary may grant botlearn-control one fixed sudoers command.
|
|
100
100
|
* Platforms that inherit no_new_privs cannot use sudo, so their root supervisor daemon
|
|
101
101
|
* invokes the same immutable launcher directly; the launcher clears supplementary groups
|
|
102
102
|
* and performs the one-way uid/gid drop. BYOA retains direct-spawn behavior.
|
|
@@ -19,7 +19,7 @@ const MANAGED_PATH = [
|
|
|
19
19
|
"/opt/node/22.23.1/bin",
|
|
20
20
|
"/usr/bin",
|
|
21
21
|
"/bin",
|
|
22
|
-
//
|
|
22
|
+
// The managed image exposes this directory as runtime-writable. Keep it last and never
|
|
23
23
|
// use it for a managed control-plane executable.
|
|
24
24
|
"/usr/local/bin",
|
|
25
25
|
].join(":");
|
package/package.json
CHANGED