Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions DEV.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ Full schema and examples: [docs/adding-rules.md](docs/adding-rules.md)
**Command** — `commands/axguard-<name>.md`
Front matter `description:` becomes the agent help text. Keep steps concrete: run which CLI, which paths, what to output.

**Skill** — `skills/axguard-<name>/SKILL.md` (orchestration) or `skills/security/<domain>/<name>/SKILL.md` (research-backed domain skill)
YAML front matter: `name`, `description`. Description must say *when* to load the skill. Domain skills follow [docs/SKILL-SCHEMA.md](docs/SKILL-SCHEMA.md) and must appear in [skills/index.yaml](skills/index.yaml).
**Skill** — a top-level directory with a `SKILL.md`: `axguard-<name>/` (orchestration) or `<name>/` (research-backed domain skill)
YAML front matter: `name`, `description`. Description must say *when* to load the skill. Domain skills follow [docs/SKILL-SCHEMA.md](docs/SKILL-SCHEMA.md) and must appear in [skills-index.yaml](skills-index.yaml).

After adding files:

Expand Down
18 changes: 16 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -469,19 +469,33 @@ Same `--agent` and `--global` / `--project` options as `install.sh`. To remove t

## Project structure

Each skill is its own top-level directory containing a `SKILL.md`, so the whole
catalogue is visible from the repo root.

```text
AXguard/
├── axguard-audit/ # 8 orchestration skills, named axguard-*
├── axguard-cso/
├── …
├── sql-injection/ # 30 security domain skills
├── prompt-injection/
├── jwt-security/
├── …
├── skills-index.yaml # skill registry — name, domain, path
├── commands/ # 31 slash commands
├── cli/ # axguard CLI entrypoint
├── engines/ # scanners, diagnostics, adapters
├── rules/ # detection rule packs (*.json)
├── skills/ # agent skills (8 orchestration + 30 security)
├── commands/ # 31 slash commands
├── fixtures/ # deliberately vulnerable test apps
├── tests/ # 438 tests
├── scripts/ # skill validation
└── docs/ # developer and feature documentation
```

Domain grouping (`ai`, `application`, `discovery`, `identity`, `infrastructure`,
`operations`) lives in the `domain:` field of `skills-index.yaml` rather than in
the directory tree.

## Docs

| Area | Docs |
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Reference skill for **pre-ship static review**. Distills web and agent vuln clas

## Domain skills (deep reasoning)

For class depth beyond this digest, load research-backed skills under `skills/security/` (registry: `skills/index.yaml`):
For class depth beyond this digest, load the research-backed domain skills (registry: `skills-index.yaml`):

| Need | Skill |
|------|--------|
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ This skill does **not** implement security analysis. It teaches when to use AXGu

**Primary interface:** AXGuard MCP tools (prefer over ad-hoc scans).
**Fallback:** if MCP is unavailable, `axguard scan .` / `axguard audit .` — then still apply the same verdict rules below.
Tool names: `references/mcp-tools.md` · catalog: [docs/mcp-tools.md](../../docs/mcp-tools.md).
Tool names: `references/mcp-tools.md` · catalog: [docs/mcp-tools.md](../docs/mcp-tools.md).

## When to call AXGuard

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# MCP tools (names only)

Prefer these over inventing scanner chains. Full contracts: [docs/mcp-tools.md](../../../docs/mcp-tools.md).
Prefer these over inventing scanner chains. Full contracts: [docs/mcp-tools.md](../../docs/mcp-tools.md).

| Tool | Role |
|------|------|
Expand Down
File renamed without changes.
File renamed without changes.
8 changes: 4 additions & 4 deletions docs/SECURITY-KNOWLEDGE-INVENTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Accessed: 2026-09-15
Repo: https://github.com/Awarexone/AXguard
Status: **30 core domain skills landed** (plus 7 orchestration skills)

## Orchestration skills (`skills/axguard-*`)
## Orchestration skills (`axguard-*`)

