Security
The security model
Legwork reads code to diagnose incidents, which means you are trusting it with source access. This page describes, plainly, how that access is constrained.
Source access is read-only
Legwork connects to your repositories through a GitHub App with read-only permissions: repository metadata, contents, Actions, and Deployments. It cannot push, open pull requests, or change anything in your repositories.
Installation tokens are short-lived and minted per analysis, only to resolve the exact commit and obtain temporary archive downloads. Neither the tokens nor the GitHub App private key ever enter an analysis sandbox, and repositories are never stored in our database — source exists only inside the active sandbox.
Disposable analysis sandboxes
Every analysis runs in its own disposable sandbox, created for that run and destroyed when it finishes — including when it fails. The working copy of your code is gone with it.
Inside the sandbox, no network access: agent inspection runs in a network namespace with no egress, and a capability probe verifies that DNS, public HTTP, private networks, and cloud metadata endpoints are unreachable from that boundary before command execution can ever be enabled.
Executing repository code is disabled by default. It stays disabled unless the full capability probe has passed in the target environment and two explicit configuration gates are set; otherwise the agent is limited to bounded static inspection — listing, searching, and reading files.
Stored credentials and secret redaction
- Callback signing secrets and notification webhook URLs are stored encrypted with AES-256-GCM.
- Service API keys are stored only as SHA-256 hashes; the plaintext is shown once at creation.
- Inbound incident payloads are scanned for secret-shaped values — API keys, tokens, webhook URLs, private keys — and redacted before they are stored.
- Outbound callbacks and notification messages are redacted again on the way out, so a secret quoted in model output never leaves the system.
30-day retention
Incident payloads, analysis runs, agent steps, diagnoses, and callback and notification delivery records expire 30 days after the run is created. A daily purge deletes expired records. Aggregate usage counters, which contain no prompt, source, log, or diagnosis content, are what remains for billing.
Outbound delivery is SSRF-safe
- Callback URLs must be credential-free HTTPS on port 443.
- DNS is resolved freshly for every delivery; loopback, private, link-local, and other non-public answers are rejected, and the approved address is pinned for the request to resist DNS rebinding.
- Every callback is signed with HMAC-SHA256 over the timestamp and body so you can authenticate it.
- Slack and Discord notification webhooks are allowlisted to their exact official hosts.
Tenant isolation
Every customer-owned record carries its organization ID, and queries always combine record IDs with the organization derived from the authenticated session or service key. Organization IDs supplied by the browser are never accepted as authority.
What the model sees
Analysis requests to the model carry the incident context and only the specific file excerpts and tool output the investigation requested — never whole repositories. Complete conversations and hidden reasoning are not persisted, and every citation in a diagnosis is validated against the actual source snapshot before the result is stored.
Reporting and questions
If you believe you have found a vulnerability, or you have questions this page does not answer, email hello@legwork.cloud. We read every report.