A Python toolset for building, validating, and packaging Cortex Platform content packs.
GoCortex Spellbook is a toolset for building, validating, and packaging Cortex Platform content packs. It solves the problem of creating compliant content packs without needing to understand the intricacies of the demisto-sdk and Cortex Platform schema requirements.
What it does:
- Creates new content pack instances with correct structure
- Generates XSIAM content templates (CorrelationRules, ParsingRules, ModelingRules)
- Validates content against Cortex Platform schemas using demisto-sdk
- Packages content into uploadable zip files
- Uploads content directly to Cortex Platform instances
Why it exists:
The demisto-sdk has many features and validation rules. Spellbook wraps it in a simpler interface and provides working templates that have been verified to upload successfully.
- Instance initialisation with optional GitHub Actions templates
- Multi-pack support within a single content instance
- Import of tenant-authored content via
summon correlationandsummon datamodel - Token-based template generation via
summon template(e.g.intel_retrohunt,parsing_modeling) - Validation using demisto-sdk, plus ruff linting and unit-test execution for Python content, matching the official demisto/content store setup
- Automated packaging into distributable zip files
- Direct upload to Cortex Platform instances
Choose your preferred method and follow the corresponding guide:
| Method | Best For | Guide |
|---|---|---|
| Docker (Local) | Most users. No Python setup required. | README_LOCAL-DOCKER.md |
| Source (Local) | Developers who want to modify Spellbook. | README_SOURCE.md |
| CI/CD | Automated builds triggered by Git tags. | README_CICD.md |
# Pull from GitHub Container Registry (preferred)
docker pull ghcr.io/gocortexio/spellbook:latest
# Or build locally from source
docker build -t gocortex-spellbook .
# Create a content instance
docker run --rm \
-v $(pwd):/content \
-v ~/.gitconfig:/home/spellbook/.gitconfig:ro \
ghcr.io/gocortexio/spellbook init my-content --author "My Organisation"
# Initialise Git (required for validation)
cd my-content
git init
git add .
git commit -s -m "Initial commit"
# Build all packs
docker run --rm \
-v $(pwd):/content \
-v ~/.gitconfig:/home/spellbook/.gitconfig:ro \
ghcr.io/gocortexio/spellbook build --allIf no packs are discovered, build --all and validate-all exit with a
grepable [ERROR] rather than reporting success, so a missing volume mount in
CI cannot produce a green pipeline and an empty release. SamplePack is excluded
from discovery; build it directly by name.
| Command | Description |
|---|---|
| init | Create a new content instance with starter pack |
| check-init | Check the initialised instance environment |
| list-instances | List all content instances |
| create | Create a new pack from template |
| list-packs | List all discovered packs |
| validate | Validate a pack using demisto-sdk |
| validate-all | Validate all packs |
| build | Build and package packs |
| upload | Upload a pack to Cortex Platform |
| version | Show version information for a pack |
| set-version | Set a specific version for a pack |
| bump-version | Automatically increment pack version |
| summon correlation | Import correlation rules from platform JSON export |
| summon datamodel | Import a data model rule from XIF text |
| summon template | Generate content from templates with token substitution |
| rename-content | Rename content items to match pack name (temporarily disabled) |
Create a new pack. By default create scaffolds a placeholder Author_image.png
(the GoCortexIO wordmark) at the pack root; use --author to set the pack
author, or --no-author-image to skip the image:
docker run --rm -v $(pwd):/content \
ghcr.io/gocortexio/spellbook create MyPack --author "My Organisation"
# skip the placeholder author image
docker run --rm -v $(pwd):/content \
ghcr.io/gocortexio/spellbook create MyPack --no-author-imageImport content authored in a Cortex Platform tenant. Both importers read from stdin, so pipe a file in or paste and press Ctrl+D:
# correlation rules from a JSON export
cat rules.json | docker run -i --rm -v $(pwd):/content \
ghcr.io/gocortexio/spellbook summon correlation MyPack
# a data model (XDM) rule from XIF (must start with [MODEL: dataset="..."])
cat rule.xif | docker run -i --rm -v $(pwd):/content \
ghcr.io/gocortexio/spellbook summon datamodel MyPacksummon datamodel writes the three-file modelling rule package (.yml, .xif,
_schema.json) into ModelingRules/, named after the dataset. Use --name to
override the name or --minimal-schema to emit only _raw_log instead of
inferring columns.
After running init, your instance has this structure:
my-content/
|-- .github/workflows/ # CI/CD pipelines (if enabled)
| |-- conjure.yml # Builds packs on version tags
| +-- validate.yml # Validates packs on PRs
|-- Packs/
| +-- SamplePack/ # Starter pack with examples
| |-- pack_metadata.json
| |-- README.md
| |-- Author_image.png # Author branding (auto-detected by demisto-sdk)
| |-- CorrelationRules/
| |-- ParsingRules/
| +-- ModelingRules/
|-- artifacts/ # Built zip files (gitignored)
|-- templates/ # Built-in templates copied during init (used by `summon template`)
+-- spellbook.yaml # Build configuration
Each instance has a spellbook.yaml file:
packs_directory: Packs
artifacts_directory: artifacts
defaults:
support: community
author: "Your Organisation"
marketplaces:
- xsoar
- marketplacev2
- platform
exclude_packs: []
validation:
enabled: true
allow_warnings: true
packaging:
create_zip: truePack versions are stored in pack_metadata.json within each pack. Use these commands to manage versions:
# Show current version
python spellbook.py version SamplePack
# Set a specific version
python spellbook.py set-version SamplePack 2.0.0
# Set version and create Git tag (stages all pack files)
python spellbook.py set-version SamplePack 2.0.0 --tag
# Increment revision (1.0.0 -> 1.0.1) - default behaviour
python spellbook.py bump-version SamplePack
# Increment revision explicitly (1.0.0 -> 1.0.1)
python spellbook.py bump-version SamplePack --revision
# Increment minor version (1.0.0 -> 1.1.0)
python spellbook.py bump-version SamplePack --minor
# Increment major version (1.0.0 -> 2.0.0)
python spellbook.py bump-version SamplePack --major
# Bump version and create Git tag for CI/CD
python spellbook.py bump-version SamplePack --tag
# Bump with custom commit message (for auto-closing issues)
python spellbook.py bump-version SamplePack --tag -m "Closes #123"The --tag flag stages all files in the pack directory, commits them, and creates a Git tag in the format PackName-v1.0.1. Use --message or -m to specify a custom commit message for CI/CD integration. Push with git push && git push origin PackName-v1.0.1 to trigger CI/CD builds.
This project is licensed under the GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later). See the LICENSE file for the full licence text.
- Cortex Platform Content Pack Format: https://xsoar.pan.dev/docs/packs/packs-format
- Demisto SDK Documentation: https://docs-cortex.paloaltonetworks.com/r/1/Demisto-SDK-Guide
