guardskills
v1.6.0
Published
Security gate for AI agent skill installers
Maintainers
Readme
GuardSkills
GuardSkills gives you three simple ways to protect your skills.
1. Protect a new skill installation
No separate security skill or new command is needed. Just add guardskills next to npx, followed
by your normal skill command.
Your usual command:
npx skills add owner/repo --skill skill-nameThe same command with GuardSkills:
npx guardskills skills add owner/repo --skill skill-nameGuardSkills scans and scores the skill before handing it to the provider's installer. If the selected policy blocks the skill, the installer does not run.
2. Scan all existing skills
Point GuardSkills at your project or skills directory and add --all:
npx guardskills scan-local /path/to/project --all --preset strictGuardSkills discovers every SKILL.md, scans each skill independently, and gives you one combined
report. Add --json for machine-readable output or --receipt /path/to/receipts to create one
audit-compatible receipt per skill.
3. Scan a single existing skill
Point GuardSkills directly at the skill folder:
npx guardskills scan-local /path/to/skill --preset strictIf the parent directory contains multiple skills, select one by folder name:
npx guardskills scan-local /path/to/skills --skill skill-folder-name --preset strictBuilt-in GitHub providers install from the exact commit GuardSkills scanned. Ambiguous or unsupported sources fail closed instead of running unscanned.
Website | npm | GitHub | Security
Current repository release: 1.5.0 (unreleased)
Provider Coverage
GuardSkills is a scanner that supports the whole skill ecosystem. Whatever provider you use, the same guardskills prepend works - one security skill to learn, covering every provider.
| Provider | Your command becomes |
|---|---|
| skills.sh | npx guardskills skills add owner/repo --skill name |
| Playbooks | npx guardskills playbooks add skill owner/repo --skill name |
| OpenSkills | npx guardskills openskills install owner/repo name |
| SkillKit | npx guardskills skillkit install owner/repo [name] |
| OpenClaw (Git/ClawHub/local) | npx guardskills openclaw skills install git:owner/repo |
| localskills | npx guardskills localskills install [email protected] |
| any other npm provider | npx guardskills <provider> ... --skill <name> |
You never learn a new command. For built-in providers and adapters, guardskills goes right after npx. For any other npm-based skill installer, do the same - prepend guardskills and it scans the GitHub source before the provider runs. Browse-only catalogs (LobeHub, Agensi, AgentSkill.sh, explainx.ai, SkillsMP, OpenAgentSkill, NanoSkill, ClaudeSkills Hub) are discovery surfaces rather than install CLIs, but the skills they index are usually GitHub sources, so the prepend still guards the install once you have the owner/repo. Cursor Directory is out of scope (Cursor rules are not SKILL.md).
List every supported provider for your installed version:
npx guardskills providers
npx guardskills providers --jsonHow coverage is layered
| Tier | Providers | How it's guarded |
|---|---|---|
| Built-in | skills.sh, Playbooks, OpenSkills, SkillKit | Dedicated command with a pinned Git checkout (GitHub and GitLab) |
| Adapter | OpenClaw (Git/ClawHub/local), SkillKit skills.sh, localskills | Dedicated immutable-artifact resolver |
| Universal prepend | any other npm provider | npx guardskills <provider> ... --skill <name> scans the GitHub source first |
Recommended: Pinned Universal Install
Suppose a provider normally asks you to run:
npx another-installer add owner/repo --skill skill-nameRun it through GuardSkills and use {checkout} as the provider's source:
npx guardskills wrap \
--source owner/repo \
--skill skill-name \
--require-pinned-handoff \
-- npx another-installer add {checkout} --skill skill-nameGuardSkills will:
- Resolve
skill-namefromowner/repo. - Record the exact Git commit.
- Scan
SKILL.mdand related files. - Calculate a risk decision using ruleset
2026.2. - Apply the selected policy preset.
- Create or reuse a clean checkout for that exact commit.
- Replace
{checkout}with the verified local directory. - Start the installer without shell-string interpolation.
The provider receives the verified checkout instead of a moving repository branch.
Compatible unpinned mode
If an installer cannot accept a local directory, keep its original source argument:
npx guardskills wrap \
--source owner/repo \
--skill skill-name \
-- npx another-installer add owner/repo --skill skill-nameThis still provides scanning, policy gating, executable restrictions, source/skill matching, and direct argument-array execution. It cannot guarantee that the provider downloads the same commit that GuardSkills scanned.
Organizations can block unpinned wrapper commands by setting policy.requirePinnedHandoff to true.
Generic Provider Prepend Mode
For an npm-based provider that is not built into GuardSkills, prepend guardskills to the provider command:
npx guardskills another-installer add owner/repo --skill skill-nameGuardSkills interprets this as:
npx another-installer add owner/repo --skill skill-nameIt scans the one GitHub source before starting the provider. The source must be an owner/repo shorthand or GitHub URL. The skill must be supplied with --skill <name> or be the only unambiguous positional argument after the source.
If a provider command contains more than one GitHub-looking value, use --guardskills-source <owner/repo> to select the source. If its skill is not exposed as --skill, use --guardskills-skill <name>; the selected source and skill must still be present in the provider command.
GuardSkills-only options such as --preset, --yes, --dry-run, and --require-pinned-handoff are removed before the provider runs. With --require-pinned-handoff, the source argument is changed to {checkout} and the provider must accept a local checkout:
npx guardskills another-installer add owner/repo --skill skill-name --require-pinned-handoffIf source or skill detection is ambiguous, generic mode stops without running the provider. OpenClaw has a dedicated adapter for its documented source types:
npx guardskills openclaw skills install git:owner/repo@feature/security-fix
npx guardskills openclaw skills install @owner/slug --version 1.2.3
npx guardskills openclaw skills install ./path/to/skill --as custom-nameGit sources are resolved at the requested ref and handed to OpenClaw as the verified local checkout. ClawHub sources are scanned from the exact versioned registry archive before that version is handed off. Local sources are scanned and rechecked immediately before handoff, but remain subject to the local filesystem's time-of-check/time-of-use boundary. SkillKit and localskills have dedicated immutable-artifact adapters; other registry and directory providers still require a provider-specific resolver contract.
The test inventory at tests/fixtures/provider-install-commands.json keeps raw installation argv for the tracked providers. It also records providers that need a registry-specific resolver, without executing network installs in the test suite.
Built-in Provider Commands
For GitHub and GitLab sources, these commands automatically install from a persistent checkout verified against the scanned commit.
Git pinned installation supports GitHub and GitLab sources. Registry adapters use their own exact snapshot/version contracts. Other Git hosts, such as Bitbucket, are rejected before cloning because GuardSkills cannot yet create a verified pinned checkout for them.
GitLab sources
Use the full GitLab URL (shorthand stays GitHub-only to stay unambiguous):
npx guardskills add https://gitlab.com/group/repo --skill skill-name
npx guardskills wrap --source https://gitlab.com/group/repo --skill skill-name \
--require-pinned-handoff -- npx installer add {checkout}Nested groups (https://gitlab.com/group/sub/repo) are supported. Set GITLAB_TOKEN for private
repositories and GITLAB_API_URL for a self-hosted GitLab instance. The same commit-pinning,
scanning, receipts, and audit guarantees apply; the pinned checkout cache keys on the full
group/repository path.
Note: generic prepend mode (npx guardskills <provider> ...) still detects GitHub sources only.
For GitLab, use the dedicated add/skills/wrap commands shown above.
skills.sh
npx guardskills skills add vercel-labs/skills --skill find-skillsInteractive selection:
npx guardskills skills add planetscale/database-skillsLegacy alias:
npx guardskills add vercel-labs/skills --skill find-skillsPlaybooks
npx guardskills playbooks add skill anthropics/skills --skill frontend-designOpenSkills
npx guardskills openskills install anthropics/skills frontend-designInteractive selection:
npx guardskills openskills install anthropics/skillsSkillKit
npx guardskills skillkit install rohitg00/skillkit dev-toolsInstaller flow without a selected skill:
npx guardskills skillkit install rohitg00/skillkitSkillKit's skills.sh registry form is scanned from the immutable registry snapshot and handed off as the same content-addressed source SkillKit fetches. GuardSkills verifies the skills.sh snapshot SHA-256 before allowing the handoff, so the bytes SkillKit installs match the bytes GuardSkills scanned as long as the skills.sh identifier is immutable. SkillKit clones the repo-level skills.sh source, so pass the repository and select the skill:
npx guardskills skillkit install skills.sh/owner/repo --skill skillUse --skills-sh-registry <url> for a compatible registry mirror. If the rich skills.sh API requires
authentication, set SKILLS_SH_TOKEN; GuardSkills can use the public immutable download endpoint
when available. SkillKit re-fetches the snapshot from skills.sh itself, so this path is safest when
the skills.sh identifier is content-addressed and not republished between scan and install. The
three-segment skills.sh/owner/repo/skill form is also accepted and normalized to the repo-level
source SkillKit clones.
localskills
Versioned localskills text and package content is resolved, checked against its content/manifest metadata, scanned, and handed off at the exact resolved version:
npx guardskills localskills install [email protected]
npx guardskills @localskills/cli install [email protected]Use --localskills-api <url> for a compatible API mirror. Directory-only marketplaces without an
immutable artifact API remain unsupported.
OpenClaw sources
OpenClaw is supported through generic prepend mode for Git, ClawHub, and local directory sources:
npx guardskills openclaw skills install git:owner/repo
npx guardskills openclaw skills install @owner/slug --version 1.2.3
npx guardskills openclaw skills install ./path/to/skill --as custom-name
npx guardskills clawhub install @owner/slug --version 1.2.3The ClawHub adapters require an exact versioned archive. If the registry only returns a provider-owned GitHub handoff or another artifact that GuardSkills cannot resolve and scan, the install is stopped.
Built-in providers
List the provider integrations available in the installed GuardSkills version:
npx guardskills providersUse a built-in provider by placing it after guardskills, for example:
npx guardskills skills add vercel-labs/skills --skill find-skillsGuardSkills scans the source before handing it to the provider. guardskills providers lists the built-in adapters and the dedicated OpenClaw generic adapter; generic prepend mode covers additional npm-based providers when the source and skill can be identified safely.
GuardSkills fails closed when an unknown provider command does not contain a safely identifiable source and skill:
Generic provider mode: Could not identify one GitHub source.Cache lifecycle
Verified Git checkouts and registry artifacts are kept in the GuardSkills cache for repeatable rechecks:
npx guardskills cache list
npx guardskills cache list --json
npx guardskills cache prune --older-than-days 30 --dry-run
npx guardskills cache prune --older-than-days 30 --yesPruning only considers recognized GuardSkills entries and requires either --dry-run or explicit
--yes confirmation.
Provider smoke checks
Run the read-only resolver smoke against public immutable endpoints:
npm run test:providers:liveThe script does not install a skill. To probe published CLI help, set explicit package versions such
as GUARDSKILLS_SKILLKIT_PACKAGE=skillkit@<version> and
GUARDSKILLS_LOCALSKILLS_PACKAGE=@localskills/cli@<version> before running it. Full provider
installation smoke tests should use disposable workspaces and pinned provider versions.
What GuardSkills Detects
The deterministic scanner looks for behavior associated with:
- Credential and environment-variable access
- Secret exfiltration
- Download-and-execute commands
- Encoded PowerShell execution
- Shell process-substitution execution
- Dynamic and obfuscated code execution
- Persistence installation and Git-hook setup
- Disabled TLS/certificate verification
- Windows LOLBin remote execution
- Destructive filesystem operations
- Privilege escalation
- Suspicious multi-step attack chains
Markdown prose is not treated as executable content. GuardSkills scans fenced code, command-like inline snippets, command-style lines, and supported script/configuration files.
See RULES.md for the complete rule matrix and scoring model.
Policy Presets
| Preset | Thresholds | Gate behavior |
|---|---|---|
| balanced | Standard | Normal warning and override controls |
| strict | Lower risk thresholds | Normal warning and override controls |
| paranoid | Strict thresholds | Only SAFE can proceed |
Select a preset from the CLI:
npx guardskills add owner/repo --skill skill-name --preset strictOr configure it for the project:
{
"configVersion": 1,
"rulesetVersion": "2026.2",
"preset": "paranoid"
}--strict remains as a compatible shorthand for --preset strict.
Use policy.minimumPreset when users and CI must not downgrade an organization-required posture.
Risk Decisions
| Decision | Balanced/strict behavior | Paranoid behavior |
|---|---|---|
| SAFE | Allow | Allow |
| WARNING | Require --yes | Block |
| UNSAFE | Block unless --force is permitted | Block |
| CRITICAL | Always block | Always block |
| UNVERIFIABLE | Block unless --allow-unverifiable is permitted | Block |
SAFE means no known high-risk pattern was detected. It is not a guarantee that a skill is safe.
Exit codes
| Code | Meaning |
|---:|---|
| 0 | Allowed or completed successfully |
| 10 | Warning requires confirmation, or audit found allowed file drift that requires review |
| 20 | Blocked by the security gate, invalid receipt, unverifiable audit, or --fail-on-change |
| 30 | Resolver, installer, or internal runtime error |
Scan Receipts
Use --receipt <path> to write an auditable JSON record:
npx guardskills add owner/repo \
--skill skill-name \
--dry-run \
--receipt .guardskills/skill-name.receipt.jsonA receipt contains:
- Receipt and configuration schema versions
- Scanner ruleset version
- Source, skill, and commit SHA
- Policy preset and risk decision
- Every scanner finding (rule ID, severity, file) from the scan
- SHA-256 hash for every scanned file
- Installer summary when applicable
- Ed25519 signature when a local signing key exists
- Integrity checksum for the complete receipt payload
Verify that the receipt has not changed:
npx guardskills verify-receipt .guardskills/skill-name.receipt.jsonMachine-readable verification:
npx guardskills verify-receipt .guardskills/skill-name.receipt.json --jsonThe integrity checksum detects accidental changes, but on its own it is not a cryptographic signature: someone who can edit the receipt can also calculate a new checksum. Receipt signing, described next, closes that gap for verification on other machines.
Signing receipts
Generate a local Ed25519 signing key once:
npx guardskills keys generateAfter that, every receipt GuardSkills writes is signed automatically. The private key stays in
~/.guardskills/keys/default.key.pem; the matching public key is
~/.guardskills/keys/default.pub.pem. Each key has a short key ID (the first 16 hex characters
of the public key SHA-256), which receipts record so verifiers know which key signed them.
Share the public key with teammates or CI:
npx guardskills keys export-public > guardskills-receipt-key.pub.pemThen verify receipts elsewhere against the pinned key:
npx guardskills verify-receipt .guardskills/skill-name.receipt.json \
--require-signature \
--public-key guardskills-receipt-key.pub.pemVerification outcomes:
VALID— the receipt integrity checksum and the Ed25519 signature both pass.INVALID— the receipt content changed after signing, or it was signed by a different key than the pinned public key. Exits20.UNSIGNED— no signature is present. Fine unless--require-signatureis set.UNKNOWN_KEY— a signature exists but its key is not available locally. Pin the public key with--public-keyto verify;--require-signaturefails closed on this state.
Teams can enforce signing without extra flags in guardskills.config.json:
{
"receipt": {
"requireSignature": true,
"publicKeyPath": ".guardskills/receipt-key.pub.pem"
}
}With this policy, guardskills audit blocks unsigned, unknown-key, and invalid-signature
receipts. An invalid signature always blocks an audit, even without the policy.
Set GUARDSKILLS_NO_SIGN=1 to write unsigned receipts from a machine that has a key.
GUARDSKILLS_KEYS_DIR relocates the key directory (also useful in CI).
Threat model, stated plainly: a local keypair does not protect a machine the attacker fully
controls — they could re-sign receipts themselves. What it protects is verification elsewhere:
a CI job, a teammate, or an auditor holding the pinned public key can prove the receipt was
produced by the key holder and was not edited afterwards. Keep the private key out of repositories
and shares; rotate with keys generate --force if it leaks (receipts signed by the old key will
then report UNKNOWN_KEY or INVALID against the new key, which is the intended behavior).
Private-key file protection depends on the filesystem. On POSIX systems the key is written with
0600 permissions; on Windows, POSIX modes are not enforced, so protect
%USERPROFILE%\.guardskills\keys with folder-level access controls if other local accounts
must not read it.
Audit an installed skill
Compare one installed skill with the exact file hashes in its single-skill receipt, then rescan the captured local content with the current ruleset:
npx guardskills audit /path/to/installed-skill \
--receipt .guardskills/skill-name.receipt.jsonUse --json --ci for deterministic CI output, or --fail-on-change when any added, modified, or
deleted file must block the audit even if the current scan remains allowed:
npx guardskills audit /path/to/installed-skill \
--receipt .guardskills/skill-name.receipt.json \
--preset strict \
--json \
--ci \
--fail-on-changeAudit verifies the receipt checksum and validates every receipt path before use. It captures one bounded local snapshot, uses those same bytes for hashing and rescanning, rejects symbolic links and special filesystem entries, and never runs an installer or contacts the original provider. Receipts record the scanner findings from the baseline scan, so audit reports exactly which findings are new, resolved, and unchanged — not just the overall risk movement. Finding IDs are deterministic (rule ID plus file path), so a finding that moves to a different file is reported as resolved-plus-new rather than silently matched. Older receipts written before findings were stored still audit correctly; the comparison simply reports that the baseline has no finding IDs.
Check whether an upstream receipt is stale
audit checks the installed files against the receipt. It deliberately does not contact the
provider. To check whether the repository's default branch has moved past the commit recorded in
one or more receipts, run:
npx guardskills check-stale .guardskills/skill-name.receipt.json
npx guardskills check-stale .guardskills/receipts/ --json --ciThis performs a lightweight head check — it does not download or rescan the repository:
CURRENT(exit0): upstream still points at the receipt's commit.STALE(exit10): upstream moved; run a fresh scan before trusting the old baseline.SKIPPED: local or version/content-pinned registry receipt with no mutable Git branch to check.ERROR(exit20): the receipt is invalid, the signature policy fails, or the provider check could not be completed.
Use --fail-on-stale in CI when stale should fail the job with exit 20. GitHub and GitLab
receipts are supported, including nested GitLab groups. A staleness result is a notification, not
an install decision: the install path still performs its own fresh scan and pinned handoff.
Verified Checkout Cache
Pinned GitHub commits are stored under:
~/.guardskills/cache/checkouts/<owner>/<repo>/<commit-sha>Before every handoff, GuardSkills checks that:
HEADequals the scanned 40-character commit SHA.- The checkout has no tracked or untracked changes.
Set GUARDSKILLS_CACHE_DIR to select another cache root.
The persistent cache is intentional. Some providers may symlink local skills, so deleting the checkout immediately could break the installed skill.
Universal Wrapper Safety Contract
--sourceand--skillare required.- The installer command must be separated with
--. - Unpinned commands must contain the same source and skill that were scanned.
- Pinned commands must contain
{checkout}and the same skill. - The executable must be a bare command resolved from
PATH, not a direct file path. - GuardSkills passes the executable and arguments directly with
shell: false. - Common token, password, secret, credential, authentication, private-key, and API-key values are redacted in the displayed command.
CRITICALcannot be overridden.
Allowed executables by default:
npx, npm, pnpm, yarn, bunx, bunUse policy.allowedExecutables to replace this list.
GuardSkills verifies that {checkout} is replaced by the scanned commit directory. A third-party installer is still responsible for correctly honoring the source argument it receives.
Scan Without Installing
Use --dry-run:
npx guardskills add owner/repo --skill skill-name --dry-runPinned universal dry run:
npx guardskills wrap \
--source owner/repo \
--skill skill-name \
--require-pinned-handoff \
--dry-run \
-- npx another-installer add {checkout} --skill skill-nameDry-run validates the handoff contract but does not create the checkout or start the installer.
CI Usage
--ci performs a deterministic scan and gate without installer handoff. Add --json for machine-readable output:
npx guardskills add owner/repo --skill skill-name --ci --jsonWith a receipt:
npx guardskills add owner/repo \
--skill skill-name \
--ci \
--json \
--preset paranoid \
--receipt artifacts/skill-name.receipt.jsonUse the process exit code to decide whether the pipeline should continue.
Other Scan Sources
Local folder
npx guardskills scan-local /path/to/skillIf the folder contains multiple skills:
npx guardskills scan-local /path/to/skills --skill skill-folder-nameScan every skill under a project or skills directory in one run:
npx guardskills scan-local /path/to/project --all --preset strictBatch mode scans every discovered SKILL.md independently, reports per-skill findings and risk,
and returns exit code 20 when any result is blocked by the selected preset. Use --json for one
combined machine-readable report. With --all, --receipt <path> names a directory where
GuardSkills writes one numbered, single-skill receipt per result, keeping each receipt compatible
with guardskills audit:
npx guardskills scan-local /path/to/project \
--all \
--json \
--receipt .guardskills/receiptsscan-local --all is a current-content security audit: it does not require previous receipts.
guardskills audit, described above, is the separate drift-audit command that compares one
installed skill with an existing receipt.
The combined JSON report includes summary.scannedSkills, summary.blockedSkills,
summary.overallLevel, counts for every decision level, and a full skills array containing each
skill's path, files, decision, findings, unverifiable reasons, and optional receipt path.
Windows PowerShell example that saves the combined report and displays the GuardSkills exit code:
npx.cmd guardskills scan-local "C:\path\to\project" `
--all `
--preset strict `
--json `
--receipt "C:\path\to\project\.guardskills\receipts" `
> "C:\path\to\project\guardskills-report.json"
$LASTEXITCODEAn exit code of 0 means no discovered skill was blocked by the selected preset. Exit code 20
means at least one skill was UNSAFE, CRITICAL, or UNVERIFIABLE; paranoid mode also blocks
WARNING. The combined report is still written when the result is blocked, so every discovered
skill can be reviewed in the same run.
ClawHub
npx guardskills scan-clawhub owner/skill-slugOr:
npx guardskills scan-clawhub https://clawhub.ai/owner/skill-slugIf the registry does not provide GitHub metadata, GuardSkills falls back to scanning the downloadable archive.
Configuration
GuardSkills automatically loads guardskills.config.json from the current directory. Use --config <path> to load another file. Explicit CLI flags override configured defaults.
{
"configVersion": 1,
"rulesetVersion": "2026.2",
"preset": "balanced",
"defaults": {
"strict": false,
"ci": false,
"json": false,
"yes": false,
"dryRun": false,
"force": false,
"allowUnverifiable": false
},
"resolver": {
"githubTimeoutMs": 15000,
"githubRetries": 2,
"githubRetryBaseMs": 300,
"maxFileBytes": 250000,
"maxAuxFiles": 40,
"maxTotalFiles": 120
},
"policy": {
"allowForce": true,
"allowUnverifiableOverride": true,
"requirePinnedHandoff": false,
"minimumPreset": "balanced",
"allowedOwners": [],
"blockedOwners": [],
"allowedRepos": [],
"blockedRepos": [],
"allowedExecutables": ["npx", "npm", "pnpm", "yarn", "bunx", "bun"]
}
}Version compatibility
- Current config schema:
1 - Current scanner ruleset:
2026.2 - Unknown explicit versions fail closed with
INVALID_CONFIG. - Older configuration files that omit version fields remain compatible and resolve to the current versions.
- Scanner behavior changes require a new ruleset version and CHANGELOG.md entry.
Organization example
{
"configVersion": 1,
"rulesetVersion": "2026.2",
"preset": "paranoid",
"policy": {
"minimumPreset": "paranoid",
"allowForce": false,
"allowUnverifiableOverride": false,
"requirePinnedHandoff": true,
"allowedOwners": ["my-company"],
"allowedExecutables": ["npx"]
}
}This configuration allows only company-owned GitHub sources, prevents preset downgrades, blocks every non-safe result, disallows overrides, and requires universal installers to use the verified checkout.
Common Options
| Option | Purpose |
|---|---|
| --preset <name> | Select balanced, strict, or paranoid |
| --strict | Compatible shorthand for strict thresholds |
| --yes | Accept WARNING outside paranoid mode |
| --force | Accept UNSAFE when policy permits |
| --allow-unverifiable | Accept unverifiable content when policy permits |
| --dry-run | Scan and report without installing |
| --ci | Deterministic gate mode without installing |
| --json | Print machine-readable output |
| --receipt <path> | Write a versioned JSON scan receipt |
| --config <path> | Load a specific configuration file |
| --github-timeout-ms <ms> | Set the GitHub request timeout |
| --github-retries <count> | Set retry attempts for retryable errors |
| --github-retry-base-ms <ms> | Set the retry backoff base delay |
| --max-file-bytes <bytes> | Limit each scanned file's size |
| --max-aux-files <count> | Limit files from auxiliary directories |
| --max-total-files <count> | Limit the total resolved files |
| --clawhub-registry <url> | Use a compatible ClawHub registry endpoint for OpenClaw installs |
Local scan options:
| Option | Purpose |
|---|---|
| --skill <name> | Scan one named skill when the path contains multiple skills |
| --all | Discover and scan every skill under the provided directory |
| --receipt <path> with --all | Write one single-skill receipt per result into this directory |
Wrapper-only option:
| Option | Purpose |
|---|---|
| --require-pinned-handoff | Require {checkout} and the exact verified commit |
Audit-only option:
| Option | Purpose |
|---|---|
| --receipt <path> | Required single-skill baseline receipt |
| --fail-on-change | Block any added, modified, or deleted file |
Staleness-check options (check-stale):
| Option | Purpose |
|---|---|
| <receipts...> | One or more receipt files or directories |
| --fail-on-stale | Return exit 20 instead of 10 when upstream moved |
| --json | Print machine-readable results |
Receipt verification options (verify-receipt):
| Option | Purpose |
|---|---|
| --require-signature | Fail unless the receipt carries a valid signature |
| --public-key <path> | Verify the signature against a pinned public key PEM |
Scoring
GuardSkills combines:
- Hard-block guardrails for high-confidence critical behavior.
- A weighted risk score from
0to100, including attack-chain bonuses.
Balanced thresholds:
| Score | Decision |
|---:|---|
| 0-29 | SAFE |
| 30-59 | WARNING |
| 60-79 | UNSAFE |
| 80-100 | CRITICAL |
Strict and paranoid thresholds:
| Score | Decision |
|---:|---|
| 0-19 | SAFE |
| 20-39 | WARNING |
| 40-59 | UNSAFE |
| 60-100 | CRITICAL |
UNVERIFIABLE is separate and is not assigned a numeric score.
Adversarial Benchmark
The versioned corpus covers safe prose and malicious evasion patterns, including encoded PowerShell, process substitution, split-token commands, shell-string downloads, reverse-order credential uploads, persistence, disabled TLS verification, and Windows LOLBin execution.
npm run test:benchmark
npm run profile:scannerCorpus: tests/benchmarks/scanner-corpus.json
The scanner performance baseline and benchmark shape are documented in PERFORMANCE_BASELINE.md.
Every confirmed bypass or false positive should be added to the corpus before changing its rule.
Instructions for AI Agents
Before installing a skill, run it through GuardSkills.
Use a built-in GuardSkills provider command when available. For an npm-based provider not listed by `guardskills providers`, prepend `guardskills` when the command contains one GitHub source and one skill:
npx guardskills <provider> <provider arguments> --skill <skill>
For an installer that needs an explicit verified checkout, use the universal wrapper:
guardskills wrap --source <owner/repo> --skill <skill> --require-pinned-handoff -- <installer> {checkout} <skill arguments>
If SAFE, continue.
If WARNING, ask for confirmation unless paranoid mode is active.
If UNSAFE or UNVERIFIABLE, stop unless the user explicitly approves an allowed override.
If CRITICAL, always stop.
Never run the installer before GuardSkills.Development
Requirements:
- Node.js 20 or newer
- npm
- Git, for pinned GitHub handoffs
git clone https://github.com/felixondesk/guardskills.git
cd guardskills
npm install
npm run ci
npm run audit:prodUseful commands:
npm run typecheck
npm test
npm run test:benchmark
npm run profile:scanner
npm run buildSecurity Boundaries
- Static analysis can miss novel or deeply obfuscated behavior.
- Only resolved, supported text files are scanned.
- Executable and archive artifacts that cannot be inspected are reported as
UNVERIFIABLEand blocked by default. SAFEis not a guarantee.- A receipt checksum is not a digital signature.
- GuardSkills cannot prove that an arbitrary third-party executable honors its documented source argument.
- Registry, local-catalog, and directory providers require dedicated resolver contracts; generic prepend mode rejects unsupported providers instead of guessing their artifact. OpenClaw's Git, ClawHub, and local paths are the documented adapter exceptions above.
- Installed skills can behave differently when combined with other tools or instructions.
Report vulnerabilities privately using SECURITY.md.
Project Documents
Security review: SECURITY_REVIEW.md.
- CHANGELOG.md — release history and compatibility changes
- RULES.md — scanner rules and scoring details
- PROJECT_PLAN.md — architecture and roadmap
- PRODUCTION_READINESS.md — release checklist
- SECURITY.md — vulnerability reporting
The scoped release security review is documented in SECURITY_REVIEW.md.
License
GuardSkills is available under the MIT License.
Support
Support the project at buymeacoffee.com/felixondess.

