Know the capture boundary, who on a team can read a transcript, and how long investigation evidence stays. A transcript leaves your machine under a grant you gave, and model analysis runs on your own key.
The capture matrix names each source, what it reads, and which reads are blocked at your tier. Secrets and personal data pass through the redactor before a capture is written. Model analysis runs on your own API key.
A transcript leaves your machine under a per-incident grant, recorded on your side and mirrored, so the hosted surface can ask and can never award itself the answer. A hosted read scrubs the classes your team marked regulated, and a policy it cannot read resolves to strict.
A request nobody answers lapses after 72 hours. A granted read closes after 14 days by default and its stored copy is purged with it; a revoke does the same at once. Who can delete a team's hosted rows, and what an export carries, is written down.
This page makes no compliance certification claim, no blanket local-only promise, and no data-residency claim. RepoOps is not SOC 2 certified; certification for the hosted tier is on the roadmap, with no auditor or date named yet. Each row below names the document that answers the question, and the disclosure further down names the module behind each defense.
Reader questions / where the answer livesDocumentation
Code stays local. A receipt, a case, a sanitized package or a session's outcome travels to the hosted account; a transcript travels only under a grant a person gave. The capture matrix lists what each source reads.
A revoke deletes the stored copy and closes the page. A request nobody answers lapses after 72 hours; a granted read closes after 14 days by default and its copy is purged with it.
Retention and deletion terms. On the hosted side an organization's retention window deletes a team's rows, and an export carries the retention label it was taken under.
Model calls, desktop appFrom your machine, on your key
Model calls, hosted tiersOur server, on your key; prompt and answer not stored
Repo content to RepoOps serversOnly when you bind an install to a hosted team
Brain Dreaming and Ask synth run on your own API key. The desktop app writes that key as a plain line in an .env file inside the RepoOps data directory, protected by that directory's owner-only permissions; it does not use a keychain, and this page does not claim one.
Vulnerability disclosure
Report a vulnerability. We answer in writing.
RepoOps is operated by PromptReports LLC, an Illinois limited liability company. If you believe you have found a vulnerability in the desktop app or the hosted surfaces at repoops.ai, email security@repoops.ai with enough detail to reproduce it. Report privately and give us a reasonable chance to fix the issue before any public disclosure. The full policy, with scope and safe harbor, is below, and a machine-readable contact is published at /.well-known/security.txt per RFC 9116.
Response commitments
AcknowledgementWithin 3 business days
Triage and severityWithin 7 business days
Remediation timelineShared once triage is complete
DisclosureCoordinated with you; credit with your permission
Disclosure policy in full, and the evidence behind each claim
Vulnerability disclosure policy
Last updated . RepoOps is operated by PromptReports LLC, an Illinois limited liability company.
1. Reporting a vulnerability
Email security@repoops.ai. Include enough detail for us to reproduce the issue: the affected surface, a description of the impact, and step-by-step reproduction instructions or a proof of concept. If you need to share sensitive details, ask us for a way to exchange them securely and we will arrange one. Please report privately and give us a reasonable chance to fix the issue before any public disclosure. Do not open a public GitHub issue for a suspected vulnerability.
2. Our response commitments
Acknowledgement of your report within 3 business days.
Triage and severity assessment within 7 business days, with an initial view of whether we can reproduce the issue.
Remediation timeline shared once triage is complete. We prioritize by severity and aim to resolve critical issues as quickly as we can.
Coordinated disclosure. We will keep you updated on our progress and coordinate a disclosure timeline with you once a fix is available. With your permission, we are happy to credit you.
3. Scope
In scope for this policy:
The hosted surfaces at repoops.ai and its sub-domains (marketing site, sign-in, billing, team management, hosted dashboard).
The hosted API endpoints under repoops.ai.
The RepoOps desktop app published as repoops-desktop, including its local server and Electron shell.
Out of scope:
Findings that require a compromised device, physical access to a user machine, or a malicious browser extension already installed.
Denial-of-service testing, automated volumetric scanning, and load testing against the hosted surfaces.
Social engineering of RepoOps staff, contractors, or users, and physical attacks.
Reports from automated scanners with no demonstrated, exploitable impact.
Issues in third-party sub-processors (Stripe, hosting providers, and the Anthropic API), which should be reported to those vendors directly. Our sub-processor list is in the Data Processing Agreement.
4. Safe harbor
We will not pursue or support legal action against researchers who, in good faith, discover and report a vulnerability in accordance with this policy. To stay within safe harbor:
Act in good faith to avoid privacy violations, data destruction, and any interruption or degradation of our services.
Only interact with accounts you own or have explicit permission to test. Do not access, modify, or exfiltrate other users' data.
Stop testing and report immediately if you encounter user data, and do not retain, share, or use it beyond what is needed to document the finding.
Give us a reasonable time to remediate before publicly disclosing.
If legal action is initiated by a third party against you for activity that complied with this policy, we will make it known that your actions were authorized. This policy does not authorize testing that violates applicable law.
5. What to expect from a good report
The most actionable reports include: the exact URL or surface, the type of issue (for example, injection, broken access control, or token handling), the impact if exploited, reproduction steps, and any supporting logs, screenshots, or a short proof-of-concept. Please do not include real third-party personal data in your report.
6. Our security posture
The desktop app runs on your machine and does not transmit the content of your repos to RepoOps servers unless you bind the install to a hosted team. Brain Dreaming and Ask synth run on your own API key (BYOK). On the desktop app they call the Anthropic API from your machine, so we never see your prompts or completions. On the hosted tiers our server makes the call, on your key, to the provider you chose, and does not store or log the prompt or the answer. For the hosted surfaces we apply encryption in transit (TLS 1.2+), encryption at rest (provider-managed), least-privilege access, audit logging, and vulnerability management. Full data-handling terms are in the Data Processing Agreement and the Privacy Policy.
7. Compliance
RepoOps is not SOC 2 certified today, and we say so plainly here rather than imply otherwise. SOC 2 Type II certification for the hosted tier is on the roadmap. We have not published an auditor, an observation window, or a target completion date, and we will not name one before it is agreed. Once that is set we will name the auditor, the Trust Services Criteria in scope (Security at minimum), and the completion date in this section.
What we do ship is evidence. RepoOps maps its signals to SOC 2, ISO 42001, NIST AI RMF, and EU AI Act controls and exports an evidence pack per repo, backed by the attestation trail (lib/compliance/evidence-pack.mjs, lib/compliance/framework-map.mjs). It is evidence for your audit, not a claim that we hold a certificate. Change management for the hosted service runs through the pull request gates (review, the CI checks, and the attestation trail on merge). Access reviews, the sub-processor list in the Data Processing Agreement, and this vulnerability-disclosure process are the evidence sources an audit will draw on.
Each card states a claim and names the module that implements it. The module paths are the receipts. These defenses run by default. Connector credentials and app secrets on the hosted side are encrypted at rest before they reach storage, and encryption fails closed when the key is unconfigured in production. The desktop app works differently and we say so rather than claim a keychain we do not use: it writes your Anthropic key and any synced connector credentials as plain lines in an .env file inside the RepoOps data directory, protected by that directory's owner-only permissions.
Hosted secrets are stored in an encrypted vault, not a plaintext .env.
Connector credentials and app secrets are AES-256-GCM encrypted before they reach the database, with a per-value random IV and a GCM auth tag. Encryption fails closed if the key is unset in production, so a misconfigured deploy never silently stores plaintext.
Every write to a person's brain is trust-tiered (write-trust).
A write from a trusted owner surface lands active; a write declaring an external source lands proposed, invisible to every reader until the owner confirms. No write can assert its own trust tier.
Marketplace packs are signed, and unsigned or untrusted packs are refused.
Packs are ed25519-signed; the installer verifies the signature against the receiving brain's trust list and rejects an untrusted signer or a tampered bundle with no skip path. Nothing is written on a failed verdict.
Secrets and PII are redacted before any capture is persisted.
The connector and telemetry paths run every payload through the shared redactor (API keys, tokens, private keys, connection strings, cards, emails) before a byte is written to the brain.
lib/redact.mjs
A marketplace install activates nothing until an explicit human approve (HELD).
A verified pack lands as one inert proposed note. It is invisible and runs nothing until you approve it on the Marketplace tab; reject deletes it and leaves no trace.
lib/marketplace/install-held.mjs
A transcript leaves your machine only when you grant it, for one incident.
Cross-repo incident work runs on a per-incident consent record with six states. A request nobody answers lapses after 72 hours, a granted read closes after 14 days, and a team can shorten both. No hosted code path writes granted: the grant is recorded on your side and mirrored, so the hosted surface can ask and can never award itself the answer.
lib/transcript-grant.mjs
A hosted read scrubs the classes your team marked regulated, and fails closed to strict.
Each team carries its own redaction policy. A hosted brain read resolves that team's classes before it returns a byte, and a policy it cannot read resolves to strict rather than to permissive.
website/lib/redaction-policy-read.ts
A standing red-team suite attacks these defenses in CI on every change.
Adversarial fixtures (poisoned pack, poisoned connector payload, prompt-injection-shaped proposal, tampered signature) assert each defense fails closed. The suite runs in the required checks job, so a regression that opens a gate fails the build before it can merge.
lib/security/redteam/redteam.test.mjs
The memory-poisoning red-team suite
A standing suite (lib/security/redteam/redteam.test.mjs) runs in our required CI checks job. It builds 4 adversarial fixtures the way a poisoning campaign would shape them and asserts each defense fails closed: the poison is rejected, redacted, or held for an explicit human approval, and never becomes an active memory. A regression that opens any gate fails the build before it can merge. Last regenerated 2026-07-13.
poisoned-packfails closed
Attack. A marketplace pack signed by a signer the receiving brain does not trust.
Defense. installPack rejects with untrusted-signer and writes nothing to the imported/ store.
lib/federation/pack-installer.mjs
poisoned-connector-payloadfails closed
Attack. A synced notes file carrying live secrets (AWS key, Slack webhook) and an injection.
Defense. Every secret is redacted before persistence and the note lands as a proposed review record, never an active memory.
lib/sync/folder-connector.mjs
injection-proposalfails closed
Attack. A marketplace-install proposal whose fields carry a prompt injection and a comment-closer.
Defense. The install stays held, the machine marker survives the injection intact, and any non-approve decision fails closed.
lib/marketplace/install-held.mjs
tampered-signaturefails closed
Attack. A trusted signer's pack whose bundle bytes are mutated after signing.
Defense. verifyBundle returns signature-invalid and installPack writes nothing.
lib/federation/signing.mjs
What the suite does not test. 4 named boundaries, because coverage without its edge is a claim without its limit:
The hosted website's TypeScript personal-write-trust guard (website/lib/personal-write-guard.ts) has its own test suite (personal-write-guard.test.ts + the me-brain integration suite); this Node suite covers the desktop/aggregator .mjs defenses.
Network-level attacks (TLS, DoS, SSRF) and infrastructure hardening are out of scope; see the vulnerability-disclosure policy on /security.
The cryptographic soundness of ed25519 itself (delegated to the audited noble-curves primitive), as opposed to our correct use of it.
Social-engineering of the human approver at the HELD gate: the suite proves the gate exists and fails closed, not that a human always decides correctly.
What an investigation inspects
These read the work an agent does and report what they find. They change nothing on their own, and each says when it could not run, because a scan that reports a clean tree it never read is worse than no scan. Captured instructions are evidence: a transcript may contain malicious text, and the investigation tools treat it as content to read, never as permission to act.
The code the agent wrote is scanned as a diff, and each finding carries the session and the dollars behind it.
RepoOps does not rebuild a static analyzer. It shells Semgrep OSS over the agent's working-tree diff and joins each finding to the session that wrote the line and that session's metered cost. With Semgrep absent the scan reports itself unavailable and says why; it never reports a clean tree it did not read.
A package name the model invented is flagged before anyone installs it.
Every dependency an agent adds is checked against the registry, so a hallucinated or squatted name is named as one. An unreachable registry degrades the row to unverified rather than to safe.
lib/dependency-provenance.mjs
A secret is caught at write time, and the record of the catch never holds the secret.
The gate runs the content of a generated file through the same pattern table the redactor uses, so there is no second list to drift out of step. A blocked event keeps the match types, the counts, a fingerprint and a redacted preview, and returns the secret-free view of the write.
lib/secret-gate.mjslib/redact.mjs
A screenshot is a text channel, and the same detectors read it.
An agent that pastes a terminal or a dashboard screenshot moves a secret into a channel no text detector watches. The image is read with local OCR and the extracted text goes through the detectors that already ship, not a second set written for images. The standard installer leaves the OCR engine out to stay small, so there every image reads as unknown, not clean; running RepoOps from source includes it.
lib/multimodal-secret-scan.mjs
Your MCP surface is inventoried, and a tool description that changes under you raises an alert.
Four defenses over the local MCP inventory: drift alerts on a changed tool description, an approved-server allowlist, canary tools that report when something calls them, and a runner that attacks your own MCP setup with the shipped attack library.