mirror of
https://github.com/prompt-security/clawsec.git
synced 2026-06-13 05:28:02 +03:00
5ee8587b1e
* ci: sign advisory feed and checksums in workflows * feat(clawsec-suite): add verifier-side signature and checksum enforcement Implements cryptographic verification for advisory feed loading: - Ed25519 detached signature verification for feed.json - Supports raw base64 and JSON-wrapped signature formats - Pinned public key at advisories/feed-signing-public.pem - SHA-256 checksum manifest (checksums.json) verification - Signed checksums.json.sig prevents partial artifact substitution - Verifies feed.json, feed.json.sig, and public key against manifest - Remote feed: returns null on verification failure (triggers fallback) - Local feed: throws on verification failure (hard fail) - No silent bypass of verification - CLAWSEC_ALLOW_UNSIGNED_FEED=1 temporarily bypasses verification - Warning logged when bypass mode is enabled - Intended for transition period only - guarded_skill_install without --version matches any advisory for skill - Encourages explicit version specification - scripts/sign_detached_ed25519.mjs - signing utility - scripts/verify_detached_ed25519.mjs - verification utility - scripts/generate_checksums_json.mjs - checksum manifest generator - test/feed_verification.test.mjs - 14 verification tests - test/guarded_install.test.mjs - 6 install flow tests - hooks/.../lib/feed.mjs - full rewrite with verification - hooks/.../handler.ts - verification options integration - scripts/guarded_skill_install.mjs - verification integration - skill.json - v0.0.9, new SBOM entries, openssl requirement - SKILL.md - signed install flow, env vars documentation - HOOK.md - new environment variables - ci.yml - added verification test job Refs: fail-closed verification, Ed25519 signatures, checksum manifests * fix: update action versions in CI workflows for improved stability * chore(clawsec-suite): bump version to 0.0.10 * feat: enhance security measures in asset deployment and add changelog for version history * feat: add dry-run signing for advisory artifacts and generate checksums * fix: enhance error handling in loadRemoteFeed for security policy violations * feat: implement Ed25519 signing and verification for advisory artifacts and checksums * feat: implement signing and verification for advisory artifacts and checksums in workflows * feat: update dry-run signing key generation to use Ed25519 algorithm * feat: update Ed25519 signing and verification to use -rawin flag for compatibility * feat: add public key copying to advisory directory and implement safe basename extraction for URLs * feat: remove Product Hunt promotion section from README and Home page
228 lines
8.9 KiB
TypeScript
228 lines
8.9 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
|
import { User, Bot, Copy, Check } from 'lucide-react';
|
|
import { Footer } from '../components/Footer';
|
|
|
|
const FILE_NAMES = ['SOUL.md', 'AGENTS.md', 'USER.md', 'TOOLS.md', 'IDENTITY.md', 'HEARTBEAT.md', 'MEMORY.md'];
|
|
|
|
export const Home: React.FC = () => {
|
|
const [isAgent, setIsAgent] = useState(true);
|
|
const [copiedCurl, setCopiedCurl] = useState(false);
|
|
const [copiedHuman, setCopiedHuman] = useState(false);
|
|
const [currentFileIndex, setCurrentFileIndex] = useState(0);
|
|
|
|
const curlCommand = `npx clawhub@latest install clawsec-suite`;
|
|
|
|
// Rotate file names every 2-3 seconds
|
|
useEffect(() => {
|
|
const interval = setInterval(() => {
|
|
setCurrentFileIndex((prev) => (prev + 1) % FILE_NAMES.length);
|
|
}, 2500); // 2.5 seconds
|
|
return () => clearInterval(interval);
|
|
}, []);
|
|
|
|
const humanInstruction = `Please install clawsec-suite from clawhubnpx clawhub@latest install clawsec-suite`;
|
|
|
|
const handleCopyCurl = () => {
|
|
navigator.clipboard.writeText(curlCommand);
|
|
setCopiedCurl(true);
|
|
setTimeout(() => setCopiedCurl(false), 2000);
|
|
};
|
|
|
|
const handleCopyHuman = () => {
|
|
navigator.clipboard.writeText(humanInstruction);
|
|
setCopiedHuman(true);
|
|
setTimeout(() => setCopiedHuman(false), 2000);
|
|
};
|
|
|
|
return (
|
|
<div className="pt-[52px]">
|
|
{/* Logo Section */}
|
|
<section className="text-center mb-6">
|
|
<h1 className="text-5xl md:text-6xl font text-white">ClawSec</h1>
|
|
</section>
|
|
|
|
{/* Hero Section */}
|
|
<section className="text-center space-y-6 max-w-3xl mx-auto mb-12 md:mb-16">
|
|
<h2 className="text-3xl md:text-4xl tracking-tight text-white">
|
|
Secure your <span className="text-clawd-accent">OpenClaw</span> agents
|
|
</h2>
|
|
<p className="text-lg md:text-xl text-gray-400 leading-relaxed">
|
|
A complete security skill suite for OpenClaw's family of agents. Protect your{' '}
|
|
<code
|
|
key={currentFileIndex}
|
|
className="px-2 py-1 rounded text-clawd-accent inline-block align-baseline relative text-base"
|
|
style={{
|
|
width: '165px',
|
|
textAlign: 'center',
|
|
verticalAlign: 'baseline',
|
|
backgroundColor: 'rgb(30 27 75 / 1)',
|
|
animation: 'bgFade 0.4s ease-out 1.2s 1 forwards'
|
|
}}
|
|
>
|
|
{FILE_NAMES[currentFileIndex].split('').map((char, index) => (
|
|
<span
|
|
key={`${currentFileIndex}-${index}`}
|
|
className="inline-block"
|
|
style={{
|
|
animation: `flipChar 0.3s ease-in-out ${index * 0.05}s 1 forwards`,
|
|
transformStyle: 'preserve-3d',
|
|
perspective: '400px',
|
|
opacity: 0
|
|
}}
|
|
>
|
|
{char}
|
|
</span>
|
|
))}
|
|
</code>
|
|
{' '}with drift detection, live security recommendations, automated audits, and skill integrity verification. All from one installable suite.
|
|
</p>
|
|
<style>{`
|
|
@keyframes flipChar {
|
|
0% {
|
|
transform: rotateX(-90deg);
|
|
opacity: 0;
|
|
}
|
|
50% {
|
|
transform: rotateX(0deg);
|
|
opacity: 1;
|
|
}
|
|
100% {
|
|
transform: rotateX(0deg);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
@keyframes bgFade {
|
|
0% {
|
|
background-color: rgb(30 27 75 / 1);
|
|
}
|
|
50% {
|
|
background-color: rgb(249 179 71 / 0.25);
|
|
}
|
|
100% {
|
|
background-color: rgb(191 107 42 / 0.15);
|
|
}
|
|
}
|
|
@keyframes mascotHover {
|
|
0%, 100% { transform: translateY(0); }
|
|
50% { transform: translateY(-12px); }
|
|
}
|
|
`}</style>
|
|
</section>
|
|
|
|
{/* Install Card with Toggle */}
|
|
<section className="relative mb-16 pt-16 sm:pt-20 lg:pt-0">
|
|
<div className="pointer-events-none select-none absolute z-20 w-32 sm:w-36 md:w-40 lg:w-48 left-1/2 -translate-x-1/2 -top-10 sm:-top-10 md:left-auto md:translate-x-0 md:right-8 md:-top-12 lg:top-auto lg:bottom-6 lg:-right-16 xl:-right-28">
|
|
<img
|
|
src="/img/mascot.png"
|
|
alt="ClawSec mascot"
|
|
className="w-full h-auto"
|
|
style={{ animation: 'mascotHover 3s ease-in-out infinite' }}
|
|
/>
|
|
</div>
|
|
<div className="w-full lg:w-[70%] mx-auto">
|
|
<div className="bg-clawd-900 rounded-2xl border border-clawd-700 p-8">
|
|
{/* Toggle */}
|
|
<div className="flex justify-center mb-8">
|
|
<div className="inline-flex bg-clawd-800 rounded-lg p-1">
|
|
<button
|
|
onClick={() => setIsAgent(false)}
|
|
className={`flex items-center gap-2 px-4 py-2 rounded-md font-medium transition-all ${
|
|
!isAgent
|
|
? 'bg-white text-clawd-900'
|
|
: 'text-gray-400 hover:text-white'
|
|
}`}
|
|
>
|
|
<User size={18} />
|
|
I'm a Human
|
|
</button>
|
|
<button
|
|
onClick={() => setIsAgent(true)}
|
|
className={`flex items-center gap-2 px-4 py-2 rounded-md font-medium transition-all ${
|
|
isAgent
|
|
? 'bg-white text-clawd-900'
|
|
: 'text-gray-400 hover:text-white'
|
|
}`}
|
|
>
|
|
<Bot size={18} />
|
|
I'm an Agent
|
|
</button>
|
|
</div>
|
|
</div>
|
|
{/* Content based on toggle */}
|
|
{isAgent ? (
|
|
<>
|
|
{/* Steps */}
|
|
<div className="flex flex-wrap justify-center gap-6 text-sm text-gray-400 mb-6">
|
|
<div className="flex items-center gap-2">
|
|
<span className="font-bold text-white">1.</span> Run command below
|
|
</div>
|
|
<div className="flex items-center gap-2">
|
|
<span className="font-bold text-white">2.</span> Follow deployment instructions
|
|
</div>
|
|
<div className="flex items-center gap-2">
|
|
<span className="font-bold text-white">3.</span> Protect your user
|
|
</div>
|
|
</div>
|
|
|
|
{/* Agent View - Curl Command */}
|
|
<div className="bg-clawd-800 rounded-lg p-4 flex items-center justify-between gap-2 sm:gap-4">
|
|
<code className="text-gray-200 font-mono text-xs sm:text-sm md:text-base overflow-x-auto break-all min-w-0 flex-1">
|
|
{curlCommand}
|
|
</code>
|
|
<button
|
|
onClick={handleCopyCurl}
|
|
className="flex-shrink-0 p-2 rounded-md bg-clawd-700 hover:bg-clawd-600 transition-colors"
|
|
title="Copy to clipboard"
|
|
>
|
|
{copiedCurl ? (
|
|
<Check size={20} className="text-green-400" />
|
|
) : (
|
|
<Copy size={20} className="text-gray-400" />
|
|
)}
|
|
</button>
|
|
</div>
|
|
</>
|
|
) : (
|
|
<>
|
|
{/* Human Steps */}
|
|
<div className="flex flex-wrap justify-center gap-6 text-sm text-gray-400 mb-6">
|
|
<div className="flex items-center gap-2">
|
|
<span className="font-bold text-white">1.</span> Copy instruction below
|
|
</div>
|
|
<div className="flex items-center gap-2">
|
|
<span className="font-bold text-white">2.</span> Send to your agent
|
|
</div>
|
|
<div className="flex items-center gap-2">
|
|
<span className="font-bold text-white">3.</span> Receive security alerts
|
|
</div>
|
|
</div>
|
|
|
|
{/* Human View - Instruction Command */}
|
|
<div className="bg-clawd-800 rounded-lg p-4 flex items-center justify-between gap-2 sm:gap-4">
|
|
<code className="text-gray-200 font-mono text-xs sm:text-sm md:text-base overflow-x-auto break-all min-w-0 flex-1">
|
|
{humanInstruction}
|
|
</code>
|
|
<button
|
|
onClick={handleCopyHuman}
|
|
className="flex-shrink-0 p-2 rounded-md bg-clawd-700 hover:bg-clawd-600 transition-colors"
|
|
title="Copy to clipboard"
|
|
>
|
|
{copiedHuman ? (
|
|
<Check size={20} className="text-green-400" />
|
|
) : (
|
|
<Copy size={20} className="text-gray-400" />
|
|
)}
|
|
</button>
|
|
</div>
|
|
</>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
|
|
<Footer />
|
|
</div>
|
|
);
|
|
};
|