| Version | Supported |
|---|---|
| 0.1.x | ✅ |
We take security seriously. If you discover a security vulnerability in APME, please report it responsibly.
DO NOT open a public GitHub issue for security vulnerabilities.
Instead, please report security issues via:
- GitHub Security Advisories: Use the "Report a vulnerability" button in the Security tab
- Description of the vulnerability
- Steps to reproduce
- Potential impact
- Suggested fix (if any)
- Acknowledgment: Within 48 hours
- Initial Assessment: Within 7 days
- Resolution Timeline: Communicated after assessment
We consider security research conducted in accordance with this policy to be:
- Authorized under anti-hacking laws
- Exempt from DMCA restrictions
- Conducted in good faith
We will not pursue legal action against researchers who follow this policy.
NEVER commit secrets to the repository.
# Check for secrets before committing
gitleaks detect --source . --verbose
# prek hooks run automatically on commit (ruff, mypy, pydoclint)
# Install with: uv tool install prek && prek install- API keys, tokens, passwords
- Private keys (*.pem, *.key, id_rsa)
- Environment files (.env, .env.local)
- Ansible Vault passwords
- Cloud credentials (AWS, GCP, Azure)
- Kubeconfig files
- Database connection strings
- Use environment variables
- Use Ansible Vault for encrypted secrets
- Use
.env.examplewith placeholder values - Document required secrets in README
# Always validate external input
def scan_path(path: Path) -> ScanResult:
resolved = path.resolve()
if not resolved.is_relative_to(allowed_root):
raise SecurityError("Path traversal detected")# NEVER use shell=True with user input
# BAD:
subprocess.run(f"scan {user_input}", shell=True)
# GOOD:
subprocess.run(["scan", user_input], shell=False)# Use safe loaders
from ruamel.yaml import YAML
yaml = YAML(typ='safe') # Prevents arbitrary code execution# Use specific versions, not :latest
FROM python:3.12-slim-bookworm
# Run as non-root user
RUN useradd -r -s /bin/false apme
USER apme
# Don't store secrets in ENV
# BAD: ENV API_KEY=secret123
# GOOD: Use runtime secrets
# Minimize attack surface
RUN apt-get update && apt-get install -y --no-install-recommends \
required-package \
&& rm -rf /var/lib/apt/lists/*# Scan images for vulnerabilities
trivy image apme-primary:latest
grype apme-primary:latest# Check for vulnerable dependencies
pip-audit
# Dependencies are managed via pyproject.toml and uv.lock
# Review dependency changes in PRs- Always commit lock files (
uv.lock) - Review dependency changes in PRs
# Production: Use TLS
credentials = grpc.ssl_channel_credentials()
channel = grpc.secure_channel('server:50051', credentials)
# Development only: Insecure channel
# channel = grpc.insecure_channel('localhost:50051')- Validate all protobuf message fields
- Set maximum message sizes
- Implement rate limiting
# NEVER log secrets
logger.info("Connecting to database") # GOOD
logger.info(f"Password: {password}") # BAD
# Sanitize user input in logs
logger.info("Scanning path", path=sanitize(user_path))Before submitting a PR, verify:
- No secrets in code or comments
- No hardcoded credentials
- Input validation for all external data
- Safe subprocess calls (no shell=True with user input)
- Dependencies updated and scanned
- Container runs as non-root user
- Sensitive data not logged
- gitleaks passes locally
# Secret detection (manual scan)
gitleaks detect --source . --verbose
# Python security linting
bandit -r src/
# Dependency vulnerabilities
pip-audit
# Container scanning
trivy image apme-primary:latestIf you believe the project has been compromised:
- Rotate all credentials immediately
- Audit git history for leaked secrets
- Notify maintainers via GitHub Security Advisory
- Document the incident for post-mortem
If secrets are committed:
# Use git-filter-repo (preferred) or BFG Repo-Cleaner
git filter-repo --path secrets.txt --invert-paths
# Force push (coordinate with team)
git push --force-with-leaseNote: Once pushed to a public repo, assume the secret is compromised and rotate it.