Security

What crosses which boundary.

Most of this page is a description of the implementation rather than a promise. Where a comfortable answer would need information we do not publish here, it says so instead.

Deployment

Where the Filtro Agent, the hosted application and third-party services sit relative to each otherThree lanes. The first holds the hosted Filtro application, its managed PostgreSQL database and its audit log. The second, drawn as a dashed boundary, is the customer's own infrastructure holding the Agent and the customer's own credentials. The third lists services involved in a run: GitHub, the customer's model provider, Resend, WorkOS, Stripe and TypeSafe.ai. An arrow labelled job and result runs from the hosted application to the Agent and back. Two arrows leave the Agent: a read-only one to GitHub, and one carrying the reported claim and source code to the customer's model provider.filtro.devHosted by usPublic appapp.filtro.dev — intake, inbox,investigation, reviewManaged PostgreSQLEvery tenant row carries aworkspace id; RLS fails closedAudit logAppend-only; the databaserejects updates and deletesYour infrastructureYou run thisFiltro AgentOutbound HTTPSonlyYour secretsRead-only GitHubtoken, model keyOther servicesInvolved in a runGitHubRead by your AgentModel providerYours, and your billResendReport intake, repliesWorkOSSign-in, directoryStripeCheckout, subscriptionTypeSafe.aiAssessment normalisationjobresultread-onlyclaim + source
The customer-hosted Agent is the only component that reads repository contents. Everything it returns to Filtro is bounded text plus evidence references.

What runs where

ComponentWhere it runsWhat it can reach
Public appOur hosting, public originIts database, its providers, and the Agent over outbound HTTPS from the Agent's side.
AgentYour infrastructureThe repositories in your local allowlist, your model provider, and Filtro for job delivery.
Internal adminPrivate service, not on the public domainOperational tooling behind an identity allowlist. It never reuses the customer runtime database role.
Migration jobSeparate, run before a releaseSchema only, under a database role distinct from the runtime roles.

Repository access and Agent credentials

Repository access is yours to grant and yours to hold. You create a fine-grained, read-only personal access token, scope it to the repositories you want investigated, and mount it in the Agent environment as a secret file. Filtro has no page for registering it, no endpoint that accepts it, and no copy of it.

The allowlist is local configuration. A report, an email, or a remote analysis bundle cannot add a repository to it. The model is given five read-only tools — list a tree, read a file, search for a literal, inspect a commit, compare revisions — and no shell, no arbitrary HTTP, no environment access and no GitHub write tool. File reads reject symlinks, submodules and common credential filenames.

The Agent authenticates with a long-lived token you generate in the app, shown once. It is exchanged for a short-lived session, and only a SHA-256 verifier of the token is stored. You can rotate or revoke an Agent at any time; revocation stops new sessions immediately, and unfinished work returns to the queue for another eligible Agent.

Model providers, and the assessment step

Two different model calls happen during an investigation, and they have different trust boundaries.

The investigation runs on your Agent against the model provider you configured. Your key, your account, your provider's data policy. This is the call that sees repository source, and it is the reason hosting the Agent yourself is a deployment decision rather than a privacy guarantee.

The final narrative and its evidence metadata are submitted to the hosted control plane, where a normalisation service turns that text into one of the five typed assessments. That step runs under our credential, and the Agent never receives it.

The practical consequence: evidence leaving your environment is a reference and an explanation, not source code — and what reaches your provider includes the report claim and the files the Agent read.

Isolation between customers

Tenant separation is enforced in the database rather than in application code. Every tenant-owned row carries a workspace identifier, queries run inside a transaction that sets that identifier locally, and row-level security policies reject any query where the setting is absent. A missing or wrong context fails closed instead of returning rows.

The public runtime database role is not a superuser, does not own the tables and cannot bypass row-level security. Migrations run under a separate owner role, and the internal admin application runs with a different role and a different access path.

A release-blocking integration suite exercises cross-workspace reads and writes, job ownership, Agent claims and pooled-connection reuse against a real PostgreSQL instance with a restricted role.

