Skip to content

Commit 505c548

Browse files
author
Weylon Solis
committed
Initial release of ForceHound
0 parents  commit 505c548

53 files changed

Lines changed: 16722 additions & 0 deletions

Some content is hidden

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

.github/dependabot.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "pip"
4+
directory: "/"
5+
schedule:
6+
interval: "weekly"
7+
open-pull-requests-limit: 10
8+
9+
- package-ecosystem: "github-actions"
10+
directory: "/"
11+
schedule:
12+
interval: "weekly"
13+
open-pull-requests-limit: 5

.github/workflows/ci.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
test:
14+
runs-on: ubuntu-latest
15+
strategy:
16+
fail-fast: false
17+
matrix:
18+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
19+
20+
steps:
21+
- uses: actions/checkout@v6
22+
23+
- name: Set up Python ${{ matrix.python-version }}
24+
uses: actions/setup-python@v6
25+
with:
26+
python-version: ${{ matrix.python-version }}
27+
28+
- name: Install dependencies
29+
run: |
30+
python -m pip install --upgrade pip
31+
pip install -e ".[dev]"
32+
33+
- name: Run unit tests
34+
run: python -m pytest tests/ --ignore=tests/integration -x -q

.github/workflows/publish.yml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: Publish to PyPI
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
repository:
7+
description: "Target repository"
8+
type: choice
9+
options:
10+
- testpypi
11+
- pypi
12+
default: testpypi
13+
run_tests:
14+
description: "Run test suite before publish"
15+
type: boolean
16+
default: true
17+
18+
permissions:
19+
contents: read
20+
id-token: write
21+
22+
jobs:
23+
build-and-publish:
24+
if: github.event_name == 'workflow_dispatch' && github.repository == 'NetSPI/ForceHound'
25+
runs-on: ubuntu-latest
26+
environment: ${{ inputs.repository }}
27+
steps:
28+
- name: Checkout
29+
uses: actions/checkout@v6
30+
31+
- name: Set up Python
32+
uses: actions/setup-python@v6
33+
with:
34+
python-version: "3.12"
35+
36+
- name: Install build tools
37+
run: python -m pip install --upgrade pip build
38+
39+
- name: Run tests
40+
if: ${{ inputs.run_tests }}
41+
run: |
42+
python -m pip install -e ".[dev]"
43+
python -m pytest tests/ -x -q
44+
45+
- name: Build dist
46+
run: python -m build
47+
48+
- name: Publish to PyPI
49+
if: ${{ inputs.repository == 'pypi' }}
50+
uses: pypa/gh-action-pypi-publish@release/v1
51+
52+
- name: Publish to TestPyPI
53+
if: ${{ inputs.repository == 'testpypi' }}
54+
uses: pypa/gh-action-pypi-publish@release/v1
55+
with:
56+
repository-url: https://test.pypi.org/legacy/

.gitignore

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Python
2+
__pycache__/
3+
*.py[cod]
4+
*.egg-info/
5+
dist/
6+
build/
7+
*.egg
8+
9+
# Virtual environments
10+
.venv/
11+
venv/
12+
env/
13+
14+
# IDE
15+
.idea/
16+
.vscode/
17+
*.swp
18+
*.swo
19+
20+
# Testing / coverage
21+
tests/
22+
scripts/
23+
.pytest_cache/
24+
.coverage
25+
htmlcov/
26+
.ruff_cache/
27+
28+
# ForceHound output & logs
29+
forcehound_output.json
30+
forcehound_integration_output.json
31+
forcehound_e2e_test.json
32+
forcehound_audit_*.jsonl
33+
forcehound_audit_*.json
34+
forcehound_deletions_*.json
35+
test_*.json
36+
37+
# OS
38+
.DS_Store
39+
Thumbs.db
40+
41+
# Claude
42+
.claude/
43+
CLAUDE.md

CONTRIBUTING.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Contributing to ForceHound
2+
3+
Thanks for your interest in contributing to ForceHound. Here's how to get started.
4+
5+
## Reporting Issues
6+
7+
When opening an issue, please include:
8+
9+
- ForceHound version (`pip show forcehound` or check `pyproject.toml`)
10+
- Python version (`python --version`)
11+
- Collector mode used (`api`, `aura`, or `both`)
12+
- Steps to reproduce the issue
13+
- Full error output or traceback
14+
- Any relevant CLI flags used
15+
16+
Do not include session IDs, access tokens, credentials, or org-identifying information in issue reports.
17+
18+
## Development Setup
19+
20+
```bash
21+
git clone https://github.com/NetSPI/ForceHound.git
22+
cd ForceHound
23+
pip install -e ".[dev]"
24+
```
25+
26+
## Running Tests
27+
28+
```bash
29+
python -m pytest tests/ -x -q
30+
```
31+
32+
## Pull Requests
33+
34+
- Open an issue first to discuss the change
35+
- Create a feature branch from `main`
36+
- Include tests for new functionality
37+
- Make sure all existing tests pass before submitting
38+
- Keep PRs focused on a single change
39+
40+
## Code Style
41+
42+
- Python 3.9+ compatible
43+
- Type hints on function signatures
44+
- Docstrings on public classes and methods

LICENSE

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
BSD 3-Clause License
2+
3+
Copyright (c) 2025, NetSPI
4+
5+
Redistribution and use in source and binary forms, with or without
6+
modification, are permitted provided that the following conditions are met:
7+
8+
1. Redistributions of source code must retain the above copyright notice, this
9+
list of conditions and the following disclaimer.
10+
11+
2. Redistributions in binary form must reproduce the above copyright notice,
12+
this list of conditions and the following disclaimer in the documentation
13+
and/or other materials provided with the distribution.
14+
15+
3. Neither the name of the copyright holder nor the names of its
16+
contributors may be used to endorse or promote products derived from
17+
this software without specific prior written permission.
18+
19+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

0 commit comments

Comments
 (0)