| Skill | Role |
|---|---|
Expand All @@ -16,7 +16,7 @@ Status: **30 core domain skills landed** (plus 7 orchestration skills)
| `axguard-report` | Report authoring |
| `axguard-knowledge` | Vuln-class digest → links to domain skills |

## Domain skills (`skills/security/`) — 30 core
## Domain skills — 30 core

### Discovery (3)
`threat-modeling`, `attack-surface-mapping`, `security-architecture-review`
Expand All @@ -36,7 +36,7 @@ Status: **30 core domain skills landed** (plus 7 orchestration skills)
### Operations (2)
`security-triage`, `security-remediation`

Registry: [`skills/index.yaml`](../skills/index.yaml)
Registry: [`skills-index.yaml`](../skills-index.yaml)
Schema: [`docs/SKILL-SCHEMA.md`](SKILL-SCHEMA.md)
Validator: `python scripts/validate_skills.py`

Expand All @@ -57,7 +57,7 @@ Validator: `python scripts/validate_skills.py`

## Design decisions

1. Keep `axguard-*` orchestration; add domain depth under `skills/security/`.
1. Keep `axguard-*` orchestration; add domain depth as new top-level skills.
2. Never invent framework IDs; leave arrays empty when UNVERIFIED (e.g. LLM Top 10 frontmatter).
3. Defensive / authorized pre-ship use only.
4. Install flattens domain skills by basename via `install_security_skills` in `install.sh`.
Expand Down
2 changes: 1 addition & 1 deletion docs/SKILL-SCHEMA.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Skill frontmatter schema (AXGuard)

Every domain skill under `skills/security/` SHOULD use this YAML frontmatter.
Every domain skill — any top-level skill directory not named `axguard-*` — SHOULD use this YAML frontmatter.

```yaml
---
Expand Down
2 changes: 1 addition & 1 deletion docs/data/research/ai-security-corpus.md
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,6 @@ Keep AI rows in a separate corpus file until schema union is implemented; link w

- Attack-path fixture: `fixtures/attack_paths_corpus/ai_mcp_tool_abuse.py`
- Rules: `rules/agent.json`, `rules/advanced.json`
- Skills: `skills/security/ai/prompt-injection/SKILL.md`, `ai-agent-security/SKILL.md`, `mcp-security/SKILL.md`
- Skills: `prompt-injection/SKILL.md`, `ai-agent-security/SKILL.md`, `mcp-security/SKILL.md`
- FP reason alignment: `docs/data/research/false-positive-corpus.md`
- Architecture: `docs/architecture.md` (Phase 4 adversary, Phase 6 attack graph)
4 changes: 2 additions & 2 deletions docs/mcp-skill-roadmap.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# AXGuard MCP → Agent Skill Roadmap

**Date:** 2026-09-17
**Status:** Skill implemented — `skills/axguard-security/` (behavioral wrapper over MCP; no duplicated engines).
**Status:** Skill implemented — `axguard-security/` (behavioral wrapper over MCP; no duplicated engines).
**Related:** [mcp-research.md](./mcp-research.md), [mcp-threat-model.md](./mcp-threat-model.md), [mcp.md](./mcp.md)

---
Expand Down Expand Up @@ -29,7 +29,7 @@ name: axguard-security
description: Analyze code for security vulnerabilities, investigate findings, verify fixes, and assess security risk before deployment.
```

Path: `skills/axguard-security/SKILL.md`
Path: `axguard-security/SKILL.md`

The skill instructs:

Expand Down
2 changes: 1 addition & 1 deletion docs/mcp-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ Does **not** modify source, execute exploits, or treat predictive risk as a veri

Verdicts remain AXGuard-owned (`VERIFIED` · `LIKELY` · `UNVERIFIED` · `FALSE_POSITIVE` · `REQUIRES_REVIEW`). Agents must not “declare vulnerable” without this evidence path.

