Skip to content

KustoKing/ContentOps

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

ContentOps powered by SecM8

Security content lifecycle management for Microsoft Sentinel and Microsoft Defender XDR.

License: Apache-2.0 Python: 3.12+ Status: pre-1.0 Code of Conduct MITRE ATT&CK coverage Detection inventory

A Python CLI plus GitHub Actions pipeline that manages the full lifecycle of detection rules across Microsoft Sentinel and Microsoft Defender XDR from a single repo, single tenant, with Git as the source of truth. Analysts author lean YAML; the pipeline validates, lints, plans, applies via ARM REST + Graph beta, watches for portal-side drift, and writes a hash-chained audit trail of every write.

CLI. contentops is the only entry point after pip install -e .. Both contentops <cmd> and python -m contentops <cmd> work.

ContentOps logo
   _____            _             _    ____            
  / ____|          | |           | |  / __ \           
 | |     ___  _ __ | |_ ___ _ __ | |_| |  | |_ __  ___ 
 | |    / _ \| '_ \| __/ _ \ '_ \| __| |  | | '_ \/ __|
 | |___| (_) | | | | ||  __/ | | | |_| |__| | |_) \__ \
  \_____\___/|_| |_|\__\___|_| |_|\__|\____/| .__/|___/
                                            | |        
                                            |_|        

Get started

One linear path. ~30 minutes from clone to first scaffolded rule.

# 1. Clone + install
git clone https://github.com/KustoKing/ContentOps.git
cd ContentOps
python -m venv .venv
# Activate (pick your shell):
.\.venv\Scripts\Activate.ps1       # Windows PowerShell
# source .venv/bin/activate         # macOS / Linux bash
python -m pip install -r requirements.txt
python -m pip install -e .

# 2. Wire credentials. The three adopter personas + locked-down
#    Windows recipes are in docs/quickstart.md; the shortest path
#    on a personal laptop is `az login` (no .env needed).
copy config\tenant.yml.example config\tenant.yml    # tenant + workspace IDs (gitignored)

# 3. Pre-flight + first rule
python -m contentops doctor                          # green = ready (L1 install only)
python -m contentops new sentinel_analytic my-first-rule
notepad detections\sentinel_analytic\my-first-rule.yml
python -m contentops lint --strict                   # PR-time gate, locally
python -m contentops plan --role prod                # read-only diff vs the tenant

python -m pip and python -m contentops are the recommended invocations — they work on locked-down corporate Windows machines where Device Guard / WDAC blocks pip-installed .exe shims. The bare contentops console script also works after pip install -e ..

When that works, read docs/OPERATOR_GUIDE.md for the daily flow and the when-things-break decision tree.

Verify your install

One command answers "is everything wired correctly?" — read-only, safe against production tenants:

contentops conformance                  # full layered report (L1–L7)
contentops conformance --scope L1,L2    # local install + tenant config only
contentops conformance --format json    # machine-readable sidecar

Layers — each printed with PASS / FAIL / SKIP and an actionable remediation hint on failure:

Layer Verifies
L1 Local install: Python, package import, envelope parse, audit chain
L2 Tenant config: tenant.yml parses, GUIDs aren't placeholders, auth env set
L3 OIDC / token acquisition (ARM + Graph) via DefaultAzureCredential
L4 Microsoft Graph permissions on the App Registration (app role assignments + federated credential subjects)
L5 Azure RBAC: every configured Sentinel workspace exists, RG exists, Sentinel onboarded
L6 Functional reach: list alertRules, list detectionRules, KQL print 1
L7 GitHub repo: required secrets exist, branch protection requires expected checks (skipped without gh CLI)

The full reference, including how to override the expected-permissions list per-fork via .contentops-conformance.yml, lives in docs/operations/deployment-conformance.md.

For a separate non-destructive end-to-end CLI matrix (every leaf command exercised against a tmpdir sandbox, three modes: offline / mocked / live), see docs/operations/e2e-capability-tests.md.

