Skip to content

Commit e3acc02

Browse files
committed
Initial import of Falcon Fusion Skills
AI coding assistant skills for building CrowdStrike Falcon Fusion workflows. Six skills coordinated by an orchestrator: workflows (lifecycle routing), authoring (action discovery, YAML, validation), deployment (import, release), execution (trigger, monitor, debug), lookup-files (Next-Gen SIEM lookup management), and setup (credential configuration). Includes live action discovery against the Fusion API, structural validation against the Charlotte JSON schema, 19 Content Library workflow examples in YAML, HTTP Action / Event Query / Python Script action support, and hook scripts for intent routing and cross-plugin advisories. Works with Claude Code, Codex, Gemini, and Copilot as a plugin or as a tool-agnostic markdown reference. Builds on the MIT-licensed security-skills community project.
1 parent 6cd1e05 commit e3acc02

101 files changed

Lines changed: 17836 additions & 2 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude-plugin/marketplace.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "fusion-marketplace",
3+
"description": "AI coding assistant skills for building CrowdStrike Falcon Fusion workflows",
4+
"owner": {
5+
"name": "CrowdStrike"
6+
},
7+
"plugins": [
8+
{
9+
"name": "crowdstrike-falcon-fusion",
10+
"source": "./",
11+
"description": "CrowdStrike Falcon Fusion SOAR skills for authoring, deploying, and executing Fusion workflows. Includes live action discovery, YAML authoring with schema validation, workflow import and release, execution monitoring, and Falcon Next-Gen SIEM lookup files.",
12+
"version": "1.0.0",
13+
"author": {
14+
"name": "CrowdStrike"
15+
},
16+
"license": "MIT",
17+
"keywords": [
18+
"crowdstrike",
19+
"falcon",
20+
"fusion",
21+
"soar",
22+
"workflow",
23+
"automation",
24+
"security"
25+
]
26+
}
27+
]
28+
}

.claude-plugin/plugin.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"name": "crowdstrike-falcon-fusion",
3+
"description": "CrowdStrike Falcon Fusion SOAR skills for authoring, deploying, and executing Fusion workflows. Includes live action discovery, YAML authoring with schema validation, workflow import and release, execution monitoring, and Falcon Next-Gen SIEM lookup files.",
4+
"version": "1.0.0",
5+
"author": {
6+
"name": "CrowdStrike"
7+
},
8+
"license": "MIT",
9+
"keywords": [
10+
"crowdstrike",
11+
"falcon",
12+
"fusion",
13+
"soar",
14+
"workflow",
15+
"automation",
16+
"security"
17+
]
18+
}

.github/copilot-instructions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
See [AGENTS.md](../AGENTS.md) for AI coding assistant instructions for this repository.

.github/dependabot.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "github-actions"
4+
directory: "/"
5+
schedule:
6+
interval: "weekly"
7+
day: "monday"
8+
time: "14:00"
9+
timezone: "UTC"
10+
ignore:
11+
- dependency-name: "actions/checkout"
12+
versions: [">=6.0.3"]
13+
- dependency-name: "actions/setup-node"
14+
versions: [">=6.3.0"]
15+
- dependency-name: "actions/setup-python"
16+
versions: [">=6.3.0"]

