Find a file
XiaoSeS 3bc97ff1b8 feat(security): add security scanning system with multi-scanner support and frontend UI (#144)
* feat(security): extend scanner config with full analyzer options

Integrate skill-scanner's 8 analysis engines and policy configuration
into SkillHub's config system. Operators can now control behavioral,
LLM, Meta, AI Defense, VirusTotal, and trigger analyzers via
application.yml or environment variables.

Changes:
- Add Analyzers and Policy nested classes to SkillScannerProperties
- Create ScanOptions record to encapsulate analyzer flags
- Update SkillScannerService to pass options in /scan body and /scan-upload query params
- Wire ScanOptions through SkillScannerConfig and SkillScannerAdapter
- Extend application.yml with full scanner config block and env var overrides
- Update all tests to verify new configuration flow

All tests pass.

* feat(security): add domain model and integrate scan into publish flow

Add SCANNING/SCAN_FAILED status to SkillVersionStatus. Introduce
SecurityScanService, SecurityScanner port, ScanTask, SecurityAudit
and related domain types. Wire scan trigger into SkillPublishService
so non-auto-publish versions enter scanning when scanner is enabled,
falling back to review task creation when disabled.

* feat(security): add infra layer for scanner HTTP client and adapters

Add WebClient-based HttpClient abstraction with WebClientHttpClient
implementation. Add SkillScannerApiResponse record, SecurityScanException,
and SecurityAuditJpaRepository. Add webflux and test dependencies to
infra module.

* feat(security): add Redis stream consumers, audit API, and DB migration

Add AbstractStreamConsumer base class, ScanTaskConsumer for processing
scan results from Redis stream, and RedisScanTaskProducer. Add
RedisStreamConfig for stream/group initialization. Add SecurityAudit
REST controller and DTO. Add V35 Flyway migration for security_audits
table.

* feat(security): add scanner config to application profiles

Add scanner enabled flag to application-local.yml and
application-test.yml. Enable behavioral analyzer by default
in application.yml.

* feat(deploy): add skill-scanner to docker-compose and k8s manifests

Add skill-scanner service to docker-compose.yml with health check.
Add scanner k8s deployment, service, and configmap entries. Wire
scanner env vars into Makefile dev-all flow. Add verify-scanner.sh
script for post-deploy validation.

* docs(security): add scanner documentation suite

Add scanner docs: configuration guide, failure impact analysis,
monitoring guide, improvement recommendations, custom rules guide,
and skill-vetter rules conversion example. Update deployment docs
with scanner section. Add security-scanning overview and PRD.

* feat(security): add skill-vetter custom rule examples

Add example Regex and YARA rules derived from skill-vetter RED FLAGS
in scanner/examples/vetter-rules/. Includes 7 Regex rules
(signatures-append.yaml) and 3 YARA rules (skillhub_vetter.yara)
covering agent memory theft, IP-based exfiltration, and browser
data theft detection.

* feat(security): add scanner Docker build context

Add Dockerfile for cisco-ai-skill-scanner container and
.env.example with LLM configuration placeholders.

* fix(security): align Finding mapping with scanner API response schema

SkillScannerApiResponse.Finding used incorrect field names (message,
location.file, location.line, code_snippet) that did not match the
scanner's actual JSON output (description, file_path, line_number,
snippet), causing all four fields to deserialize as null.

Flatten Finding to match scanner API: remove nested Location, rename
fields to description/file_path/line_number/snippet. Add skill_name
and timestamp to SkillScannerApiResponse. Extend SecurityFinding with
remediation, analyzer, and metadata fields to capture LLM analyzer
output. Retain 8-arg compact constructor for backward compatibility.

* chore(security): add debug logging to scanner response mapping

Log raw scanner API response and mapped SecurityFinding fields
side-by-side to help verify data consistency between scanner
output and database records.

* feat(security): add multi-scanner support and soft delete for security audits

- Add ScannerType enum for type-safe scanner identification
- Update V35 migration to support multiple scanners and soft delete
- Remove CASCADE delete, use code-level soft delete (deleted_at)
- Add repository methods for querying latest audit by scanner type
- Update SecurityScanService to handle scanner type parameter
- Integrate soft delete in SkillHardDeleteService
- Update all tests to use ScannerType enum

This enables multiple scanner integrations (skill-scanner, future LLM/compliance scanners)
and preserves complete audit history through soft deletion.

* feat(security): add security audit UI to review detail and skill detail pages

Display security scan results on the review detail page (full audit
section with collapsible findings) and the skill detail sidebar (compact
summary with dialog for details).  Handles empty/404 gracefully by
returning null, avoids loading shimmer flicker, and separates lifecycle
action buttons with a visual divider.

