diff --git a/skills/clawsec-nanoclaw/CHANGELOG.md b/skills/clawsec-nanoclaw/CHANGELOG.md index c09d023f..8366a2d1 100644 --- a/skills/clawsec-nanoclaw/CHANGELOG.md +++ b/skills/clawsec-nanoclaw/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## [0.0.11] - 2026-07-22 + +### Changed + +- Reclassified the package as a deprecated, runtime-unverified NanoClaw v1-era integration prototype with no asserted support range. +- Removed actionable setup, restart, scheduling, integrity, and signing instructions from the packaged user-facing Markdown where they were not proven against an official NanoClaw runtime. +- Marked NanoClaw v2 as incompatible and documented its additive skill and two-database host/container boundaries. +- Excluded runtime-unverified TypeScript, policy JSON, and PEM artifacts from the release SBOM while retaining the frozen source in the repository as migration evidence. +- Added a static legacy-status contract test for the non-installable, documentation-only release boundary. + ## [0.0.10] - 2026-06-23 ### Changed diff --git a/skills/clawsec-nanoclaw/INSTALL.md b/skills/clawsec-nanoclaw/INSTALL.md index 056f5112..de3dd02e 100644 --- a/skills/clawsec-nanoclaw/INSTALL.md +++ b/skills/clawsec-nanoclaw/INSTALL.md @@ -1,327 +1,92 @@ -# ClawSec for NanoClaw - Installation Guide +# Historical NanoClaw Integration Record -This guide shows how to add ClawSec security monitoring to your NanoClaw deployment. +> **Do not install this package.** This file preserves the failed assumptions of an earlier NanoClaw v1-era integration template. It is not an installation guide. -## Overview +## Classification -ClawSec provides security advisory monitoring for NanoClaw through: -- **MCP Tools**: Agents can check for vulnerabilities via `clawsec_check_advisories` -- **Advisory Feed**: Automatic monitoring of https://clawsec.prompt.security/advisories/feed.json -- **Signature Verification**: Ed25519-signed feeds ensure integrity -- **Exploitability Context**: Advisories include exploitability score and rationale for triage +- Package: `clawsec-nanoclaw` +- Version: `0.0.11` +- Status: historical and unverified +- Supported NanoClaw versions: none asserted +- NanoClaw v2: incompatible +- Runtime activation: prohibited until a separate implementation passes its own acceptance suite -## Prerequisites +NanoClaw has no reviewed direct Agent Skills CLI target; do not substitute an OpenClaw or another unrelated target. -- NanoClaw >= 0.1.0 -- Node.js >= 18.0.0 -- Write access to NanoClaw installation directory +## Why the Former Procedure Was Withdrawn -## Installation Steps +The previous procedure instructed operators to copy modules into a NanoClaw checkout and import them from the agent runner. That does not establish a working module boundary. -### 1. Copy Skill Files +The files under `mcp-tools/` declare these identifiers without importing or receiving them: -Copy the `clawsec-nanoclaw` skill directory to your NanoClaw installation: +- `server` +- `writeIpcFile` +- `TASKS_DIR` +- `groupFolder` -```bash -# From the ClawSec repository -cp -r skills/clawsec-nanoclaw /path/to/your/nanoclaw/skills/ -``` +TypeScript `declare` statements emit no JavaScript. ES modules also do not inherit lexical variables from their importers. Importing these files therefore cannot bind the identifiers that their top-level registration and handlers use. -### 2. Integrate MCP Tools +Additional retained assumptions were not qualified against an upstream runtime: -Add the ClawSec MCP tools to your NanoClaw container agent runner. +- `guardian/integrity-monitor.ts` declares a `glob` namespace but imports or receives no runtime implementation, so `glob.sync` is unbound. +- `host-services/ipc-handlers.ts` declares `writeResponse` but imports or implements no such function. +- `host-services/skill-signature-handler.ts` uses CommonJS `__dirname` in an ES module without defining an equivalent ESM path. +- Docker Compose restart commands did not match the reviewed v1 service model. +- Some host services hard-code paths that belong to the container view. +- Group, task, cache, result, and integrity paths are not bound to one verified NanoClaw layout. +- The host IPC wrapper is incomplete and has no end-to-end response-path test. +- No apply, update, removal, interruption-recovery, or rollback transaction was tested. -**File**: `container/agent-runner/src/ipc-mcp-stdio.ts` +The old commands and code snippets were removed so an agent cannot mistake them for a supported installation path. -```typescript -// Add these imports at the top to register all ClawSec MCP tools: +## NanoClaw v2 Boundary -// Advisory tools: clawsec_check_advisories, clawsec_check_skill_safety, -// clawsec_list_advisories, clawsec_refresh_cache -import '../../../skills/clawsec-nanoclaw/mcp-tools/advisory-tools.js'; +NanoClaw v2 is a ground-up rewrite. Current official documentation describes: -// Signature verification: clawsec_verify_skill_package -import '../../../skills/clawsec-nanoclaw/mcp-tools/signature-verification.js'; +- A Node.js host and one container per active session. +- Per-session `inbound.db` and `outbound.db` files with opposite writer ownership. +- Additive code-carrying skills executed by a coding harness. +- Skills that copy reviewed files, append explicit registration imports, pin dependencies, run integration tests, and provide `REMOVE.md` when state is left behind. +- Scheduled tasks managed by current host surfaces rather than the retired v1 `schedule_task` MCP example. -// Integrity monitoring: clawsec_check_integrity, clawsec_approve_change, -// clawsec_integrity_status, clawsec_verify_audit -import '../../../skills/clawsec-nanoclaw/mcp-tools/integrity-tools.js'; -``` +These upstream facts were observed on 2026-07-22. Reverify the current official documentation and source revision before relying on them for a migration decision. -Each file calls `server.tool()` directly to register its tools. The `server`, -`writeIpcFile`, `TASKS_DIR`, and `groupFolder` variables must be available in -the scope where these files are imported (they are declared as ambient globals -in each tool file). +This package instead preserves v1-era message-file IPC, runner reach-ins, and path assumptions. Do not translate them by changing path strings. -### 3. Integrate IPC Handlers +## Existing Fork Assessment -Add the host-side IPC handlers for ClawSec operations. +If an operator already has a historical customization, perform a read-only assessment: -**File**: `src/ipc.ts` +1. Record the exact NanoClaw commit and local modifications. +2. Locate every ClawSec file, import, service, task, cache, baseline, and result path. +3. Determine whether any process actually loads the modules and capture its logs without restarting it. +4. Record file digests, ownership, permissions, host/container location, and dependencies. +5. Identify how to disable the customization without deleting state. +6. Prepare rollback and migration steps for operator review. -```typescript -// Add these imports at the top -import { handleAdvisoryIpc } from '../skills/clawsec-nanoclaw/host-services/ipc-handlers.js'; -import { AdvisoryCacheManager } from '../skills/clawsec-nanoclaw/host-services/advisory-cache.js'; -import { SkillSignatureVerifier } from '../skills/clawsec-nanoclaw/host-services/skill-signature-handler.js'; +If current authorization does not permit access to live logs, record runtime execution evidence as unknown. Do not infer that the customization works or is inactive. -// Initialize these once in host startup and pass through deps -const advisoryCacheManager = new AdvisoryCacheManager('/workspace/project/data', logger); -const signatureVerifier = new SkillSignatureVerifier(); +Do not run the historical setup or removal instructions from an older release. Do not mutate the deployment merely to test whether the integration works. -// In processTaskIpc switch: -case 'refresh_advisory_cache': -case 'verify_skill_signature': - await handleAdvisoryIpc( - data, - { advisoryCacheManager, signatureVerifier }, - logger, - sourceGroup - ); - break; -default: - // existing task handling -} -``` +## Qualification Required for Any Replacement -### 4. Start Advisory Cache Service +A new NanoClaw package must be developed separately and must provide: -Add the advisory cache manager to your host services. +- A declared, pinned NanoClaw v2 support range. +- A complete additive apply plan with exact preimages and postimages. +- An explicit registration boundary; no ambient globals. +- Integration tests that fail when required wiring is absent. +- Correct host/container path ownership and database-writer invariants. +- Idempotent apply, update, resume, remove, and rollback behavior. +- `REMOVE.md` for every persistent change. +- Remote harness acceptance using the exact copied candidate bytes. +- Signed qualification and installation receipts before stable release. -**File**: `src/index.ts` (or your main entry point) +Treat a successor as available only when the current published release and its acceptance evidence prove that status. A roadmap entry, source directory, branch, pull request, or version-shaped label is not availability evidence. -```typescript -import { AdvisoryCacheManager } from '../skills/clawsec-nanoclaw/host-services/advisory-cache.js'; +## Official References -// Start the service when your host process starts -async function main() { - // ... your existing initialization ... - - // Initialize cache manager and prime it at startup - const advisoryCacheManager = new AdvisoryCacheManager('/workspace/project/data', logger); - await advisoryCacheManager.initialize(); - - // Recommended refresh cadence (6h) - setInterval(() => { - advisoryCacheManager.refresh().catch((error) => { - logger.error({ error }, 'Periodic advisory cache refresh failed'); - }); - }, 6 * 60 * 60 * 1000); - - // ... rest of your startup ... -} -``` - -### 5. Restart NanoClaw - -Restart your NanoClaw instance to load the new MCP tools and services: - -```bash -# Stop NanoClaw -docker-compose down - -# Start with new configuration -docker-compose up -d -``` - -## Verification - -Test that ClawSec is working: - -### 1. Check MCP Tools Available - -From within a NanoClaw agent session, the following tools should be available: - -**Advisory Tools** (mcp-tools/advisory-tools.ts): -- `clawsec_check_advisories` - Scan installed skills for vulnerabilities -- `clawsec_check_skill_safety` - Pre-installation safety check -- `clawsec_list_advisories` - List all advisories with filtering -- `clawsec_refresh_cache` - Request immediate advisory cache refresh - -**Signature Verification** (mcp-tools/signature-verification.ts): -- `clawsec_verify_skill_package` - Verify Ed25519 signature on skill packages - - Uses pinned ClawSec public key (no runtime key override) - - Accepts staged package/signature paths only under `/tmp`, `/var/tmp`, `/workspace/ipc`, `/workspace/project/data`, `/workspace/project/tmp`, `/workspace/project/downloads` - -**Integrity Monitoring** (mcp-tools/integrity-tools.ts): -- `clawsec_check_integrity` - Check protected files for unauthorized changes -- `clawsec_approve_change` - Approve intentional file modification as new baseline -- `clawsec_integrity_status` - View current baseline status -- `clawsec_verify_audit` - Verify audit log hash chain integrity - -### 2. Test Advisory Checking - -Ask your NanoClaw agent: -``` -Check if any of my installed skills have security advisories -``` - -The agent should use the `clawsec_check_advisories` tool and report results. - -### 3. Check Advisory Cache - -Verify the cache file was created: -```bash -cat /workspace/project/data/clawsec-advisory-cache.json -``` - -You should see: -- `feed`: Array of advisories -- `fetchedAt`: Timestamp of last update -- `verified`: Should be `true` -- `publicKeyFingerprint`: SHA-256 fingerprint of the pinned signing key - -## Usage Examples - -### Agent Commands - -Once installed, your NanoClaw agents can: - -**Check for vulnerabilities:** -``` -Scan my installed skills for security issues -``` - -**Pre-installation check:** -``` -Is it safe to install skill-name@1.0.0? -``` - -**List all advisories:** -``` -Show me all ClawSec security advisories -``` - -### Manual Tool Invocation - -You can also call the MCP tools directly from agent code: - -```typescript -// Check all installed skills -const result = await tools.clawsec_check_advisories({ - installRoot: '/home/node/.claude/skills' -}); - -// Check specific skill before installation -const safetyCheck = await tools.clawsec_check_skill_safety({ - skillName: 'risky-skill', - skillVersion: '1.0.0' -}); -``` - -## Configuration - -### Cache Location - -Default: `/workspace/project/data/clawsec-advisory-cache.json` - -To change, pass a different data directory path to `new AdvisoryCacheManager(dataDir, logger)`. - -### Refresh Interval - -Default: 6 hours - -To change, update the `setInterval(...)` duration (in milliseconds) in host startup. - -### Feed URL - -Default: `https://clawsec.prompt.security/advisories/feed.json` - -To use a mirror or custom feed, update `FEED_URL` in `skills/clawsec-nanoclaw/host-services/advisory-cache.ts`. - -## Platform-Specific Advisories - -ClawSec advisories can target specific platforms: - -- **`platforms: ["nanoclaw"]`**: Only affects NanoClaw -- **`platforms: ["openclaw"]`**: Only affects OpenClaw/MoltBot -- **`platforms: ["openclaw", "nanoclaw"]`**: Affects both -- **No `platforms` field**: Applies to all platforms - -Platform metadata is preserved in advisory records and can be filtered by your policy layer. - -## Security - -### Signature Verification - -All advisory feeds are Ed25519 signed. The public key is pinned in: -``` -skills/clawsec-nanoclaw/advisories/feed-signing-public.pem -``` - -Feeds failing signature verification are rejected. - -### Cache Integrity - -The advisory cache includes: -- Cryptographic signature of feed contents -- Verification status -- Timestamp of last successful fetch - -Never manually edit the cache file - it will break signature verification. - -## Troubleshooting - -### Tools Not Appearing - -**Problem**: MCP tools not showing up in agent - -**Solution**: -1. Check that you added the import and registration in `ipc-mcp-stdio.ts` -2. Restart the container -3. Check container logs for import errors - -### Cache Not Updating - -**Problem**: Advisory cache is empty or stale - -**Solution**: -1. Check that `AdvisoryCacheManager.initialize()` is called in your host entry point -2. Verify network access to `clawsec.prompt.security` -3. Check host logs for fetch errors -4. Manually trigger: `curl https://clawsec.prompt.security/advisories/feed.json` - -### Signature Verification Failing - -**Problem**: Cache shows `"verified": false` - -**Solution**: -1. Ensure public key file exists at correct path -2. Check file permissions (should be readable) -3. Verify feed URL is correct (not using HTTP instead of HTTPS) -4. Check for corrupted downloads (try clearing cache and refetching) - -### IPC Communication Issues - -**Problem**: Tools return errors about IPC - -**Solution**: -1. Verify IPC handlers are registered in `src/ipc.ts` -2. Check that IPC directory exists and is writable -3. Ensure host process is running -4. Check host logs for handler errors - -## Uninstallation - -To remove ClawSec from NanoClaw: - -1. Remove MCP tool registration from `ipc-mcp-stdio.ts` -2. Remove IPC handler registration from `src/ipc.ts` -3. Remove `AdvisoryCacheManager` initialization from host entry point -4. Delete the skill directory: `rm -rf skills/clawsec-nanoclaw` -5. Delete the cache file: `rm /workspace/project/data/clawsec-advisory-cache.json` -6. Restart NanoClaw - -## Support - -- **Documentation**: https://clawsec.prompt.security/ -- **Issues**: https://github.com/prompt-security/clawsec/issues -- **Security**: security@prompt.security - -## License - -AGPL-3.0-or-later - ---- - -**Questions?** Open an issue or check the main ClawSec documentation. +- [NanoClaw architecture](https://docs.nanoclaw.dev/concepts/architecture) +- [NanoClaw v2 skills](https://docs.nanoclaw.dev/extend/overview) +- [Writing NanoClaw skills](https://docs.nanoclaw.dev/extend/writing-skills) +- [Migrate from NanoClaw v1](https://docs.nanoclaw.dev/migrate-from-v1) diff --git a/skills/clawsec-nanoclaw/README.md b/skills/clawsec-nanoclaw/README.md index 4c9401cd..08c2837d 100644 --- a/skills/clawsec-nanoclaw/README.md +++ b/skills/clawsec-nanoclaw/README.md @@ -1,159 +1,58 @@ -# ClawSec for NanoClaw +# ClawSec NanoClaw v1-Era Template -ClawSec now supports NanoClaw, a containerized WhatsApp bot powered by Claude agents. +> **Status:** Deprecated, historical, and runtime-unverified. This package is retained as migration evidence. It is not a supported NanoClaw adapter and must not be installed into NanoClaw v2. -## Vercel Skills Installation +## Compatibility -Install with the Vercel Skills CLI for this harness: +- No NanoClaw runtime version is advertised as supported. The package has not passed an end-to-end harness test against a pinned upstream release. +- NanoClaw v2 is incompatible with this template. +- NanoClaw v2 uses a Node.js host, per-session `inbound.db` and `outbound.db` transport, additive code-carrying skills, and current host registration surfaces. +- This template assumes retired v1-era message-file IPC, paths, scheduling, and source reach-ins. -```bash -npx skills add prompt-security/clawsec --skill clawsec-nanoclaw -a openclaw -y -``` +NanoClaw has no reviewed direct Agent Skills CLI target; do not substitute `--agent openclaw` or another unrelated target. -## What Changed +Read the [historical integration record](./INSTALL.md) for the known limitations. It is not an installation procedure. -### Advisory Feed Monitoring -- **NVD CVE Pipeline**: Now monitors for NanoClaw-specific keywords - - "NanoClaw", "WhatsApp-bot", "baileys" (WhatsApp library) - - Container-related vulnerabilities -- **Platform Targeting**: Advisories can specify `platforms: ["nanoclaw"]` for NanoClaw-specific issues +## Why It Is Unverified -### Keywords Added -The CVE monitoring now includes: -- `NanoClaw` - Direct product name -- `WhatsApp-bot` - Core functionality -- `baileys` - WhatsApp client library dependency +The bundled MCP modules declare `server`, `writeIpcFile`, `TASKS_DIR`, and `groupFolder` as ambient identifiers. Importing an ES module does not make module-local variables from the importer visible to the imported module. The historical instructions therefore do not provide a working registration boundary. -## Advisory Schema +Other retained assumptions also differ from the official v1 and v2 trees: -Advisories now support optional `platforms` field: +- The old restart instructions referenced Docker Compose even though the reviewed v1 trees use host services and a separate container build step. +- Several host services use container-side paths. +- The historical group, task, and message-file paths do not represent NanoClaw v2's database model. +- The package has no tested apply, update, remove, rollback, or recovery transaction. -```json -{ - "id": "CVE-2026-XXXXX", - "platforms": ["openclaw", "nanoclaw"], - "severity": "critical", - "type": "prompt_injection", - "affected": ["skill-name@1.0.0"], - "action": "Update to version 1.0.1" -} -``` +Unit tests cover isolated ClawSec helper invariants. They do not prove that NanoClaw loads or executes this package. -**Platform values:** -- `"openclaw"` - Affects OpenClaw/ClawdBot/MoltBot only -- `"nanoclaw"` - Affects NanoClaw only -- `["openclaw", "nanoclaw"]` - Affects both platforms -- (empty/missing) - Applies to all platforms (backward compatible) +## Preserved Evidence -## ClawSec NanoClaw Skill +The source remains available for migration analysis and future test fixtures: -ClawSec provides a complete security skill for NanoClaw deployments: +- Advisory matching and feed-signature helpers. +- Historical MCP declarations and message-file handlers. +- Historical package-signature and integrity components. +- v1-era path and policy assumptions that future migration checks must detect. -**Location**: `skills/clawsec-nanoclaw/` +Do not interpret preserved source as an available protection or installation path. -### Features +## Replacement Direction -- **9 MCP Tools** for agents to manage security: - - `clawsec_check_advisories` - Scan installed skills for vulnerabilities - - `clawsec_check_skill_safety` - Pre-installation safety checks - - `clawsec_list_advisories` - Browse advisory feed with filtering - - `clawsec_refresh_cache` - Request immediate advisory cache refresh - - `clawsec_verify_skill_package` - Verify Ed25519 signatures on skill packages - - `clawsec_check_integrity` - Check protected files for unauthorized changes - - `clawsec_approve_change` - Approve intentional file modifications - - `clawsec_integrity_status` - View file baseline status - - `clawsec_verify_audit` - Verify audit log hash chain +Current NanoClaw support will be implemented as separate v2-native packages: -- **Advisory Cache Service**: Host-managed feed fetching with signature validation -- **Signature Verification**: Ed25519-signed feeds ensure integrity -- **Exploitability Context**: Surfaces `exploitability_score` and rationale to reduce alert fatigue -- **IPC Communication**: Container-safe host communication +- `clawsec-core-nanoclaw` +- `clawsec-suite-nanoclaw` +- `clawsec-drift-guardian-nanoclaw` -### Installation +None is available merely because its name appears here. Each package must use NanoClaw v2's additive skill workflow, include complete apply and removal behavior, and pass remote harness acceptance before it can claim support. -1. Copy the skill to your NanoClaw deployment: - ```bash - cp -r skills/clawsec-nanoclaw /path/to/nanoclaw/skills/ - ``` +## Official NanoClaw References -2. Follow the detailed guide at `skills/clawsec-nanoclaw/INSTALL.md` +- [NanoClaw architecture](https://docs.nanoclaw.dev/concepts/architecture) +- [NanoClaw v2 skills](https://docs.nanoclaw.dev/extend/overview) +- [Migrate from NanoClaw v1](https://docs.nanoclaw.dev/migrate-from-v1) -### Quick Integration +## Security Reporting -The skill integrates into three places: - -**1. MCP Tools** (container): -```typescript -// container/agent-runner/src/ipc-mcp-stdio.ts -import '../../../skills/clawsec-nanoclaw/mcp-tools/advisory-tools.js'; -``` - -**2. IPC Handlers** (host): -```typescript -// src/ipc.ts -import { handleAdvisoryIpc } from '../skills/clawsec-nanoclaw/host-services/ipc-handlers.js'; -``` - -**3. Cache Service** (host): -```typescript -// src/index.ts -import { AdvisoryCacheManager } from '../skills/clawsec-nanoclaw/host-services/advisory-cache.js'; -``` - -### Advisory Feed - -NanoClaw consumes the same feed as OpenClaw: -``` -https://clawsec.prompt.security/advisories/feed.json -``` - -The feed is Ed25519 signed and automatically fetched by the cache service. - -## Team Credits - -This integration was developed by a team of 8 specialized agents coordinated to adapt ClawSec for NanoClaw: - -- **pioneer-repo-scout** - ClawSec architecture analysis -- **pioneer-nanoclaw-scout** - NanoClaw architecture analysis -- **architect** - Integration design and coordination -- **advisory-specialist** - Advisory feed integration -- **integrity-specialist** - File integrity design -- **installer-specialist** - Signature verification implementation -- **tester** - Test infrastructure and validation -- **documenter** - Documentation - -Total contribution: 3000+ lines of code and comprehensive design documents. - -## What's Included - -The `clawsec-nanoclaw` skill provides: - -- **1,730 lines** of production-ready TypeScript code -- **MCP Tools** (350 lines): Agent-facing vulnerability checking -- **Advisory Cache** (492 lines): Automatic feed fetching and caching -- **Signature Verification** (387 lines): Ed25519 signature validation -- **Advisory Matching** (289 lines): Skill-to-vulnerability correlation -- **IPC Handlers** (212 lines): Container-to-host communication -- **Complete Documentation**: Installation guide, usage examples, troubleshooting - -## Future Enhancements - -Planned features for future releases: -- File integrity monitoring (soul-guardian adaptation for containers) -- Real-time advisory alerts via WebSocket -- WhatsApp-native security alert formatting -- Behavioral analysis and anomaly detection -- Custom/private advisory feed support - -## Documentation - -- [Skill Documentation](skills/clawsec-nanoclaw/SKILL.md) - Features and architecture -- [Installation Guide](skills/clawsec-nanoclaw/INSTALL.md) - Detailed setup instructions -- [ClawSec Main README](README.md) - Overall ClawSec documentation -- [Security & Signing](../../wiki/security-signing-runbook.md) - Signature verification details - -## Support - -- **Issues**: https://github.com/prompt-security/clawsec/issues -- **Security**: security@prompt.security -- NanoClaw Repository: https://github.com/qwibitai/nanoclaw +Report ClawSec issues through the repository's security policy. For NanoClaw behavior, verify findings against a pinned upstream source revision and the current official documentation. diff --git a/skills/clawsec-nanoclaw/SKILL.md b/skills/clawsec-nanoclaw/SKILL.md index 63bf3a06..a79de631 100644 --- a/skills/clawsec-nanoclaw/SKILL.md +++ b/skills/clawsec-nanoclaw/SKILL.md @@ -1,289 +1,91 @@ --- name: clawsec-nanoclaw -version: 0.0.10 -description: Use when checking for security vulnerabilities in NanoClaw skills, before installing new skills, or when asked about security advisories affecting the bot +version: 0.0.11 +description: Use when auditing or migrating historical ClawSec artifacts from a NanoClaw v1-era fork; this package is an unverified template with no supported runtime range, must not be installed, and is incompatible with NanoClaw v2 --- -# ClawSec for NanoClaw +# Audit the Historical ClawSec NanoClaw Template -Security advisory monitoring that protects your WhatsApp bot from known vulnerabilities in skills and dependencies. +Treat this package as migration evidence only. -## Vercel Skills Installation +## Stop Gate -Install with the Vercel Skills CLI for this harness: +- Do not install, import, or activate the bundled TypeScript. +- Do not claim that any NanoClaw version is supported by this package. +- Do not use the package as evidence of NanoClaw v2 support. +- Do not copy v1-era paths, message-file handlers, scheduler examples, or service commands into v2. +- Do not treat isolated unit tests as a harness acceptance result. -```bash -npx skills add prompt-security/clawsec --skill clawsec-nanoclaw -a openclaw -y -``` +NanoClaw has no reviewed direct Agent Skills CLI target; do not substitute `--agent openclaw` or another unrelated target. -## Overview +Read the [historical integration record](./INSTALL.md) before assessing an existing deployment. It documents why the former integration procedure is not runnable as written. -ClawSec provides MCP tools that check installed skills against a curated feed of security advisories. It prevents installation of vulnerable skills, includes exploitability context for triage, and alerts you to issues in existing ones. +## Compatibility Result -**Core principle:** Check before you install. Monitor what's running. +Return these conclusions when asked whether this package can be installed: -## When to Use +- Status: historical, unverified v1-era template. +- Supported NanoClaw range: none asserted. +- NanoClaw v2: incompatible. +- Installation recommendation: do not install. +- Successor status: prove availability from the current published release and its acceptance evidence; do not infer it from a roadmap, directory, branch, pull request, or version label. -Use ClawSec tools when: -- Installing a new skill (check safety first) -- User asks "are my skills secure?" -- Investigating suspicious behavior -- Regular security audits -- After receiving security notifications +## Why the Runtime Is Not Qualified -Do NOT use for: -- Code review (use other tools) -- Performance issues (different concern) -- General debugging +The MCP modules use ambient declarations for `server`, `writeIpcFile`, `TASKS_DIR`, and `groupFolder`. Those declarations satisfy TypeScript but create no runtime binding. Importing the modules cannot access module-local identifiers from NanoClaw's runner. -## MCP Tools Available +The remaining source also leaves `glob` and `writeResponse` without runtime implementations and uses CommonJS `__dirname` in an ES module. It preserves unqualified assumptions about host/container paths, message-file IPC, group state, scheduling, restart behavior, and writable state. No pinned NanoClaw checkout has passed a complete apply, run, remove, and rollback test for this package. -### Pre-Installation Check +## Allowed Uses -```typescript -// Before installing any skill -const safety = await tools.clawsec_check_skill_safety({ - skillName: 'new-skill', - skillVersion: '1.0.0' // optional -}); +Use the package only to: -if (!safety.safe) { - // Show user the risks before proceeding - console.warn(`Security issues: ${safety.advisories.map(a => a.id)}`); -} -``` +- Identify historical ClawSec files in a customized NanoClaw v1-era checkout. +- Compare those files with the operator's actual fork and service configuration. +- Produce a read-only migration inventory. +- Preserve source as test-vector input for future migration tooling. +- Explain why the old integration must not be copied into NanoClaw v2. -### Security Audit +Do not modify or remove an operator's existing deployment without an explicit reviewed plan and rollback path. -```typescript -// Check all installed skills (defaults to ~/.claude/skills in the container) -const result = await tools.clawsec_check_advisories({ - installRoot: '/home/node/.claude/skills' // optional -}); +## Migration Inventory -if (result.matches.some((m) => - m.advisory.severity === 'critical' || m.advisory.exploitability_score === 'high' -)) { - // Alert user immediately - console.error('Urgent advisories found!'); -} -``` +Record evidence without executing the package: -### Browse Advisories +1. Pin the exact NanoClaw source commit and record its reported version. +2. Locate every copied ClawSec file and every source reach-in. +3. Locate service, task, hook, database, cache, and integrity state owned by the old customization. +4. Record file digests, permissions, ownership, and whether each path is host-side or container-side. +5. Record any active process or scheduler that imports or invokes the historical code. +6. Identify conflicts with NanoClaw v2's additive skill workflow and two-database host/container boundary. +7. Propose disable, migration, and rollback steps without executing them. -```typescript -// List advisories with filters -const advisories = await tools.clawsec_list_advisories({ - severity: 'high', // optional - exploitabilityScore: 'high' // optional -}); -``` +If current authorization does not permit access to live logs, record runtime execution evidence as unknown. Do not infer success or inactivity from missing evidence. -## Quick Reference +## Preserved Source Boundaries -| Task | Tool | Key Parameter | -|------|------|---------------| -| Pre-install check | `clawsec_check_skill_safety` | `skillName` | -| Audit all skills | `clawsec_check_advisories` | `installRoot` (optional) | -| Browse feed | `clawsec_list_advisories` | `severity`, `type`, `exploitabilityScore` (optional) | -| Verify package signature | `clawsec_verify_skill_package` | `packagePath` | -| Refresh advisory cache | `clawsec_refresh_cache` | (none) | -| Check file integrity | `clawsec_check_integrity` | `mode`, `autoRestore` (optional) | -| Approve file change | `clawsec_approve_change` | `path` | -| View baseline status | `clawsec_integrity_status` | `path` (optional) | -| Verify audit log | `clawsec_verify_audit` | (none) | +- `mcp-tools/` contains historical declarations, not a supported registration API. +- `host-services/` contains unqualified v1-era host integration attempts. +- `guardian/` contains a historical integrity implementation, not the future NanoClaw drift guardian. +- `lib/` contains isolated helpers that may inform common contracts only after independent review. +- `advisories/feed-signing-public.pem` is a feed-verification key and is not release-installation authority. -## Common Patterns +## Future v2 Requirements -### Pattern 1: Safe Skill Installation +A supported NanoClaw package must be implemented separately. Require it to: -```typescript -// ALWAYS check before installing -const safety = await tools.clawsec_check_skill_safety({ - skillName: userRequestedSkill -}); +- Target a pinned NanoClaw v2 range and current official architecture. +- Use an explicit registration API or reviewed additive reach-in with a failing-when-removed integration test. +- Keep authoritative trust and receipts on the host, outside agent-controlled state. +- Provide idempotent apply, update, removal, resume, and rollback behavior. +- Ship `REMOVE.md` whenever apply leaves state. +- Run NanoClaw host build/tests and Bun tests for any agent-runner change. +- Pass the remote lab and release lifecycle before any support claim. -if (safety.safe) { - // Proceed with installation - await installSkill(userRequestedSkill); -} else { - // Show user the risks and get confirmation - await showSecurityWarning(safety.advisories); - if (await getUserConfirmation()) { - await installSkill(userRequestedSkill); - } -} -``` +The v2 architecture statements above reflect official upstream material observed on 2026-07-22. Reverify the current documentation and source revision before making a migration or support decision. -### Pattern 2: Periodic Security Check +## References -```typescript -// Add to scheduled tasks -schedule_task({ - prompt: "Check advisories using clawsec_check_advisories and alert when critical or high-exploitability matches appear", - schedule_type: "cron", - schedule_value: "0 9 * * *" // Daily at 9am -}); -``` - -### Pattern 3: User Security Query - -``` -User: "Are my skills secure?" - -You: I'll check installed skills for known vulnerabilities. -[Use clawsec_check_advisories] - -Response: -✅ No urgent issues found. -- 2 low-severity/low-exploitability advisories -- All skills up to date -``` - -## Common Mistakes - -### ❌ Installing without checking -```typescript -// DON'T -await installSkill('untrusted-skill'); -``` - -```typescript -// DO -const safety = await tools.clawsec_check_skill_safety({ - skillName: 'untrusted-skill' -}); -if (safety.safe) await installSkill('untrusted-skill'); -``` - -### ❌ Ignoring exploitability context -```typescript -// DON'T: Use severity only -if (advisory.severity === 'high') { - notifyNow(advisory); -} -``` - -```typescript -// DO: Use exploitability + severity -if ( - advisory.exploitability_score === 'high' || - advisory.severity === 'critical' -) { - notifyNow(advisory); -} -``` - -### ❌ Skipping critical severity -```typescript -// DON'T: Ignore high exploitability in medium severity advisories -if (advisory.severity === 'critical') alert(); -``` - -```typescript -// DO: Prioritize exploitability and severity together -if (advisory.exploitability_score === 'high' || advisory.severity === 'critical') { - // Alert immediately -} -``` - -## Implementation Details - -**Feed Source**: https://clawsec.prompt.security/advisories/feed.json - -This signed feed is consolidated. NanoClaw receives NVD CVEs, approved community advisories, and provisional GHSA-without-CVE advisories through the same default URL. - -**Update Frequency**: Every 6 hours (automatic) - -**Signature Verification**: Ed25519 signed feeds -**Package Verification Policy**: pinned key only, bounded package/signature paths - -**Cache Location**: `/workspace/project/data/clawsec-advisory-cache.json` - -See [INSTALL.md](./INSTALL.md) for setup and [docs/](./docs/) for advanced usage. - -## Real-World Impact - -- Prevents installation of skills with known RCE vulnerabilities -- Alerts to supply chain attacks in dependencies -- Provides actionable remediation steps -- Zero false positives (curated feed only) - -## Release Artifact Verification - -For standalone installs, verify the signed release manifest before trusting `SKILL.md`, `skill.json`, or the archive. The `skill.json` file is the package metadata/SBOM source, and the release pipeline signs `checksums.json` with the ClawSec release key. - -```bash -set -euo pipefail - -SKILL_NAME="clawsec-nanoclaw" -VERSION="0.0.10" -REPO="prompt-security/clawsec" -TAG="${SKILL_NAME}-v${VERSION}" -BASE="https://github.com/${REPO}/releases/download/${TAG}" -ZIP_NAME="${SKILL_NAME}-v${VERSION}.zip" -TMP_DIR="$(mktemp -d)" -trap 'rm -rf "$TMP_DIR"' EXIT - -RELEASE_PUBKEY_SHA256="711424e4535f84093fefb024cd1ca4ec87439e53907b305b79a631d5befba9c8" - -curl -fsSL "$BASE/checksums.json" -o "$TMP_DIR/checksums.json" -curl -fsSL "$BASE/checksums.sig" -o "$TMP_DIR/checksums.sig" -curl -fsSL "$BASE/signing-public.pem" -o "$TMP_DIR/signing-public.pem" -curl -fsSL "$BASE/$ZIP_NAME" -o "$TMP_DIR/$ZIP_NAME" -curl -fsSL "$BASE/SKILL.md" -o "$TMP_DIR/SKILL.md" -curl -fsSL "$BASE/skill.json" -o "$TMP_DIR/skill.json" - -ACTUAL_PUBKEY_SHA256="$(openssl pkey -pubin -in "$TMP_DIR/signing-public.pem" -outform DER | shasum -a 256 | awk '{print $1}')" -if [ "$ACTUAL_PUBKEY_SHA256" != "$RELEASE_PUBKEY_SHA256" ]; then - echo "ERROR: signing-public.pem fingerprint mismatch" >&2 - exit 1 -fi - -openssl base64 -d -A -in "$TMP_DIR/checksums.sig" -out "$TMP_DIR/checksums.sig.bin" -openssl pkeyutl -verify -rawin -pubin \ - -inkey "$TMP_DIR/signing-public.pem" \ - -sigfile "$TMP_DIR/checksums.sig.bin" \ - -in "$TMP_DIR/checksums.json" >/dev/null - -hash_file() { - if command -v shasum >/dev/null 2>&1; then - shasum -a 256 "$1" | awk '{print $1}' - else - sha256sum "$1" | awk '{print $1}' - fi -} - -verify_manifest_file() { - asset="$1" - path="$2" - expected="$(jq -r --arg asset "$asset" '.files[$asset].sha256 // empty' "$TMP_DIR/checksums.json")" - if [ -z "$expected" ]; then - echo "ERROR: checksums.json missing $asset" >&2 - exit 1 - fi - actual="$(hash_file "$path")" - if [ "$actual" != "$expected" ]; then - echo "ERROR: checksum mismatch for $asset" >&2 - exit 1 - fi -} - -expected_archive="$(jq -r '.archive.sha256 // empty' "$TMP_DIR/checksums.json")" -if [ -z "$expected_archive" ]; then - echo "ERROR: checksums.json missing archive.sha256" >&2 - exit 1 -fi -actual_archive="$(hash_file "$TMP_DIR/$ZIP_NAME")" -if [ "$actual_archive" != "$expected_archive" ]; then - echo "ERROR: archive checksum mismatch" >&2 - exit 1 -fi - -verify_manifest_file "SKILL.md" "$TMP_DIR/SKILL.md" -verify_manifest_file "skill.json" "$TMP_DIR/skill.json" - -echo "Signed release manifest, archive, SKILL.md, and skill.json verified." -``` - -Only install or extract the archive after this verification succeeds. +- [NanoClaw architecture](https://docs.nanoclaw.dev/concepts/architecture) +- [NanoClaw v2 skills](https://docs.nanoclaw.dev/extend/overview) +- [Migrate from NanoClaw v1](https://docs.nanoclaw.dev/migrate-from-v1) diff --git a/skills/clawsec-nanoclaw/docs/INTEGRITY.md b/skills/clawsec-nanoclaw/docs/INTEGRITY.md index 780922e0..9632067b 100644 --- a/skills/clawsec-nanoclaw/docs/INTEGRITY.md +++ b/skills/clawsec-nanoclaw/docs/INTEGRITY.md @@ -1,567 +1,56 @@ -# File Integrity Monitoring for NanoClaw +# Historical NanoClaw Integrity Component Record -ClawSec's file integrity monitoring protects critical NanoClaw configuration files from unauthorized modification. +> **Status:** Deprecated and runtime-unverified. This v1-era source is migration evidence, not an active integrity guardian. It is incompatible with NanoClaw v2. -## What It Does +## Do Not Activate -**Protects Critical Files:** -- `registered_groups.json` - Prevents unauthorized group access -- `CLAUDE.md` files - Protects agent instructions -- Container/host code - Alerts on unexpected changes +Do not copy the files under `guardian/` or `host-services/` into a NanoClaw deployment. Do not enable automatic restoration from this package. It has no supported NanoClaw runtime range and has not passed a pinned harness acceptance test. -**How It Works:** -1. **Baseline**: Stores SHA-256 hashes of approved file states -2. **Monitoring**: Periodically checks files for changes (drift) -3. **Restore**: Automatically reverts critical files to approved versions -4. **Audit**: Maintains tamper-evident log of all operations +## Why the Old Policy Is Not a Valid Posture Model -## Quick Start +The retained policy and documentation mix host and container namespaces and include obsolete or nonexistent paths: -### Step 1: Verify Installation +- `/workspace/project/data/registered_groups.json` is not the active v1 group database. +- `/workspace/project/host/**/*.ts` does not map to the official v1 host source tree. +- `/workspace/group/CLAUDE.md` is a container-side path presented to a host monitor. +- `/workspace/project/data/soul-guardian` is another container-side path used as host state. +- `/workspace/ipc` represents the retired v1 message-file transport, not NanoClaw v2's two-database session boundary. -Check that integrity monitoring is available: +Because the monitored objects are not derived from a verified checkout and scope, a successful local hash comparison would not prove NanoClaw posture integrity. -```bash -# From container -ls /workspace/project/skills/clawsec-nanoclaw/guardian/ -# Should show: policy.json, integrity-monitor.ts -``` +## Security Limits -### Step 2: Initialize Baselines +- A hash chain can detect internal sequence changes relative to its chosen first record; it does not independently authenticate that first record. +- A locally generated baseline is not trustworthy merely because later hashes match it. +- Automatic restoration can destroy legitimate changes and must remain off unless a future guardian authenticates its baseline and obtains explicit operator approval. +- The historical code has no verified registration, scheduler, service, disable, removal, or rollback path. +- ClawSec installs no schedule. Any refresh or integrity cadence in a v1-era fork is an operator-owned customization. -The first time integrity monitoring runs, it creates baselines automatically: +## Preserved Files -```typescript -// Agent calls this (happens automatically on first integrity check) -await tools.clawsec_check_integrity(); -``` +- `guardian/integrity-monitor.ts` — historical implementation input for future tests. +- `guardian/policy.json` — inventory of obsolete path assumptions that migration tooling should detect. +- `host-services/integrity-handler.ts` — historical message-file handler. +- `mcp-tools/integrity-tools.ts` — historical ambient-global MCP declarations. -This creates: -``` -/workspace/project/data/soul-guardian/ -├── baselines.json # SHA-256 hashes -├── approved/ # File snapshots -│ ├── registered_groups.json -│ └── CLAUDE.md -├── patches/ # Diffs (empty initially) -├── quarantine/ # Tampered files (empty initially) -└── audit.jsonl # Event log -``` +Their presence is not capability evidence. -### Step 3: Enable Scheduled Monitoring +## Future Drift Guardian Requirements -Add to main group's scheduled tasks: +Implement `clawsec-drift-guardian-nanoclaw` as a separate NanoClaw v2-native package. Require it to: -```typescript -schedule_task({ - prompt: ` - Check file integrity with clawsec_check_integrity. - If drift detected and files restored, send WhatsApp message: - "⚠️ SECURITY ALERT +- Derive posture from a pinned, supported v2 checkout and explicit host scope. +- Keep authoritative baselines and receipts outside agent-controlled paths. +- Authenticate the baseline before comparing drift. +- Default to read-only detection. +- Disclose every persistent path and keep restoration opt-in. +- Provide idempotent apply, disable, remove, resume, and rollback behavior. +- Ship `REMOVE.md` whenever it leaves state. +- Test every host registration reach-in and database ownership boundary. +- Pass remote harness acceptance before claiming availability. - Unauthorized changes detected and automatically reverted: - [list files that were restored] +## References - Review details: /workspace/project/data/soul-guardian/patches/" - `, - schedule_type: 'cron', - schedule_value: '*/30 * * * *', // Every 30 minutes - context_mode: 'isolated' -}); -``` - -That's it! Integrity monitoring is now active. - -## MCP Tools Reference - -### 1. `clawsec_check_integrity` - -Check all protected files for unauthorized changes. - -**Parameters:** -- `mode` (optional): `'check'` (default) or `'status'` - - `check`: Detect drift and auto-restore - - `status`: View baselines only (no drift detection) -- `autoRestore` (optional): `true` (default) or `false` - - If `false`, drift is detected but not auto-fixed - -**Output:** -```json -{ - "success": true, - "timestamp": "2026-02-25T12:00:00Z", - "drift_detected": false, - "files": [ - { - "path": "/workspace/project/data/registered_groups.json", - "status": "ok", - "mode": "restore", - "expected_sha": "abc123...", - "found_sha": "abc123..." - } - ], - "summary": { - "total": 3, - "ok": 3, - "drifted": 0, - "restored": 0, - "alerted": 0, - "errors": 0 - } -} -``` - -**Example:** -```typescript -const result = await tools.clawsec_check_integrity(); - -if (result.drift_detected) { - console.log('⚠️ Drift detected!'); - for (const file of result.files) { - if (file.status === 'restored') { - console.log(`✅ Restored: ${file.path}`); - console.log(` Diff: ${file.patch_path}`); - } else if (file.status === 'drifted') { - console.log(`⚠️ Changed: ${file.path} (alert only)`); - } - } -} -``` - -### 2. `clawsec_approve_change` - -Approve an intentional file modification as the new baseline. - -**When to use:** -- After legitimately updating CLAUDE.md -- After adding/removing groups in registered_groups.json -- After any intentional change to protected files - -**Parameters:** -- `path` (required): Absolute path to file -- `note` (optional): Explanation for audit log - -**Output:** -```json -{ - "success": true, - "path": "/workspace/group/CLAUDE.md", - "approved_at": "2026-02-25T12:00:00Z", - "approved_by": "agent", - "note": "Added new skill instructions" -} -``` - -**Example:** -```typescript -// After editing CLAUDE.md -await tools.clawsec_approve_change({ - path: '/workspace/group/CLAUDE.md', - note: 'Updated agent instructions for new skill' -}); - -console.log('✅ Change approved - new baseline created'); -``` - -### 3. `clawsec_integrity_status` - -View current baseline status without checking for drift. - -**Parameters:** -- `path` (optional): Specific file, or all if omitted - -**Output:** -```json -{ - "success": true, - "baseline_age": "2026-02-25T10:00:00Z", - "files": [ - { - "path": "/workspace/project/data/registered_groups.json", - "mode": "restore", - "priority": "critical", - "has_baseline": true, - "baseline_sha": "abc123...", - "approved_at": "2026-02-25T10:00:00Z", - "snapshot_exists": true - } - ] -} -``` - -**Example:** -```typescript -const status = await tools.clawsec_integrity_status(); - -console.log('Protected files:'); -for (const file of status.files) { - console.log(`- ${file.path} (${file.mode}, ${file.priority})`); - console.log(` Last approved: ${file.approved_at}`); -} -``` - -### 4. `clawsec_verify_audit` - -Verify audit log hash chain integrity. - -**No parameters.** - -**Output:** -```json -{ - "success": true, - "valid": true, - "entries": 42, - "errors": [] -} -``` - -**Example:** -```typescript -const verification = await tools.clawsec_verify_audit(); - -if (!verification.valid) { - console.log('🚨 CRITICAL: Audit log has been tampered with!'); - console.log('Errors:', verification.errors); -} else { - console.log(`✅ Audit log verified (${verification.entries} entries)`); -} -``` - -## Protected Files Policy - -### Critical Priority (Auto-Restore) - -**`/workspace/project/data/registered_groups.json`** -- **Risk**: Tampering grants unauthorized group access -- **Action**: Immediate auto-restore + alert - -**`/workspace/group/CLAUDE.md`** -- **Risk**: Modifies agent behavior -- **Action**: Immediate auto-restore + alert - -**`/workspace/project/groups/global/CLAUDE.md`** -- **Risk**: Affects all groups -- **Action**: Immediate auto-restore + alert - -### Medium Priority (Alert Only) - -**Container code** (`/workspace/project/container/**/*.ts`) -- **Risk**: Unexpected code changes -- **Action**: Alert for review (no auto-restore) - -**Host code** (`/workspace/project/host/**/*.ts`) -- **Risk**: Unexpected code changes -- **Action**: Alert for review (no auto-restore) - -### Ignored - -**IPC files** (`/workspace/ipc/**/*`) -- Changes are expected and frequent - -**Conversations** (`/workspace/group/conversations/**/*`) -- Changes are expected and frequent - -## Workflow Examples - -### Scenario 1: Scheduled Monitoring - -**Setup:** -```typescript -schedule_task({ - prompt: 'Run clawsec_check_integrity and alert on drift', - schedule_type: 'cron', - schedule_value: '*/30 * * * *' -}); -``` - -**What happens:** -1. Every 30 minutes, agent checks integrity -2. If drift detected in critical files: - - Files auto-restored to baseline - - Tampered versions quarantined - - Diff patch generated - - User alerted via WhatsApp -3. If drift in non-critical files: - - Alert only, no auto-restore - -### Scenario 2: Updating Agent Instructions - -**Workflow:** -```typescript -// 1. Edit CLAUDE.md -fs.writeFileSync('/workspace/group/CLAUDE.md', newInstructions); - -// 2. Test changes -// ... verify agent behaves correctly ... - -// 3. Approve changes -await tools.clawsec_approve_change({ - path: '/workspace/group/CLAUDE.md', - note: 'Added instructions for new weather skill' -}); - -// 4. Future integrity checks will use this new baseline -``` - -### Scenario 3: Adding a New Group - -**Workflow:** -```typescript -// 1. Add group to registered_groups.json -const groups = JSON.parse(fs.readFileSync('/workspace/project/data/registered_groups.json')); -groups['new-jid'] = { name: 'Family', folder: 'family', trigger: '@Andy' }; -fs.writeFileSync('/workspace/project/data/registered_groups.json', JSON.stringify(groups, null, 2)); - -// 2. Approve the change -await tools.clawsec_approve_change({ - path: '/workspace/project/data/registered_groups.json', - note: 'Added family group' -}); -``` - -### Scenario 4: Investigating Drift - -**When drift is detected:** -```typescript -const result = await tools.clawsec_check_integrity(); - -if (result.drift_detected) { - for (const file of result.files) { - if (file.status === 'restored') { - // Critical file was auto-restored - console.log(`🔧 Auto-restored: ${file.path}`); - console.log(`📄 Diff: ${file.patch_path}`); - console.log(`📦 Quarantine: ${file.quarantine_path}`); - - // Review the diff - const diff = fs.readFileSync(file.patch_path, 'utf-8'); - console.log('Changes that were reverted:'); - console.log(diff); - } - } -} -``` - -## Security Model - -### Threat Model - -**Protects Against:** -- Unauthorized file modifications -- Group hijacking (via registered_groups.json tampering) -- Agent instruction poisoning (via CLAUDE.md changes) -- Accidental file corruption - -**Does NOT Protect Against:** -- Attacker with full host access (can modify baselines) -- Simultaneous baseline + file modification -- Malicious scheduled tasks that approve their own changes - -### Baseline Storage - -**Location:** `/workspace/project/data/soul-guardian/` - -**Access Control:** -- Baselines written only by host process -- Containers access via IPC only -- No container can modify its own baselines - -**Integrity:** -- SHA-256 hashes (industry standard) -- Hash-chained audit log (tamper-evident) -- Atomic file operations (safe restores) - -### Audit Log - -**Format:** JSONL with hash chaining - -**Each entry includes:** -```json -{ - "ts": "2026-02-25T12:00:00Z", - "event": "drift", - "actor": "agent", - "path": "/workspace/group/CLAUDE.md", - "expected_sha": "abc123...", - "found_sha": "def456...", - "chain": { - "prev": "previous_entry_hash", - "hash": "this_entry_hash" - } -} -``` - -**Chain calculation:** -``` -hash = SHA-256(prev_hash + '\n' + canonical_json(entry_without_chain)) -``` - -This makes tampering detectable: changing any entry breaks the chain. - -## Troubleshooting - -### Integrity Check Fails - -**Symptom:** `clawsec_check_integrity` returns `success: false` - -**Causes:** -1. IntegrityService not initialized -2. Policy file missing -3. Baselines corrupted - -**Solution:** -```bash -# Check service status -ls /workspace/project/data/soul-guardian/ - -# If missing, reinitialize -rm -rf /workspace/project/data/soul-guardian/ -# Next integrity check will recreate baselines -``` - -### False Positives (Legitimate Changes Flagged) - -**Symptom:** File keeps getting restored even though changes are legitimate - -**Cause:** Baseline not updated after intentional changes - -**Solution:** -```typescript -await tools.clawsec_approve_change({ - path: '/path/to/file', - note: 'Legitimate change' -}); -``` - -### Audit Chain Broken - -**Symptom:** `clawsec_verify_audit` returns `valid: false` - -**Causes:** -1. Audit log manually edited -2. Filesystem corruption -3. Security breach - -**Solution:** -```typescript -const verification = await tools.clawsec_verify_audit(); -console.log('Errors:', verification.errors); - -// If corruption, backup and reset -cp /workspace/project/data/soul-guardian/audit.jsonl /tmp/audit-backup.jsonl -rm /workspace/project/data/soul-guardian/audit.jsonl -// Audit log will restart on next operation -``` - -### High Disk Usage - -**Symptom:** `/workspace/project/data/soul-guardian/` grows large - -**Causes:** -- Many drift events generate patches -- Quarantine files accumulate - -**Solution:** -```bash -# Clean old patches (older than 30 days) -find /workspace/project/data/soul-guardian/patches/ -mtime +30 -delete - -# Clean quarantine (after review) -rm /workspace/project/data/soul-guardian/quarantine/* -``` - -## Performance - -**Overhead:** -- Baseline check: ~10ms per file -- SHA-256 computation: ~1ms per KB -- Restore operation: ~20ms per file - -**Typical deployment:** -- 3-5 protected files -- 30-minute check interval -- < 0.1% CPU usage -- < 5MB disk usage - -## Advanced Topics - -### Custom Policy - -While the default policy is pinned by the skill, you can fork it: - -```bash -cp /workspace/project/skills/clawsec-nanoclaw/guardian/policy.json /workspace/project/data/custom-policy.json -``` - -Edit and reinitialize: -```typescript -// Update IntegrityMonitor initialization -new IntegrityMonitor({ - policyPath: '/workspace/project/data/custom-policy.json', - stateDir: '/workspace/project/data/soul-guardian' -}); -``` - -### Manual Baseline Export - -```bash -# Export current baselines -cp /workspace/project/data/soul-guardian/baselines.json /tmp/baselines-backup.json - -# Export approved snapshots -tar -czf /tmp/approved-snapshots.tar.gz /workspace/project/data/soul-guardian/approved/ -``` - -### Baseline Import (Disaster Recovery) - -```bash -# Restore baselines -cp /tmp/baselines-backup.json /workspace/project/data/soul-guardian/baselines.json - -# Restore snapshots -tar -xzf /tmp/approved-snapshots.tar.gz -C /workspace/project/data/soul-guardian/ -``` - -## FAQ - -**Q: Can I disable auto-restore for testing?** - -A: Yes, use `autoRestore: false`: -```typescript -await tools.clawsec_check_integrity({ autoRestore: false }); -``` - -**Q: How do I protect additional files?** - -A: Edit `policy.json` and add targets: -```json -{ - "path": "/workspace/group/my-config.json", - "mode": "restore", - "priority": "high", - "description": "My custom config" -} -``` - -**Q: What happens if both baseline and file are modified?** - -A: The most recent baseline wins. Always approve legitimate changes immediately. - -**Q: Can I run integrity checks on-demand?** - -A: Yes, just call `clawsec_check_integrity` from any agent. - -**Q: Is the audit log encrypted?** - -A: No, but it's hash-chained for tamper detection. Encryption can be added in Phase 3. - -## Support - -- **Documentation**: https://clawsec.prompt.security/ -- **Issues**: https://github.com/prompt-security/clawsec/issues -- **Security Reports**: security@prompt.security - ---- - -**Ready to protect your NanoClaw deployment? Start with the [Quick Start](#quick-start) guide above.** +- [NanoClaw architecture](https://docs.nanoclaw.dev/concepts/architecture) +- [NanoClaw security model](https://docs.nanoclaw.dev/concepts/security) +- [Migrate from NanoClaw v1](https://docs.nanoclaw.dev/migrate-from-v1) diff --git a/skills/clawsec-nanoclaw/docs/SKILL_SIGNING.md b/skills/clawsec-nanoclaw/docs/SKILL_SIGNING.md index 5719dd49..8065246a 100644 --- a/skills/clawsec-nanoclaw/docs/SKILL_SIGNING.md +++ b/skills/clawsec-nanoclaw/docs/SKILL_SIGNING.md @@ -1,488 +1,72 @@ -# Skill Package Signing and Verification +# Historical NanoClaw Signature Component Record -This document explains how ClawSec signs skill packages and how NanoClaw agents verify signatures before installation. +> **Status:** Deprecated and runtime-unverified. This v1-era source is migration evidence, not a supported package-verification workflow. It is incompatible with NanoClaw v2. ---- +## Do Not Use It to Authorize Installation -## Table of Contents +Do not copy or activate the historical verifier. A valid signature proves only that bytes match the selected key and signed input. It does not prove code safety, current catalog authorization, advisory clearance, or operator approval. -1. [Overview](#overview) -2. [For Skill Publishers: How to Sign Packages](#for-skill-publishers-how-to-sign-packages) -3. [For NanoClaw Agents: How to Verify Signatures](#for-nanoclaw-agents-how-to-verify-signatures) -4. [Security Properties](#security-properties) -5. [Key Management](#key-management) -6. [Troubleshooting](#troubleshooting) +The bundled MCP and host integration has not passed an end-to-end NanoClaw test. Its machine-readable `install` recommendation must not be treated as installation authority. ---- +## Trust-Domain Mismatch -## Overview +The historical handler expects a detached `.sig` and defaults to the embedded advisory-feed public key. That is not the current ClawSec release contract. -Skill signature verification prevents **supply chain attacks** by ensuring skill packages haven't been tampered with during distribution. ClawSec uses **Ed25519 digital signatures** to sign skill packages, and NanoClaw agents verify these signatures before installation. +ClawSec release artifacts use a signed `checksums.json` manifest whose authenticated archive digest binds the release ZIP. Release verification also requires a pinned release trust root, exact package identity and version, safe archive validation, and an installation receipt. The advisory-feed key and release-manifest trust domain must not be treated as interchangeable. -### Why Signature Verification? +No supported ClawSec publisher flow creates the detached archive signatures expected by this legacy handler. -Without signature verification, an attacker could: -- **Replace** a legitimate skill package with a malicious one during download -- **Modify** package contents to inject backdoors or steal data -- **Distribute** trojan skills that appear legitimate but contain malware +## Runtime Limitations -Signature verification ensures: -- ✅ **Authenticity**: Package comes from ClawSec (or trusted publisher) -- ✅ **Integrity**: Package hasn't been modified since signing -- ✅ **Non-repudiation**: Signer can't deny signing the package +- The MCP module depends on ambient identifiers that imports do not bind at runtime. +- The host verifier uses unqualified v1-era path assumptions. +- The historical host response path is incomplete. +- The ESM integration and key-path resolution were never proven in a composed upstream build. +- No pinned NanoClaw checkout passed request, response, rejection, cleanup, or removal tests. +- The documentation defines no supported key-rotation or multi-key transition protocol. ---- +## Isolated Invariants Preserved in Source -## For Skill Publishers: How to Sign Packages +The retained code and unit tests still provide review input for narrow properties: -### Prerequisites +- Reject caller-supplied public-key overrides. +- Reject unsigned bypass requests. +- Bound package and signature paths before reading them. +- Verify an Ed25519 signature with a configured key. +- Return evidence to a caller rather than extracting a package. -- OpenSSL 1.1.1+ (for Ed25519 support) -- Private Ed25519 signing key (generate once, keep secure) -- Skill package ready for distribution +These isolated properties do not make the NanoClaw integration operational. -### Step 1: Generate Ed25519 Keypair (One-Time Setup) +## Publisher Workflow -```bash -# Generate private key (KEEP THIS SECRET!) -openssl genpkey -algorithm ED25519 -out clawsec-signing-private.pem +This package defines no publisher key-generation, signing, distribution, or rotation workflow. Do not generate a local key, sign an arbitrary archive, and expect ClawSec or NanoClaw to authorize it. -# Extract public key (share this with users) -openssl pkey -in clawsec-signing-private.pem -pubout -out clawsec-signing-public.pem +Use the ClawSec release pipeline only after the relevant package has passed the private lifecycle and promotion gates. Production release keys must never be copied to a harness lab or agent-controlled path. -# Secure the private key -chmod 600 clawsec-signing-private.pem -``` +## Future Ownership -**⚠️ CRITICAL**: Never commit the private key to version control! Store it securely: -- Local machine: `~/.ssh/clawsec-signing-private.pem` with `chmod 600` -- CI/CD: GitHub Secrets, AWS Secrets Manager, or similar -- Team: 1Password, Vault, or hardware security module (HSM) +The future `clawsec-core-nanoclaw` package, not a guardian or suite, must own deterministic release verification. Require it to: -### Step 2: Package Your Skill +- Authenticate pinned root metadata and the exact release manifest. +- Verify the canonical archive digest and package identity. +- Reject unsafe archive entries before writing. +- Install the exact verified bytes through a NanoClaw v2-native transaction. +- Record scope, origin, preimages, postimages, signer, and result in a receipt. +- Keep trust roots and authoritative receipts on the host. +- Separate advisory-feed verification from release-installation authorization. +- Fail closed on unknown keys, identities, versions, paths, or partial state. -```bash -# Create skill package (tarball or zip) -tar -czf my-skill-1.0.0.tar.gz -C skills/my-skill . +## Preserved Files -# Or as a zip file -zip -r my-skill-1.0.0.zip skills/my-skill/ -``` +- `mcp-tools/signature-verification.ts` +- `host-services/skill-signature-handler.ts` +- `lib/signatures.ts` +- `advisories/feed-signing-public.pem` -### Step 3: Sign the Package - -```bash -# Create detached Ed25519 signature -openssl dgst -sha512 -sign clawsec-signing-private.pem \ - -out my-skill-1.0.0.tar.gz.sig \ - my-skill-1.0.0.tar.gz - -# Verify the signature was created -ls -lh my-skill-1.0.0.tar.gz.sig -# Should show a ~64-byte file -``` - -**Signature Format**: Detached Ed25519 signature, base64-encoded, stored in `.sig` file. - -### Step 4: Distribute Package + Signature - -Distribute **both** files together: -- `my-skill-1.0.0.tar.gz` (the skill package) -- `my-skill-1.0.0.tar.gz.sig` (the signature) - -Users will verify the signature against your public key before installation. - -### Step 5: Publish Public Key - -Share your public key with users via: -- **Pinned in repository**: Commit `clawsec-signing-public.pem` to your repo -- **Website**: Host at `https://yoursite.com/clawsec-signing-public.pem` -- **DNS TXT record**: Publish as base64-encoded TXT record -- **Skill metadata**: Embed in `skill.json` - ---- - -## For NanoClaw Agents: How to Verify Signatures - -### Quick Start - -```typescript -// Verify a downloaded skill package before installation -const verification = await tools.clawsec_verify_skill_package({ - packagePath: '/tmp/my-skill-1.0.0.tar.gz' - // signaturePath auto-detected as /tmp/my-skill-1.0.0.tar.gz.sig -}); - -const result = JSON.parse(verification.content[0].text); - -if (!result.valid) { - console.log('⚠️ SIGNATURE VERIFICATION FAILED!'); - console.log(`Reason: ${result.reason || result.error}`); - console.log('DO NOT install this package.'); - return; -} - -console.log(`✓ Signature valid (signer: ${result.signer})`); -console.log(`Package hash: ${result.packageInfo.sha256}`); -console.log('Safe to proceed with installation.'); -``` - -### MCP Tool: `clawsec_verify_skill_package` - -**Parameters:** -- `packagePath` (required): Absolute path to skill package (`.tar.gz`, `.tar`, `.tgz`, or `.zip`) -- `signaturePath` (optional): Path to signature file (auto-detects `.sig` if omitted) - -Path policy: -- Files must be under one of: `/tmp`, `/var/tmp`, `/workspace/ipc`, `/workspace/project/data`, `/workspace/project/tmp`, `/workspace/project/downloads` -- Symlinks are rejected -- Signatures must use `.sig` - -**Returns:** -```typescript -{ - success: boolean, // Operation completed without errors - valid: boolean, // Signature is cryptographically valid - recommendation: string, // "install" | "block" | "review" - signer: string, // "clawsec" - algorithm: "Ed25519", // Signature algorithm - verifiedAt: string, // ISO timestamp - packageInfo: { - size: number, // Package file size in bytes - sha256: string // SHA-256 hash of package - }, - error?: string // Error message if failed -} -``` - -### Usage Patterns - -#### Pattern 1: Basic Pre-Installation Check - -```typescript -async function installSkill(packagePath: string) { - // Verify signature first - const verification = await tools.clawsec_verify_skill_package({ packagePath }); - const result = JSON.parse(verification.content[0].text); - - if (result.recommendation === 'block') { - throw new Error(`Cannot install: ${result.reason || result.error}`); - } - - // Signature valid - proceed with extraction - extractPackage(packagePath, '/workspace/project/skills/'); -} -``` - -#### Pattern 2: Combined Security Checks - -```typescript -async function installSkillSafely(packagePath: string, skillName: string) { - // Step 1: Verify signature - const sigVerify = await tools.clawsec_verify_skill_package({ packagePath }); - const sigResult = JSON.parse(sigVerify.content[0].text); - - if (!sigResult.valid) { - throw new Error(`Signature invalid: ${sigResult.reason}`); - } - - // Step 2: Check advisories - const advisory = await tools.clawsec_check_skill_safety({ skillName }); - const advResult = JSON.parse(advisory.content[0].text); - - if (!advResult.safe) { - throw new Error(`Known vulnerabilities: ${advResult.advisories.map(a => a.id).join(', ')}`); - } - - // Both checks passed - safe to install - extractPackage(packagePath, '/workspace/project/skills/'); - console.log(`✓ Installed ${skillName} (verified + no advisories)`); -} -``` - -#### Pattern 3: Download and Verify Workflow - -```typescript -async function downloadAndInstallSkill(url: string) { - const packagePath = `/tmp/${Date.now()}-skill.tar.gz`; - const signaturePath = `${packagePath}.sig`; - - // Download package - await fetch(url).then(r => r.arrayBuffer()).then(buf => { - fs.writeFileSync(packagePath, Buffer.from(buf)); - }); - - // Download signature - await fetch(`${url}.sig`).then(r => r.text()).then(sig => { - fs.writeFileSync(signaturePath, sig); - }); - - // Verify before installation - const verification = await tools.clawsec_verify_skill_package({ - packagePath, - signaturePath - }); - - const result = JSON.parse(verification.content[0].text); - - if (!result.valid) { - fs.unlinkSync(packagePath); // Delete tampered file - fs.unlinkSync(signaturePath); - throw new Error('Signature verification failed'); - } - - // Install verified package - extractPackage(packagePath, '/workspace/project/skills/'); - - // Cleanup - fs.unlinkSync(packagePath); - fs.unlinkSync(signaturePath); -} -``` - -### Error Handling - -```typescript -const verification = await tools.clawsec_verify_skill_package({ packagePath }); -const result = JSON.parse(verification.content[0].text); - -// Check result.success first (operation completed) -if (!result.success) { - console.error('Verification operation failed:', result.error); - // Reasons: file not found, service unavailable, timeout - return; -} - -// Then check result.valid (signature cryptographically valid) -if (!result.valid) { - console.error('Invalid signature:', result.reason); - // Reasons: signature mismatch, tampered package, invalid format - return; -} - -// Finally check recommendation -switch (result.recommendation) { - case 'install': - console.log('✓ Safe to install'); - break; - case 'block': - console.error('⛔ Installation blocked'); - break; - case 'review': - console.warn('⚠️ Manual review recommended'); - break; -} -``` - ---- - -## Security Properties - -### What Signature Verification Prevents - -✅ **Prevents:** -- **Tampering**: Detecting if package contents were modified after signing -- **MITM attacks**: Detecting if package was swapped during download -- **Malicious mirrors**: Ensuring package comes from trusted source -- **Accidental corruption**: Detecting file corruption during transfer - -### What Signature Verification Does NOT Prevent - -❌ **Does Not Prevent:** -- **Malicious signed packages**: If the publisher's key is compromised -- **Zero-day vulnerabilities**: Bugs unknown to the publisher -- **Social engineering**: Convincing users to trust malicious publishers -- **Time-of-check-to-time-of-use**: Package modified after verification - -**Defense in Depth**: Combine signature verification with: -1. **Advisory checking** (`clawsec_check_skill_safety`) -2. **Code review** (manual inspection of skill code) -3. **Sandboxing** (run skills in isolated containers) -4. **Monitoring** (detect suspicious behavior at runtime) - -### Trust Model - -Signature verification relies on **trust in the public key**: - -``` -┌─────────────────────────────────────────────────┐ -│ You trust ClawSec's public key │ -│ ↓ │ -│ ClawSec signs package with private key │ -│ ↓ │ -│ You verify signature with ClawSec's public key │ -│ ↓ │ -│ Signature valid → Package is authentic │ -└─────────────────────────────────────────────────┘ -``` - -**Key Question**: How do you establish trust in the public key? -- **Pinned in repository**: Public key committed to ClawSec repo (trust GitHub) -- **HTTPS website**: Download from `https://clawsec.prompt.security/` (trust TLS/CA) -- **Out-of-band verification**: Compare key fingerprint via phone, Signal, etc. -- **Web of Trust**: Multiple trusted sources publish the same key - ---- - -## Key Management - -### ClawSec's Pinned Public Key - -**Location**: `/workspace/project/skills/clawsec-nanoclaw/advisories/feed-signing-public.pem` - -This is the **same key** used for advisory feed verification, providing a single trust anchor for all ClawSec security operations. - -**Key Fingerprint** (for manual verification): -```bash -# Compute fingerprint of pinned key -openssl pkey -pubin -in feed-signing-public.pem -outform DER | \ - openssl dgst -sha256 -binary | base64 -# Expected: -``` - -### Public Key Policy - -The verifier always uses the pinned ClawSec public key from this skill package. -Runtime public-key overrides are intentionally not supported. - -### Key Rotation - -If ClawSec's signing key is compromised or needs rotation: - -1. **Generate new keypair** (keep private key secure) -2. **Sign all packages** with new key -3. **Publish new public key** to all distribution channels -4. **Update pinned key** in `/workspace/project/skills/clawsec-nanoclaw/advisories/` -5. **Deprecate old key** after transition period (e.g., 90 days) - -During transition, support **dual signatures**: -- `package.tar.gz.sig` (old key) -- `package.tar.gz.sig2` (new key) - -Agents can verify with either key during the overlap period. - ---- - -## Troubleshooting - -### Error: "Signature file not found" - -**Cause**: Missing `.sig` file or incorrect path. - -**Solution**: -```bash -# Check if signature exists -ls -l /tmp/skill.tar.gz.sig - -# If missing, download signature -curl -o /tmp/skill.tar.gz.sig https://example.com/skill.tar.gz.sig - -# Or specify explicit path -clawsec_verify_skill_package({ - packagePath: '/tmp/skill.tar.gz', - signaturePath: '/tmp/custom-signature.sig' -}) -``` - -### Error: "Signature verification failed" - -**Cause**: Package was tampered with, or signature doesn't match package. - -**Solution**: -```bash -# Re-download package and signature -curl -o /tmp/skill.tar.gz https://example.com/skill.tar.gz -curl -o /tmp/skill.tar.gz.sig https://example.com/skill.tar.gz.sig - -# Verify manually with OpenSSL -openssl dgst -sha512 -verify clawsec-signing-public.pem \ - -signature /tmp/skill.tar.gz.sig /tmp/skill.tar.gz -# Should output: "Verified OK" -``` - -### Error: "Invalid PEM format" - -**Cause**: Public key file is corrupted or not in PEM format. - -**Solution**: -```bash -# Check public key format -head -1 /path/to/public-key.pem -# Should output: "-----BEGIN PUBLIC KEY-----" - -# Re-download public key -curl -o clawsec-signing-public.pem \ - https://clawsec.prompt.security/clawsec-signing-public.pem -``` - -### Error: "Package file not found" - -**Cause**: Incorrect path or file doesn't exist. - -**Solution**: -```bash -# Use absolute paths (required) -clawsec_verify_skill_package({ - packagePath: '/tmp/skill.tar.gz' // ✓ Absolute - // packagePath: './skill.tar.gz' // ✗ Relative (won't work) -}) - -# Verify file exists -stat /tmp/skill.tar.gz -``` - -### Verification Times Out (>5s) - -**Cause**: Large package (>50MB) or slow disk I/O. - -**Solution**: -```bash -# Check package size -ls -lh /tmp/skill.tar.gz - -# For very large packages, verification can take time -# Consider splitting into smaller skill modules -``` - ---- - -## Appendix: Signature File Format - -ClawSec uses **Ed25519 detached signatures** in raw binary format, base64-encoded. - -**File Structure**: -``` -my-skill-1.0.0.tar.gz.sig: - Line 1: base64-encoded signature (88 characters) -``` - -**Example**: -``` -MEQCIDxyz...ABC123== -``` - -**Properties**: -- Algorithm: Ed25519 (EdDSA with Curve25519) -- Signature size: 64 bytes (88 characters base64) -- Hash function: SHA-512 (internal to Ed25519) -- Format: Raw binary, base64-encoded - -**Verification Algorithm**: -1. Decode base64 signature → 64-byte binary -2. Hash package with SHA-512 -3. Verify Ed25519 signature(hash, publicKey) → boolean - ---- +Treat them as historical/test-vector input only. ## References -- [Ed25519 Specification (RFC 8032)](https://tools.ietf.org/html/rfc8032) -- [OpenSSL Ed25519 Documentation](https://www.openssl.org/docs/man3.0/man7/Ed25519.html) -- [ClawSec Security Architecture](https://clawsec.prompt.security/docs/architecture) -- [Supply Chain Attack Prevention](https://owasp.org/www-community/attacks/Supply_Chain_Attack) - ---- - -**Document Version**: 1.0.0 -**Last Updated**: 2026-02-25 -**Maintainer**: ClawSec Security Team +- [NanoClaw architecture](https://docs.nanoclaw.dev/concepts/architecture) +- [NanoClaw v2 skills](https://docs.nanoclaw.dev/extend/overview) +- [ClawSec security and signing runbook](../../../wiki/security-signing-runbook.md) diff --git a/skills/clawsec-nanoclaw/skill.json b/skills/clawsec-nanoclaw/skill.json index 22e21a5b..622625c5 100644 --- a/skills/clawsec-nanoclaw/skill.json +++ b/skills/clawsec-nanoclaw/skill.json @@ -1,23 +1,19 @@ { "name": "clawsec-nanoclaw", - "version": "0.0.10", - "description": "ClawSec security suite for NanoClaw - Advisory feed monitoring, MCP tools for vulnerability checking, and Ed25519 signature verification for containerized WhatsApp bot agents", + "version": "0.0.11", + "description": "Deprecated, runtime-unverified NanoClaw v1-era integration prototype retained only as migration and test-vector evidence; incompatible with NanoClaw v2", "author": "prompt-security", "license": "AGPL-3.0-or-later", "homepage": "https://clawsec.prompt.security/", + "installable": false, "keywords": [ "security", "nanoclaw", - "whatsapp-bot", - "mcp-tools", - "advisory", - "feed", - "threat-intel", - "containers", - "signature-verification", - "vulnerability-scanning", - "agents", - "ai" + "legacy", + "deprecated", + "migration", + "historical", + "test-vectors" ], "platform": "nanoclaw", "sbom": { @@ -25,7 +21,7 @@ { "path": "SKILL.md", "required": true, - "description": "NanoClaw skill documentation" + "description": "Historical-template status and migration guidance" }, { "path": "CHANGELOG.md", @@ -35,106 +31,30 @@ { "path": "INSTALL.md", "required": true, - "description": "Installation guide for NanoClaw deployments" - }, - { - "path": "mcp-tools/advisory-tools.ts", - "required": true, - "description": "MCP tools for advisory checking in container context" - }, - { - "path": "host-services/advisory-cache.ts", - "required": true, - "description": "Host-side advisory cache manager with periodic feed fetching" - }, - { - "path": "host-services/ipc-handlers.ts", - "required": true, - "description": "IPC handlers for MCP tool requests" - }, - { - "path": "lib/signatures.ts", - "required": true, - "description": "Ed25519 signature verification utilities" - }, - { - "path": "lib/local_file_io.ts", - "required": true, - "description": "Local file access helpers used by signature verification routines" - }, - { - "path": "lib/advisories.ts", - "required": true, - "description": "Advisory matching and vulnerability detection" - }, - { - "path": "lib/types.ts", - "required": true, - "description": "TypeScript type definitions" - }, - { - "path": "lib/risk.ts", - "required": true, - "description": "Shared advisory risk evaluation logic for host and MCP tools" - }, - { - "path": "advisories/feed-signing-public.pem", - "required": true, - "description": "Pinned Ed25519 public key for feed signature verification" - }, - { - "path": "mcp-tools/signature-verification.ts", - "required": true, - "description": "Phase 1: MCP tool for skill package signature verification" - }, - { - "path": "host-services/skill-signature-handler.ts", - "required": true, - "description": "Phase 1: Host-side signature verification service" + "description": "Historical integration record; explicitly not an installation guide" }, { "path": "docs/SKILL_SIGNING.md", "required": true, - "description": "Phase 1: Documentation for skill signing and verification" - }, - { - "path": "mcp-tools/integrity-tools.ts", - "required": true, - "description": "Phase 2: MCP tools for file integrity monitoring" - }, - { - "path": "host-services/integrity-handler.ts", - "required": true, - "description": "Phase 2: Host-side integrity monitoring service" - }, - { - "path": "guardian/integrity-monitor.ts", - "required": true, - "description": "Phase 2: Core file integrity monitoring engine" - }, - { - "path": "guardian/policy.json", - "required": true, - "description": "Phase 2: NanoClaw-specific file protection policy" + "description": "Historical signature component record" }, { "path": "docs/INTEGRITY.md", "required": true, - "description": "Phase 2: Documentation for file integrity monitoring" + "description": "Historical integrity component record" } ] }, - "capabilities": [ - "Advisory feed monitoring from clawsec.prompt.security", - "MCP tools for agent-initiated vulnerability scans", - "Exploitability-aware advisory prioritization for agent environments", - "Pre-installation skill safety checks", - "Ed25519 signature verification for advisory feeds", - "Platform metadata preserved in advisory records for downstream filtering", - "Containerized agent support with IPC communication" - ], + "capabilities": [], "nanoclaw": { - "mcp_tools": [ + "status": "deprecated-runtime-unverified", + "lineage": "v1-era", + "runtime_verified": false, + "supported_versions": [], + "incompatible_generations": [ + "v2" + ], + "historical_mcp_tool_names": [ "clawsec_check_advisories", "clawsec_check_skill_safety", "clawsec_list_advisories", @@ -145,11 +65,7 @@ "clawsec_integrity_status", "clawsec_verify_audit" ], - "requires": { - "node": ">=18.0.0", - "nanoclaw": ">=0.1.0" - }, - "integration": { + "historical_integration_assumptions": { "mcp_tools_file": "container/agent-runner/src/ipc-mcp-stdio.ts", "ipc_handlers_file": "src/ipc.ts", "cache_location": "/workspace/project/data/clawsec-advisory-cache.json" diff --git a/skills/clawsec-nanoclaw/test/nanoclaw-legacy-status.test.mjs b/skills/clawsec-nanoclaw/test/nanoclaw-legacy-status.test.mjs new file mode 100644 index 00000000..73e3d0db --- /dev/null +++ b/skills/clawsec-nanoclaw/test/nanoclaw-legacy-status.test.mjs @@ -0,0 +1,140 @@ +import assert from 'node:assert/strict'; +import fs from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const testDir = path.dirname(fileURLToPath(import.meta.url)); +const skillRoot = path.resolve(testDir, '..'); + +function read(relativePath) { + return fs.readFileSync(path.join(skillRoot, relativePath), 'utf8'); +} + +function frontmatterValue(markdown, key) { + const match = markdown.match(new RegExp(`^${key}:\\s*(.+)$`, 'm')); + assert.ok(match, `SKILL.md frontmatter must define ${key}`); + return match[1].trim(); +} + +const skillJson = JSON.parse(read('skill.json')); +const skill = read('SKILL.md'); +const readme = read('README.md'); +const install = read('INSTALL.md'); +const signing = read('docs/SKILL_SIGNING.md'); +const integrity = read('docs/INTEGRITY.md'); +const changelog = read('CHANGELOG.md'); + +assert.equal(skillJson.version, '0.0.11', 'skill.json must carry the truthfulness release version'); +assert.equal(frontmatterValue(skill, 'version'), '0.0.11', 'SKILL.md must match skill.json version'); +assert.match(skillJson.description, /deprecated[\s\S]*runtime-unverified/i); +assert.equal(skillJson.installable, false, 'a deprecated unverified template must be non-installable'); +assert.deepEqual(skillJson.capabilities, [], 'an unverified template must not advertise active capabilities'); +assert.equal(skillJson.nanoclaw?.status, 'deprecated-runtime-unverified'); +assert.equal(skillJson.nanoclaw?.lineage, 'v1-era'); +assert.equal(skillJson.nanoclaw?.runtime_verified, false); +assert.deepEqual(skillJson.nanoclaw?.supported_versions, []); +assert.deepEqual(skillJson.nanoclaw?.incompatible_generations, ['v2']); +assert.equal(skillJson.nanoclaw?.requires, undefined, 'unverified metadata must not advertise runtime requirements'); +assert.equal(skillJson.nanoclaw?.integration, undefined, 'historical paths must not be presented as an active integration'); + +const statusDocuments = new Map([ + ['skill.json description', skillJson.description], + ['SKILL.md', skill], + ['README.md', readme], + ['INSTALL.md', install], + ['docs/SKILL_SIGNING.md', signing], + ['docs/INTEGRITY.md', integrity], +]); + +for (const [label, text] of statusDocuments) { + assert.match(text, /(?:v1-era|NanoClaw v1)/i, `${label} must identify the historical v1-era lineage`); + assert.match(text, /(?:runtime-unverified|runtime unverified|unverified)/i, + `${label} must state that runtime support is unverified`); + assert.match(text, /NanoClaw v2[\s\S]{0,120}incompatible|incompatible[\s\S]{0,120}NanoClaw v2/i, + `${label} must state NanoClaw v2 incompatibility`); +} + +for (const [label, text] of [['SKILL.md', skill], ['README.md', readme]]) { + assert.match(text, /NanoClaw has no reviewed direct Agent Skills CLI target/i, + `${label} must state that NanoClaw has no reviewed direct target`); + assert.match(text, /\[[^\]]*(?:install|integration)[^\]]*\]\(\.\/INSTALL\.md\)/i, + `${label} must link the packaged historical integration record`); + assert.doesNotMatch(text, /npx\s+skills\s+add/i, + `${label} must not present a Skills CLI install command`); +} + +for (const [label, text] of statusDocuments) { + assert.doesNotMatch(text, />=\s*0\.1\.0\s*<\s*2\.0\.0/i, + `${label} must not advertise the invented legacy support range`); + assert.doesNotMatch(text, /Supported NanoClaw range:\s*`?[^\n]*\d+\.\d+/i, + `${label} must not advertise a numeric support range`); + assert.doesNotMatch(text, /SQLite IPC/i, + `${label} must use the explicit two-database boundary terminology`); +} + +assert.match(install, /not an installation guide/i); +assert.match(install, /declare[\s\S]*emit no JavaScript/i, + 'the historical record must explain the ambient-declaration runtime failure'); +assert.match(install, /ES modules[\s\S]*do not inherit lexical variables/i, + 'the historical record must explain the module-scope failure'); +assert.match(install, /glob[\s\S]{0,180}(?:no runtime implementation|unbound)/i, + 'the historical record must identify the unbound glob implementation'); +assert.match(install, /writeResponse[\s\S]{0,180}(?:imports or implements no|no implementation)/i, + 'the historical record must identify the missing writeResponse implementation'); +assert.match(install, /__dirname[\s\S]{0,180}ES module/i, + 'the historical record must identify the CommonJS __dirname use in ESM'); +assert.doesNotMatch(install, /docker-compose\s+(?:down|up)|docker\s+compose\s+(?:down|up)/i, + 'the withdrawn record must not retain false service commands'); +assert.doesNotMatch(install, /\bcp\s+-r\b|\bimport\s+['"][.]{1,2}\//i, + 'the withdrawn record must not contain actionable legacy copy/import steps'); + +assert.match(integrity, /not an active integrity guardian/i); +assert.match(integrity, /Automatic restoration[\s\S]*must remain off/i); +assert.doesNotMatch(integrity, /schedule_task\s*\(/i, + 'historical integrity documentation must not include an activation example'); + +assert.match(signing, /not a supported package-verification workflow/i); +assert.match(signing, /signed `checksums\.json` manifest/i); +assert.match(signing, /machine-readable `install` recommendation must not be treated as installation authority/i); +assert.doesNotMatch(signing, /Safe to install|proceed with extraction|extractPackage\(/i, + 'historical signing documentation must not authorize installation'); + +assert.doesNotMatch(skill, /prevents installation of vulnerable skills/i, + 'the skill must not claim ownership of a host installer'); +assert.doesNotMatch(readme, /ClawSec now supports NanoClaw/i, + 'the README must not make an unqualified support claim'); +const packagedPaths = skillJson.sbom?.files?.map((entry) => entry.path) ?? []; +const expectedPackagedPaths = [ + 'CHANGELOG.md', + 'INSTALL.md', + 'SKILL.md', + 'docs/INTEGRITY.md', + 'docs/SKILL_SIGNING.md', +]; +assert.deepEqual([...packagedPaths].sort(), expectedPackagedPaths, + 'the release SBOM must contain only essential migration and status documentation'); +for (const packagedPath of packagedPaths) { + assert.doesNotMatch(packagedPath, /\.ts$/i, + 'the release SBOM must not ship runtime-unverified TypeScript'); + assert.doesNotMatch(packagedPath, /(?:^|\/)policy\.json$/i, + 'the release SBOM must not ship the historical policy JSON'); + assert.doesNotMatch(packagedPath, /\.pem$/i, + 'the release SBOM must not ship historical PEM material'); +} +assert.match(skill, /successor[\s\S]{0,180}current published release[\s\S]{0,180}acceptance evidence/i, + 'successor availability must require current release and acceptance evidence'); +assert.match(skill, /live logs[\s\S]{0,180}runtime execution evidence as unknown/i, + 'missing live-log access must leave runtime evidence unknown'); +assert.match(skill, /upstream material observed on 2026-07-22[\s\S]{0,180}Reverify/i, + 'observed upstream facts must carry a revalidation requirement'); +assert.match(changelog, /^## \[0\.0\.11\] - 2026-07-22$/m, + 'CHANGELOG.md must record the truthfulness release'); +assert.match(changelog, /runtime-unverified NanoClaw v1-era integration prototype/i); +assert.match(changelog, /packaged user-facing Markdown/i, + 'the changelog must scope instruction removal to the packaged Markdown'); +assert.match(changelog, /Excluded runtime-unverified TypeScript, policy JSON, and PEM artifacts from the release SBOM/i, + 'the changelog must record the documentation-only release boundary'); + +assert.ok(skill.split('\n').length < 500, 'SKILL.md must remain concise enough for skill context'); + +console.log('NanoClaw legacy status contract tests passed.'); diff --git a/skills/clawsec-nanoclaw/test/security-hardening.test.mjs b/skills/clawsec-nanoclaw/test/security-hardening.test.mjs index 494aeffb..39cccd92 100644 --- a/skills/clawsec-nanoclaw/test/security-hardening.test.mjs +++ b/skills/clawsec-nanoclaw/test/security-hardening.test.mjs @@ -6,6 +6,8 @@ import test from 'node:test'; import vm from 'node:vm'; import { fileURLToPath } from 'node:url'; +import './nanoclaw-legacy-status.test.mjs'; + const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const SKILL_ROOT = path.resolve(__dirname, '..');