Contributor Security Policy
Effective Date: 2026-03-02
Last Review: 2026-03-02
Next Review: 2026-09-02
Owner: Greg Felice, Project Lead
1. Purpose
This policy provides security guidelines for anyone contributing to the tomo project. It establishes expectations for secure development practices, vulnerability handling, and code review standards that protect the SDK's users and the project's infrastructure.
2. Scope
This policy applies to all contributors, including:
- Project maintainers with commit access
- External contributors submitting pull requests
- CI/CD automation that modifies code or publishes artifacts
- Anyone with access to project infrastructure
3. No Secrets in Code
3.1 Prohibited Content
The following must never appear in source code, configuration files, documentation, or commit messages:
| Category |
Examples |
| Credentials |
Passwords, API keys, tokens, private keys |
| Connection strings |
Database URLs with credentials, service endpoints with auth |
| Infrastructure details |
Internal IP addresses, server hostnames (in public repos) |
| Personal data |
Email addresses (except in LICENSE/CONTRIBUTORS), phone numbers |
| Encryption keys |
AES keys, HMAC secrets, JWT signing keys |
3.2 Where Secrets Belong
| Context |
Storage |
| Development |
Environment variables, .env files (gitignored) |
| CI/CD |
Woodpecker secrets manager |
| Production |
Environment variables, secrets manager, Ansible vault |
| Documentation |
Reference placeholder values (e.g., your-api-key-here) |
3.3 Prevention Controls
| Control |
Implementation |
.gitignore |
Excludes .env, *.pem, *.key, credentials.*, secrets.* |
| Pre-commit hook |
trufflehog runs locally before each commit (optional but recommended) |
| CI gate |
trufflehog runs on every push; blocks merge on any finding |
| Code review |
Reviewer checks for hardcoded secrets (see review checklist) |
3.4 If a Secret Is Accidentally Committed
- Do not just delete it in a follow-up commit — it remains in Git history
- Immediately notify the Project Lead
- Rotate the exposed credential
- Remove from Git history using
git filter-repo (Project Lead will handle)
- Force-push the cleaned branch (Project Lead authorization required)
- Document the incident
4. Dependency Management
4.1 Adding a New Dependency
Before adding a dependency to pyproject.toml, evaluate:
| Criterion |
Check |
| Necessity |
Can this be accomplished with stdlib or existing dependencies? |
| License |
Is it compatible with Apache 2.0? (MIT, BSD, Apache, LGPL are acceptable; GPL requires review) |
| Maintenance |
Is the project actively maintained? Last release within 12 months? |
| Security history |
Any known CVEs? How quickly were they addressed? |
| Popularity |
Is it widely used? (reduces risk of abandonment) |
| Scope |
Is the dependency minimal, or does it pull in a large transitive tree? |
4.2 Dependency Review in PRs
When a PR adds or updates dependencies:
- [ ] Dependency justification documented in PR description
- [ ] License verified as compatible
- [ ]
pip-audit passes with no new findings
- [ ] Transitive dependency tree reviewed for unexpected additions
- [ ] Version constraint is appropriately specified (avoid unconstrained
>=)
4.3 Version Pinning Strategy
| Dependency Type |
Pinning Strategy |
| Core runtime (psycopg, antlr4) |
Pin major + minor, allow patch (>=3.1,<3.2) |
| Optional backends (igraph, networkit) |
Pin major, allow minor (>=0.10,<1.0) |
| Dev/test tools (pytest, ruff, mypy) |
Pin in CI lockfile, update quarterly |
| Docker base image |
Pin by digest in production, tag in development |
5. Secure Coding Practices
| Context |
Requirement |
| Cypher query parameters |
Always use parameterized queries; never interpolate user input into Cypher strings |
| SQL generation |
Use psycopg's SQL composition (sql.SQL, sql.Identifier); never use f-strings or string concatenation |
| User-provided graph names |
Validate against allowlist pattern (^[a-zA-Z_][a-zA-Z0-9_]*$) |
| File paths |
Never construct paths from user input without sanitization |
5.2 Error Handling
| Practice |
Rationale |
| Do not expose stack traces to end users |
May reveal internal paths, versions, or configuration |
| Do not log credentials or sensitive parameters |
Logs may be stored in less-secure locations |
| Use specific exception types |
Catch specific exceptions, not bare except: |
| Include actionable error messages |
Help users fix the problem without exposing internals |
5.3 Cryptography
| Practice |
Standard |
| Do not implement custom cryptography |
Use established libraries (e.g., cryptography, hashlib) |
| Use strong algorithms |
AES-256, SHA-256 minimum; no MD5 or SHA-1 for security purposes |
| Use secure random |
secrets module, not random |
5.4 AGE/PostgreSQL-Specific
| Practice |
Rationale |
Use LOAD 'age' and SET search_path in every session |
Required for AGE function resolution; prevents stale session state |
| Validate agtype parsing output |
Malformed agtype from wire could cause parser exceptions |
Do not expose raw graphid values externally |
Internal identifiers; may change after dump/restore |
| Sanitize graph labels in DDL |
CREATE GRAPH and CREATE VLABEL/ELABEL use identifiers, not parameters |
6. Security-Focused Code Review Checklist
Reviewers should verify the following for every PR:
6.1 General Security
- [ ] No hardcoded secrets, credentials, or tokens
- [ ] No sensitive data in log statements or error messages
- [ ] Input validation applied to all external inputs
- [ ] Error handling does not expose internal details
6.2 SQL and Cypher Safety
- [ ] All queries use parameterized inputs (no string interpolation)
- [ ] SQL identifiers use
psycopg.sql.Identifier() or sql.SQL()
- [ ] No raw user input in
CREATE GRAPH, CREATE VLABEL, or CREATE ELABEL statements
- [ ] Connection handling follows the AGE session setup pattern
6.3 Dependencies
- [ ] New dependencies are justified and license-compatible
- [ ]
pip-audit CI gate passes
- [ ] No unnecessary transitive dependencies introduced
6.4 Data Handling
- [ ] PII is not logged or stored unnecessarily
- [ ] Temporary files are cleaned up (use
tempfile with context managers)
- [ ] Credentials are read from environment, not from files in the repo
6.5 Tests
- [ ] Security-relevant behavior has test coverage
- [ ] Tests do not contain real credentials or production data
- [ ] Test fixtures use representative but synthetic data
7. Reporting Vulnerabilities
7.1 For External Reporters
If you discover a security vulnerability in tomo:
- Do not open a public issue
- Email security@rizlabs.com with:
- Description of the vulnerability
- Steps to reproduce
- Potential impact assessment
- Your contact information (for follow-up)
- You will receive an acknowledgment within 48 hours
- See
SECURITY.md in the repository root for full disclosure policy
7.2 For Contributors
If you discover a vulnerability during development or code review:
- Do not commit a fix to a public branch before coordinating
- Contact the Project Lead directly (email or Signal)
- The fix will be developed in a private branch and released with a security advisory
- Credit will be given unless you prefer to remain anonymous
7.3 Response SLAs
| Severity |
Acknowledgment |
Fix Target |
Disclosure |
| Critical (RCE, data breach) |
24 hours |
72 hours |
After fix is published |
| High (privilege escalation, significant data exposure) |
48 hours |
7 days |
After fix is published |
| Medium (limited impact vulnerability) |
72 hours |
30 days |
After fix is published |
| Low (informational, hardening) |
5 business days |
Next release |
In release notes |
8. Development Environment Security
8.1 Requirements for Contributors with Infrastructure Access
| Requirement |
Standard |
| Disk encryption |
Full-disk encryption (LUKS, FileVault, BitLocker) on development machines |
| Screen lock |
Auto-lock after 5 minutes of inactivity |
| SSH keys |
Ed25519 or RSA 4096-bit, with passphrase |
| Git signing |
Recommended (GPG or SSH signing) for commit attribution |
| 2FA |
Required on GitHub, Forgejo, and all project services |
8.2 Recommendations for All Contributors
| Recommendation |
Rationale |
| Use a virtual environment |
Isolate project dependencies from system Python |
| Keep development tools updated |
ruff, mypy, pytest, bandit — latest stable versions |
| Run security checks locally |
bandit src/ and pip-audit before pushing |
| Review CI results |
Do not ignore CI failures — investigate and fix |
9. Compliance Mapping
| SOC 2 Criteria |
Control |
| CC8.1 |
Change management and code review controls |
| CC6.1 |
Secure development practices (no secrets in code) |
| CC7.1 |
Detection of unauthorized or insecure code changes |
| CC1.4 |
Communication of security responsibilities to personnel |
| CC2.2 |
Internal communication of policies and expectations |