* docs(security): add security audit UI PRD

* fix(security): replace LocalDateTime with Instant in security audit and align controller test with list API

SecurityAudit and SecurityScanService used LocalDateTime.now() which
violated the project time guardrail. Replaced with Instant and
Clock.systemUTC() to match existing conventions.

Also fixed SecurityAuditControllerTest to mock the correct repository
method (findLatestActiveByVersionId) and assert against the list
response shape.

* test(security): add useQuery mock for security audit components in frontend tests

The SecurityAuditSummary and SecurityAuditSection components use
useQuery via useSecurityAudits hook, which was missing from the
@tanstack/react-query mocks in skill-detail and review-detail tests.
2026-03-23 09:56:03 +08:00
.github feat(profile): add field policy config and GET response 2026-03-20 14:59:21 +08:00
deploy feat(security): add security scanning system with multi-scanner support and frontend UI (#144) 2026-03-23 09:56:03 +08:00
docs feat(security): add security scanning system with multi-scanner support and frontend UI (#144) 2026-03-23 09:56:03 +08:00
document fix(auth): enable local bootstrap admin by default (#141) 2026-03-20 16:10:20 +08:00
monitoring feat(ops): add optional runtime registry mirroring 2026-03-15 14:30:04 +08:00
scanner feat(security): add security scanning system with multi-scanner support and frontend UI (#144) 2026-03-23 09:56:03 +08:00
scripts feat(security): add security scanning system with multi-scanner support and frontend UI (#144) 2026-03-23 09:56:03 +08:00
server feat(security): add security scanning system with multi-scanner support and frontend UI (#144) 2026-03-23 09:56:03 +08:00
web feat(security): add security scanning system with multi-scanner support and frontend UI (#144) 2026-03-23 09:56:03 +08:00
.env.release.draft fix: official site urls removed 2026-03-16 21:25:55 +08:00
.env.release.example chore(runtime): default release runtime to latest 2026-03-19 20:36:45 +08:00
.gitignore docs(agents): add repository guidance notes 2026-03-20 14:58:15 +08:00
CODE_OF_CONDUCT.md Add OpenAPI drift validation and docs updates 2026-03-13 11:06:55 +08:00
compose.release.yml chore(runtime): default release runtime to latest 2026-03-19 20:36:45 +08:00
CONTRIBUTING.md Add OpenAPI drift validation and docs updates 2026-03-13 11:06:55 +08:00
docker-compose.staging.yml cli login fix 2026-03-16 17:33:12 +08:00
docker-compose.yml feat(security): add security scanning system with multi-scanner support and frontend UI (#144) 2026-03-23 09:56:03 +08:00
LICENSE Add OpenAPI drift validation and docs updates 2026-03-13 11:06:55 +08:00
Makefile feat(security): add security scanning system with multi-scanner support and frontend UI (#144) 2026-03-23 09:56:03 +08:00
README.md fix(auth): enable local bootstrap admin by default (#141) 2026-03-20 16:10:20 +08:00
README_zh.md fix(auth): enable local bootstrap admin by default (#141) 2026-03-20 16:10:20 +08:00
skillhub-logo.svg docs: improve README with logo, badges, and Zread documentation link 2026-03-13 19:13:44 +08:00

SkillHub Logo

SkillHub

An enterprise-grade, open-source agent skill registry — publish, discover, and manage reusable skill packages across your organization.

DeepWiki Docs License Build Docker Java React


SkillHub is a self-hosted platform that gives teams a private, governed place to share agent skills. Publish a skill package, push it to a namespace, and let others find it through search or install it via CLI. Built for on-premise deployment behind your firewall, with the same polish you'd expect from a public registry.

📖 Full Documentation →

Highlights

  • Self-Hosted & Private — Deploy on your own infrastructure. Keep proprietary skills behind your firewall with full data sovereignty. One make dev-all command to get running locally.
  • Publish & Version — Upload agent skill packages with semantic versioning, custom tags (beta, stable), and automatic latest tracking.
  • Discover — Full-text search with filters by namespace, downloads, ratings, and recency. Visibility rules ensure users only see what they're authorized to.
  • Team Namespaces — Organize skills under team or global scopes. Each namespace has its own members, roles (Owner / Admin / Member), and publishing policies.
  • Review & Governance — Team admins review within their namespace; platform admins gate promotions to the global scope. Governance actions are audit-logged for compliance.
  • Social Features — Star skills, rate them, and track downloads. Build a community around your organization's best practices.
  • Account Merging — Consolidate multiple OAuth identities and API tokens under a single user account.
  • API Token Management — Generate scoped tokens for CLI and programmatic access with prefix-based secure hashing.
  • CLI-First — Native REST API plus a compatibility layer for existing ClawHub-style registry clients. Native CLI APIs are the primary supported path while protocol compatibility continues to expand.
  • Pluggable Storage — Local filesystem for development, S3 / MinIO for production. Swap via config.
  • Internationalization — Multi-language support with i18next.

Quick Start

Start the full local stack with one of the following commands:

Official images:

rm -rf /tmp/skillhub-runtime
curl -fsSL https://imageless.oss-cn-beijing.aliyuncs.com/runtime-github.sh | sh -s -- up

The default command pulls the latest stable release images. Use --version edge if you want the newest build from main.

Aliyun mirror shortcut:

rm -rf /tmp/skillhub-aliyun
curl -fsSL https://imageless.oss-cn-beijing.aliyuncs.com/runtime.sh | sh -s -- up --home /tmp/skillhub-aliyun --aliyun --version latest

If deployment runs into problems, clear the existing runtime home and retry.

Prerequisites

  • Docker & Docker Compose

Local Development

make dev-all

Then open:

  • Web UI: http://localhost:3000
  • Backend API: http://localhost:8080

By default, make dev-all starts the backend with the local profile. In that mode, local development keeps the mock-auth users below and also creates a password-based bootstrap admin account by default:

  • local-user for normal publishing and namespace operations
  • local-admin with SUPER_ADMIN for review and admin flows

Use them with the X-Mock-User-Id header in local development.

The local bootstrap admin is enabled by default in application-local.yml:

  • username: BOOTSTRAP_ADMIN_USERNAME (admin by default)
  • password: BOOTSTRAP_ADMIN_PASSWORD In local app-level fallback it is ChangeMe!2026.
  • For local source startup, set the environment variable BOOTSTRAP_ADMIN_ENABLED=false before starting the backend.
  • For container or release environments, configure the same value in .env.release or the Compose environment.
  • The shipped release template still uses replace-this-admin-password and must be changed before first login.

Stop everything with:

make dev-all-down

Reset local dependencies and start from a clean slate with:

make dev-all-reset

Run make help to see all available commands.

Useful backend commands:

make test
make test-backend-app
make build-backend-app

Do not run ./mvnw -pl skillhub-app clean test directly under server/. skillhub-app depends on sibling modules in the same repo, and a standalone clean build can fall back to stale artifacts from the local Maven repository, which surfaces misleading cannot find symbol and signature-mismatch errors. Use -am, or the make test-backend-app and make build-backend-app targets above.

For the full development workflow (local dev → staging → PR), see docs/dev-workflow.md.

API Contract Sync

OpenAPI types for the web client are checked into the repository. When backend API contracts change, regenerate the SDK and commit the updated generated file:

make generate-api

For a stricter end-to-end drift check, run:

./scripts/check-openapi-generated.sh

This starts local dependencies, boots the backend, regenerates the frontend schema, and fails if the checked-in SDK is stale.

Container Runtime

Published runtime images are built by GitHub Actions and pushed to GHCR. This is the supported path for anyone who wants a ready-to-use local environment without building the backend or frontend on their machine. Published images target both linux/amd64 and linux/arm64.

  1. Copy the runtime environment template.
  2. Pick an image tag.
  3. Start the stack with Docker Compose.
cp .env.release.example .env.release

Recommended image tags:

  • SKILLHUB_VERSION=edge for the latest main build
  • SKILLHUB_VERSION=vX.Y.Z for a fixed release

Start the runtime:

make validate-release-config
docker compose --env-file .env.release -f compose.release.yml up -d

Then open:

  • Web UI: SKILLHUB_PUBLIC_BASE_URL 对应的地址
  • Backend API: http://localhost:8080

Stop it with:

docker compose --env-file .env.release -f compose.release.yml down

The runtime stack uses its own Compose project name, so it does not collide with containers from make dev-all.

The production Compose stack now defaults to the docker profile only. It does not enable local mock auth. Bootstrap admin is disabled by default; if you turn it on explicitly, the backend seeds a local admin account from environment variables for the first login:

  • username: BOOTSTRAP_ADMIN_USERNAME
  • password: BOOTSTRAP_ADMIN_PASSWORD

Recommended production baseline:

  • set SKILLHUB_PUBLIC_BASE_URL to the final HTTPS entrypoint
  • keep PostgreSQL / Redis bound to 127.0.0.1
  • use external S3 / OSS via SKILLHUB_STORAGE_S3_*
  • keep BOOTSTRAP_ADMIN_ENABLED=false unless you intentionally need bootstrap login
  • rotate or disable the bootstrap admin after initial setup
  • run make validate-release-config before docker compose up -d

If the GHCR package remains private, run docker login ghcr.io before docker compose up -d.

Monitoring

A Prometheus + Grafana monitoring stack lives under monitoring/. It scrapes the backend's Actuator Prometheus endpoint.

Start it with:

cd monitoring
docker compose -f docker-compose.monitoring.yml up -d

Then open:

  • Prometheus: http://localhost:9090
  • Grafana: http://localhost:3001 (admin / admin)

By default Prometheus scrapes http://host.docker.internal:8080/actuator/prometheus, so start the backend locally on port 8080 first.

Kubernetes

Basic Kubernetes manifests are available under deploy/k8s/:

  • configmap.yaml
  • secret.yaml.example
  • backend-deployment.yaml
  • frontend-deployment.yaml
  • services.yaml
  • ingress.yaml

Apply them after creating your own secret:

kubectl apply -f deploy/k8s/configmap.yaml
kubectl apply -f deploy/k8s/secret.yaml
kubectl apply -f deploy/k8s/backend-deployment.yaml
kubectl apply -f deploy/k8s/frontend-deployment.yaml
kubectl apply -f deploy/k8s/services.yaml
kubectl apply -f deploy/k8s/ingress.yaml

Smoke Test

A lightweight smoke test script is available at scripts/smoke-test.sh.

Run it against a local backend:

./scripts/smoke-test.sh http://localhost:8080

Architecture

┌─────────────┐     ┌─────────────┐     ┌──────────────┐
│   Web UI    │     │  CLI Tools  │     │  REST API    │
│  (React 19) │     │             │     │              │
└──────┬──────┘     └──────┬──────┘     └──────┬───────┘
       │                   │                   │
       └───────────────────┼───────────────────┘
                           │
                    ┌──────▼──────┐
                    │   Nginx     │
                    └──────┬──────┘
                           │
                    ┌──────▼──────┐
                    │ Spring Boot │  Auth · RBAC · Core Services
                    │   (Java 21) │  OAuth2 · API Tokens · Audit
                    └──────┬──────┘
                           │
              ┌────────────┼────────────┐
              │            │            │
       ┌──────▼───┐  ┌─────▼────┐  ┌────▼────┐
       │PostgreSQL│  │  Redis   │  │ Storage │
       │    16    │  │    7     │  │ S3/MinIO│
       └──────────┘  └──────────┘  └─────────┘

Backend (Spring Boot 3.2.3, Java 21):

  • Multi-module Maven project with clean architecture
  • Modules: app, domain, auth, search, storage, infra
  • PostgreSQL 16 with Flyway migrations
  • Redis for session management
  • S3/MinIO for skill package storage

Frontend (React 19, TypeScript, Vite):

  • TanStack Router for routing
  • TanStack Query for data fetching
  • Tailwind CSS + Radix UI for styling
  • OpenAPI TypeScript for type-safe API client
  • i18next for internationalization

Usage with Agent Platforms

SkillHub works as a skill registry backend for several agent platforms. Point any of the clients below at your SkillHub instance to publish, discover, and install skills.

OpenClaw

OpenClaw is an open-source agent skill CLI. Configure it to use your SkillHub endpoint as the registry:

# Configure registry URL
export CLAWHUB_REGISTRY=https://skillhub.your-company.com

# Authenticate once if needed
clawhub login --token YOUR_API_TOKEN

# Search and install skills
npx clawhub search email
npx clawhub install my-skill
npx clawhub install my-namespace--my-skill

# Publish a skill
npx clawhub publish ./my-skill

📖 Complete OpenClaw Integration Guide →

AstronClaw

AstronClaw is the skill marketplace provided by iFlytek's Astron platform. You can connect it to a self-hosted SkillHub registry to manage and distribute private skills within your organization, or browse publicly shared skills on the Astron platform.

astron-agent

astron-agent is the iFlytek Astron agent framework. Skills stored in SkillHub can be referenced and loaded directly by astron-agent, enabling a governed, versioned skill lifecycle from development to production.


🌟 Show & Tell — Have you built something with SkillHub? We'd love to hear about it! Share your use case, integration, or deployment story in the Discussions → Show and Tell category.

Contributing

Contributions are welcome. Please open an issue first to discuss what you'd like to change.

📞 Support

License

Apache License 2.0