Skip to content

Commit 9de54a5

Browse files
authored
chore: add GitHub security governance (#2)
* chore: add detect-secrets pre-commit hook Prevents credential leaks before commit: - Yelp detect-secrets with baseline file - Excludes lock files and test fixtures - 28 secret pattern detectors enabled * chore: add dependabot for automated dependency updates Weekly updates for: - GitHub Actions (grouped minor/patch) - Python pip dependencies (grouped by type) - Rust Cargo dependencies (security team review) * ci: add CodeQL SAST workflow Static analysis for security vulnerabilities: - Python analysis with security-extended queries - Runs on push, PR, and weekly schedule - SARIF results uploaded to Security tab + artifacts * docs: enhance PR template with security checklist Added sections: - Security checklist (secrets, input validation, OWASP) - Dependency review requirements - Backward compatibility checklist - Performance change documentation * ci: add GitHub App token support for release-please Enables optional GitHub App auth for branch protection bypass: - Falls back to GITHUB_TOKEN if APP_ID/APP_PRIVATE_KEY not set - Controlled via USE_APP_TOKEN repository variable
1 parent 1fe06ef commit 9de54a5

File tree

7 files changed

+687
-1
lines changed

7 files changed

+687
-1
lines changed

.github/CODEOWNERS

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# CODEOWNERS for cachekit-py
2+
# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
3+
#
4+
# These owners will be requested for review when someone opens a pull request
5+
# that modifies code that they own. Order matters - last matching pattern wins.
6+
7+
# Default: repository maintainers own everything
8+
* @cachekit-io/maintainers
9+
10+
# ─────────────────────────────────────────────────────────────────────────────
11+
# CRITICAL SECURITY PATHS
12+
# These require security team review for any changes
13+
# ─────────────────────────────────────────────────────────────────────────────
14+
15+
# Rust core - memory safety, FFI boundaries, cryptography
16+
/rust/ @cachekit-io/maintainers @cachekit-io/security
17+
18+
# Security-critical Python modules
19+
/src/cachekit/serializers/ @cachekit-io/maintainers @cachekit-io/security
20+
/src/cachekit/reliability/ @cachekit-io/maintainers @cachekit-io/security
21+
22+
# ─────────────────────────────────────────────────────────────────────────────
23+
# CI/CD AND RELEASE INFRASTRUCTURE
24+
# Changes here can compromise supply chain
25+
# ─────────────────────────────────────────────────────────────────────────────
26+
27+
/.github/workflows/ @cachekit-io/maintainers @cachekit-io/security
28+
/.github/CODEOWNERS @cachekit-io/maintainers
29+
/release-please-config.json @cachekit-io/maintainers
30+
/.release-please-manifest.json @cachekit-io/maintainers
31+
32+
# ─────────────────────────────────────────────────────────────────────────────
33+
# BUILD AND DEPENDENCY CONFIGURATION
34+
# Supply chain attack surface
35+
# ─────────────────────────────────────────────────────────────────────────────
36+
37+
/pyproject.toml @cachekit-io/maintainers
38+
/rust/Cargo.toml @cachekit-io/maintainers @cachekit-io/security
39+
/rust/Cargo.lock @cachekit-io/maintainers
40+
/.pre-commit-config.yaml @cachekit-io/maintainers
41+
42+
# ─────────────────────────────────────────────────────────────────────────────
43+
# SECURITY DOCUMENTATION
44+
# ─────────────────────────────────────────────────────────────────────────────
45+
46+
/SECURITY.md @cachekit-io/maintainers @cachekit-io/security
47+
/.github/SECURITY.md @cachekit-io/maintainers @cachekit-io/security
48+
49+
# ─────────────────────────────────────────────────────────────────────────────
50+
# DOCUMENTATION
51+
# Lower barrier - docs team can approve
52+
# ─────────────────────────────────────────────────────────────────────────────
53+
54+
/docs/ @cachekit-io/maintainers
55+
/README.md @cachekit-io/maintainers
56+
/CHANGELOG.md @cachekit-io/maintainers
57+
58+
# ─────────────────────────────────────────────────────────────────────────────
59+
# TESTS
60+
# Test changes generally safe, but fuzzing/security tests need security review
61+
# ─────────────────────────────────────────────────────────────────────────────
62+
63+
/tests/ @cachekit-io/maintainers
64+
/tests/security/ @cachekit-io/maintainers @cachekit-io/security
65+
/tests/fuzz/ @cachekit-io/maintainers @cachekit-io/security

.github/dependabot.yml

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# Dependabot configuration for cachekit-py
2+
# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
3+
4+
version: 2
5+
6+
registries:
7+
# No private registries - all deps are public
8+
9+
updates:
10+
# ─────────────────────────────────────────────────────────────────────────
11+
# GitHub Actions
12+
# Keep CI/CD supply chain current
13+
# ─────────────────────────────────────────────────────────────────────────
14+
- package-ecosystem: "github-actions"
15+
directory: "/"
16+
schedule:
17+
interval: "weekly"
18+
day: "monday"
19+
time: "09:00"
20+
timezone: "America/Los_Angeles"
21+
commit-message:
22+
prefix: "ci"
23+
labels:
24+
- "dependencies"
25+
- "github-actions"
26+
reviewers:
27+
- "cachekit-io/maintainers"
28+
# Group minor/patch updates to reduce PR noise
29+
groups:
30+
actions-minor:
31+
patterns:
32+
- "*"
33+
update-types:
34+
- "minor"
35+
- "patch"
36+
37+
# ─────────────────────────────────────────────────────────────────────────
38+
# Python (pip/uv)
39+
# ─────────────────────────────────────────────────────────────────────────
40+
- package-ecosystem: "pip"
41+
directory: "/"
42+
schedule:
43+
interval: "weekly"
44+
day: "monday"
45+
time: "09:00"
46+
timezone: "America/Los_Angeles"
47+
commit-message:
48+
prefix: "chore"
49+
labels:
50+
- "dependencies"
51+
- "python"
52+
reviewers:
53+
- "cachekit-io/maintainers"
54+
# Ignore pre-releases unless explicitly opted in
55+
ignore:
56+
- dependency-name: "*"
57+
update-types: ["version-update:semver-prerelease"]
58+
# Group by type to reduce PR noise
59+
groups:
60+
# Security-sensitive dependencies get individual PRs
61+
# (not grouped - we want to review each)
62+
python-dev:
63+
patterns:
64+
- "pytest*"
65+
- "ruff"
66+
- "basedpyright"
67+
- "faker"
68+
- "hypothesis"
69+
update-types:
70+
- "minor"
71+
- "patch"
72+
python-runtime:
73+
patterns:
74+
- "redis*"
75+
- "pydantic*"
76+
- "tenacity"
77+
- "prometheus-client"
78+
- "psutil"
79+
update-types:
80+
- "minor"
81+
- "patch"
82+
python-serialization:
83+
patterns:
84+
- "blake3"
85+
- "msgpack"
86+
- "orjson"
87+
- "xxhash"
88+
update-types:
89+
- "minor"
90+
- "patch"
91+
92+
# ─────────────────────────────────────────────────────────────────────────
93+
# Rust (Cargo)
94+
# ─────────────────────────────────────────────────────────────────────────
95+
- package-ecosystem: "cargo"
96+
directory: "/rust"
97+
schedule:
98+
interval: "weekly"
99+
day: "monday"
100+
time: "09:00"
101+
timezone: "America/Los_Angeles"
102+
commit-message:
103+
prefix: "chore"
104+
labels:
105+
- "dependencies"
106+
- "rust"
107+
reviewers:
108+
- "cachekit-io/maintainers"
109+
- "cachekit-io/security" # Rust deps affect memory safety
110+
# Security-critical crates get individual attention
111+
# cachekit-core is pinned exactly, so dependabot won't touch it
112+
groups:
113+
rust-dev:
114+
patterns:
115+
- "criterion"
116+
- "proptest"
117+
- "divan"
118+
- "fastrand"
119+
- "iai-callgrind"
120+
- "pprof"
121+
- "ctor"
122+
update-types:
123+
- "minor"
124+
- "patch"

.github/pull_request_template.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,35 @@ Why are these changes needed? What problem do they solve?
1111
- [ ] Bug fix (non-breaking)
1212
- [ ] New feature (non-breaking)
1313
- [ ] Breaking change
14+
- [ ] Performance improvement
1415
- [ ] Documentation update
16+
- [ ] Refactoring (no behavior change)
17+
- [ ] CI/CD or tooling change
18+
19+
---
20+
21+
## Security Checklist
22+
23+
**For ALL PRs, verify:**
24+
25+
- [ ] No secrets, credentials, or API keys in code or comments
26+
- [ ] No hardcoded sensitive data (use env vars or config)
27+
- [ ] User input is validated/sanitized where applicable
28+
- [ ] Error messages don't leak sensitive information
29+
30+
**For PRs touching security-critical paths** (`/rust/`, `/src/cachekit/serializers/`, `/src/cachekit/reliability/`, workflows):
31+
32+
- [ ] Changes reviewed by security team (@cachekit-io/security)
33+
- [ ] No new `unsafe` blocks without justification
34+
- [ ] Cryptographic code uses audited libraries (no custom crypto)
35+
- [ ] FFI boundaries maintain memory safety guarantees
36+
37+
**For PRs adding/updating dependencies:**
38+
39+
- [ ] Dependency is from trusted source with active maintenance
40+
- [ ] No known CVEs (`pip-audit` / `cargo-audit` clean)
41+
- [ ] License is compatible (MIT, Apache-2.0, BSD)
42+
- [ ] Justified: not adding unnecessary attack surface
1543

1644
---
1745

@@ -38,6 +66,15 @@ Why are these changes needed? What problem do they solve?
3866
- [ ] Integration tests added/updated
3967
- [ ] Tests pass: `make test-critical`
4068
- [ ] No test regressions
69+
- [ ] For performance changes: Benchmark results attached
70+
71+
---
72+
73+
## Backward Compatibility
74+
75+
- [ ] API is backward compatible OR breaking change is documented
76+
- [ ] No removal of public APIs without deprecation period
77+
- [ ] Migration path documented for breaking changes
4178

4279
---
4380

.github/workflows/codeql.yml

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# CodeQL Static Application Security Testing (SAST)
2+
# https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning-for-a-repository
3+
#
4+
# Analyzes Python and Rust code for:
5+
# - Security vulnerabilities (injection, XSS, SSRF, etc.)
6+
# - Code quality issues
7+
# - Supply chain risks
8+
# - Common programming errors
9+
#
10+
# Results appear in GitHub Security tab and as PR annotations.
11+
12+
name: CodeQL
13+
14+
on:
15+
push:
16+
branches: [main]
17+
pull_request:
18+
branches: [main]
19+
schedule:
20+
# Weekly deep scan on Sunday at 3am UTC
21+
- cron: "0 3 * * 0"
22+
workflow_dispatch:
23+
# Manual trigger for ad-hoc security analysis
24+
25+
permissions:
26+
contents: read
27+
security-events: write # Required for uploading SARIF results
28+
actions: read # Required for workflow status
29+
30+
concurrency:
31+
group: codeql-${{ github.workflow }}-${{ github.ref }}
32+
cancel-in-progress: true
33+
34+
jobs:
35+
analyze:
36+
name: Analyze (${{ matrix.language }})
37+
runs-on: ubuntu-latest
38+
timeout-minutes: 30
39+
40+
strategy:
41+
fail-fast: false
42+
matrix:
43+
language:
44+
- python
45+
# Note: Rust support is limited in CodeQL
46+
# We rely on cargo-audit, cargo-deny, and Miri for Rust security
47+
# CodeQL language config
48+
# https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#changing-the-languages-that-are-analyzed
49+
50+
steps:
51+
- name: Checkout repository
52+
uses: actions/checkout@v4
53+
54+
# Python setup for accurate analysis
55+
- name: Set up Python
56+
if: matrix.language == 'python'
57+
uses: actions/setup-python@v5
58+
with:
59+
python-version: "3.12"
60+
61+
- name: Install Python dependencies
62+
if: matrix.language == 'python'
63+
run: |
64+
python -m pip install --upgrade pip
65+
# Install dependencies so CodeQL can analyze import resolution
66+
pip install -e ".[data]" || pip install -e .
67+
68+
# Initialize CodeQL
69+
- name: Initialize CodeQL
70+
uses: github/codeql-action/init@v3
71+
with:
72+
languages: ${{ matrix.language }}
73+
# Use security-extended for maximum coverage
74+
# Options: security-extended, security-and-quality
75+
queries: security-extended
76+
# Config file for custom queries (optional)
77+
# config-file: .github/codeql/codeql-config.yml
78+
79+
# Autobuild attempts to build any compiled code
80+
# For Python, this is largely a no-op but ensures imports resolve
81+
- name: Autobuild
82+
uses: github/codeql-action/autobuild@v3
83+
84+
# Run CodeQL analysis
85+
- name: Perform CodeQL Analysis
86+
uses: github/codeql-action/analyze@v3
87+
with:
88+
category: "/language:${{ matrix.language }}"
89+
# Upload SARIF to GitHub Security tab
90+
upload: true
91+
# Also output SARIF for artifact storage
92+
output: sarif-results
93+
94+
# Archive SARIF for audit trail
95+
- name: Upload SARIF artifact
96+
uses: actions/upload-artifact@v4
97+
with:
98+
name: codeql-sarif-${{ matrix.language }}
99+
path: sarif-results
100+
retention-days: 90

.github/workflows/release-please.yml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,23 @@ jobs:
1717
tag_name: ${{ steps.release.outputs.tag_name }}
1818
version: ${{ steps.release.outputs.version }}
1919
steps:
20+
# Use GitHub App for token vending (avoids branch protection issues with GITHUB_TOKEN)
21+
# If APP_ID/APP_PRIVATE_KEY not set, falls back to GITHUB_TOKEN
22+
- name: Generate GitHub App token
23+
id: app-token
24+
uses: actions/create-github-app-token@v2
25+
if: ${{ vars.USE_APP_TOKEN == 'true' }}
26+
with:
27+
app-id: ${{ secrets.APP_ID }}
28+
private-key: ${{ secrets.APP_PRIVATE_KEY }}
29+
2030
- name: Run release-please
2131
id: release
2232
uses: googleapis/release-please-action@v4
2333
with:
2434
manifest-file: .release-please-manifest.json
2535
config-file: release-please-config.json
26-
token: ${{ secrets.GITHUB_TOKEN }}
36+
token: ${{ steps.app-token.outputs.token || secrets.GITHUB_TOKEN }}
2737

2838
build-wheels:
2939
name: Build wheels (${{ matrix.target }})

.pre-commit-config.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,20 @@ repos:
4848
- id: check-added-large-files
4949
args: [--maxkb=1000]
5050
- id: check-merge-conflict
51+
52+
# Secret scanning - prevent credential leaks
53+
# Uses Yelp's detect-secrets with high entropy detection
54+
- repo: https://github.com/Yelp/detect-secrets
55+
rev: v1.5.0
56+
hooks:
57+
- id: detect-secrets
58+
args:
59+
- --baseline
60+
- .secrets.baseline
61+
exclude: |
62+
(?x)^(
63+
.*\.lock$|
64+
.*\.sum$|
65+
tests/fixtures/.*|
66+
docs/.*\.md$
67+
)$

0 commit comments

Comments
 (0)