š¬ Skill Evidenceops OpenClaw Plugin & Skill | ClawHub
Looking to integrate Skill Evidenceops into your AI workflows? This free OpenClaw plugin from ClawHub helps you automate coding agents & ides tasks instantly, without having to write custom tools from scratch.
What this skill does
Forensic media triage with chain of custody. Use when receiving images, videos, audio, PDFs, or documents that need evidence-grade handling, integrity verification, and audit trails.
Install
openclaw skills install @msrovani/skill-evidenceopsnpx clawhub@latest install skill-evidenceopsFull SKILL.md
Open original| name | version | description |
|---|---|---|
| evidenceops | 1.0.0 | Forensic media triage with chain of custody. Use when receiving images, videos, audio, PDFs, or documents that need evidence-grade handling, integrity verification, and audit trails. |
SKILL.md content below is scrollable.
EvidenceOps - Forensic Media Triage
What It Does
EvidenceOps provides forensic-grade handling of media files with complete chain of custody:
- Media Intake - Accept images, videos, audio, PDFs, and documents from any channel
- Immutable Storage - Store originals in append-only vault with cryptographic hashes
- Metadata Extraction - Extract EXIF, file properties, and media information without altering originals
- Derivative Generation - Create thumbnails, transcripts, previews in separate folders
- Chain of Custody - Maintain tamper-evident audit trail with hash chain
- Integrity Verification - Verify evidence hasn't been modified post-ingest
- Audit Trail - Complete JSONL audit log for compliance
What It NEVER Does
- NEVER modifies original evidence files after ingest
- NEVER stores secrets, API keys, or credentials in manifests or logs
- NEVER accepts unsanitized paths from user input
- NEVER executes untrusted code or downloads remote scripts
- NEVER exfiltrates data to external services without explicit configuration
- NEVER bypasses channel allowlists or pairing requirements
- NEVER stores real personal data in example files
Prerequisites
Before using this skill, ensure:
- Plugin
@openclaw/evidence-vaultis installed and initialized - Vault storage directory is configured with appropriate permissions
- Channel allowlist is configured for trusted sources only
- Retention policies comply with your legal requirements
Workflow
Step 1: Receive Media
When media is received via any channel:
User sends: [image/video/document]
Required Information:
- File content (from attachment)
- Original filename
- Source channel (whatsapp, telegram, email, etc.)
- Sender identifier
- Message ID (if available)
Step 2: Create or Select Case
IF user specifies existing caseId:
USE that caseId
ELSE IF user requests new case:
CREATE case with format: case-{YYYY}-{NNN}
EXAMPLE: case-2026-001
ELSE:
ASK user: "Should I create a new case or add to existing case [case-2026-XXX]?"
Case ID Format: case-{year}-{sequence}
- Must match pattern:
^case-[a-zA-Z0-9_-]+$ - Examples:
case-2026-001,case-incident-alpha,case-legal-2026-q1
Step 3: Stage Original (Read-Only)
Before ingest:
- Save received file to temporary staging area
- Calculate SHA-256 hash immediately
- Record file size and MIME type
- DO NOT modify the file
# Staging directory structure
/tmp/evidence-staging/
āāā {caseId}/
ā āāā {timestamp}-{filename}
Step 4: Extract Metadata
Extract metadata WITHOUT modifying original:
For Images:
- EXIF data (camera, GPS, timestamps)
- Dimensions
- Color profile
For Videos:
- Duration
- Codec information
- Resolution
For Audio:
- Duration
- Sample rate
- Codec
For PDFs:
- Page count
- Author (if embedded)
- Creation date
# Use Read tool or appropriate extraction commands
# NEVER write back to original file
Step 5: Generate Derivatives (Optional)
Create derivative artifacts in SEPARATE folder:
derivatives/
āāā thumbnails/
ā āāā {evidenceId}-thumb.jpg
āāā transcripts/
ā āāā {evidenceId}-transcript.txt
āāā previews/
āāā {evidenceId}-preview.pdf
Derivative Types:
thumbnail- Reduced resolution image/video previewtranscript- Speech-to-text for audio/videopreview- PDF or text representationocr- Extracted text from images
Step 6: Ingest to Vault
Call the evidence.ingest tool:
{
"filePath": "/path/to/staged/file",
"filename": "original-filename.jpg",
"caseId": "case-2026-001",
"channel": "whatsapp",
"sender": "[email protected]",
"messageId": "msg-abc123",
"retentionDays": 2555,
"metadata": {
"exif": { ... },
"extracted": { ... }
}
}
Response:
{
"success": true,
"evidenceId": "ev-abc123...",
"sha256": "a1b2c3...",
"vaultUrl": "file:///vault/cases/case-2026-001/originals/ev-abc123.jpg",
"timestamp": "2026-02-17T10:30:00.000Z"
}
Step 7: Update Manifest
The manifest is automatically updated by the ingest operation.
Manifest Location: {vault}/cases/{caseId}/manifest.json
Manifest Contents:
- Case metadata
- Evidence items with hashes
- Derivatives
- Chain of custody entries
- Retention policy
Step 8: Return Receipt
Provide user with evidence receipt:
š EVIDENCE RECEIPT
Case ID: case-2026-001
Evidence ID: ev-abc123...
File: original-filename.jpg
SHA-256: a1b2c3d4e5f6...
Size: 1.2 MB
Received: 2026-02-17 10:30:00 UTC
Vault: file:///vault/cases/case-2026-001/originals/ev-abc123.jpg
ā
Chain of custody established
ā
Original preserved immutably
ā
Audit trail active
Tool Reference
evidence.ingest
Ingest a file into the evidence vault.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| filePath | string | Yes | Path to the staged file |
| filename | string | Yes | Original filename |
| caseId | string | Yes | Case identifier |
| channel | string | No | Source channel |
| sender | string | No | Sender identifier |
| messageId | string | No | Message ID from source |
| retentionDays | number | No | Retention period |
| metadata | object | No | Additional metadata |
Returns: { evidenceId, sha256, vaultUrl, timestamp }
evidence.verify
Verify evidence integrity.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| evidenceId | string | Yes | Evidence to verify |
| caseId | string | No | Limit search to case |
Returns: { verified, details: { originalIntact, hashMatch, lastVerifiedAt } }
evidence.manifest
Get case manifest.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| caseId | string | Yes | Case identifier |
Returns: Complete case manifest with all items
evidence.export
Export case as archive.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| caseId | string | Yes | Case identifier |
| format | string | No | 'zip' or 'tar' (default: zip) |
Returns: { exportPath, sha256, size, itemCount }
evidence.access_log
Get audit trail.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| caseId | string | Yes | Case identifier |
| limit | number | No | Max events (default: 100) |
Returns: { events: [ ... ], count }
SECURITY POSTURE
Channel Allowlist Configuration
Configure which channels can submit evidence:
# ~/.openclaw/openclaw.json
{
"plugins": {
"evidence-vault": {
"channelAllowlist": ["whatsapp", "telegram", "email"],
"channelDenylist": ["public-discord"],
"requirePairing": true
}
}
}
Pairing Requirements
For Direct Messages (DMs):
- REQUIRE pairing before accepting evidence
- BLOCK unpaired DMs by default
- LOG rejected ingestion attempts
For Group Channels:
- VERIFY channel is in allowlist
- REJECT evidence from untrusted channels
- NEVER auto-ingest from public channels
Path Sanitization Rules
ALL paths are validated:
- No path traversal -
../sequences rejected - No null bytes -
\0rejected - No home directory -
~/rejected - Canonicalization - Paths resolved before validation
- Base path check - Must be within vault directory
Violations result in: E_PATH_TRAVERSAL error + audit log entry
Destructive Action Confirmation
Before any potentially destructive operation:
- EXPORT - Confirm export destination
- RETENTION DELETE - Require explicit confirmation (if enabled)
- LEGAL HOLD RELEASE - Require explicit confirmation
Confirmation format:
ā ļø DESTRUCTIVE ACTION
You are about to: [describe action]
Case: [caseId]
Items affected: [count]
Type "CONFIRM" to proceed:
Secrets Handling
NEVER include in logs or manifests:
- API keys
- Passwords
- Tokens
- Credit card numbers
- Email addresses (redacted)
- Phone numbers (redacted)
- SSN (redacted)
Redaction is automatic via regex patterns.
Troubleshooting
Error: E_PATH_TRAVERSAL
Cause: Filename or path contains disallowed characters
Solution:
- Filenames are automatically sanitized
- If error persists, check for unusual characters
- Original filename is preserved in manifest metadata
Error: E_INVALID_MIME
Cause: File type not in allowed list
Solution:
- Check
allowedMimeTypesconfiguration - Add MIME type to allowlist if appropriate
- Verify file is not corrupted
Error: E_SIZE_LIMIT
Cause: File exceeds maximum size
Solution:
- Check
maxFileSizeBytesconfiguration - Split large files if appropriate
- Compress before ingest (note in metadata)
Error: E_CHANNEL_BLOCKED
Cause: Evidence from blocked or non-allowlisted channel
Solution:
- Verify channel in allowlist
- Check if pairing is required
- Review security configuration
Error: E_HASH_MISMATCH
Cause: Evidence file modified after ingest
Solution:
- This indicates potential tampering
- Review access logs for case
- Escalate per incident response procedures
Verification Fails
Symptoms: verified: false in verify response
Diagnostic steps:
- Check if original file exists
- Compare current hash with manifest hash
- Review audit log for modifications
- Check filesystem permissions
Configuration Example
# openclaw.yaml
plugins:
evidence-vault:
driver: filesystem # or s3
basePath: /var/evidence-vault
maxFileSizeBytes: 524288000 # 500MB
defaultRetentionDays: 2555 # 7 years
allowedMimeTypes:
- image/jpeg
- image/png
- video/mp4
- audio/mpeg
- application/pdf
channelAllowlist:
- whatsapp
- telegram
- slack
requirePairing: true
# S3 driver options (if driver: s3)
s3:
endpoint: https://s3.example.com
bucket: evidence-vault
region: us-east-1
objectLock: true
Legal and Compliance Notes
LGPD/GDPR Considerations
- Tag sensitive data with
sensitivityTag - Configure appropriate retention periods
- Never store real personal data in examples
- Implement data subject access request procedures
Retention Policies
| Sensitivity | Default Retention |
|---|---|
| public | 365 days |
| internal | 1825 days (5 years) |
| confidential | 2555 days (7 years) |
| restricted | Legal hold |
Audit Requirements
All operations logged to JSONL audit file:
- Case creation/deletion
- Evidence ingest
- Verification attempts
- Export operations
- Access requests
Audit log retention: Same as case retention