clawmoat 0.5.0 → 0.8.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/CONTRIBUTING.md +4 -2
- package/README.md +86 -3
- package/SECURITY.md +58 -10
- package/bin/clawmoat.js +298 -1
- package/clawmoat-0.8.0.tgz +0 -0
- package/docs/blog/386-malicious-skills.html +255 -0
- package/docs/blog/40000-exposed-openclaw-instances.html +194 -0
- package/docs/blog/agent-trust-protocol.html +197 -0
- package/docs/blog/clawmoat-vs-llamafirewall-nemo-guardrails.html +223 -0
- package/docs/blog/ibm-experts-agent-runtime-protection.html +238 -0
- package/docs/blog/index.html +168 -0
- package/docs/blog/mcp-30-cves-security-crisis.html +279 -0
- package/docs/blog/microsoft-openclaw-workstation-security.html +234 -0
- package/docs/blog/nist-ai-agent-standards-clawmoat.html +369 -0
- package/docs/blog/oasis-websocket-hijack.html +205 -0
- package/docs/blog/ollama-openclaw-security.html +154 -0
- package/docs/blog/openclaw-enterprise-readiness-claw10.html +198 -0
- package/docs/blog/openclaw-security-reckoning-2026.html +361 -0
- package/docs/blog/supply-chain-agents.html +166 -0
- package/docs/blog/supply-chain-agents.md +79 -0
- package/docs/business/index.html +530 -0
- package/docs/business/install.html +247 -0
- package/docs/checklist.html +168 -0
- package/docs/finance/index.html +217 -0
- package/docs/hall-of-fame.html +168 -0
- package/docs/index.html +328 -90
- package/docs/install.sh +557 -0
- package/docs/privacy-policy/index.html +122 -0
- package/docs/scan/index.html +214 -0
- package/docs/sitemap.xml +132 -2
- package/docs/support/index.html +124 -0
- package/docs/terms-of-service/index.html +122 -0
- package/examples/basic-usage.js +38 -0
- package/package.json +1 -1
- package/server/index.js +179 -14
- package/server/index.js.patch +1 -0
- package/src/finance/index.js +585 -0
- package/src/finance/mcp-firewall.js +486 -0
- package/src/guardian/cve-verify.js +129 -0
- package/src/guardian/gateway-monitor.js +590 -0
- package/src/guardian/index.js +3 -1
- package/src/guardian/insider-threat.js +498 -0
- package/src/index.js +3 -0
- package/src/middleware/openclaw.js +28 -1
package/docs/install.sh
ADDED
|
@@ -0,0 +1,557 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ============================================================================
|
|
3
|
+
# ClawMoat Installer — Enterprise-Grade AI Agent Security
|
|
4
|
+
# https://clawmoat.com/business/install.html
|
|
5
|
+
#
|
|
6
|
+
# Usage:
|
|
7
|
+
# curl -fsSL https://clawmoat.com/install.sh | bash
|
|
8
|
+
# curl -fsSL https://clawmoat.com/install.sh | bash -s -- --enterprise
|
|
9
|
+
#
|
|
10
|
+
# ⚠️ This script runs locally — no data is sent anywhere.
|
|
11
|
+
# It installs ClawMoat via npm and generates a local config.
|
|
12
|
+
# Source: https://github.com/ClawMoat/clawmoat
|
|
13
|
+
#
|
|
14
|
+
# Exit codes: 0 = success, 1 = error
|
|
15
|
+
# ============================================================================
|
|
16
|
+
|
|
17
|
+
set -euo pipefail
|
|
18
|
+
|
|
19
|
+
# ─── Colors & Formatting ────────────────────────────────────────────────────
|
|
20
|
+
|
|
21
|
+
RED='\033[0;31m'
|
|
22
|
+
GREEN='\033[0;32m'
|
|
23
|
+
YELLOW='\033[1;33m'
|
|
24
|
+
BLUE='\033[0;34m'
|
|
25
|
+
CYAN='\033[0;36m'
|
|
26
|
+
BOLD='\033[1m'
|
|
27
|
+
DIM='\033[2m'
|
|
28
|
+
RESET='\033[0m'
|
|
29
|
+
|
|
30
|
+
# Disable colors if not a terminal
|
|
31
|
+
if [ ! -t 1 ]; then
|
|
32
|
+
RED='' GREEN='' YELLOW='' BLUE='' CYAN='' BOLD='' DIM='' RESET=''
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
# ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
36
|
+
|
|
37
|
+
info() { echo -e "${BLUE}ℹ${RESET} $*"; }
|
|
38
|
+
success() { echo -e "${GREEN}✅${RESET} $*"; }
|
|
39
|
+
warn() { echo -e "${YELLOW}⚠️${RESET} $*"; }
|
|
40
|
+
error() { echo -e "${RED}❌${RESET} $*" >&2; }
|
|
41
|
+
step() { echo -e "\n${BOLD}${CYAN}▸ $*${RESET}"; }
|
|
42
|
+
divider() { echo -e "${DIM}────────────────────────────────────────────────────${RESET}"; }
|
|
43
|
+
|
|
44
|
+
# ─── Flags ───────────────────────────────────────────────────────────────────
|
|
45
|
+
|
|
46
|
+
ENTERPRISE=false
|
|
47
|
+
DRY_RUN=false
|
|
48
|
+
CLAWMOAT_DIR="$HOME/.clawmoat"
|
|
49
|
+
CONFIG_FILE="$CLAWMOAT_DIR/config.json"
|
|
50
|
+
|
|
51
|
+
for arg in "$@"; do
|
|
52
|
+
case "$arg" in
|
|
53
|
+
--enterprise) ENTERPRISE=true ;;
|
|
54
|
+
--dry-run) DRY_RUN=true ;;
|
|
55
|
+
--help|-h)
|
|
56
|
+
echo "ClawMoat Installer"
|
|
57
|
+
echo ""
|
|
58
|
+
echo "Usage: bash install.sh [OPTIONS]"
|
|
59
|
+
echo ""
|
|
60
|
+
echo "Options:"
|
|
61
|
+
echo " --enterprise Enable FinanceGuard, McpFirewall, SOX templates"
|
|
62
|
+
echo " --dry-run Show what would be done without making changes"
|
|
63
|
+
echo " --help Show this help message"
|
|
64
|
+
exit 0
|
|
65
|
+
;;
|
|
66
|
+
*)
|
|
67
|
+
error "Unknown option: $arg"
|
|
68
|
+
exit 1
|
|
69
|
+
;;
|
|
70
|
+
esac
|
|
71
|
+
done
|
|
72
|
+
|
|
73
|
+
# ─── Banner ──────────────────────────────────────────────────────────────────
|
|
74
|
+
|
|
75
|
+
echo ""
|
|
76
|
+
echo -e "${BOLD}🏰 ClawMoat Installer${RESET}"
|
|
77
|
+
echo -e "${DIM} Enterprise-Grade AI Agent Security${RESET}"
|
|
78
|
+
divider
|
|
79
|
+
echo ""
|
|
80
|
+
echo -e "${DIM}⚠️ This script runs locally — no data is sent anywhere.${RESET}"
|
|
81
|
+
echo -e "${DIM} All configuration stays on your machine at ~/.clawmoat/${RESET}"
|
|
82
|
+
echo ""
|
|
83
|
+
|
|
84
|
+
if $ENTERPRISE; then
|
|
85
|
+
info "Enterprise mode enabled"
|
|
86
|
+
fi
|
|
87
|
+
if $DRY_RUN; then
|
|
88
|
+
warn "Dry run — no changes will be made"
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
# ─── Step 1: Detect OS ──────────────────────────────────────────────────────
|
|
92
|
+
|
|
93
|
+
step "Detecting operating system..."
|
|
94
|
+
|
|
95
|
+
OS="unknown"
|
|
96
|
+
ARCH="$(uname -m)"
|
|
97
|
+
|
|
98
|
+
case "$(uname -s)" in
|
|
99
|
+
Linux*)
|
|
100
|
+
if grep -qiE "microsoft|wsl" /proc/version 2>/dev/null; then
|
|
101
|
+
OS="wsl"
|
|
102
|
+
info "Detected: WSL (Windows Subsystem for Linux) — $ARCH"
|
|
103
|
+
else
|
|
104
|
+
OS="linux"
|
|
105
|
+
info "Detected: Linux — $ARCH"
|
|
106
|
+
fi
|
|
107
|
+
;;
|
|
108
|
+
Darwin*)
|
|
109
|
+
OS="macos"
|
|
110
|
+
info "Detected: macOS — $ARCH"
|
|
111
|
+
;;
|
|
112
|
+
*)
|
|
113
|
+
error "Unsupported operating system: $(uname -s)"
|
|
114
|
+
error "ClawMoat supports Linux, macOS, and WSL."
|
|
115
|
+
exit 1
|
|
116
|
+
;;
|
|
117
|
+
esac
|
|
118
|
+
|
|
119
|
+
# ─── Step 2: Check Node.js ──────────────────────────────────────────────────
|
|
120
|
+
|
|
121
|
+
step "Checking Node.js..."
|
|
122
|
+
|
|
123
|
+
NODE_OK=false
|
|
124
|
+
MIN_NODE_MAJOR=18
|
|
125
|
+
|
|
126
|
+
check_node_version() {
|
|
127
|
+
if command -v node &>/dev/null; then
|
|
128
|
+
NODE_VERSION="$(node -v 2>/dev/null | sed 's/^v//')"
|
|
129
|
+
NODE_MAJOR="${NODE_VERSION%%.*}"
|
|
130
|
+
if [ "$NODE_MAJOR" -ge "$MIN_NODE_MAJOR" ] 2>/dev/null; then
|
|
131
|
+
return 0
|
|
132
|
+
fi
|
|
133
|
+
fi
|
|
134
|
+
return 1
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if check_node_version; then
|
|
138
|
+
NODE_OK=true
|
|
139
|
+
success "Node.js v$NODE_VERSION found"
|
|
140
|
+
else
|
|
141
|
+
warn "Node.js v${MIN_NODE_MAJOR}+ is required but not found."
|
|
142
|
+
echo ""
|
|
143
|
+
|
|
144
|
+
if $DRY_RUN; then
|
|
145
|
+
info "Would install Node.js via nvm"
|
|
146
|
+
else
|
|
147
|
+
echo -e " ${BOLD}Install Node.js via nvm?${RESET} (recommended)"
|
|
148
|
+
echo -e " This installs nvm and Node.js LTS in your home directory."
|
|
149
|
+
echo ""
|
|
150
|
+
read -rp " Install? [Y/n] " INSTALL_NODE
|
|
151
|
+
INSTALL_NODE="${INSTALL_NODE:-Y}"
|
|
152
|
+
|
|
153
|
+
if [[ "$INSTALL_NODE" =~ ^[Yy]$ ]]; then
|
|
154
|
+
step "Installing nvm..."
|
|
155
|
+
export NVM_DIR="${NVM_DIR:-$HOME/.nvm}"
|
|
156
|
+
|
|
157
|
+
if [ ! -d "$NVM_DIR" ]; then
|
|
158
|
+
curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
|
|
159
|
+
fi
|
|
160
|
+
|
|
161
|
+
# Source nvm
|
|
162
|
+
# shellcheck source=/dev/null
|
|
163
|
+
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
|
|
164
|
+
|
|
165
|
+
info "Installing Node.js LTS..."
|
|
166
|
+
nvm install --lts
|
|
167
|
+
nvm use --lts
|
|
168
|
+
|
|
169
|
+
if check_node_version; then
|
|
170
|
+
NODE_OK=true
|
|
171
|
+
success "Node.js v$NODE_VERSION installed"
|
|
172
|
+
else
|
|
173
|
+
error "Node.js installation failed. Please install manually:"
|
|
174
|
+
echo " https://nodejs.org/"
|
|
175
|
+
exit 1
|
|
176
|
+
fi
|
|
177
|
+
else
|
|
178
|
+
error "Node.js v${MIN_NODE_MAJOR}+ is required. Install it from https://nodejs.org/"
|
|
179
|
+
exit 1
|
|
180
|
+
fi
|
|
181
|
+
fi
|
|
182
|
+
fi
|
|
183
|
+
|
|
184
|
+
# ─── Step 3: Install ClawMoat ───────────────────────────────────────────────
|
|
185
|
+
|
|
186
|
+
step "Installing ClawMoat..."
|
|
187
|
+
|
|
188
|
+
if $DRY_RUN; then
|
|
189
|
+
info "Would run: npm install -g clawmoat"
|
|
190
|
+
else
|
|
191
|
+
if command -v clawmoat &>/dev/null; then
|
|
192
|
+
CURRENT_VERSION="$(clawmoat --version 2>/dev/null || echo 'unknown')"
|
|
193
|
+
info "ClawMoat already installed (v$CURRENT_VERSION). Updating..."
|
|
194
|
+
fi
|
|
195
|
+
|
|
196
|
+
npm install -g clawmoat 2>&1 | tail -3
|
|
197
|
+
success "ClawMoat installed: $(clawmoat --version 2>/dev/null || echo 'latest')"
|
|
198
|
+
fi
|
|
199
|
+
|
|
200
|
+
# ─── Step 4: Create directory structure ──────────────────────────────────────
|
|
201
|
+
|
|
202
|
+
step "Setting up ~/.clawmoat/..."
|
|
203
|
+
|
|
204
|
+
DIRS=(
|
|
205
|
+
"$CLAWMOAT_DIR"
|
|
206
|
+
"$CLAWMOAT_DIR/audit"
|
|
207
|
+
"$CLAWMOAT_DIR/reports"
|
|
208
|
+
"$CLAWMOAT_DIR/templates"
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
if $ENTERPRISE; then
|
|
212
|
+
DIRS+=(
|
|
213
|
+
"$CLAWMOAT_DIR/finance"
|
|
214
|
+
"$CLAWMOAT_DIR/mcp-firewall"
|
|
215
|
+
"$CLAWMOAT_DIR/sox"
|
|
216
|
+
)
|
|
217
|
+
fi
|
|
218
|
+
|
|
219
|
+
if $DRY_RUN; then
|
|
220
|
+
for d in "${DIRS[@]}"; do
|
|
221
|
+
info "Would create: $d"
|
|
222
|
+
done
|
|
223
|
+
else
|
|
224
|
+
for d in "${DIRS[@]}"; do
|
|
225
|
+
mkdir -p "$d"
|
|
226
|
+
done
|
|
227
|
+
success "Directory structure created"
|
|
228
|
+
fi
|
|
229
|
+
|
|
230
|
+
# ─── Step 5: Generate hardened config ────────────────────────────────────────
|
|
231
|
+
|
|
232
|
+
step "Generating hardened security configuration..."
|
|
233
|
+
|
|
234
|
+
TIMESTAMP="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
235
|
+
|
|
236
|
+
# Build the enterprise section if needed
|
|
237
|
+
ENTERPRISE_JSON=""
|
|
238
|
+
if $ENTERPRISE; then
|
|
239
|
+
ENTERPRISE_JSON=',
|
|
240
|
+
"enterprise": {
|
|
241
|
+
"financeGuard": {
|
|
242
|
+
"enabled": true,
|
|
243
|
+
"mode": "monitor",
|
|
244
|
+
"alertOnHighValue": true,
|
|
245
|
+
"thresholdUsd": 1000
|
|
246
|
+
},
|
|
247
|
+
"mcpFirewall": {
|
|
248
|
+
"enabled": true,
|
|
249
|
+
"mode": "read-only",
|
|
250
|
+
"allowedTools": [],
|
|
251
|
+
"blockedServers": [],
|
|
252
|
+
"logAllCalls": true
|
|
253
|
+
},
|
|
254
|
+
"soxCompliance": {
|
|
255
|
+
"enabled": true,
|
|
256
|
+
"auditRetentionDays": 2555,
|
|
257
|
+
"templateDir": "~/.clawmoat/sox",
|
|
258
|
+
"controlsFile": "~/.clawmoat/sox/controls.json",
|
|
259
|
+
"segregationOfDuties": true
|
|
260
|
+
}
|
|
261
|
+
}'
|
|
262
|
+
fi
|
|
263
|
+
|
|
264
|
+
CONFIG_CONTENT='{
|
|
265
|
+
"_clawmoat": {
|
|
266
|
+
"version": "1.0.0",
|
|
267
|
+
"generatedAt": "'"$TIMESTAMP"'",
|
|
268
|
+
"generatedBy": "install.sh",
|
|
269
|
+
"os": "'"$OS"'"
|
|
270
|
+
},
|
|
271
|
+
"permissions": {
|
|
272
|
+
"tier": "worker",
|
|
273
|
+
"note": "Worker tier: read workspace, write workspace, no system changes. Upgrade to standard/full in config if needed."
|
|
274
|
+
},
|
|
275
|
+
"forbiddenZones": [
|
|
276
|
+
{ "path": "~/.ssh", "label": "SSH keys", "severity": "critical" },
|
|
277
|
+
{ "path": "~/.gnupg", "label": "GPG keys", "severity": "critical" },
|
|
278
|
+
{ "path": "~/.aws", "label": "AWS credentials", "severity": "critical" },
|
|
279
|
+
{ "path": "~/.gcloud", "label": "Google Cloud creds", "severity": "critical" },
|
|
280
|
+
{ "path": "~/.azure", "label": "Azure credentials", "severity": "critical" },
|
|
281
|
+
{ "path": "~/.kube", "label": "Kubernetes config", "severity": "critical" },
|
|
282
|
+
{ "path": "~/.docker", "label": "Docker credentials", "severity": "high" },
|
|
283
|
+
{ "path": "~/.npmrc", "label": "npm credentials", "severity": "high" },
|
|
284
|
+
{ "path": "~/.pypirc", "label": "PyPI credentials", "severity": "high" },
|
|
285
|
+
{ "path": "~/.netrc", "label": "Network credentials", "severity": "critical" },
|
|
286
|
+
{ "path": "~/.git-credentials", "label": "Git credentials", "severity": "critical" },
|
|
287
|
+
{ "path": "~/.config/gcloud", "label": "Google Cloud config", "severity": "high" },
|
|
288
|
+
{ "path": "~/.config/gh", "label": "GitHub CLI tokens", "severity": "high" },
|
|
289
|
+
{ "path": "~/.password-store", "label": "Password store", "severity": "critical" },
|
|
290
|
+
{ "path": "~/.1password", "label": "1Password data", "severity": "critical" },
|
|
291
|
+
{ "path": "/etc/shadow", "label": "System passwords", "severity": "critical" },
|
|
292
|
+
{ "path": "/etc/sudoers", "label": "Sudo configuration", "severity": "critical" }
|
|
293
|
+
],
|
|
294
|
+
"forbiddenPatterns": [
|
|
295
|
+
{ "pattern": "Cookies|Login Data|Web Data", "label": "Browser credentials", "severity": "critical" },
|
|
296
|
+
{ "pattern": ".keychain|.keychain-db", "label": "macOS Keychain", "severity": "critical" },
|
|
297
|
+
{ "pattern": "wallet.dat|seed.txt|mnemonic", "label": "Crypto wallet", "severity": "critical" },
|
|
298
|
+
{ "pattern": ".kdbx|KeePass", "label": "KeePass database", "severity": "critical" },
|
|
299
|
+
{ "pattern": ".env|.env.local|.env.prod", "label": "Environment secrets", "severity": "high" }
|
|
300
|
+
],
|
|
301
|
+
"network": {
|
|
302
|
+
"egressLogging": true,
|
|
303
|
+
"logFile": "~/.clawmoat/audit/network.log",
|
|
304
|
+
"allowedDomains": [],
|
|
305
|
+
"blockedDomains": [],
|
|
306
|
+
"alertOnUnknownEgress": true
|
|
307
|
+
},
|
|
308
|
+
"secretScanning": {
|
|
309
|
+
"enabled": true,
|
|
310
|
+
"scanOnFileAccess": true,
|
|
311
|
+
"patterns": ["AWS_ACCESS_KEY", "GITHUB_TOKEN", "PRIVATE_KEY", "password", "secret", "api_key"],
|
|
312
|
+
"alertOnDetection": true
|
|
313
|
+
},
|
|
314
|
+
"audit": {
|
|
315
|
+
"enabled": true,
|
|
316
|
+
"logDir": "~/.clawmoat/audit",
|
|
317
|
+
"retentionDays": 90,
|
|
318
|
+
"logFileAccess": true,
|
|
319
|
+
"logCommandExecution": true,
|
|
320
|
+
"logNetworkRequests": true,
|
|
321
|
+
"tamperProtection": true
|
|
322
|
+
},
|
|
323
|
+
"alerts": {
|
|
324
|
+
"webhookUrl": "",
|
|
325
|
+
"emailTo": "",
|
|
326
|
+
"slackChannel": "",
|
|
327
|
+
"note": "Configure at least one alert channel. Webhook receives JSON POST on security events."
|
|
328
|
+
}'"$ENTERPRISE_JSON"'
|
|
329
|
+
}'
|
|
330
|
+
|
|
331
|
+
if $DRY_RUN; then
|
|
332
|
+
info "Would write config to: $CONFIG_FILE"
|
|
333
|
+
echo -e "${DIM}$CONFIG_CONTENT${RESET}" | head -20
|
|
334
|
+
echo -e "${DIM} ... (truncated)${RESET}"
|
|
335
|
+
else
|
|
336
|
+
if [ -f "$CONFIG_FILE" ]; then
|
|
337
|
+
BACKUP="$CONFIG_FILE.backup.$(date +%s)"
|
|
338
|
+
cp "$CONFIG_FILE" "$BACKUP"
|
|
339
|
+
warn "Existing config backed up to: $BACKUP"
|
|
340
|
+
fi
|
|
341
|
+
|
|
342
|
+
echo "$CONFIG_CONTENT" > "$CONFIG_FILE"
|
|
343
|
+
chmod 600 "$CONFIG_FILE"
|
|
344
|
+
success "Config written to $CONFIG_FILE (mode 600)"
|
|
345
|
+
fi
|
|
346
|
+
|
|
347
|
+
# ─── Step 5b: Enterprise templates ──────────────────────────────────────────
|
|
348
|
+
|
|
349
|
+
if $ENTERPRISE && ! $DRY_RUN; then
|
|
350
|
+
step "Setting up enterprise templates..."
|
|
351
|
+
|
|
352
|
+
# SOX audit control template
|
|
353
|
+
cat > "$CLAWMOAT_DIR/sox/controls.json" << 'SOXEOF'
|
|
354
|
+
{
|
|
355
|
+
"framework": "SOX-AI-Agent",
|
|
356
|
+
"version": "1.0",
|
|
357
|
+
"controls": [
|
|
358
|
+
{
|
|
359
|
+
"id": "AC-01",
|
|
360
|
+
"name": "Agent Permission Tiers",
|
|
361
|
+
"description": "AI agents operate under least-privilege permission tiers",
|
|
362
|
+
"frequency": "continuous",
|
|
363
|
+
"evidence": "~/.clawmoat/audit/*.log"
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
"id": "AC-02",
|
|
367
|
+
"name": "Credential Zone Protection",
|
|
368
|
+
"description": "Forbidden zones prevent agent access to credentials",
|
|
369
|
+
"frequency": "continuous",
|
|
370
|
+
"evidence": "~/.clawmoat/config.json → forbiddenZones"
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
"id": "AC-03",
|
|
374
|
+
"name": "Secret Detection",
|
|
375
|
+
"description": "Real-time scanning for leaked secrets in agent output",
|
|
376
|
+
"frequency": "continuous",
|
|
377
|
+
"evidence": "~/.clawmoat/audit/secrets.log"
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
"id": "AU-01",
|
|
381
|
+
"name": "Audit Trail Integrity",
|
|
382
|
+
"description": "Tamper-protected logging of all agent actions",
|
|
383
|
+
"frequency": "continuous",
|
|
384
|
+
"evidence": "~/.clawmoat/audit/"
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
"id": "NW-01",
|
|
388
|
+
"name": "Network Egress Monitoring",
|
|
389
|
+
"description": "All outbound network requests logged and reviewed",
|
|
390
|
+
"frequency": "continuous",
|
|
391
|
+
"evidence": "~/.clawmoat/audit/network.log"
|
|
392
|
+
}
|
|
393
|
+
]
|
|
394
|
+
}
|
|
395
|
+
SOXEOF
|
|
396
|
+
chmod 600 "$CLAWMOAT_DIR/sox/controls.json"
|
|
397
|
+
success "SOX audit templates created"
|
|
398
|
+
|
|
399
|
+
# MCP Firewall default config
|
|
400
|
+
cat > "$CLAWMOAT_DIR/mcp-firewall/config.json" << 'MCPEOF'
|
|
401
|
+
{
|
|
402
|
+
"mode": "read-only",
|
|
403
|
+
"logAllCalls": true,
|
|
404
|
+
"allowedTools": [],
|
|
405
|
+
"blockedServers": [],
|
|
406
|
+
"rateLimiting": {
|
|
407
|
+
"enabled": true,
|
|
408
|
+
"maxCallsPerMinute": 60
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
MCPEOF
|
|
412
|
+
chmod 600 "$CLAWMOAT_DIR/mcp-firewall/config.json"
|
|
413
|
+
success "MCP Firewall configured (read-only mode)"
|
|
414
|
+
fi
|
|
415
|
+
|
|
416
|
+
# ─── Step 6: Security scan ──────────────────────────────────────────────────
|
|
417
|
+
|
|
418
|
+
step "Running initial security scan..."
|
|
419
|
+
|
|
420
|
+
REPORT_FILE="$CLAWMOAT_DIR/reports/initial-scan-$(date +%Y%m%d-%H%M%S).txt"
|
|
421
|
+
FINDINGS=0
|
|
422
|
+
CRITICAL=0
|
|
423
|
+
|
|
424
|
+
scan_report() {
|
|
425
|
+
echo "$*" >> "$REPORT_FILE"
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
if ! $DRY_RUN; then
|
|
429
|
+
|
|
430
|
+
echo "# ClawMoat Initial Security Report" > "$REPORT_FILE"
|
|
431
|
+
echo "# Generated: $TIMESTAMP" >> "$REPORT_FILE"
|
|
432
|
+
echo "# OS: $OS ($ARCH)" >> "$REPORT_FILE"
|
|
433
|
+
echo "" >> "$REPORT_FILE"
|
|
434
|
+
|
|
435
|
+
# Check for exposed credential files
|
|
436
|
+
echo "## Credential Exposure Check" >> "$REPORT_FILE"
|
|
437
|
+
|
|
438
|
+
CRED_PATHS=(
|
|
439
|
+
"$HOME/.ssh"
|
|
440
|
+
"$HOME/.aws"
|
|
441
|
+
"$HOME/.gnupg"
|
|
442
|
+
"$HOME/.gcloud"
|
|
443
|
+
"$HOME/.azure"
|
|
444
|
+
"$HOME/.kube"
|
|
445
|
+
"$HOME/.docker"
|
|
446
|
+
"$HOME/.npmrc"
|
|
447
|
+
"$HOME/.pypirc"
|
|
448
|
+
"$HOME/.netrc"
|
|
449
|
+
"$HOME/.git-credentials"
|
|
450
|
+
"$HOME/.password-store"
|
|
451
|
+
"$HOME/.1password"
|
|
452
|
+
"$HOME/.env"
|
|
453
|
+
)
|
|
454
|
+
|
|
455
|
+
for cred in "${CRED_PATHS[@]}"; do
|
|
456
|
+
if [ -e "$cred" ]; then
|
|
457
|
+
FINDINGS=$((FINDINGS + 1))
|
|
458
|
+
CRITICAL=$((CRITICAL + 1))
|
|
459
|
+
label="$(basename "$cred")"
|
|
460
|
+
scan_report " [FOUND] $cred — will be protected by ClawMoat"
|
|
461
|
+
warn "Found: $cred — ${GREEN}now protected${RESET}"
|
|
462
|
+
fi
|
|
463
|
+
done
|
|
464
|
+
|
|
465
|
+
# Check file permissions on sensitive items
|
|
466
|
+
echo "" >> "$REPORT_FILE"
|
|
467
|
+
echo "## Permission Check" >> "$REPORT_FILE"
|
|
468
|
+
|
|
469
|
+
if [ -d "$HOME/.ssh" ]; then
|
|
470
|
+
SSH_PERMS="$(stat -c '%a' "$HOME/.ssh" 2>/dev/null || stat -f '%A' "$HOME/.ssh" 2>/dev/null || echo 'unknown')"
|
|
471
|
+
if [ "$SSH_PERMS" != "700" ] && [ "$SSH_PERMS" != "unknown" ]; then
|
|
472
|
+
scan_report " [WARN] ~/.ssh permissions are $SSH_PERMS (should be 700)"
|
|
473
|
+
warn "~/.ssh permissions: $SSH_PERMS (recommended: 700)"
|
|
474
|
+
FINDINGS=$((FINDINGS + 1))
|
|
475
|
+
fi
|
|
476
|
+
fi
|
|
477
|
+
|
|
478
|
+
# Check for .env files in common locations
|
|
479
|
+
echo "" >> "$REPORT_FILE"
|
|
480
|
+
echo "## Environment File Check" >> "$REPORT_FILE"
|
|
481
|
+
|
|
482
|
+
ENV_COUNT=0
|
|
483
|
+
while IFS= read -r -d '' envfile; do
|
|
484
|
+
ENV_COUNT=$((ENV_COUNT + 1))
|
|
485
|
+
scan_report " [FOUND] $envfile"
|
|
486
|
+
done < <(find "$HOME" -maxdepth 3 -name '.env*' -type f -print0 2>/dev/null | head -z -20)
|
|
487
|
+
|
|
488
|
+
if [ "$ENV_COUNT" -gt 0 ]; then
|
|
489
|
+
FINDINGS=$((FINDINGS + ENV_COUNT))
|
|
490
|
+
info "Found $ENV_COUNT .env file(s) — secret scanning will monitor these"
|
|
491
|
+
fi
|
|
492
|
+
|
|
493
|
+
# Node/npm global check
|
|
494
|
+
echo "" >> "$REPORT_FILE"
|
|
495
|
+
echo "## Node.js Environment" >> "$REPORT_FILE"
|
|
496
|
+
scan_report " Node.js: $(node -v 2>/dev/null || echo 'not found')"
|
|
497
|
+
scan_report " npm: $(npm -v 2>/dev/null || echo 'not found')"
|
|
498
|
+
scan_report " Global prefix: $(npm prefix -g 2>/dev/null || echo 'unknown')"
|
|
499
|
+
|
|
500
|
+
chmod 600 "$REPORT_FILE"
|
|
501
|
+
success "Security report saved to: $REPORT_FILE"
|
|
502
|
+
|
|
503
|
+
fi # end if not dry-run
|
|
504
|
+
|
|
505
|
+
# ─── Summary ─────────────────────────────────────────────────────────────────
|
|
506
|
+
|
|
507
|
+
echo ""
|
|
508
|
+
divider
|
|
509
|
+
echo ""
|
|
510
|
+
echo -e "${BOLD}🏰 ClawMoat Installation Complete!${RESET}"
|
|
511
|
+
echo ""
|
|
512
|
+
echo -e " ${GREEN}✅${RESET} OS detected: $OS ($ARCH)"
|
|
513
|
+
if $NODE_OK; then
|
|
514
|
+
echo -e " ${GREEN}✅${RESET} Node.js: v${NODE_VERSION:-unknown}"
|
|
515
|
+
fi
|
|
516
|
+
echo -e " ${GREEN}✅${RESET} ClawMoat: installed"
|
|
517
|
+
echo -e " ${GREEN}✅${RESET} Config: $CONFIG_FILE"
|
|
518
|
+
echo -e " ${GREEN}✅${RESET} Permission tier: worker (least-privilege)"
|
|
519
|
+
echo -e " ${GREEN}✅${RESET} Forbidden zones: 17 credential paths protected"
|
|
520
|
+
echo -e " ${GREEN}✅${RESET} Secret scanning: enabled"
|
|
521
|
+
echo -e " ${GREEN}✅${RESET} Network logging: enabled"
|
|
522
|
+
echo -e " ${GREEN}✅${RESET} Audit trail: enabled"
|
|
523
|
+
|
|
524
|
+
if $ENTERPRISE; then
|
|
525
|
+
echo -e " ${GREEN}✅${RESET} FinanceGuard: monitor mode"
|
|
526
|
+
echo -e " ${GREEN}✅${RESET} MCP Firewall: read-only"
|
|
527
|
+
echo -e " ${GREEN}✅${RESET} SOX templates: installed"
|
|
528
|
+
fi
|
|
529
|
+
|
|
530
|
+
if [ "${FINDINGS:-0}" -gt 0 ]; then
|
|
531
|
+
echo ""
|
|
532
|
+
echo -e " ${YELLOW}📊${RESET} Security findings: ${BOLD}$FINDINGS${RESET} items found and now protected"
|
|
533
|
+
fi
|
|
534
|
+
|
|
535
|
+
echo ""
|
|
536
|
+
divider
|
|
537
|
+
echo ""
|
|
538
|
+
echo -e "${BOLD}Next steps:${RESET}"
|
|
539
|
+
echo ""
|
|
540
|
+
echo -e " 1. ${CYAN}Configure alerts${RESET} — edit ~/.clawmoat/config.json"
|
|
541
|
+
echo -e " Set webhookUrl, emailTo, or slackChannel for security alerts"
|
|
542
|
+
echo ""
|
|
543
|
+
echo -e " 2. ${CYAN}Test your setup${RESET}"
|
|
544
|
+
echo -e " $ clawmoat scan"
|
|
545
|
+
echo ""
|
|
546
|
+
echo -e " 3. ${CYAN}View documentation${RESET}"
|
|
547
|
+
echo -e " https://clawmoat.com/docs"
|
|
548
|
+
echo ""
|
|
549
|
+
|
|
550
|
+
if ! $ENTERPRISE; then
|
|
551
|
+
echo -e " 💼 ${BOLD}Need enterprise features?${RESET} Re-run with --enterprise:"
|
|
552
|
+
echo -e " $ curl -fsSL https://clawmoat.com/install.sh | bash -s -- --enterprise"
|
|
553
|
+
echo ""
|
|
554
|
+
fi
|
|
555
|
+
|
|
556
|
+
echo -e "${DIM}Questions? https://clawmoat.com/support/ • GitHub: ClawMoat/clawmoat${RESET}"
|
|
557
|
+
echo ""
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Privacy Policy — ClawMoat</title>
|
|
7
|
+
<meta name="description" content="ClawMoat Privacy Policy. How we collect, use, and protect your information.">
|
|
8
|
+
<link rel="canonical" href="https://clawmoat.com/privacy-policy/">
|
|
9
|
+
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🏰</text></svg>">
|
|
10
|
+
<style>
|
|
11
|
+
*{margin:0;padding:0;box-sizing:border-box}
|
|
12
|
+
:root{--navy:#0F172A;--navy-light:#1E293B;--navy-mid:#334155;--blue:#3B82F6;--emerald:#10B981;--white:#F8FAFC;--gray:#94A3B8}
|
|
13
|
+
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;background:var(--navy);color:var(--white);line-height:1.8}
|
|
14
|
+
a{color:var(--blue)}
|
|
15
|
+
.container{max-width:740px;margin:0 auto;padding:0 24px}
|
|
16
|
+
nav{background:rgba(15,23,42,.95);backdrop-filter:blur(12px);border-bottom:1px solid rgba(59,130,246,.15);padding:16px 0;position:fixed;top:0;left:0;right:0;z-index:100}
|
|
17
|
+
nav .container{display:flex;align-items:center;justify-content:space-between}
|
|
18
|
+
.logo{font-size:1.1rem;font-weight:700;color:var(--white);text-decoration:none}
|
|
19
|
+
.logo span{color:var(--emerald)}
|
|
20
|
+
nav a{color:var(--gray);font-size:.85rem;text-decoration:none}
|
|
21
|
+
nav a:hover{color:var(--white)}
|
|
22
|
+
article{padding:120px 0 80px}
|
|
23
|
+
h1{font-size:2rem;font-weight:800;margin-bottom:8px}
|
|
24
|
+
.updated{color:var(--gray);font-size:.85rem;margin-bottom:40px}
|
|
25
|
+
h2{font-size:1.2rem;font-weight:700;margin:36px 0 12px;color:var(--white)}
|
|
26
|
+
p{color:var(--gray);margin-bottom:16px;font-size:.95rem}
|
|
27
|
+
ul{color:var(--gray);margin:0 0 16px 24px;font-size:.95rem}
|
|
28
|
+
li{margin-bottom:6px}
|
|
29
|
+
</style>
|
|
30
|
+
</head>
|
|
31
|
+
<body>
|
|
32
|
+
<nav><div class="container"><a href="/" class="logo">🏰 Claw<span>Moat</span></a><div style="display:flex;gap:20px"><a href="/">Home</a><a href="/terms-of-service/">Terms</a><a href="/privacy-policy/">Privacy</a></div></div></nav>
|
|
33
|
+
<article><div class="container">
|
|
34
|
+
<h1>Privacy Policy</h1>
|
|
35
|
+
<p class="updated">Last Updated: February 26, 2026</p>
|
|
36
|
+
|
|
37
|
+
<p>This Privacy Policy describes how Leopold Care, LLC dba ClawMoat ("we", "us", "our") collects, uses, and discloses information about you when you use our website (clawmoat.com), open-source software, paid services, and related tools (collectively, the "Services").</p>
|
|
38
|
+
|
|
39
|
+
<p>By using our Services, you agree to the collection, use, and disclosure of your information as described in this Privacy Policy. If you do not agree, please do not use the Services.</p>
|
|
40
|
+
|
|
41
|
+
<h2>1. Information We Collect</h2>
|
|
42
|
+
|
|
43
|
+
<p><strong>Information You Provide:</strong></p>
|
|
44
|
+
<ul>
|
|
45
|
+
<li><strong>Account information</strong> — name, email address, and password when you create an account or subscribe to a paid plan.</li>
|
|
46
|
+
<li><strong>Payment information</strong> — credit card or billing information processed securely through Stripe. We do not store your full payment card details.</li>
|
|
47
|
+
<li><strong>Contact form submissions</strong> — name, email, company, and any details you provide through our inquiry forms.</li>
|
|
48
|
+
<li><strong>Communications</strong> — information you provide when contacting us via email at hello@clawmoat.com.</li>
|
|
49
|
+
</ul>
|
|
50
|
+
|
|
51
|
+
<p><strong>Information Collected Automatically:</strong></p>
|
|
52
|
+
<ul>
|
|
53
|
+
<li><strong>Usage data</strong> — pages visited, time on site, referral source, browser type, device type, and IP address.</li>
|
|
54
|
+
<li><strong>Cookies</strong> — we use essential cookies for site functionality. We do not use tracking cookies or third-party advertising cookies.</li>
|
|
55
|
+
</ul>
|
|
56
|
+
|
|
57
|
+
<p><strong>Open-Source Software (npm package):</strong></p>
|
|
58
|
+
<ul>
|
|
59
|
+
<li>The ClawMoat open-source npm package does <strong>not</strong> collect any telemetry, usage data, or personal information by default.</li>
|
|
60
|
+
<li>The software runs entirely on your machine. No data is sent to our servers unless you explicitly configure webhook alerts or opt into telemetry.</li>
|
|
61
|
+
<li>If you opt into telemetry, only anonymized usage statistics are collected (e.g., feature usage counts). No personal data, file contents, or credentials are ever transmitted.</li>
|
|
62
|
+
</ul>
|
|
63
|
+
|
|
64
|
+
<h2>2. How We Use Your Information</h2>
|
|
65
|
+
<ul>
|
|
66
|
+
<li>To provide, maintain, and improve the Services</li>
|
|
67
|
+
<li>To process payments and manage subscriptions</li>
|
|
68
|
+
<li>To respond to your inquiries and provide customer support</li>
|
|
69
|
+
<li>To send service-related communications (not marketing, unless you opt in)</li>
|
|
70
|
+
<li>To comply with legal obligations</li>
|
|
71
|
+
<li>To detect and prevent fraud or security incidents</li>
|
|
72
|
+
</ul>
|
|
73
|
+
|
|
74
|
+
<h2>3. How We Share Your Information</h2>
|
|
75
|
+
<p>We do not sell your personal information. We may share information with:</p>
|
|
76
|
+
<ul>
|
|
77
|
+
<li><strong>Service providers</strong> — Stripe (payments), GitHub Pages (hosting), and email providers, solely to deliver the Services.</li>
|
|
78
|
+
<li><strong>Legal requirements</strong> — if required by law, court order, or governmental authority.</li>
|
|
79
|
+
<li><strong>Business transfers</strong> — in connection with a merger, acquisition, or sale of assets, with notice to you.</li>
|
|
80
|
+
</ul>
|
|
81
|
+
|
|
82
|
+
<h2>4. Data Security</h2>
|
|
83
|
+
<p>We implement reasonable technical and organizational measures to protect your information. However, no method of transmission over the Internet is 100% secure.</p>
|
|
84
|
+
|
|
85
|
+
<h2>5. Data Retention</h2>
|
|
86
|
+
<p>We retain your information for as long as your account is active or as needed to provide Services. You may request deletion of your account and associated data at any time by contacting us.</p>
|
|
87
|
+
|
|
88
|
+
<h2>6. Your Rights</h2>
|
|
89
|
+
<p>Depending on your location, you may have the right to:</p>
|
|
90
|
+
<ul>
|
|
91
|
+
<li>Access, correct, or delete your personal information</li>
|
|
92
|
+
<li>Object to or restrict processing of your information</li>
|
|
93
|
+
<li>Data portability</li>
|
|
94
|
+
<li>Withdraw consent at any time</li>
|
|
95
|
+
</ul>
|
|
96
|
+
<p>To exercise these rights, contact us at <a href="mailto:hello@clawmoat.com">hello@clawmoat.com</a>.</p>
|
|
97
|
+
|
|
98
|
+
<h2>7. California Residents (CCPA)</h2>
|
|
99
|
+
<p>If you are a California resident, you have the right to know what personal information we collect, request deletion, and opt out of the sale of personal information. We do not sell personal information.</p>
|
|
100
|
+
|
|
101
|
+
<h2>8. Children's Privacy</h2>
|
|
102
|
+
<p>Our Services are not directed to children under 13. We do not knowingly collect personal information from children under 13.</p>
|
|
103
|
+
|
|
104
|
+
<h2>9. Third-Party Links</h2>
|
|
105
|
+
<p>Our Services may contain links to third-party websites. We are not responsible for their privacy practices.</p>
|
|
106
|
+
|
|
107
|
+
<h2>10. Changes to This Policy</h2>
|
|
108
|
+
<p>We may update this Privacy Policy from time to time. We will notify you of material changes by posting the updated policy on this page with a new "Last Updated" date.</p>
|
|
109
|
+
|
|
110
|
+
<h2>11. Contact Us</h2>
|
|
111
|
+
<p>If you have questions about this Privacy Policy, contact us at:</p>
|
|
112
|
+
<p>
|
|
113
|
+
Leopold Care, LLC dba ClawMoat<br>
|
|
114
|
+
10000 Washington Blvd<br>
|
|
115
|
+
Culver City, CA 90232<br>
|
|
116
|
+
Email: <a href="mailto:hello@clawmoat.com">hello@clawmoat.com</a><br>
|
|
117
|
+
Phone: <a href="tel:+16503838190">(650) 383-8190</a>
|
|
118
|
+
</p>
|
|
119
|
+
|
|
120
|
+
</div></article>
|
|
121
|
+
</body>
|
|
122
|
+
</html>
|