.github/workflows/main.yml

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
name: Fusion Skills CI
2+
3+
on:
4+
pull_request:
5+
branches: [main]
6+
push:
7+
branches: [main]
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
shellcheck:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v4
17+
- name: Install ShellCheck
18+
run: command -v shellcheck || { sudo apt-get update -qq && sudo apt-get install -y -qq shellcheck; }
19+
- name: Run ShellCheck
20+
run: |
21+
shellcheck hooks/*.sh bin/*.sh
22+
shellcheck --severity=error *.sh
23+
24+
test-hooks:
25+
runs-on: ubuntu-latest
26+
steps:
27+
- uses: actions/checkout@v4
28+
- uses: actions/setup-python@v5
29+
with:
30+
python-version: "3.10"
31+
- name: Install dependencies
32+
run: |
33+
python -m venv .venv
34+
source .venv/bin/activate
35+
pip install --upgrade pip
36+
pip install pyyaml crowdstrike-falconpy
37+
- name: Run hook tests
38+
run: |
39+
source .venv/bin/activate
40+
./test-hooks.sh
41+
- name: Run structural validation
42+
run: |
43+
source .venv/bin/activate
44+
./test-validate.sh
45+
46+
pylint:
47+
runs-on: ubuntu-latest
48+
steps:
49+
- uses: actions/checkout@v4
50+
- uses: actions/setup-python@v5
51+
with:
52+
python-version: "3.10"
53+
- name: Install dependencies
54+
run: |
55+
python -m venv .venv
56+
source .venv/bin/activate
57+
pip install --upgrade pip
58+
pip install pylint crowdstrike-falconpy pyyaml tomli
59+
- name: Run pylint (fail-under=10 enforced by .pylintrc)
60+
run: |
61+
source .venv/bin/activate
62+
pylint --rcfile=.pylintrc \
63+
common/scripts/*.py \
64+
skills/authoring/scripts/*.py \
65+
skills/deployment/scripts/*.py \
66+
skills/execution/scripts/*.py \
67+
skills/lookup-files/scripts/*.py \
68+
bin/*.py
69+
70+
validate:
71+
runs-on: ubuntu-latest
72+
steps:
73+
- uses: actions/checkout@v4
74+
- uses: actions/setup-python@v5
75+
with:
76+
python-version: "3.10"
77+
- name: Validate JSON files
78+
run: |
79+
for f in \
80+
hooks/hooks.json \
81+
.claude-plugin/plugin.json \
82+
.claude-plugin/marketplace.json \
83+
test-result-schema.json \
84+
verify-result-schema.json; do
85+
echo "Validating $f"
86+
python -m json.tool "$f" > /dev/null
87+
done
88+
- name: Validate SKILL.md frontmatter
89+
run: |
90+
fail=0
91+
for skill in skills/*/SKILL.md; do
92+
for field in name description version; do
93+
if ! head -20 "$skill" | grep -q "^${field}:"; then
94+
echo "FAIL: $skill missing '$field' in frontmatter"
95+
fail=1
96+
fi
97+
done
98+
done
99+
exit $fail
100+
- name: Validate skill size budgets
101+
run: |
102+
fail=0
103+
MAX_TOKENS=5500
104+
WARN_TOKENS=4500
105+
DESC_BUDGET=8000
106+
total_desc=0
107+
for skill in skills/*/SKILL.md; do
108+
words=$(wc -w < "$skill")
109+
tokens=$(( words * 4 / 3 ))
110+
if [ "$tokens" -gt "$MAX_TOKENS" ]; then
111+
echo "FAIL: $skill is ~${tokens} tokens (max $MAX_TOKENS)"
112+
fail=1
113+
elif [ "$tokens" -gt "$WARN_TOKENS" ]; then
114+
echo "WARN: $skill is ~${tokens} tokens (approaching $MAX_TOKENS limit)"
115+
else
116+
echo "OK: $skill ~${tokens} tokens"
117+
fi
118+
desc_len=$(python -c "
119+
import yaml
120+
with open('$skill') as f:
121+
parts = f.read().split('---')
122+
if len(parts) >= 3:
123+
fm = yaml.safe_load(parts[1])
124+
print(len(fm.get('description', '')))
125+
else:
126+
print(0)
127+
")
128+
total_desc=$(( total_desc + desc_len ))
129+
done
130+
echo "Total description chars: $total_desc / $DESC_BUDGET"
131+
if [ "$total_desc" -gt "$DESC_BUDGET" ]; then
132+
echo "FAIL: total description chars ($total_desc) exceeds budget ($DESC_BUDGET)"
133+
fail=1
134+
fi
135+
exit $fail
136+
- name: Validate hook scripts are executable
137+
run: |
138+
fail=0
139+
for script in hooks/*.sh; do
140+
[ -x "$script" ] || { echo "FAIL: $script is not executable"; fail=1; }
141+
done
142+
exit $fail
143+
- name: Validate Python scripts are syntactically valid
144+
run: |
145+
fail=0
146+
while IFS= read -r py; do
147+
if ! python -c "import ast, sys; ast.parse(open(sys.argv[1], encoding='utf-8').read())" "$py"; then
148+
echo "FAIL: $py has a syntax error"
149+
fail=1
150+
fi
151+
done < <(find . -name '*.py' -not -path '*/__pycache__/*')
152+
exit $fail
153+
- name: Validate no PLACEHOLDER values in example workflows
154+
run: |
155+
fail=0
156+
while IFS= read -r wf; do
157+
if grep -qE 'PLACEHOLDER_[A-Z_]+' "$wf"; then
158+
echo "FAIL: $wf contains PLACEHOLDER_* values (action IDs must be resolved)"
159+
grep -nE 'PLACEHOLDER_[A-Z_]+' "$wf"
160+
fail=1
161+
fi
162+
done < <(find skills/authoring/examples -name '*.yaml' -o -name '*.yml')
163+
[ $fail -eq 0 ] && echo "No PLACEHOLDER_* values in example workflows"
164+
exit $fail
165+
- name: Validate version consistency
166+
run: |
167+
fail=0
168+
plugin_version=$(jq -r '.version' .claude-plugin/plugin.json)
169+
marketplace_version=$(jq -r '.plugins[0].version' .claude-plugin/marketplace.json)
170+
echo "plugin.json version: $plugin_version"
171+
echo "marketplace.json plugins[0].version: $marketplace_version"
172+
173+
# marketplace.json must match plugin.json
174+
if [ "$marketplace_version" != "$plugin_version" ]; then
175+
echo "FAIL: marketplace.json plugins[0].version '$marketplace_version' != plugin.json '$plugin_version'"
176+
fail=1
177+
fi
178+
179+
# All SKILL.md versions must match plugin.json
180+
for skill in skills/*/SKILL.md; do
181+
skill_version=$(sed -n 's/^version: *//p' "$skill")
182+
if [ "$skill_version" != "$plugin_version" ]; then
183+
echo "FAIL: $skill version '$skill_version' != plugin.json '$plugin_version'"
184+
fail=1
185+
fi
186+
done
187+
188+
# CHANGELOG must have an entry for this version
189+
if ! grep -q "## \[${plugin_version}\]" CHANGELOG.md; then
190+
echo "FAIL: CHANGELOG.md missing entry for version $plugin_version"
191+
fail=1
192+
fi
193+
194+
[ $fail -eq 0 ] && echo "All versions consistent: $plugin_version"
195+
exit $fail
196+
197+
markdownlint:
198+
runs-on: ubuntu-latest
199+
steps:
200+
- uses: actions/checkout@v4
201+
- uses: actions/setup-node@v4
202+
with:
203+
node-version: 22
204+
- name: Run markdownlint
205+
run: npx markdownlint-cli2 "**/*.md"

.gitignore

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Local action discovery cache (per-user, never shipped)
2+
.action_cache.json
3+
4+
# Python
5+
__pycache__/
6+
*.pyc
7+
8+
# Credentials
9+
.env
10+
.idea/
11+
.playwright-mcp/
12+
working/

.markdownlint.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"MD007": false,
3+
"MD009": false,
4+
"MD012": false,
5+
"MD013": false,
6+
"MD022": false,
7+
"MD024": { "siblings_only": true },
8+
"MD028": false,
9+
"MD031": false,
10+
"MD032": false,
11+
"MD033": false,
12+
"MD034": false,
13+
"MD036": false,
14+
"MD040": false,
15+
"MD041": false,
16+
"MD045": false,
17+
"MD051": false,
18+
"MD059": false,
19+
"MD060": false
20+
}

0 commit comments

Comments
 (0)