**Agent Skill:** prefer MCP tools via `skills/axguard-security` rather than inventing scan chains.
**Agent Skill:** prefer MCP tools via `axguard-security` rather than inventing scan chains.

---

Expand Down
2 changes: 1 addition & 1 deletion docs/mcp.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ The behavioral layer above MCP (no duplicated scanners):
```text
AI Coding Agent
↓
AXGuard Agent Skill (`skills/axguard-security`)
AXGuard Agent Skill (`axguard-security`)
↓
AXGuard MCP
↓
Expand Down
4 changes: 2 additions & 2 deletions docs/plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ Manifest: `.claude-plugin/plugin.json`
## Layout expectations

```text
skills/axguard-audit/SKILL.md
skills/axguard-cso/SKILL.md
axguard-audit/SKILL.md
axguard-cso/SKILL.md
…
commands/axguard-audit.md
commands/axguard-scan.md
Expand Down
File renamed without changes.
40 changes: 8 additions & 32 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,26 +35,7 @@ done
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$ROOT"

copy_tree_items() {
local src_glob="$1"
local dest_dir="$2"
local label="$3"
mkdir -p "$dest_dir"
local item name
for item in $src_glob; do
[ -e "$item" ] || continue
# Skip the security/ namespace directory itself; nested skills installed separately
[ "$(basename "$item")" = "security" ] && continue
[ "$(basename "$item")" = "index.yaml" ] && continue
name="$(basename "$item")"
rm -rf "$dest_dir/$name"
mkdir -p "$dest_dir/$name"
cp -R "$item"/. "$dest_dir/$name/"
echo "installed $label: $name → $dest_dir/$name"
done
}

