Skip to content

Commit 3462b07

Browse files
committed
Initial import clean copy (no history)
0 parents  commit 3462b07

Some content is hidden

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

51 files changed

+11894
-0
lines changed

.env.example

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# CourtListener API Token (get free at https://www.courtlistener.com/sign-in/)
2+
COURTLISTENER_API_TOKEN=
3+
4+
# Transport: stdio (default) or http
5+
TRANSPORT=stdio
6+
7+
# HTTP server settings (only used when TRANSPORT=http)
8+
HOST=0.0.0.0
9+
PORT=8000

.github/workflows/secret-scan.yaml

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
name: Secret Scanning
2+
3+
on:
4+
push:
5+
branches: [ main, master, develop ]
6+
pull_request:
7+
branches: [ main, master, develop ]
8+
9+
jobs:
10+
secret-scan:
11+
name: Detect Secrets
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v4
17+
with:
18+
fetch-depth: 0 # Full history for comprehensive scanning
19+
20+
- name: Set up Python
21+
uses: actions/setup-python@v5
22+
with:
23+
python-version: '3.11'
24+
25+
- name: Install detect-secrets
26+
run: |
27+
pip install detect-secrets
28+
29+
- name: Run detect-secrets scan
30+
run: |
31+
detect-secrets scan \
32+
--exclude-files '\.md$' \
33+
--exclude-files 'package-lock\.json' \
34+
--exclude-files '\.lock$' \
35+
--baseline .secrets.baseline
36+
37+
- name: Check for secrets in git history (last 100 commits)
38+
run: |
39+
# Scan recent git history for accidentally committed secrets
40+
git log --all --pretty=format: -p -100 | \
41+
detect-secrets scan --stdin \
42+
--exclude-files '\.md$' || true
43+
44+
- name: Security scan summary
45+
if: always()
46+
run: |
47+
echo "Secret scanning complete"
48+
echo "If secrets were detected, the job will fail above"
49+
echo "To update baseline: detect-secrets scan --baseline .secrets.baseline"
50+
51+
prompt-injection-check:
52+
name: Prompt Injection Security Scan
53+
runs-on: ubuntu-latest
54+
55+
steps:
56+
- name: Checkout repository
57+
uses: actions/checkout@v4
58+
59+
- name: Set up Python
60+
uses: actions/setup-python@v5
61+
with:
62+
python-version: '3.11'
63+
64+
- name: Install uv
65+
uses: astral-sh/setup-uv@v3
66+
67+
- name: Install dependencies
68+
run: uv sync
69+
70+
- name: Run prompt injection detection
71+
run: |
72+
echo "Scanning for prompt injection patterns..."
73+
74+
# Create baseline if it doesn't exist, then check against it
75+
if [ ! -f .prompt_injections.baseline ]; then
76+
echo "Creating baseline for first time..."
77+
uv run python .security/check_prompt_injections.py --update-baseline src/ tests/ *.md *.yml *.yaml *.json
78+
echo "Baseline created: .prompt_injections.baseline"
79+
else
80+
echo "Using existing baseline..."
81+
if uv run python .security/check_prompt_injections.py --baseline src/ tests/ *.yml *.yaml *.json; then
82+
echo "No NEW prompt injection patterns detected"
83+
echo "All findings match baseline (existing known findings)."
84+
else
85+
echo "NEW prompt injection patterns found!"
86+
echo ""
87+
echo "These findings are NOT in the baseline and require review."
88+
echo "These patterns may indicate attempts to:"
89+
echo "- Override system instructions (ignore previous instructions)"
90+
echo "- Extract sensitive prompts or API tokens"
91+
echo "- Change AI behavior (you are now a different AI)"
92+
echo "- Bypass security controls (admin mode on)"
93+
echo "- Fabricate legal citations"
94+
echo "- Social engineering (we became friends)"
95+
echo ""
96+
echo "To update baseline with legitimate findings:"
97+
echo " uv run python .security/check_prompt_injections.py --update-baseline src/ tests/ *.md *.yml *.yaml *.json"
98+
echo ""
99+
echo "If these are legitimate test cases or documentation examples,"
100+
echo "consider updating the baseline and committing the change."
101+
exit 1
102+
fi
103+
fi

.gitignore

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
__pycache__/
2+
*.py[cod]
3+
*$py.class
4+
*.egg-info/
5+
dist/
6+
build/
7+
.eggs/
8+
*.egg
9+
.env
10+
.venv/
11+
venv/
12+
*.log
13+
.pytest_cache/
14+
.coverage
15+
coverage.json
16+
htmlcov/
17+
.mypy_cache/
18+
.ruff_cache/
19+
nul
20+
devtunnel.exe
21+
CLAUDE.md
22+
.claude/
23+
audits/