What is stored, and what is not

Held per workspace

DataContents
Reports and submissionsReport text, the intake decision, and the researcher address.
ConversationsEvery inbound and outbound message in the workspace thread, with provider delivery status.
InvestigationsAssessment, confidence value, claims, uncertainties, suggested validation, and evidence references: repository, commit, path, line range, explanation.
RemediationReferences you or your team record: pull request, issue, commit, note, and a human confirmation.
Audit eventsActor, operation, timestamp and changed values for every recorded action.
Workspace and billingOrganizations, memberships, Agent registrations, hashed Agent tokens, and billing event records.

Not sent to Filtro

Two things worth being precise about

“Not uploaded to Filtro” is not the same as “never transmitted to a third party”. Source code reaches your model provider. And the investigation narrative is written by that model, so short identifiers, paths and symbols from your code can appear in the narrative stored in your workspace. The Agent rejects fenced blocks, credential-looking strings and verbatim source lines of 40 characters or more, and those checks are backstops rather than a guarantee.

Logs, diagnostics and retention

Telemetry, when you configure an endpoint, is exported over OTLP with report bodies, email content, attachments, source code, prompts, model bodies, tokens and secrets excluded. The Agent's own operational counters — files inspected, model calls, API calls, retries — are visible in the workspace.

Audit records are written in the same transaction as the change they describe, and the database refuses updates and deletes against them. That protection is a property of the application database, not of the infrastructure: an administrator with direct database access is outside it, which is the same caveat any append-only log carries.

Workspace records are retained while they are needed to provide the service and to meet legal obligations. Access, correction and deletion requests go to[email protected]. We have not published a per-record retention schedule, and the product has no self-serve delete for an individual report; both are open items rather than features, and we would rather say so than imply otherwise.

Updates and investigation behaviour

The Agent is deployed as an immutable version. Analysis behaviour is versioned separately as published bundles, and every job names the exact bundle it runs against, so a queued or retried investigation cannot silently pick up new behaviour. The Agent refuses a bundle that needs a capability its binary does not have, or a version newer than itself, rather than running a degraded job.

Investigation ceilings — tool calls, files, bytes of source, model turns, wall-clock time — are enforced locally and can be tightened by the bundle. Hitting one of them ends the investigation as needing more evidence.

Services involved

ServiceRoleChosen by
Application and database hostingRuns the public app, the private admin and the managed PostgreSQL instance.Us
WorkOSAuthentication, sessions, organization directory, team invitations.Us
StripeCheckout, invoices, subscription lifecycle, and webhook-driven access state.Us
ResendReceives inbound reports addressed to a workspace and sends replies to researchers.Us
TypeSafe.aiNormalises an investigation narrative and its evidence into a typed assessment.Us
Model providerRuns the investigation on the code your Agent reads.You
GitHubHosts the repositories the Agent reads.You
Telemetry endpointOptional OTLP export of operational metrics.You

Encryption, assurance and contact

Application, Agent and provider traffic is HTTPS. Session cookies are sealed with a key of at least 32 characters held in the hosting platform's secret store, and provider credentials are supplied to the services that need them as secret values or mounted files. Encryption at rest depends on the hosting and database provider your deployment runs on, so rather than make a blanket claim we do not evidence, ask us for the current answer for the environment you are evaluating.

On assurance: this page does not claim a certification, and the audit evidence export does not confer one. What the export does is record what happened — timestamped events with actors, decisions, policy snapshots, communications and remediation references — mapped to named criteria such as SOC 2 CC7.1 and ISO 27001 A.8.8 so that your own assessor has something concrete to look at. If your procurement process needs a signed agreement, a subprocessor list, an encryption statement or a penetration test summary, ask before you buy and we will tell you exactly where we stand.

Report a security problem to[email protected]. Please include reproduction steps and affected components, and give us a window before disclosing publicly. Do not include secrets, tokens or customer data in the first message.

Read the rest of the data picture

The privacy page covers what we process and how to reach us. The example investigationshows what an assessment actually contains.