Mirror into a private GitHub Enterprise repo

Enterprise adopters typically host the code in their own GitHub Enterprise (GHEC or GHES) org rather than working directly against the public mirror. The recommended topology is:

  • origin → your private GHE repo (where you push, run CI, branch-protect)
  • upstreamKustoKing/ContentOps (the nightly-rebuilt public mirror)

You only do the import once. After that you periodically fetch from upstream and merge into your origin/main.

Windows PowerShell

# 1. Sign in to your GitHub Enterprise host
gh auth login --hostname github.<your-ghe>
gh auth status --hostname github.<your-ghe>

# Optional: clear stale cached Git credentials if pushes 401/403.
# When prompted enter `protocol=https`, `host=github.<your-ghe>`,
# then press Enter twice.
# git credential-manager erase

# 2. Clone the public mirror into a working directory
cd C:\work
git clone https://github.com/KustoKing/ContentOps.git contentops
cd contentops

# 3. Re-wire remotes: public becomes upstream, private GHE becomes origin
git remote rename origin upstream
git remote add origin https://github.<your-ghe>/<org>/<repo>.git
git remote -v

# 4. Push main + tags to your private GHE repo
git branch --show-current                          # confirm branch name
git push -u origin main                            # or `master` if that's your default
git push origin --tags

Linux / macOS bash

# 1. Sign in to your GitHub Enterprise host
gh auth login --hostname github.<your-ghe>
gh auth status --hostname github.<your-ghe>

# If cached creds misbehave, inspect `git config --global credential.helper`
# and clear the relevant entry (osxkeychain, libsecret, store, etc.).

# 2. Clone the public mirror into a working directory
mkdir -p ~/work && cd ~/work
git clone https://github.com/KustoKing/ContentOps.git contentops
cd contentops

# 3. Re-wire remotes: public becomes upstream, private GHE becomes origin
git remote rename origin upstream
git remote add origin https://github.<your-ghe>/<org>/<repo>.git
git remote -v

# 4. Push main + tags to your private GHE repo
git branch --show-current                          # confirm branch name
git push -u origin main                            # or `master` if that's your default
git push origin --tags

Pulling updates from upstream

The public mirror is rebuilt nightly, so a weekly merge is usually plenty. Same three commands on both shells:

git fetch upstream
git merge upstream/main
git push origin main

See docs/quickstart.md for the mirror's sync cadence, and docs/quickstart.md if a GHEC org with SAML SSO returns 404 on git push or gh repo view.

Reference

Once you're past Day-1, these are the docs to bookmark.


Tech stack

Layer Technology
Language Python 3.12+
CLI Click
HTTP httpx
Validation Pydantic v2
YAML PyYAML (custom block-scalar dumper)
Auth azure-identity (DefaultAzureCredential)
CI/CD GitHub Actions (OIDC)
Sentinel ARM REST 2025-07-01-preview
Defender Microsoft Graph Security beta

Single tenant. Single-tenant App Registration with OIDC federated credentials for production; client-secret fallback for local dev.


Contributing

See CONTRIBUTING.md for the local setup, the DCO sign-off requirement, branch protection, and the status promotion lifecycle. Community expectations are documented in CODE_OF_CONDUCT.md. Security reports go through the private channel in SECURITY.md.


License + trademarks

Code is licensed under the Apache License 2.0. You may use, modify, and redistribute it - including commercially. A patent grant comes with the license; see Apache 2.0 §3.

The names ContentOps and SecM8 are trademarks of KustoKing / SecM8 and are NOT licensed under Apache 2.0 (the license explicitly disclaims trademark rights in §6). You may not name a fork "ContentOps", use the SecM8 wordmark in marketing, or imply SecM8 endorsement without permission. See TRADEMARK.md for the full policy.

Attribution is appreciated but not required - see NOTICE.

About

Security content lifecycle management for Microsoft Sentinel and Microsoft Defender XDR.

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages