First of all, thank you for taking the time to contribute. 🎉
PySOC is a community project and we welcome contributions of all sizes — from typo fixes in the docs to entirely new detectors. This document explains the expectations and the process.
- Code of Conduct
- Project philosophy
- Before you start
- Development workflow
- Pull request checklist
- Reporting bugs
- Suggesting features
By participating in this project you agree to abide by the Code of Conduct. Please be kind.
Before contributing, please internalise these principles — they explain why the code looks the way it does:
- Zero runtime dependencies. PySOC runs on the Python standard library alone. Adding a new runtime dep is a serious decision — open an issue to discuss before opening a PR.
- TDD. Tests are written before the implementation. The
tests/directory is the spec; thesrc/directory is the implementation of that spec. Seedocs/DEVELOPMENT.md. - Immutable models.
EventandAlertarefrozen=True. If you need to "modify" an event, usedataclasses.replace. - ECS-inspired schema. New event fields should follow the Elastic Common Schema naming where possible. If ECS doesn't have a sensible name, document why you deviated.
- Emit, don't suppress. Detectors emit alerts with rich context; they do not silently filter. Suppression is the analyst's job.
- Documented FPs. Every detector carries a
notefield describing common false positives. New detectors must follow this convention.
- Open an issue describing what you want to change. We'll discuss the approach and avoid wasted work. (Typo fixes don't need an issue.)
- Check the roadmap in
docs/ROADMAP.md— your idea may already be planned, or already rejected with rationale.
# 1. Fork and clone
git clone https://github.com/<your-username>/pysoc.git
cd pysoc
# 2. Create a virtual environment and install dev deps
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
# 3. Create a branch
git checkout -b feature/my-new-detector
# 4. Write tests first. Run them. They should fail.
pytest tests/unit/test_my_new_detector.py
# 5. Implement until tests pass.
pytest tests/unit/test_my_new_detector.py
# 6. Run the full suite + lint.
pytest
ruff check src tests # if you have ruff installed
# 7. Commit and push. Use conventional-commits-style messages.
git commit -m "feat(detect): add AG-001 admin-group-add detector"
git push -u origin feature/my-new-detector
# 8. Open a pull request. Fill in the template.Before opening a PR, please confirm:
- An issue exists for the change (or it's a trivial fix).
- Tests were written first and pass:
pytest. - No new runtime dependencies were added (or an issue was opened to discuss the trade-off).
- New detectors / parsers / reporters follow the existing patterns
(see
docs/DEVELOPMENT.md). - New detectors include a
notefield describing common FPs. - Documentation updated:
- [ ]
docs/DETECTION_RULES.mdfor new rules - [ ]CHANGELOG.mdunder[Unreleased]- [ ]README.mdtable-of-contents / tables if relevant - Commit messages follow Conventional Commits:
feat:,fix:,docs:,test:,refactor:,chore:,perf:. - Branch is up to date with
main.
Open a GitHub issue with:
- PySOC version (
python -m pysoc --versionorpip show pysoc). - Python version and OS.
- Reproduction steps — ideally a shell script that generates mock data and runs the pipeline.
- Expected vs actual behaviour.
- Logs / stack trace (sanitised).
Open a GitHub issue with the prefix [Proposal] and include:
- Use case — what problem does this solve?
- Proposed API — what would the user code look like?
- Trade-offs — does this break the zero-deps rule? Does it add FPs?
- Alternatives considered — what else did you look at?
We'll discuss and either accept, defer to the roadmap, or politely decline with rationale.
Thank you again for contributing! 🙏