.pre-commit-config.yaml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Pre-commit hooks for CourtListener Citation Validation MCP
2+
# Install: pip install pre-commit && pre-commit install
3+
# Run manually: pre-commit run --all-files
4+
5+
repos:
6+
- repo: https://github.com/Yelp/detect-secrets
7+
rev: v1.5.0
8+
hooks:
9+
- id: detect-secrets
10+
args:
11+
- '--baseline'
12+
- '.secrets.baseline'
13+
- '--exclude-files'
14+
- '\.md$'
15+
- '--exclude-files'
16+
- 'package-lock\.json'
17+
- '--exclude-files'
18+
- '\.lock$'
19+
exclude: ^\.secrets\.baseline$
20+
21+
- repo: https://github.com/pre-commit/pre-commit-hooks
22+
rev: v4.5.0
23+
hooks:
24+
- id: trailing-whitespace
25+
exclude: ^\.secrets\.baseline$
26+
- id: end-of-file-fixer
27+
exclude: ^\.secrets\.baseline$
28+
- id: check-yaml
29+
- id: check-added-large-files
30+
args: ['--maxkb=1000']
31+
- id: check-json
32+
- id: check-merge-conflict
33+
- id: detect-private-key
34+
35+
- repo: local
36+
hooks:
37+
- id: prompt-injection-check
38+
name: Check for prompt injection patterns
39+
entry: uv run python .security/check_prompt_injections.py
40+
language: system
41+
files: \.(py|txt|md|yml|yaml|json|js|ts|html|xml|csv)$
42+
exclude: \.security/.*_detector\.py$

.prompt_injections.baseline

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
".pre-commit-config.yaml": {},
3+
"docker-compose.yml": {},
4+
"pyproject.toml": {}
5+
}

.secrets.baseline

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
{
2+
"version": "1.5.0",
3+
"plugins_used": [
4+
{
5+
"name": "ArtifactoryDetector"
6+
},
7+
{
8+
"name": "AWSKeyDetector"
9+
},
10+
{
11+
"name": "AzureStorageKeyDetector"
12+
},
13+
{
14+
"name": "Base64HighEntropyString",
15+
"limit": 4.5
16+
},
17+
{
18+
"name": "BasicAuthDetector"
19+
},
20+
{
21+
"name": "CloudantDetector"
22+
},
23+
{
24+
"name": "DiscordBotTokenDetector"
25+
},
26+
{
27+
"name": "GitHubTokenDetector"
28+
},
29+
{
30+
"name": "GitLabTokenDetector"
31+
},
32+
{
33+
"name": "HexHighEntropyString",
34+
"limit": 3.0
35+
},
36+
{
37+
"name": "IbmCloudIamDetector"
38+
},
39+
{
40+
"name": "IbmCosHmacDetector"
41+
},
42+
{
43+
"name": "IPPublicDetector"
44+
},
45+
{
46+
"name": "JwtTokenDetector"
47+
},
48+
{
49+
"name": "KeywordDetector",
50+
"keyword_exclude": ""
51+
},
52+
{
53+
"name": "MailchimpDetector"
54+
},
55+
{
56+
"name": "NpmDetector"
57+
},
58+
{
59+
"name": "OpenAIDetector"
60+
},
61+
{
62+
"name": "PrivateKeyDetector"
63+
},
64+
{
65+
"name": "PypiTokenDetector"
66+
},
67+
{
68+
"name": "SendGridDetector"
69+
},
70+
{
71+
"name": "SlackDetector"
72+
},
73+
{
74+
"name": "SoftlayerDetector"
75+
},
76+
{
77+
"name": "SquareOAuthDetector"
78+
},
79+
{
80+
"name": "StripeDetector"
81+
},
82+
{
83+
"name": "TelegramBotTokenDetector"
84+
},
85+
{
86+
"name": "TwilioKeyDetector"
87+
}
88+
],
89+
"filters_used": [
90+
{
91+
"path": "detect_secrets.filters.allowlist.is_line_allowlisted"
92+
},
93+
{
94+
"path": "detect_secrets.filters.common.is_baseline_file",
95+
"filename": ".secrets.baseline"
96+
},
97+
{
98+
"path": "detect_secrets.filters.common.is_ignored_due_to_verification_policies",
99+
"min_level": 2
100+
},
101+
{
102+
"path": "detect_secrets.filters.heuristic.is_indirect_reference"
103+
},
104+
{
105+
"path": "detect_secrets.filters.heuristic.is_likely_id_string"
106+
},
107+
{
108+
"path": "detect_secrets.filters.heuristic.is_lock_file"
109+
},
110+
{
111+
"path": "detect_secrets.filters.heuristic.is_not_alphanumeric_string"
112+
},
113+
{
114+
"path": "detect_secrets.filters.heuristic.is_potential_uuid"
115+
},
116+
{
117+
"path": "detect_secrets.filters.heuristic.is_prefixed_with_dollar_sign"
118+
},
119+
{
120+
"path": "detect_secrets.filters.heuristic.is_sequential_string"
121+
},
122+
{
123+
"path": "detect_secrets.filters.heuristic.is_swagger_file"
124+
},
125+
{
126+
"path": "detect_secrets.filters.heuristic.is_templated_secret"
127+
},
128+
{
129+
"path": "detect_secrets.filters.regex.should_exclude_file",
130+
"pattern": [
131+
"\\.md$",
132+
"\\.lock$"
133+
]
134+
}
135+
],
136+
"results": {
137+
"tests\\unit\\test_log_sanitizer.py": [
138+
{
139+
"type": "Hex High Entropy String",
140+
"filename": "tests\\unit\\test_log_sanitizer.py",
141+
"hashed_secret": "f0d30a5da82d2ab63b1425e9b959d8c3975342f5",
142+
"is_verified": false,
143+
"line_number": 25
144+
}
145+
]
146+
},
147+
"generated_at": "2026-03-04T06:14:01Z"
148+
}

0 commit comments

Comments
 (0)