mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-04-08 18:33:28 +08:00
fix: make insaits hook opt-in
This commit is contained in:
@@ -25,7 +25,7 @@ User request → Claude picks a tool → PreToolUse hook runs → Tool executes
|
|||||||
| **Git push reminder** | `Bash` | Reminds to review changes before `git push` | 0 (warns) |
|
| **Git push reminder** | `Bash` | Reminds to review changes before `git push` | 0 (warns) |
|
||||||
| **Doc file warning** | `Write` | Warns about non-standard `.md`/`.txt` files (allows README, CLAUDE, CONTRIBUTING, CHANGELOG, LICENSE, SKILL, docs/, skills/); cross-platform path handling | 0 (warns) |
|
| **Doc file warning** | `Write` | Warns about non-standard `.md`/`.txt` files (allows README, CLAUDE, CONTRIBUTING, CHANGELOG, LICENSE, SKILL, docs/, skills/); cross-platform path handling | 0 (warns) |
|
||||||
| **Strategic compact** | `Edit\|Write` | Suggests manual `/compact` at logical intervals (every ~50 tool calls) | 0 (warns) |
|
| **Strategic compact** | `Edit\|Write` | Suggests manual `/compact` at logical intervals (every ~50 tool calls) | 0 (warns) |
|
||||||
| **InsAIts security monitor** | `*` | Detects credential exposure, prompt injection, hallucinations, and behavioral anomalies (23 types) before tool execution. Blocks on critical findings, warns on non-critical. Writes audit log to `.insaits_audit_session.jsonl`. Requires `pip install insa-its`. [Details](../scripts/hooks/insaits-security-monitor.py) | 2 (blocks critical) / 0 (warns) |
|
| **InsAIts security monitor (opt-in)** | `Bash\|Write\|Edit\|MultiEdit` | Optional security scan for high-signal tool inputs. Disabled unless `ECC_ENABLE_INSAITS=1`. Blocks on critical findings, warns on non-critical, and writes audit log to `.insaits_audit_session.jsonl`. Requires `pip install insa-its`. [Details](../scripts/hooks/insaits-security-monitor.py) | 2 (blocks critical) / 0 (warns) |
|
||||||
|
|
||||||
### PostToolUse Hooks
|
### PostToolUse Hooks
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@
|
|||||||
"description": "Capture tool use observations for continuous learning"
|
"description": "Capture tool use observations for continuous learning"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"matcher": "*",
|
"matcher": "Bash|Write|Edit|MultiEdit",
|
||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
@@ -73,7 +73,7 @@
|
|||||||
"timeout": 15
|
"timeout": 15
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "InsAIts AI security monitor: detects credential exposure, prompt injection, hallucinations, and 20+ anomaly types before tool execution. Requires: pip install insa-its"
|
"description": "Optional InsAIts AI security monitor for Bash/Edit/Write flows. Enable with ECC_ENABLE_INSAITS=1. Requires: pip install insa-its"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"PreCompact": [
|
"PreCompact": [
|
||||||
|
|||||||
@@ -11,17 +11,18 @@ Writes audit events to .insaits_audit_session.jsonl for forensic tracing.
|
|||||||
|
|
||||||
Setup:
|
Setup:
|
||||||
pip install insa-its
|
pip install insa-its
|
||||||
|
export ECC_ENABLE_INSAITS=1
|
||||||
|
|
||||||
Add to .claude/settings.json:
|
Add to .claude/settings.json:
|
||||||
{
|
{
|
||||||
"hooks": {
|
"hooks": {
|
||||||
"PreToolUse": [
|
"PreToolUse": [
|
||||||
{
|
{
|
||||||
"matcher": ".*",
|
"matcher": "Bash|Write|Edit|MultiEdit",
|
||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "python3 scripts/hooks/insaits-security-monitor.py"
|
"command": "node scripts/hooks/insaits-security-wrapper.js"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,10 @@ const { spawnSync } = require('child_process');
|
|||||||
|
|
||||||
const MAX_STDIN = 1024 * 1024;
|
const MAX_STDIN = 1024 * 1024;
|
||||||
|
|
||||||
|
function isEnabled(value) {
|
||||||
|
return ['1', 'true', 'yes', 'on'].includes(String(value || '').toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
let raw = '';
|
let raw = '';
|
||||||
process.stdin.setEncoding('utf8');
|
process.stdin.setEncoding('utf8');
|
||||||
process.stdin.on('data', chunk => {
|
process.stdin.on('data', chunk => {
|
||||||
@@ -25,6 +29,11 @@ process.stdin.on('data', chunk => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
process.stdin.on('end', () => {
|
process.stdin.on('end', () => {
|
||||||
|
if (!isEnabled(process.env.ECC_ENABLE_INSAITS)) {
|
||||||
|
process.stdout.write(raw);
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
const scriptDir = __dirname;
|
const scriptDir = __dirname;
|
||||||
const pyScript = path.join(scriptDir, 'insaits-security-monitor.py');
|
const pyScript = path.join(scriptDir, 'insaits-security-monitor.py');
|
||||||
|
|
||||||
|
|||||||
@@ -203,6 +203,24 @@ async function runTests() {
|
|||||||
}
|
}
|
||||||
})) passed++; else failed++;
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
// insaits-security-wrapper.js tests
|
||||||
|
console.log('\ninsaits-security-wrapper.js:');
|
||||||
|
|
||||||
|
if (await asyncTest('passes through input unchanged when integration is disabled', async () => {
|
||||||
|
const stdinData = JSON.stringify({
|
||||||
|
tool_name: 'Write',
|
||||||
|
tool_input: { file_path: 'src/index.ts', content: 'console.log("ok");' }
|
||||||
|
});
|
||||||
|
const result = await runScript(
|
||||||
|
path.join(scriptsDir, 'insaits-security-wrapper.js'),
|
||||||
|
stdinData,
|
||||||
|
{ ECC_ENABLE_INSAITS: '' }
|
||||||
|
);
|
||||||
|
assert.strictEqual(result.code, 0, `Exit code should be 0, got ${result.code}`);
|
||||||
|
assert.strictEqual(result.stdout, stdinData, 'Should pass stdin through unchanged');
|
||||||
|
assert.strictEqual(result.stderr, '', 'Should stay silent when integration is disabled');
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
// check-console-log.js tests
|
// check-console-log.js tests
|
||||||
console.log('\ncheck-console-log.js:');
|
console.log('\ncheck-console-log.js:');
|
||||||
|
|
||||||
@@ -1237,6 +1255,29 @@ async function runTests() {
|
|||||||
}
|
}
|
||||||
})) passed++; else failed++;
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
if (test('InsAIts hook is opt-in and scoped to high-signal tool inputs', () => {
|
||||||
|
const hooksPath = path.join(__dirname, '..', '..', 'hooks', 'hooks.json');
|
||||||
|
const hooks = JSON.parse(fs.readFileSync(hooksPath, 'utf8'));
|
||||||
|
const insaitsHook = hooks.hooks.PreToolUse.find(entry =>
|
||||||
|
entry.description && entry.description.includes('InsAIts')
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.ok(insaitsHook, 'Should define an InsAIts PreToolUse hook');
|
||||||
|
assert.strictEqual(
|
||||||
|
insaitsHook.matcher,
|
||||||
|
'Bash|Write|Edit|MultiEdit',
|
||||||
|
'InsAIts hook should avoid matching every tool'
|
||||||
|
);
|
||||||
|
assert.ok(
|
||||||
|
insaitsHook.description.includes('ECC_ENABLE_INSAITS=1'),
|
||||||
|
'InsAIts hook should document explicit opt-in'
|
||||||
|
);
|
||||||
|
assert.ok(
|
||||||
|
insaitsHook.hooks[0].command.includes('insaits-security-wrapper.js'),
|
||||||
|
'InsAIts hook should execute through the JS wrapper'
|
||||||
|
);
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
// plugin.json validation
|
// plugin.json validation
|
||||||
console.log('\nplugin.json Validation:');
|
console.log('\nplugin.json Validation:');
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user