@blogic-cz/agent-tools 1.6.16 → 1.6.17
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
CHANGED
|
@@ -249,6 +249,17 @@ import { handleToolExecuteBefore } from "@blogic-cz/agent-tools/credential-guard
|
|
|
249
249
|
export default { handleToolExecuteBefore };
|
|
250
250
|
```
|
|
251
251
|
|
|
252
|
+
Guard refusals include recovery guidance for the policy that blocked the command. Direct CLI
|
|
253
|
+
refusals preserve the configured wrapper or suggestion. Built-in wrappers support `--help`;
|
|
254
|
+
consult this README and the tool's own help to find an existing bounded operation.
|
|
255
|
+
|
|
256
|
+
Interactive and login shells load startup files. Supported noninteractive literal forms pass
|
|
257
|
+
only when the guard proves their complete closed body. The guard sees command text, not external
|
|
258
|
+
script contents, so removing shell flags does not certify a script. The guard provides no generic
|
|
259
|
+
approved external-script executor. Review or implement a repository-owned bounded operation with
|
|
260
|
+
secret injection and filtered output when existing tools do not cover the task. Environment
|
|
261
|
+
approval permits exact nonsensitive reads, not script execution or environment forwarding.
|
|
262
|
+
|
|
252
263
|
## Tools
|
|
253
264
|
|
|
254
265
|
| Binary | Description |
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/credential-guard/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAmB,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAK5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAM/D,8CAA8C;AAC9C,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,+CAA+C;AAC/C,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B,CAAC;AAQF,+CAA+C;AAC/C,MAAM,MAAM,eAAe,GAAG;IAC5B,uBAAuB,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;IACxE,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC3E,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IAC7C,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IAC7C,sBAAsB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IACrD,iBAAiB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACjF,kBAAkB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IACjD,kBAAkB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CACxD,CAAC;AA4+FF,6CAA6C;AAC7C,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAErE;AAED,2CAA2C;AAC3C,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAEpE;AAED,2CAA2C;AAC3C,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAEpE;AAMD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,CAAC,EAAE,qBAAqB,GAAG,eAAe,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/credential-guard/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAmB,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAK5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAM/D,8CAA8C;AAC9C,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,+CAA+C;AAC/C,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B,CAAC;AAQF,+CAA+C;AAC/C,MAAM,MAAM,eAAe,GAAG;IAC5B,uBAAuB,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;IACxE,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC3E,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IAC7C,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IAC7C,sBAAsB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IACrD,iBAAiB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACjF,kBAAkB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IACjD,kBAAkB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CACxD,CAAC;AA4+FF,6CAA6C;AAC7C,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAErE;AAED,2CAA2C;AAC3C,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAEpE;AAED,2CAA2C;AAC3C,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAEpE;AAMD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,CAAC,EAAE,qBAAqB,GAAG,eAAe,CA4arF;AAQD,kEAAkE;AAClE,eAAO,MAAM,uBAAuB,UAl8GD,SAAS,UAAU,UAAU,KAAK,IAk8GM,CAAC;AAE5E,oDAAoD;AACpD,eAAO,MAAM,aAAa,YAp8GC,MAAM,KAAK;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAo8GjB,CAAC;AAExD,yEAAyE;AACzE,eAAO,MAAM,aAAa,aAt8GE,MAAM,KAAK,OAs8GgB,CAAC;AAExD,yDAAyD;AACzD,eAAO,MAAM,aAAa,aAx8GE,MAAM,KAAK,OAw8GgB,CAAC;AAExD,oEAAoE;AACpE,eAAO,MAAM,sBAAsB,YA18GC,MAAM,KAAK,OA08G0B,CAAC;AAE1E,iDAAiD;AACjD,eAAO,MAAM,iBAAiB,YA58GC,MAAM,KAAK;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IA48Gf,CAAC;AAEhE,wDAAwD;AACxD,eAAO,MAAM,kBAAkB,YA98GC,MAAM,KAAK,OA88GsB,CAAC;AAElE,8EAA8E;AAC9E,eAAO,MAAM,kBAAkB,YAh9GC,MAAM,KAAK,MAAM,GAAG,IAg9Ga,CAAC"}
|
package/package.json
CHANGED
|
@@ -3426,6 +3426,55 @@ export function createCredentialGuard(config?: CredentialGuardConfig): Credentia
|
|
|
3426
3426
|
}
|
|
3427
3427
|
}
|
|
3428
3428
|
|
|
3429
|
+
function blockedCliRecovery(blockedTool: { name: string; wrapper: string }): string {
|
|
3430
|
+
// Custom suggestions can be prose or commands. Preserve them without inventing a binary.
|
|
3431
|
+
const hasKnownHelp = DEFAULT_BLOCKED_CLI_TOOLS.some(
|
|
3432
|
+
({ wrapper }) => wrapper === blockedTool.wrapper,
|
|
3433
|
+
);
|
|
3434
|
+
return (
|
|
3435
|
+
`Configured recovery: ${blockedTool.wrapper}\n` +
|
|
3436
|
+
(hasKnownHelp ? `Discover supported operations: ${blockedTool.wrapper} --help\n` : "") +
|
|
3437
|
+
`Check the project README and the tool's documented help for the bounded operation.`
|
|
3438
|
+
);
|
|
3439
|
+
}
|
|
3440
|
+
|
|
3441
|
+
function dangerousCommandRecovery(command: string, reason: string): string {
|
|
3442
|
+
if (reason.startsWith("invokes a blocked CLI")) {
|
|
3443
|
+
const blockedTool = getBlockedCliTool(command);
|
|
3444
|
+
if (blockedTool) return blockedCliRecovery(blockedTool);
|
|
3445
|
+
}
|
|
3446
|
+
const externalExecutionRecovery =
|
|
3447
|
+
`The guard sees the command, not external script contents. Removing shell flags does not certify a script. ` +
|
|
3448
|
+
`No generic approved external-script executor is provided by this guard. Review or implement a repository-owned bounded operation ` +
|
|
3449
|
+
`with secret injection and filtered output; discover existing operations in the project README and tool help.`;
|
|
3450
|
+
if (reason.startsWith("cannot prove") && reason.includes("shell")) {
|
|
3451
|
+
return (
|
|
3452
|
+
`Interactive and login shells load startup files, which can execute code or load credentials. ` +
|
|
3453
|
+
`Only supported noninteractive literal forms, such as sh -c or zsh -f -c, with a completely proved closed body can pass. ` +
|
|
3454
|
+
externalExecutionRecovery
|
|
3455
|
+
);
|
|
3456
|
+
}
|
|
3457
|
+
if (reason.includes("file")) {
|
|
3458
|
+
return (
|
|
3459
|
+
`Use a nonsensitive example/template or a bounded wrapper operation that returns only the needed fields. ` +
|
|
3460
|
+
`A matched sensitive path or an unverifiable file-access form remains blocked; do not copy or dump credential files.`
|
|
3461
|
+
);
|
|
3462
|
+
}
|
|
3463
|
+
if (reason.includes("environment")) {
|
|
3464
|
+
return (
|
|
3465
|
+
`Do not dump or forward the environment. For a known nonsensitive value, use an exact approved name ` +
|
|
3466
|
+
`with printenv NAME; approval is configured in credentialGuard.allowedEnvironmentVariables. ` +
|
|
3467
|
+
`This does not approve execution or secret values. ` +
|
|
3468
|
+
externalExecutionRecovery
|
|
3469
|
+
);
|
|
3470
|
+
}
|
|
3471
|
+
return (
|
|
3472
|
+
`The guard cannot verify this command form as permitted. Check the project README and tool help ` +
|
|
3473
|
+
`for an existing bounded operation, or review the guard proof and add a regression test before changing policy. ` +
|
|
3474
|
+
externalExecutionRecovery
|
|
3475
|
+
);
|
|
3476
|
+
}
|
|
3477
|
+
|
|
3429
3478
|
function enforceToolExecuteBefore(input: HookInput, output: HookOutput): void {
|
|
3430
3479
|
// Normalize tool name across platforms:
|
|
3431
3480
|
// - AI coding agents pass capitalized: "Bash", "Read", "Write", "Edit"
|
|
@@ -3472,8 +3521,8 @@ export function createCredentialGuard(config?: CredentialGuardConfig): Credentia
|
|
|
3472
3521
|
throw new Error(
|
|
3473
3522
|
`\u{1F6AB} Command blocked: ${dangerousReason}; this command might expose secrets.\n\n` +
|
|
3474
3523
|
`Command: ${command}\n\n` +
|
|
3475
|
-
|
|
3476
|
-
`
|
|
3524
|
+
`${dangerousCommandRecovery(command, dangerousReason)}\n\n` +
|
|
3525
|
+
`Tool inventory and usage: https://github.com/blogic-cz/agent-tools#tools`,
|
|
3477
3526
|
);
|
|
3478
3527
|
}
|
|
3479
3528
|
|
|
@@ -3489,14 +3538,10 @@ export function createCredentialGuard(config?: CredentialGuardConfig): Credentia
|
|
|
3489
3538
|
|
|
3490
3539
|
const blockedTool = getBlockedCliTool(command);
|
|
3491
3540
|
if (blockedTool) {
|
|
3492
|
-
const skillName = blockedTool.wrapper.replace("agent-tools-", "") + "-tool";
|
|
3493
3541
|
throw new Error(
|
|
3494
3542
|
`\u{1F6AB} Direct ${blockedTool.name} usage blocked.\n\n` +
|
|
3495
3543
|
`AI agents must use wrapper tools for security and audit.\n\n` +
|
|
3496
|
-
|
|
3497
|
-
`Example: bun ${skillName} --help\n\n` +
|
|
3498
|
-
`Think this tool should be allowed? Review the project repository, extend the whitelist, and submit a PR.\n` +
|
|
3499
|
-
`→ Skill "${skillName}"`,
|
|
3544
|
+
blockedCliRecovery(blockedTool),
|
|
3500
3545
|
);
|
|
3501
3546
|
}
|
|
3502
3547
|
}
|