shield-harness 0.1.0
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/.claude/hooks/lib/ocsf-mapper.js +279 -0
- package/.claude/hooks/lib/openshell-detect.js +235 -0
- package/.claude/hooks/lib/policy-compat.js +176 -0
- package/.claude/hooks/lib/session-modules/.gitkeep +0 -0
- package/.claude/hooks/lib/sh-utils.js +340 -0
- package/.claude/hooks/lint-on-save.js +240 -0
- package/.claude/hooks/sh-circuit-breaker.js +113 -0
- package/.claude/hooks/sh-config-guard.js +275 -0
- package/.claude/hooks/sh-data-boundary.js +390 -0
- package/.claude/hooks/sh-dep-audit.js +101 -0
- package/.claude/hooks/sh-elicitation.js +244 -0
- package/.claude/hooks/sh-evidence.js +193 -0
- package/.claude/hooks/sh-gate.js +365 -0
- package/.claude/hooks/sh-injection-guard.js +196 -0
- package/.claude/hooks/sh-instructions.js +212 -0
- package/.claude/hooks/sh-output-control.js +217 -0
- package/.claude/hooks/sh-permission-learn.js +227 -0
- package/.claude/hooks/sh-permission.js +157 -0
- package/.claude/hooks/sh-pipeline.js +623 -0
- package/.claude/hooks/sh-postcompact.js +173 -0
- package/.claude/hooks/sh-precompact.js +114 -0
- package/.claude/hooks/sh-quiet-inject.js +148 -0
- package/.claude/hooks/sh-session-end.js +143 -0
- package/.claude/hooks/sh-session-start.js +277 -0
- package/.claude/hooks/sh-subagent.js +86 -0
- package/.claude/hooks/sh-task-gate.js +141 -0
- package/.claude/hooks/sh-user-prompt.js +185 -0
- package/.claude/hooks/sh-worktree.js +230 -0
- package/.claude/patterns/injection-patterns.json +137 -0
- package/.claude/policies/openshell-default.yaml +65 -0
- package/.claude/rules/binding-governance.md +62 -0
- package/.claude/rules/channel-security.md +90 -0
- package/.claude/rules/coding-principles.md +79 -0
- package/.claude/rules/dev-environment.md +40 -0
- package/.claude/rules/implementation-context.md +132 -0
- package/.claude/rules/language.md +26 -0
- package/.claude/rules/security.md +109 -0
- package/.claude/rules/testing.md +43 -0
- package/LICENSE +21 -0
- package/README.ja.md +176 -0
- package/README.md +174 -0
- package/bin/shield-harness.js +241 -0
- package/package.json +42 -0
package/README.md
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# Shield Harness
|
|
4
|
+
|
|
5
|
+
**Auto-defense security harness for Claude Code — approval-free, safe autonomous development**
|
|
6
|
+
|
|
7
|
+
> **Alpha (v0.1.0)**: Security model is under active development. Permission rules and design documents are being aligned. Not recommended for production use yet.
|
|
8
|
+
|
|
9
|
+
[](#)
|
|
10
|
+
[](README.ja.md)
|
|
11
|
+
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
## What is Shield Harness
|
|
15
|
+
|
|
16
|
+
A security harness that governs Claude Code through multi-layered defense:
|
|
17
|
+
hooks + rules + permissions + settings deployed in the `.claude/` directory.
|
|
18
|
+
|
|
19
|
+
## Quick Start
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx shield-harness init [--profile minimal|standard|strict]
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Why Shield Harness
|
|
26
|
+
|
|
27
|
+
- **Hooks-driven defense**: 22 security hooks monitor every Claude Code operation
|
|
28
|
+
- **Approval-free mode**: Delegate all security decisions to hooks, eliminating human approval dialogs
|
|
29
|
+
- **fail-close principle**: Automatically stops when safety conditions cannot be verified
|
|
30
|
+
- **Evidence recording**: Tamper-proof SHA-256 hash chain records all allow/deny decisions
|
|
31
|
+
|
|
32
|
+
## Architecture Overview
|
|
33
|
+
|
|
34
|
+
3-layer defense model:
|
|
35
|
+
|
|
36
|
+
| Layer | Defense | Implementation |
|
|
37
|
+
| -------- | ------------------ | -------------------------------------------------- |
|
|
38
|
+
| Layer 1 | Permission control | `settings.json` deny/allow rules |
|
|
39
|
+
| Layer 2 | Hook defense | 22 Node.js hook scripts |
|
|
40
|
+
| Layer 3 | Sandbox | Claude Code native sandbox (bubblewrap / Seatbelt) |
|
|
41
|
+
| Layer 3b | Container sandbox | NVIDIA OpenShell (optional, Docker environments) |
|
|
42
|
+
|
|
43
|
+
## Profiles
|
|
44
|
+
|
|
45
|
+
| Profile | Description | Approval-free | Use case |
|
|
46
|
+
| ------------ | -------------- | ------------- | ------------------------------------------- |
|
|
47
|
+
| **minimal** | Minimal config | Enabled | Low-risk tasks |
|
|
48
|
+
| **standard** | Recommended | Enabled | Normal development |
|
|
49
|
+
| **strict** | Strict config | Disabled | When security audit requires human approval |
|
|
50
|
+
|
|
51
|
+
## Hook Catalog
|
|
52
|
+
|
|
53
|
+
| # | Hook | Event | Responsibility |
|
|
54
|
+
| --- | ---------------- | --------------------- | ------------------------------------------------ |
|
|
55
|
+
| 1 | permission | PreToolUse | 4-category tool usage classification |
|
|
56
|
+
| 2 | gate | PreToolUse | 7 attack vector inspection for Bash commands |
|
|
57
|
+
| 3 | injection-guard | PreToolUse | 9-category 50+ pattern injection detection |
|
|
58
|
+
| 4 | data-boundary | PreToolUse | Production data boundary + jurisdiction tracking |
|
|
59
|
+
| 5 | quiet-inject | PreToolUse | Auto-inject quiet flags |
|
|
60
|
+
| 6 | evidence | PostToolUse | SHA-256 hash chain evidence |
|
|
61
|
+
| 7 | output-control | PostToolUse | Output truncation + token budget |
|
|
62
|
+
| 8 | dep-audit | PostToolUse | Package install detection |
|
|
63
|
+
| 9 | lint-on-save | PostToolUse | Auto lint execution |
|
|
64
|
+
| 10 | session-start | SessionStart | Session init + integrity baseline |
|
|
65
|
+
| 11 | session-end | SessionEnd | Cleanup + statistics |
|
|
66
|
+
| 12 | circuit-breaker | Stop | Retry limit (3 attempts) |
|
|
67
|
+
| 13 | config-guard | ConfigChange | Settings change monitoring |
|
|
68
|
+
| 14 | user-prompt | UserPromptSubmit | User input injection scanning |
|
|
69
|
+
| 15 | permission-learn | PermissionRequest | Permission learning guard |
|
|
70
|
+
| 16 | elicitation | Elicitation | Phishing + scope guard |
|
|
71
|
+
| 17 | subagent | SubagentStart | Subagent budget constraint (25%) |
|
|
72
|
+
| 18 | instructions | InstructionsLoaded | Rule file integrity monitoring |
|
|
73
|
+
| 19 | precompact | PreCompact | Pre-compaction backup |
|
|
74
|
+
| 20 | postcompact | PostCompact | Post-compaction restore + verify |
|
|
75
|
+
| 21 | worktree | WorktreeCreate/Remove | Security propagation + evidence merge |
|
|
76
|
+
| 22 | task-gate | TaskCompleted | Test gate |
|
|
77
|
+
|
|
78
|
+
## Pipeline
|
|
79
|
+
|
|
80
|
+
STG gate-driven automation pipeline:
|
|
81
|
+
|
|
82
|
+
| STG0 | STG1 | STG2 | STG3 | STG4 | STG5 | STG6 |
|
|
83
|
+
| :--: | :----: | :--: | :----: | :--: | :----: | :------: |
|
|
84
|
+
| Reqs | Design | Impl | Verify | CI | Commit | PR/Merge |
|
|
85
|
+
|
|
86
|
+
## Layer 3: Sandbox (OS-Level Isolation)
|
|
87
|
+
|
|
88
|
+
Layer 3 relies on Claude Code's built-in sandbox. Shield Harness does not implement its own sandbox — it leverages Layers 1 & 2 to compensate when sandboxing is unavailable.
|
|
89
|
+
|
|
90
|
+
### Platform Support
|
|
91
|
+
|
|
92
|
+
| OS | Sandbox | Technology | Status |
|
|
93
|
+
| -------------- | ------------- | ------------------ | --------------------------------------- |
|
|
94
|
+
| macOS | Supported | Seatbelt | Auto-enabled |
|
|
95
|
+
| Linux | Supported | bubblewrap + socat | `sudo apt-get install bubblewrap socat` |
|
|
96
|
+
| WSL2 | Supported | bubblewrap + socat | Same as Linux |
|
|
97
|
+
| WSL1 | Not supported | — | Kernel features missing |
|
|
98
|
+
| Windows native | Not supported | — | Planned by Anthropic |
|
|
99
|
+
|
|
100
|
+
### Windows Native: Security Gap & Mitigation
|
|
101
|
+
|
|
102
|
+
On Windows native, Claude Code's sandbox features (`sandbox.filesystem.*`, `sandbox.network.*`, `sandbox.autoAllow`) do not function. Shield Harness compensates through:
|
|
103
|
+
|
|
104
|
+
- **Layer 1**: `permissions.deny` includes Windows-specific commands (`type`, `del`, `format`, `Invoke-WebRequest`)
|
|
105
|
+
- **Layer 2**: All 22 hooks operate normally — injection detection, evidence recording, and gate checks are fully functional
|
|
106
|
+
- **Limitation**: Child process file access cannot be restricted at the OS level; raw socket communication bypasses command pattern matching
|
|
107
|
+
|
|
108
|
+
For enterprise environments, supplementing with Windows Firewall outbound rules for process-level network control is recommended.
|
|
109
|
+
|
|
110
|
+
### Layer 3b: NVIDIA OpenShell (Optional)
|
|
111
|
+
|
|
112
|
+
[NVIDIA OpenShell](https://github.com/NVIDIA/OpenShell) (Apache 2.0) provides **kernel-level isolation** for AI agents via Docker:
|
|
113
|
+
|
|
114
|
+
| Mechanism | Target | Protection |
|
|
115
|
+
| ------------ | ---------- | ------------------------- |
|
|
116
|
+
| Landlock LSM | Filesystem | denyWrite / denyRead |
|
|
117
|
+
| Seccomp BPF | Syscalls | Socket / process restrict |
|
|
118
|
+
| Network NS | Network | Domain-level deny |
|
|
119
|
+
|
|
120
|
+
Key benefits for Windows users:
|
|
121
|
+
|
|
122
|
+
- Policies exist **outside** the agent process — the agent cannot disable its own guardrails
|
|
123
|
+
- Runs on Docker Desktop + WSL2 backend (typical Windows dev setup)
|
|
124
|
+
- Reduces residual risk from 5% to <1%
|
|
125
|
+
- Freely removable — stop the container and Shield Harness falls back to Layer 1-2
|
|
126
|
+
|
|
127
|
+
> **Note**: OpenShell is Alpha (v0.0.13) — APIs may change with future releases.
|
|
128
|
+
|
|
129
|
+
## Channel Integration
|
|
130
|
+
|
|
131
|
+
Supports Claude Code Channels (Telegram/Discord).
|
|
132
|
+
Channel-sourced messages automatically receive severity boost for enhanced security.
|
|
133
|
+
|
|
134
|
+
## System Requirements
|
|
135
|
+
|
|
136
|
+
| Tool | Version | Purpose | Required |
|
|
137
|
+
| ------------ | ------------------ | ----------------------------------- | ------------------ |
|
|
138
|
+
| Git | 2.x | Version control | Required |
|
|
139
|
+
| Git Bash | (bundled with Git) | Hook script runtime | Required (Windows) |
|
|
140
|
+
| Node.js | 18+ | Hook execution + NFKC normalization | Required |
|
|
141
|
+
| PowerShell 7 | 7.x (`pwsh`) | Sync scripts | Recommended |
|
|
142
|
+
| GitHub CLI | 2.x (`gh`) | PR creation/merge automation | Optional |
|
|
143
|
+
|
|
144
|
+
OS: Windows-native first (Git Bash), WSL2/Linux compatible.
|
|
145
|
+
|
|
146
|
+
## Versioning
|
|
147
|
+
|
|
148
|
+
Shield Harness follows [Semantic Versioning](https://semver.org/):
|
|
149
|
+
|
|
150
|
+
| Bump | Condition | Example |
|
|
151
|
+
| ------- | -------------------------------------------------------------- | ------------------------------------ |
|
|
152
|
+
| `patch` | Bug fixes, pattern updates, documentation fixes | injection-patterns.json update |
|
|
153
|
+
| `minor` | New features (backward compatible), Phase must-tasks completed | OCSF support, new hook, CLI option |
|
|
154
|
+
| `major` | Breaking changes | Schema incompatible, settings change |
|
|
155
|
+
|
|
156
|
+
**Release trigger**: `git tag v1.x.x && git push origin v1.x.x` triggers `release.yml` (automated npm publish + GitHub Release). Security fixes trigger an immediate patch release.
|
|
157
|
+
|
|
158
|
+
## References
|
|
159
|
+
|
|
160
|
+
Shield Harness was designed by surveying 40+ Claude Code security projects. Key references:
|
|
161
|
+
|
|
162
|
+
| Project | Influence |
|
|
163
|
+
| ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
164
|
+
| [claude-guardrails](https://github.com/dwarvesf/claude-guardrails) | npx install pattern, 50+ injection patterns, deny rule catalog |
|
|
165
|
+
| [claude-warden](https://github.com/johnzfitch/claude-warden) | 3-tier profiles, token governance (quiet-inject, output-control), ConfigChange self-protection |
|
|
166
|
+
| [claude-hooks](https://github.com/lasso-security/claude-hooks) | 5-category injection detection, YAML pattern definitions |
|
|
167
|
+
| [tobari](https://github.com/Sora-bluesky/tobari) | 22-hook architecture, SHA-256 hash chain evidence, STG gate pipeline, PermissionRequest adaptive learning |
|
|
168
|
+
| [OpenClaw](https://github.com/openclaw/openclaw) | 18 CVE/security issue lessons (gateway auth, credential management, symlink traversal), channel integration design |
|
|
169
|
+
| [everything-claude-code](https://github.com/affaan-m/everything-claude-code) | AgentShield security integration (1,282 tests, 102 rules), comprehensive skill/agent catalog |
|
|
170
|
+
| [NVIDIA OpenShell](https://github.com/NVIDIA/OpenShell) | Layer 3b kernel-level sandbox (Landlock, Seccomp BPF, Network NS), declarative YAML policies |
|
|
171
|
+
|
|
172
|
+
## License
|
|
173
|
+
|
|
174
|
+
MIT
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
|
|
7
|
+
const PROFILES = ["minimal", "standard", "strict"];
|
|
8
|
+
const DEFAULT_PROFILE = "standard";
|
|
9
|
+
|
|
10
|
+
// Source directories within the npm package
|
|
11
|
+
const PKG_ROOT = path.resolve(__dirname, "..");
|
|
12
|
+
const HOOK_SRC = path.join(PKG_ROOT, ".claude", "hooks");
|
|
13
|
+
const PATTERN_SRC = path.join(PKG_ROOT, ".claude", "patterns");
|
|
14
|
+
const RULES_SRC = path.join(PKG_ROOT, ".claude", "rules");
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Recursively copy a directory.
|
|
18
|
+
* @param {string} src
|
|
19
|
+
* @param {string} dest
|
|
20
|
+
*/
|
|
21
|
+
function copyDir(src, dest) {
|
|
22
|
+
if (!fs.existsSync(src)) return;
|
|
23
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
24
|
+
|
|
25
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
26
|
+
const srcPath = path.join(src, entry.name);
|
|
27
|
+
const destPath = path.join(dest, entry.name);
|
|
28
|
+
|
|
29
|
+
if (entry.isDirectory()) {
|
|
30
|
+
copyDir(srcPath, destPath);
|
|
31
|
+
} else {
|
|
32
|
+
fs.copyFileSync(srcPath, destPath);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Main init command.
|
|
39
|
+
* @param {string} profile
|
|
40
|
+
*/
|
|
41
|
+
function init(profile) {
|
|
42
|
+
const targetDir = process.cwd();
|
|
43
|
+
const claudeDir = path.join(targetDir, ".claude");
|
|
44
|
+
const shieldHarnessDir = path.join(targetDir, ".shield-harness");
|
|
45
|
+
|
|
46
|
+
// Check if already initialized
|
|
47
|
+
if (fs.existsSync(path.join(claudeDir, "hooks", "sh-gate.js"))) {
|
|
48
|
+
console.error("Shield Harness is already initialized in this directory.");
|
|
49
|
+
console.error("To re-initialize, remove .claude/hooks/sh-*.js first.");
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
console.log(`Initializing Shield Harness (profile: ${profile})...`);
|
|
54
|
+
|
|
55
|
+
// Copy hooks
|
|
56
|
+
copyDir(HOOK_SRC, path.join(claudeDir, "hooks"));
|
|
57
|
+
console.log(" [OK] hooks/");
|
|
58
|
+
|
|
59
|
+
// Copy patterns
|
|
60
|
+
copyDir(PATTERN_SRC, path.join(claudeDir, "patterns"));
|
|
61
|
+
console.log(" [OK] patterns/");
|
|
62
|
+
|
|
63
|
+
// Copy rules
|
|
64
|
+
copyDir(RULES_SRC, path.join(claudeDir, "rules"));
|
|
65
|
+
console.log(" [OK] rules/");
|
|
66
|
+
|
|
67
|
+
// Create .shield-harness runtime directories
|
|
68
|
+
fs.mkdirSync(path.join(shieldHarnessDir, "config"), { recursive: true });
|
|
69
|
+
fs.mkdirSync(path.join(shieldHarnessDir, "logs"), { recursive: true });
|
|
70
|
+
fs.mkdirSync(path.join(shieldHarnessDir, "state"), { recursive: true });
|
|
71
|
+
console.log(" [OK] .shield-harness/");
|
|
72
|
+
|
|
73
|
+
// Create default pipeline config
|
|
74
|
+
const pipelineConfig = {
|
|
75
|
+
auto_commit: false,
|
|
76
|
+
auto_push: false,
|
|
77
|
+
auto_pr: false,
|
|
78
|
+
auto_merge: false,
|
|
79
|
+
auto_branch_cleanup: false,
|
|
80
|
+
commit_message_format: "[{task_id}] STG{gate}: {intent}",
|
|
81
|
+
pr_template: ".github/pull_request_template.md",
|
|
82
|
+
protected_branches: ["main", "master"],
|
|
83
|
+
approval_free: profile !== "strict",
|
|
84
|
+
sync_views_on_commit: true,
|
|
85
|
+
sync_views_on_session_start: true,
|
|
86
|
+
auto_tag: false,
|
|
87
|
+
version_bump: "patch",
|
|
88
|
+
auto_pickup_next_task: false,
|
|
89
|
+
auto_skip_blocked: false,
|
|
90
|
+
blocked_notification_channel: null,
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const configPath = path.join(
|
|
94
|
+
shieldHarnessDir,
|
|
95
|
+
"config",
|
|
96
|
+
"pipeline-config.json",
|
|
97
|
+
);
|
|
98
|
+
if (!fs.existsSync(configPath)) {
|
|
99
|
+
fs.writeFileSync(
|
|
100
|
+
configPath,
|
|
101
|
+
JSON.stringify(pipelineConfig, null, 2) + "\n",
|
|
102
|
+
);
|
|
103
|
+
console.log(" [OK] pipeline-config.json");
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
console.log("");
|
|
107
|
+
console.log(`Shield Harness initialized successfully (profile: ${profile}).`);
|
|
108
|
+
console.log("Run 'claude' to start a secured session.");
|
|
109
|
+
|
|
110
|
+
// OpenShell setup guide (Layer 3b)
|
|
111
|
+
printOpenShellGuide();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Detect OpenShell status and print a setup guide.
|
|
116
|
+
* fail-safe: never throws, prints basic guide on any error.
|
|
117
|
+
*/
|
|
118
|
+
function printOpenShellGuide() {
|
|
119
|
+
console.log("");
|
|
120
|
+
console.log("─── OpenShell Setup (Layer 3b: Sandbox Isolation) ───");
|
|
121
|
+
console.log("");
|
|
122
|
+
|
|
123
|
+
let status;
|
|
124
|
+
try {
|
|
125
|
+
const {
|
|
126
|
+
detectOpenShell,
|
|
127
|
+
} = require("../.claude/hooks/lib/openshell-detect");
|
|
128
|
+
status = detectOpenShell();
|
|
129
|
+
} catch {
|
|
130
|
+
// Detection library not available — show basic guide
|
|
131
|
+
printBasicGuide();
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (status.available) {
|
|
136
|
+
// OpenShell is running
|
|
137
|
+
console.log(" [OK] OpenShell detected and running");
|
|
138
|
+
console.log(` Version: ${status.version || "unknown"}`);
|
|
139
|
+
if (status.update_available && status.latest_version) {
|
|
140
|
+
console.log(
|
|
141
|
+
` Update available: ${status.version} -> ${status.latest_version}`,
|
|
142
|
+
);
|
|
143
|
+
console.log(" Run: openshell update");
|
|
144
|
+
}
|
|
145
|
+
console.log("");
|
|
146
|
+
console.log(" Layer 3b sandbox isolation is active.");
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Not fully available — guide based on what's missing
|
|
151
|
+
switch (status.reason) {
|
|
152
|
+
case "docker_not_found":
|
|
153
|
+
console.log(" [1/3] Install Docker Desktop:");
|
|
154
|
+
console.log(" https://www.docker.com/products/docker-desktop/");
|
|
155
|
+
console.log("");
|
|
156
|
+
console.log(" [2/3] Install NVIDIA OpenShell:");
|
|
157
|
+
console.log(" https://github.com/NVIDIA/OpenShell");
|
|
158
|
+
console.log(" pip install openshell");
|
|
159
|
+
console.log("");
|
|
160
|
+
console.log(" [3/3] Start a sandbox:");
|
|
161
|
+
console.log(" openshell sandbox start");
|
|
162
|
+
break;
|
|
163
|
+
|
|
164
|
+
case "openshell_not_installed":
|
|
165
|
+
console.log(" [OK] Docker detected");
|
|
166
|
+
console.log("");
|
|
167
|
+
console.log(" [1/2] Install NVIDIA OpenShell:");
|
|
168
|
+
console.log(" https://github.com/NVIDIA/OpenShell");
|
|
169
|
+
console.log(" pip install openshell");
|
|
170
|
+
console.log("");
|
|
171
|
+
console.log(" [2/2] Start a sandbox:");
|
|
172
|
+
console.log(" openshell sandbox start");
|
|
173
|
+
break;
|
|
174
|
+
|
|
175
|
+
case "container_not_running":
|
|
176
|
+
console.log(" [OK] Docker detected");
|
|
177
|
+
console.log(` [OK] OpenShell installed (v${status.version || "?"})`);
|
|
178
|
+
if (status.update_available && status.latest_version) {
|
|
179
|
+
console.log(
|
|
180
|
+
` Update available: ${status.version} -> ${status.latest_version}`,
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
console.log("");
|
|
184
|
+
console.log(" [1/1] Start the sandbox:");
|
|
185
|
+
console.log(" openshell sandbox start");
|
|
186
|
+
break;
|
|
187
|
+
|
|
188
|
+
default:
|
|
189
|
+
printBasicGuide();
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
console.log("");
|
|
194
|
+
console.log(" OpenShell adds container-level isolation to Shield Harness,");
|
|
195
|
+
console.log(" limiting blast radius even if a hook bypass is found.");
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Fallback: print basic setup guide without detection.
|
|
200
|
+
*/
|
|
201
|
+
function printBasicGuide() {
|
|
202
|
+
console.log(" For enhanced security, set up NVIDIA OpenShell:");
|
|
203
|
+
console.log(" https://github.com/NVIDIA/OpenShell");
|
|
204
|
+
console.log("");
|
|
205
|
+
console.log(" Setup steps:");
|
|
206
|
+
console.log(" 1. Install Docker Desktop");
|
|
207
|
+
console.log(" 2. pip install openshell");
|
|
208
|
+
console.log(" 3. openshell sandbox start");
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// ---------------------------------------------------------------------------
|
|
212
|
+
// CLI
|
|
213
|
+
// ---------------------------------------------------------------------------
|
|
214
|
+
|
|
215
|
+
const args = process.argv.slice(2);
|
|
216
|
+
const command = args[0];
|
|
217
|
+
|
|
218
|
+
if (command === "init") {
|
|
219
|
+
let profile = DEFAULT_PROFILE;
|
|
220
|
+
const profileIdx = args.indexOf("--profile");
|
|
221
|
+
if (profileIdx !== -1 && args[profileIdx + 1]) {
|
|
222
|
+
profile = args[profileIdx + 1];
|
|
223
|
+
if (!PROFILES.includes(profile)) {
|
|
224
|
+
console.error(`Unknown profile: ${profile}`);
|
|
225
|
+
console.error(`Available profiles: ${PROFILES.join(", ")}`);
|
|
226
|
+
process.exit(1);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
init(profile);
|
|
230
|
+
} else {
|
|
231
|
+
const pkg = require("../package.json");
|
|
232
|
+
console.log(`Shield Harness v${pkg.version}`);
|
|
233
|
+
console.log("");
|
|
234
|
+
console.log("Usage:");
|
|
235
|
+
console.log(" npx shield-harness init [--profile minimal|standard|strict]");
|
|
236
|
+
console.log("");
|
|
237
|
+
console.log("Profiles:");
|
|
238
|
+
console.log(" minimal — Minimal config, approval-free");
|
|
239
|
+
console.log(" standard — Recommended (default), approval-free");
|
|
240
|
+
console.log(" strict — Strict config, requires human approval");
|
|
241
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "shield-harness",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Security harness for Claude Code — hooks-driven, zero-hassle defense",
|
|
5
|
+
"bin": {
|
|
6
|
+
"shield-harness": "./bin/shield-harness.js"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
".claude/hooks/",
|
|
10
|
+
".claude/patterns/",
|
|
11
|
+
".claude/policies/",
|
|
12
|
+
".claude/rules/",
|
|
13
|
+
"bin/"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"test": "node --test tests/*.test.js",
|
|
17
|
+
"test:evidence": "node --test tests/evidence-integrity.test.js",
|
|
18
|
+
"test:gate": "node --test tests/gate-evasion.test.js",
|
|
19
|
+
"test:injection": "node --test tests/injection-evasion.test.js",
|
|
20
|
+
"test:config": "node --test tests/config-guard-evasion.test.js",
|
|
21
|
+
"test:boundary": "node --test tests/data-boundary-evasion.test.js",
|
|
22
|
+
"test:output": "node --test tests/output-security.test.js",
|
|
23
|
+
"test:ocsf": "node --test tests/ocsf-mapper.test.js",
|
|
24
|
+
"test:policy-compat": "node --test tests/policy-compat.test.js"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"claude-code",
|
|
28
|
+
"security",
|
|
29
|
+
"hooks",
|
|
30
|
+
"harness",
|
|
31
|
+
"ai-safety"
|
|
32
|
+
],
|
|
33
|
+
"author": "Sora",
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "https://github.com/Sora-bluesky/shield-harness.git"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=18"
|
|
41
|
+
}
|
|
42
|
+
}
|