If you discover a security vulnerability in Grinta, please report it responsibly. Do not open a public issue, discussion, or pull request that describes an unpatched vulnerability.
- Preferred — open a private GitHub Security Advisory: https://github.com/josephsenior/Grinta-Coding-Agent/security/advisories/new
- Email —
security@app.ai(PGP optional, plain text accepted). - Include:
- Description of the vulnerability and affected component(s).
- Steps to reproduce, ideally with a minimal repository or prompt.
- Potential impact (data exfiltration, code execution, privilege boundary, supply-chain, etc.).
- Affected version (
grinta --version) and OS. - Suggested fix or mitigation, if any.
- Acknowledgement: within 48 hours.
- Triage and severity assessment: within 1 week.
- Fix and coordinated disclosure: critical issues within 2 weeks; lower severities tracked in the next maintenance release.
- Credit: reporters are credited in the release notes unless they request otherwise.
Good-faith security research that follows this policy will not be pursued. Please avoid privacy violations, data destruction, denial of service against shared infrastructure, and access to systems you do not own.
Only the active release line receives security fixes. Earlier versions are best-effort.
| Version | Supported |
|---|---|
| 1.0.x | ✅ |
| < 1.0 | ❌ |
Grinta is a local-first developer tool that runs with the privileges of the user invoking it. The threat model, built-in protections, and out-of-scope attacks are documented in detail in docs/SECURITY_CHECKLIST.md. The summary below captures the boundaries operators care about most.
- The agent runs inside the same OS user as the operator. There is no sandbox, container, namespace, or process isolation.
- Pointing Grinta at an untrusted repository is equivalent to executing that repository’s build scripts under your account. Treat it accordingly.
- The local LLM provider, MCP servers, and any plugins you enable are part of the trusted compute base.
- Risk classifier (
SecurityAnalyzer/command_analyzer.py) assigns every proposed shell action a NONE / LOW / MEDIUM / HIGH / CRITICAL band before execution. - Hard CRITICAL refusal gate in
safety_validator.py::_should_block_actionblocks CRITICAL actions regardless of profile, model, or autonomy level. hardened_localexecution profile scopes git, package, and network- capable commands to the active workspace, with workspace-rooted cwd checks for terminal sessions, file uploads, and direct file access.- Pattern-based shell guard detects
rm -rf /, force pushes to protected branches, encoded payloads, privilege escalation, and common exfiltration shapes. - Circuit breakers and stuck detection halt the agent on error-rate spikes, repeated tool failures, monologue loops, and runaway token / cost-acceleration patterns.
- Per-task budget guards cap token spend and wall-clock time to limit blast radius from prompt injection or model misbehaviour.
- Secrets in
settings.jsonshould be referenced via${ENV_VAR}indirection; the canonical secret source is your shell environment or a sibling.envfile under the app settings root (~/.grinta/when installed, or the repository root /APP_ROOTwhen running from source) — not the JSON itself. Grinta resolves placeholders throughbackend/core/config/api_key_manager.py. OS keychain integration is not implemented today. - The secret masker strips known secret patterns (provider API keys, JWTs, cloud credentials) from event-stream output, audit logs, and panel renders before display.
- Audit logs may still capture sensitive content from tool output. Treat
~/.grinta/workspaces/<id>/storage/<session>/audit/as confidential.
- The default runtime makes no outbound calls beyond the LLM endpoint(s) you configure and the MCP servers you enable.
- Telemetry and crash reporting are off by default and require explicit
opt-in. See
backend/telemetry/. - The legacy local web surface — when enabled for tooling — restricts CORS to localhost,
ships strict security headers, and supports CSRF protection via
APP_CSRF_ENABLED. The supported interactive surface for 1.0 is the Textual TUI and non-interactive CLI runner.
- File-based storage (default): all session state, ledgers, audit logs, and
checkpoints stay on the local disk under
~/.grinta/. - PostgreSQL (optional, knowledge-base migrations only):
backend/persistence/knowledge_base/migrations/can apply SQL migrations when you opt into a Postgres-backed knowledge store. You are responsible for transport encryption and credential management. This is not required for normal CLI usage. - Workspace data is never uploaded to a third party by Grinta itself.
[rag]/ ChromaDB — Grinta uses the embeddedPersistentClientonly (local disk under the project workspace). It does not start or expose the ChromaDB HTTP/FastAPI server. Do not run a standalone ChromaDB server on an untrusted network; CVE-2026-45829 affects network-exposed ChromaDB API deployments until upstream ships a fix.
- Builds use
hatchlingand a pinneduv.lock. - Dependencies are scanned via Dependabot; security-relevant updates are prioritised in the next patch release.
- Release artefacts (PyPI sdist + wheel, Homebrew formula, Scoop manifest) publish a SHA256 in their metadata. Verify before installing in sensitive environments.
Before running Grinta against an unfamiliar repository:
- Read docs/SECURITY_CHECKLIST.md.
- Set
security.execution_profile = "hardened_local"insettings.json. - Lower autonomy with
/autonomy conservativefor the first few interactions. - Confirm a clean
git statusso the post-session diff is meaningful. - Review the audit log after the session ends.