install_security_skills() {
install_skills() {
local dest_dir="$1"
mkdir -p "$dest_dir"
local skill_md skill_dir name
Expand All @@ -64,8 +45,8 @@ install_security_skills() {
rm -rf "$dest_dir/$name"
mkdir -p "$dest_dir/$name"
cp -R "$skill_dir"/. "$dest_dir/$name/"
echo "installed security skill: $name → $dest_dir/$name"
done < <(find skills/security -type f -name SKILL.md 2>/dev/null | sort)
echo "installed skill: $name → $dest_dir/$name"
done < <(find . -mindepth 2 -maxdepth 2 -type f -name SKILL.md 2>/dev/null | sort)
}

copy_files() {
Expand All @@ -86,17 +67,15 @@ install_claude() {
local root
if [ "$SCOPE" = "project" ]; then root=".claude"; else root="$HOME/.claude"; fi
echo "AXguard → Claude Code ($SCOPE)"
copy_tree_items "skills/*" "$root/skills" "skill"
install_security_skills "$root/skills"
install_skills "$root/skills"
copy_files "commands/*.md" "$root/commands" "command"
}

install_cursor() {
local root
if [ "$SCOPE" = "project" ]; then root=".cursor"; else root="$HOME/.cursor"; fi
echo "AXguard → Cursor ($SCOPE)"
copy_tree_items "skills/*" "$root/skills" "skill"
install_security_skills "$root/skills"
install_skills "$root/skills"
# Cursor also picks up project rules; commands map to skills for slash-style prompts
mkdir -p "$root/commands"
copy_files "commands/*.md" "$root/commands" "command"
Expand All @@ -110,26 +89,23 @@ install_opencode() {
root="${OPENCODE_CONFIG_DIR:-$HOME/.config/opencode}"
fi
echo "AXguard → OpenCode ($SCOPE)"
copy_tree_items "skills/*" "$root/skills" "skill"
install_security_skills "$root/skills"
install_skills "$root/skills"
copy_files "commands/*.md" "$root/commands" "command"
}

install_codex() {
local root
if [ "$SCOPE" = "project" ]; then root=".codex"; else root="${CODEX_HOME:-$HOME/.codex}"; fi
echo "AXguard → Codex ($SCOPE)"
copy_tree_items "skills/*" "$root/skills" "skill"
install_security_skills "$root/skills"
install_skills "$root/skills"
copy_files "commands/*.md" "$root/commands" "command"
}

install_agents() {
local root
if [ "$SCOPE" = "project" ]; then root=".agents"; else root="$HOME/.agents"; fi
echo "AXguard → shared Agent Skills ($SCOPE)"
copy_tree_items "skills/*" "$root/skills" "skill"
install_security_skills "$root/skills"
install_skills "$root/skills"
}

echo ""
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion references/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ Public Sources → Collection → Normalization → Dedup → Classification
→ Validation → Framework Mapping → Skill Generation → Review → SKILL.md
```

Skill registry: [`../skills/index.yaml`](../skills/index.yaml)
Skill registry: [`../skills-index.yaml`](../skills-index.yaml)
Schema: [`../docs/SKILL-SCHEMA.md`](../docs/SKILL-SCHEMA.md)
Validator: `python scripts/validate_skills.py`
29 changes: 17 additions & 12 deletions scripts/validate_skills.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,21 @@
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
SKILL_ROOTS = [ROOT / "skills"]
INDEX = ROOT / "skills" / "index.yaml"
INDEX = ROOT / "skills-index.yaml"

# Skills live in top-level directories. Orchestration skills are named
# axguard-*; everything else is a security domain skill, which carries
# stricter frontmatter and section requirements.
ORCHESTRATION_PREFIX = "axguard-"


def iter_skills():
for base in SKILL_ROOTS:
if not base.exists():
continue
for path in sorted(base.rglob("SKILL.md")):
yield path
for path in sorted(ROOT.glob("*/SKILL.md")):
yield path


def is_domain_skill(path) -> bool:
return not path.parent.name.startswith(ORCHESTRATION_PREFIX)


def parse_frontmatter(text: str) -> tuple[dict[str, str], str]:
Expand Down Expand Up @@ -60,7 +65,7 @@ def main() -> int:
names[name] = path
if not meta.get("description"):
errors.append(f"{path}: missing description")
if "skills/security/" in str(path).replace("\\", "/"):
if is_domain_skill(path):
for key in ("version", "domain", "license"):
if key not in meta:
errors.append(f"{path}: security skill missing '{key}'")
Expand All @@ -76,16 +81,16 @@ def main() -> int:
for rel in parse_index_paths(index_text):
p = ROOT / rel
if not p.is_file():
errors.append(f"skills/index.yaml: missing path {rel}")
errors.append(f"skills-index.yaml: missing path {rel}")
# Every security domain skill should be registered
for path in iter_skills():
if "skills/security/" not in str(path).replace("\\", "/"):
if not is_domain_skill(path):
continue
rel = str(path.relative_to(ROOT)).replace("\\", "/")
if rel not in index_text:
errors.append(f"skills/index.yaml: unlisted security skill {rel}")
errors.append(f"skills-index.yaml: unlisted security skill {rel}")
else:
errors.append("skills/index.yaml missing")
errors.append("skills-index.yaml missing")

print(f"skills scanned: {count}")
if errors:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@ Operational skill — inherit CWE/OWASP IDs from the finding’s domain skill wh

## References

- AXGuard `skills/axguard-remediate/SKILL.md`
- AXGuard `axguard-remediate/SKILL.md`
- https://owasp.org/www-project-cheat-sheets/ (methodology; no large verbatim copies)
- Domain skill Remediation sections in `skills/security/`
- Remediation sections in the domain skills

## Research Provenance

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ Operational skill — no primary CWE/OWASP entry. Findings retain the framework

## References

- AXGuard `skills/axguard-triage/SKILL.md`
- AXGuard `axguard-triage/SKILL.md`
- https://owasp.org/Top10/ (severity context only)

## Research Provenance
Expand Down
File renamed without changes.
Loading