feat: merge Gitea webhook security into setup wizard (issue #2)
Integrates the 5-layer Gitea webhook security system from sol/clawgravity-hook-security (v2.0) into the setup wizard. ## What's added ### New files (from clawgravity-hook-security v2.0) - scripts/webhook-security/gitea-hmac-verify.js -- njs HMAC-SHA256 module - scripts/webhook-security/gitea-approve-repo -- allowlist helper - scripts/webhook-security/rotate-webhook-secret.sh -- monthly secret rotation (templated) - scripts/webhook-security/webhook-audit-alert.sh -- daily audit summaries (templated) - scripts/webhook-security/ntfy-blocked-pickup.sh -- blocked webhook alerts (templated) - templates/webhook-security/nginx-site.conf.example - templates/webhook-security/nginx.conf.example - templates/webhook-security/gitea-repo-allowlist.json.example - docs/WEBHOOK-SECURITY.md -- full documentation - docs/SECURITY-AUDIT.md -- 35-case test matrix - tests/test-webhook-security.sh -- 48 offline tests ### Modified files - setup.sh: Step 11 (webhook security wizard with 6 sub-sections) - scripts/uninstall.sh: webhook security cleanup section - README.md: Webhook Security section after Quick Start - Makefile: test target now runs test-webhook-security.sh - .secret-scan-allowlist: allowlist docs/SECURITY-AUDIT.md (test fixture) ## Security layers 1. IP allowlisting (nginx) 2. Rate limiting 10 req/s burst 20 (nginx) 3. Payload size 1MB (nginx) 4. HMAC-SHA256 signature verification (njs) 5. Per-repository allowlist (njs) ## make check - prettier: PASS - secret-scan: PASS - tests: 48/48 PASS Closes #2
This commit is contained in:
392
setup.sh
Executable file → Normal file
392
setup.sh
Executable file → Normal file
@@ -1019,6 +1019,388 @@ else
|
||||
ERRORS=$((ERRORS + 1))
|
||||
fi
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# STEP 11: Gitea Webhook Security (Optional)
|
||||
# ============================================================================
|
||||
header "Step 11: Gitea Webhook Security (Optional)"
|
||||
|
||||
echo -e " ${DIM}Installs 5-layer HMAC-based security for your Gitea webhook endpoint.${NC}"
|
||||
echo -e " ${DIM}Provides: IP allowlisting, rate limiting, payload size limits, HMAC${NC}"
|
||||
echo -e " ${DIM}signature verification, and per-repository allowlisting.${NC}"
|
||||
echo -e " ${DIM}Source: sol/clawgravity-hook-security (v2.0)${NC}"
|
||||
echo ""
|
||||
|
||||
WEBHOOK_SECURITY_INSTALLED=false
|
||||
|
||||
if ! confirm "Set up Gitea webhook security?" "Y"; then
|
||||
warn "Skipping webhook security setup (can be added later by re-running setup.sh)"
|
||||
else
|
||||
# --- 11.1: Prerequisite checks ---
|
||||
info "Checking webhook security prerequisites..."
|
||||
WH_MISSING=0
|
||||
|
||||
if command -v nginx &>/dev/null; then
|
||||
success "nginx found: $(nginx -v 2>&1 | head -1)"
|
||||
else
|
||||
warn "nginx not found"
|
||||
echo -e " ${DIM}Install: apt-get install -y nginx${NC}"
|
||||
WH_MISSING=$((WH_MISSING + 1))
|
||||
fi
|
||||
|
||||
# Check for njs module
|
||||
NJS_OK=false
|
||||
if nginx -V 2>&1 | grep -q 'http_js_module\|njs'; then
|
||||
NJS_OK=true
|
||||
success "nginx njs module detected"
|
||||
elif dpkg -l libnginx-mod-http-js 2>/dev/null | grep -q '^ii'; then
|
||||
NJS_OK=true
|
||||
success "libnginx-mod-http-js installed"
|
||||
elif [ -f /usr/lib/nginx/modules/ngx_http_js_module.so ]; then
|
||||
NJS_OK=true
|
||||
success "njs module found at /usr/lib/nginx/modules/"
|
||||
else
|
||||
warn "nginx njs module not detected"
|
||||
echo -e " ${DIM}Install: apt-get install -y libnginx-mod-http-js${NC}"
|
||||
WH_MISSING=$((WH_MISSING + 1))
|
||||
fi
|
||||
|
||||
if command -v jq &>/dev/null; then
|
||||
success "jq found"
|
||||
else
|
||||
warn "jq not found (required for rotation/audit scripts)"
|
||||
if confirm " Install jq now?" "Y"; then
|
||||
apt-get install -y jq 2>&1 | tail -3
|
||||
if command -v jq &>/dev/null; then
|
||||
success "jq installed"
|
||||
else
|
||||
warn "jq installation failed — install manually: apt-get install -y jq"
|
||||
WH_MISSING=$((WH_MISSING + 1))
|
||||
fi
|
||||
else
|
||||
warn "jq is required for rotation scripts — install later: apt-get install -y jq"
|
||||
WH_MISSING=$((WH_MISSING + 1))
|
||||
fi
|
||||
fi
|
||||
|
||||
if command -v openssl &>/dev/null; then
|
||||
success "openssl found"
|
||||
else
|
||||
error "openssl not found — required for secret generation"
|
||||
WH_MISSING=$((WH_MISSING + 1))
|
||||
fi
|
||||
|
||||
if [ "$WH_MISSING" -gt 0 ]; then
|
||||
warn "$WH_MISSING prerequisite(s) missing."
|
||||
if ! confirm " Continue anyway? (some steps may not complete)" "N"; then
|
||||
warn "Skipping webhook security setup. Install missing deps and re-run."
|
||||
else
|
||||
info "Continuing with available tools..."
|
||||
fi
|
||||
fi
|
||||
|
||||
# --- 11.2: Interactive prompts ---
|
||||
header "Step 11.2: Webhook Security Configuration"
|
||||
|
||||
echo -e " ${DIM}We'll collect the configuration values needed to deploy the security system.${NC}"
|
||||
echo ""
|
||||
|
||||
# Gitea server IP
|
||||
echo -e " ${BOLD}Gitea Server IP${NC}"
|
||||
echo -e " ${DIM}The IP address of your Gitea server (for nginx allowlisting, Layer 1).${NC}"
|
||||
echo -e " ${DIM}Find it with: dig +short YOUR_GITEA_DOMAIN${NC}"
|
||||
WH_GITEA_IP=$(ask " Gitea server IP" "127.0.0.1")
|
||||
|
||||
echo ""
|
||||
|
||||
# Webhook HMAC secret
|
||||
echo -e " ${BOLD}Webhook HMAC Secret${NC}"
|
||||
echo -e " ${DIM}Used to verify Gitea webhook signatures (Layer 4).${NC}"
|
||||
echo -e " ${DIM}Must match the secret configured in your Gitea webhook settings.${NC}"
|
||||
if confirm " Auto-generate a secure secret with openssl?" "Y"; then
|
||||
WH_SECRET=$(openssl rand -hex 32)
|
||||
success "Generated secret: ${WH_SECRET:0:8}...${WH_SECRET: -8} (64 hex chars)"
|
||||
echo -e " ${YELLOW}Important: After setup, update your Gitea webhook secret to this value.${NC}"
|
||||
echo -e " ${DIM}Gitea Settings -> Webhooks -> [your hook] -> Secret${NC}"
|
||||
else
|
||||
WH_SECRET=$(ask " Enter webhook secret" "")
|
||||
if [ -z "$WH_SECRET" ]; then
|
||||
WH_SECRET=$(openssl rand -hex 32)
|
||||
warn "No secret provided — auto-generated: ${WH_SECRET:0:8}..."
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Trusted owners
|
||||
echo -e " ${BOLD}Trusted Gitea Owners${NC}"
|
||||
echo -e " ${DIM}All repositories from these owners are allowed (Layer 5).${NC}"
|
||||
echo -e " ${DIM}Space-separated list of Gitea usernames/org names.${NC}"
|
||||
echo -e " ${DIM}Individual repos can be added later with: gitea-approve-repo owner/repo${NC}"
|
||||
WH_TRUSTED_OWNERS=$(ask " Trusted owners (space-separated)" "")
|
||||
|
||||
echo ""
|
||||
|
||||
# ntfy topic (optional)
|
||||
echo -e " ${BOLD}ntfy Alert Topic (optional)${NC}"
|
||||
echo -e " ${DIM}Receive instant ntfy.sh alerts when blocked webhooks are detected.${NC}"
|
||||
echo -e " ${DIM}Leave blank to skip notifications.${NC}"
|
||||
WH_NTFY_TOPIC=$(ask " ntfy topic URL (e.g. https://ntfy.sh/my-topic)" "")
|
||||
|
||||
echo ""
|
||||
|
||||
# OpenClaw port
|
||||
echo -e " ${BOLD}OpenClaw Gateway Port${NC}"
|
||||
echo -e " ${DIM}The port your OpenClaw gateway listens on (for nginx proxy_pass).${NC}"
|
||||
WH_OPENCLAW_PORT=$(ask " OpenClaw port" "3000")
|
||||
|
||||
echo ""
|
||||
|
||||
# Gitea API for rotation script
|
||||
echo -e " ${BOLD}Gitea Instance URL${NC}"
|
||||
echo -e " ${DIM}Base URL of your Gitea instance (for secret rotation script).${NC}"
|
||||
WH_GITEA_INSTANCE=$(ask " Gitea URL" "https://git.example.com")
|
||||
|
||||
echo ""
|
||||
|
||||
# Webhook URL match pattern
|
||||
echo -e " ${BOLD}Webhook URL Match Pattern${NC}"
|
||||
echo -e " ${DIM}Pattern to identify your OpenClaw webhook hooks in Gitea (for rotation).${NC}"
|
||||
WH_WEBHOOK_URL_MATCH=$(ask " Webhook URL pattern (e.g. yourdomain.com/hooks/gitea)" "")
|
||||
|
||||
echo ""
|
||||
|
||||
# Scan owners for rotation
|
||||
echo -e " ${BOLD}Gitea Owner(s) to Scan for Rotation${NC}"
|
||||
echo -e " ${DIM}Space-separated list of Gitea owners whose repos will have webhooks rotated.${NC}"
|
||||
WH_SCAN_OWNERS=$(ask " Owners to scan" "${WH_TRUSTED_OWNERS:-your-org}")
|
||||
|
||||
echo ""
|
||||
|
||||
# Mattermost config for audit (optional)
|
||||
echo -e " ${BOLD}Mattermost Audit Integration (optional)${NC}"
|
||||
echo -e " ${DIM}Daily audit summaries posted to a Mattermost channel.${NC}"
|
||||
WH_MATTERMOST_URL=$(ask " Mattermost URL (leave blank to skip)" "")
|
||||
WH_MATTERMOST_CHANNEL=""
|
||||
WH_MATTERMOST_GITEA_REPO=""
|
||||
if [ -n "$WH_MATTERMOST_URL" ]; then
|
||||
WH_MATTERMOST_CHANNEL=$(ask " Mattermost channel ID" "")
|
||||
WH_MATTERMOST_GITEA_REPO=$(ask " Gitea repo for audit anomaly issues (e.g. myorg/webhook-security)" "")
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# --- 11.3: Deploy files ---
|
||||
header "Step 11.3: Deploying Webhook Security Files"
|
||||
|
||||
WH_INSTALL_DIR="/opt/webhook-security"
|
||||
WH_NJS_DIR="/etc/nginx/njs"
|
||||
WH_SECRET_FILE="/etc/nginx/gitea-webhook-secret"
|
||||
WH_ALLOWLIST_FILE="/etc/nginx/gitea-repo-allowlist.json"
|
||||
|
||||
# Create directories
|
||||
mkdir -p "$WH_INSTALL_DIR/scripts"
|
||||
mkdir -p "$WH_NJS_DIR"
|
||||
success "Created $WH_INSTALL_DIR/scripts"
|
||||
success "Created $WH_NJS_DIR"
|
||||
|
||||
# Copy njs HMAC module
|
||||
cp "$SCRIPT_DIR/scripts/webhook-security/gitea-hmac-verify.js" "$WH_NJS_DIR/"
|
||||
chmod 644 "$WH_NJS_DIR/gitea-hmac-verify.js"
|
||||
success "Installed njs module: $WH_NJS_DIR/gitea-hmac-verify.js"
|
||||
|
||||
# Write secret file
|
||||
printf '%s' "$WH_SECRET" > "$WH_SECRET_FILE"
|
||||
chown root:www-data "$WH_SECRET_FILE" 2>/dev/null || chown root:root "$WH_SECRET_FILE"
|
||||
chmod 640 "$WH_SECRET_FILE"
|
||||
success "Installed secret: $WH_SECRET_FILE (permissions: root:www-data 640)"
|
||||
|
||||
# Build allowlist JSON from trusted owners
|
||||
WH_TRUSTED_OWNERS_JSON="[]"
|
||||
if [ -n "$WH_TRUSTED_OWNERS" ]; then
|
||||
WH_TRUSTED_OWNERS_JSON=$(python3 -c "
|
||||
import json, sys
|
||||
owners = '$WH_TRUSTED_OWNERS'.split()
|
||||
print(json.dumps(owners))
|
||||
")
|
||||
fi
|
||||
python3 -c "
|
||||
import json
|
||||
data = {
|
||||
'_comment': 'Gitea webhook repo allowlist. Edits take effect immediately (no nginx reload needed).',
|
||||
'repos': [],
|
||||
'trusted_owners': $WH_TRUSTED_OWNERS_JSON
|
||||
}
|
||||
with open('$WH_ALLOWLIST_FILE', 'w') as f:
|
||||
json.dump(data, f, indent=4)
|
||||
f.write('\n')
|
||||
"
|
||||
chmod 644 "$WH_ALLOWLIST_FILE"
|
||||
success "Installed allowlist: $WH_ALLOWLIST_FILE"
|
||||
info " Trusted owners: ${WH_TRUSTED_OWNERS:-none configured yet}"
|
||||
info " Add repos later with: gitea-approve-repo owner/repo"
|
||||
|
||||
# Install templated scripts with substitutions
|
||||
for script in rotate-webhook-secret.sh webhook-audit-alert.sh ntfy-blocked-pickup.sh; do
|
||||
SED_CMD=(sed
|
||||
-e "s|@@GITEA_API@@|$WH_GITEA_INSTANCE|g"
|
||||
-e "s|@@WEBHOOK_URL_MATCH@@|$WH_WEBHOOK_URL_MATCH|g"
|
||||
-e "s|@@SCAN_OWNERS@@|$WH_SCAN_OWNERS|g"
|
||||
-e "s|@@NTFY_TOPIC@@|${WH_NTFY_TOPIC:-https://ntfy.sh/YOUR_NTFY_TOPIC}|g"
|
||||
-e "s|@@MATTERMOST_URL@@|${WH_MATTERMOST_URL:-YOUR_MATTERMOST_URL}|g"
|
||||
-e "s|@@MATTERMOST_CHANNEL_ID@@|${WH_MATTERMOST_CHANNEL:-YOUR_MATTERMOST_CHANNEL_ID}|g"
|
||||
-e "s|@@GITEA_API_BASE@@|$WH_GITEA_INSTANCE|g"
|
||||
-e "s|@@GITEA_REPO@@|${WH_MATTERMOST_GITEA_REPO:-YOUR_GITEA_REPO}|g"
|
||||
)
|
||||
"${SED_CMD[@]}" "$SCRIPT_DIR/scripts/webhook-security/$script" \
|
||||
> "$WH_INSTALL_DIR/scripts/$script"
|
||||
chmod 755 "$WH_INSTALL_DIR/scripts/$script"
|
||||
success "Installed $WH_INSTALL_DIR/scripts/$script"
|
||||
done
|
||||
|
||||
# Task 11.4: Install gitea-approve-repo to /usr/local/bin/
|
||||
cp "$SCRIPT_DIR/scripts/webhook-security/gitea-approve-repo" /usr/local/bin/gitea-approve-repo
|
||||
chmod 755 /usr/local/bin/gitea-approve-repo
|
||||
success "Installed /usr/local/bin/gitea-approve-repo"
|
||||
|
||||
# --- 11.4: nginx config guidance ---
|
||||
header "Step 11.4: nginx Configuration Guidance"
|
||||
|
||||
echo -e " ${BOLD}The security system requires two nginx configuration changes:${NC}"
|
||||
echo ""
|
||||
echo -e " ${BOLD}1. In /etc/nginx/nginx.conf (inside the http {} block):${NC}"
|
||||
echo -e " ${DIM}─────────────────────────────────────────────────────────${NC}"
|
||||
cat "$SCRIPT_DIR/templates/webhook-security/nginx.conf.example"
|
||||
echo -e " ${DIM}─────────────────────────────────────────────────────────${NC}"
|
||||
echo ""
|
||||
echo -e " ${BOLD}2. In your site config (e.g. /etc/nginx/sites-enabled/openclaw):${NC}"
|
||||
echo -e " ${DIM}The location blocks for /hooks/gitea are in:${NC}"
|
||||
echo -e " ${DIM}$SCRIPT_DIR/templates/webhook-security/nginx-site.conf.example${NC}"
|
||||
echo ""
|
||||
echo -e " ${DIM}Replace YOUR_DOMAIN, YOUR_GITEA_SERVER_IP, YOUR_OPENCLAW_PORT,${NC}"
|
||||
echo -e " ${DIM}and YOUR_OPENCLAW_GATEWAY_TOKEN with your actual values.${NC}"
|
||||
echo ""
|
||||
|
||||
if confirm " Display full site config example now?" "N"; then
|
||||
echo ""
|
||||
echo -e "${DIM}"
|
||||
cat "$SCRIPT_DIR/templates/webhook-security/nginx-site.conf.example" | \
|
||||
sed -e "s|YOUR_GITEA_SERVER_IP|$WH_GITEA_IP|g" \
|
||||
-e "s|YOUR_OPENCLAW_PORT|$WH_OPENCLAW_PORT|g"
|
||||
echo -e "${NC}"
|
||||
fi
|
||||
|
||||
# --- 11.5: Optional cron setup ---
|
||||
header "Step 11.5: Cron Jobs (Optional)"
|
||||
|
||||
echo -e " ${DIM}Three automated tasks can be set up via cron:${NC}"
|
||||
echo ""
|
||||
echo " 1. Secret rotation (monthly, 1st of month at 3am UTC)"
|
||||
echo " Command: $WH_INSTALL_DIR/scripts/rotate-webhook-secret.sh"
|
||||
echo ""
|
||||
echo " 2. Blocked webhook alerts (every minute, scans nginx error.log)"
|
||||
echo " Command: $WH_INSTALL_DIR/scripts/ntfy-blocked-pickup.sh"
|
||||
echo ""
|
||||
echo " 3. Daily audit summary (5am UTC)"
|
||||
echo " Command: $WH_INSTALL_DIR/scripts/webhook-audit-alert.sh"
|
||||
echo ""
|
||||
|
||||
CRON_ADDED=0
|
||||
if confirm " Install monthly secret rotation cron job?" "Y"; then
|
||||
CRON_LINE="0 3 1 * * $WH_INSTALL_DIR/scripts/rotate-webhook-secret.sh >> /var/log/webhook-secret-rotation.log 2>&1"
|
||||
(crontab -l 2>/dev/null; echo "$CRON_LINE") | sort -u | crontab -
|
||||
success "Added rotation cron: 0 3 1 * * ..."
|
||||
CRON_ADDED=$((CRON_ADDED + 1))
|
||||
fi
|
||||
|
||||
if [ -n "$WH_NTFY_TOPIC" ] && confirm " Install blocked-webhook ntfy alerts cron (every minute)?" "Y"; then
|
||||
CRON_LINE="* * * * * $WH_INSTALL_DIR/scripts/ntfy-blocked-pickup.sh"
|
||||
(crontab -l 2>/dev/null; echo "$CRON_LINE") | sort -u | crontab -
|
||||
success "Added ntfy-blocked-pickup cron: * * * * * ..."
|
||||
CRON_ADDED=$((CRON_ADDED + 1))
|
||||
fi
|
||||
|
||||
if [ -n "$WH_MATTERMOST_URL" ] && confirm " Install daily audit summary cron (5am UTC)?" "Y"; then
|
||||
CRON_LINE="5 0 * * * MATTERMOST_BOT_TOKEN=YOUR_BOT_TOKEN $WH_INSTALL_DIR/scripts/webhook-audit-alert.sh >> /var/log/webhook-audit.log 2>&1"
|
||||
(crontab -l 2>/dev/null; echo "$CRON_LINE") | sort -u | crontab -
|
||||
success "Added audit cron: 5 0 * * * ..."
|
||||
warn "Edit the cron entry to set MATTERMOST_BOT_TOKEN: crontab -e"
|
||||
CRON_ADDED=$((CRON_ADDED + 1))
|
||||
fi
|
||||
|
||||
if [ "$CRON_ADDED" -eq 0 ]; then
|
||||
info "No cron jobs added. You can add them manually — see docs/WEBHOOK-SECURITY.md"
|
||||
fi
|
||||
|
||||
# --- 11.6: Verification ---
|
||||
header "Step 11.6: Webhook Security Verification"
|
||||
|
||||
WH_ERRORS=0
|
||||
|
||||
# Check njs module file
|
||||
if [ -f "$WH_NJS_DIR/gitea-hmac-verify.js" ]; then
|
||||
success "njs module installed: $WH_NJS_DIR/gitea-hmac-verify.js"
|
||||
else
|
||||
error "njs module NOT found: $WH_NJS_DIR/gitea-hmac-verify.js"
|
||||
WH_ERRORS=$((WH_ERRORS + 1))
|
||||
fi
|
||||
|
||||
# Check secret file
|
||||
if [ -f "$WH_SECRET_FILE" ]; then
|
||||
SECRET_LEN=$(wc -c < "$WH_SECRET_FILE")
|
||||
SECRET_PERMS=$(stat -c '%a' "$WH_SECRET_FILE" 2>/dev/null || stat -f '%Mp%Lp' "$WH_SECRET_FILE" 2>/dev/null)
|
||||
if [ "$SECRET_LEN" -ge 32 ]; then
|
||||
success "Secret file: $WH_SECRET_FILE (${SECRET_LEN} chars, perms: $SECRET_PERMS)"
|
||||
else
|
||||
error "Secret file too short (${SECRET_LEN} chars)"
|
||||
WH_ERRORS=$((WH_ERRORS + 1))
|
||||
fi
|
||||
else
|
||||
error "Secret file NOT found: $WH_SECRET_FILE"
|
||||
WH_ERRORS=$((WH_ERRORS + 1))
|
||||
fi
|
||||
|
||||
# Check allowlist
|
||||
if [ -f "$WH_ALLOWLIST_FILE" ]; then
|
||||
if python3 -c "import json; json.load(open('$WH_ALLOWLIST_FILE'))" 2>/dev/null; then
|
||||
success "Allowlist file: $WH_ALLOWLIST_FILE (valid JSON)"
|
||||
else
|
||||
error "Allowlist file has invalid JSON: $WH_ALLOWLIST_FILE"
|
||||
WH_ERRORS=$((WH_ERRORS + 1))
|
||||
fi
|
||||
else
|
||||
error "Allowlist file NOT found: $WH_ALLOWLIST_FILE"
|
||||
WH_ERRORS=$((WH_ERRORS + 1))
|
||||
fi
|
||||
|
||||
# Check gitea-approve-repo
|
||||
if [ -x /usr/local/bin/gitea-approve-repo ]; then
|
||||
success "gitea-approve-repo: /usr/local/bin/gitea-approve-repo (executable)"
|
||||
else
|
||||
error "gitea-approve-repo not found/executable"
|
||||
WH_ERRORS=$((WH_ERRORS + 1))
|
||||
fi
|
||||
|
||||
# nginx config test (if nginx is available and njs module found)
|
||||
if command -v nginx &>/dev/null && $NJS_OK; then
|
||||
if nginx -t 2>/dev/null; then
|
||||
success "nginx -t: config is valid"
|
||||
else
|
||||
warn "nginx -t failed — config changes may be needed (see Step 11.4 guidance above)"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$WH_ERRORS" -eq 0 ]; then
|
||||
success "Webhook security installed successfully"
|
||||
WEBHOOK_SECURITY_INSTALLED=true
|
||||
else
|
||||
warn "$WH_ERRORS webhook security error(s) — review output above"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
info "Reference: $SCRIPT_DIR/docs/WEBHOOK-SECURITY.md for full documentation"
|
||||
info "Security audit: $SCRIPT_DIR/docs/SECURITY-AUDIT.md"
|
||||
fi
|
||||
# ============================================================================
|
||||
# SUMMARY
|
||||
# ============================================================================
|
||||
@@ -1049,6 +1431,9 @@ fi
|
||||
echo " - Anthropic model configured in openclaw.json"
|
||||
echo " - Auth profiles updated for all agents"
|
||||
echo " - oauth.json created with fresh token"
|
||||
if [ "$WEBHOOK_SECURITY_INSTALLED" = true ]; then
|
||||
echo " - Webhook security: njs module, secret, allowlist, helper scripts"
|
||||
fi
|
||||
echo ""
|
||||
echo -e " ${BOLD}Useful commands:${NC}"
|
||||
if [ "$USE_INOTIFY" = true ]; then
|
||||
@@ -1062,8 +1447,13 @@ if [ "$TRIGGER_INSTALLED" = true ]; then
|
||||
echo " journalctl -u trigger-claude-refresh -n 20 # Trigger logs"
|
||||
echo " systemctl list-timers trigger-claude-refresh* # Check trigger timer"
|
||||
fi
|
||||
if [ "$WEBHOOK_SECURITY_INSTALLED" = true ]; then
|
||||
echo " gitea-approve-repo owner/repo # Add repo to allowlist"
|
||||
echo " cat /etc/nginx/gitea-repo-allowlist.json # View allowlist"
|
||||
echo " /opt/webhook-security/scripts/rotate-webhook-secret.sh --dry-run"
|
||||
fi
|
||||
echo " ./scripts/verify.sh # Health check"
|
||||
echo " ./setup.sh --uninstall # Remove everything"
|
||||
echo ""
|
||||
echo -e " ${DIM}Created by ROOH — <project-url>${NC}"
|
||||
echo ""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user