Trust

Trust Center

How Kirto is built and run, how to report a vulnerability, and what happens after you do.

Report a vulnerability

Email [email protected]. A GitHub issue, pull request or discussion is a public channel, and a report does not belong in one. The address reaches the maintainer of both products directly.

Say which product and version, what you did, what happened, and what you expected. Machine-readable: /.well-known/security.txt.

What happens after you report

Gate. The policy that ships in Gate's repository commits to the following:

Flow. Flow's repository has no security policy file yet, so Flow makes no response-time or disclosure commitment. A Flow report goes to the same address.

Neither product has a tagged release yet. main is the only version of each, and a fix lands there. Gate's policy adds that once releases begin, the newest tag carries security fixes and older tags get critical fixes on a best-effort basis. Gate's releases and compatibility page is where any longer commitment will be written.

Three things start a report: a one-line title, a technical description of the flaw and where it lives, and reproduction steps. For Gate, the smallest config and request that shows it, or a kirto-gate -test-rules case. For Flow, the model and the case history that shows it. The tag, commit or image digest you tested, who you are, the impact as you see it, a suggested fix and your disclosure plans all help, and none of them is required.

Where your data goes

Both products are self-hosted: the control plane runs in your network. Kirto runs no hosted service in your data path, so there is no subprocessor between your traffic and your providers.

Gate

The binary sends Kirto nothing. There is no licence check, no activation, no usage report and no diagnostic upload. The licence carries no metering code, so no build has one compiled out.

The outbound connections Gate makes are the ones your configuration turns on: the model providers, MCP servers and peer agents you route to; your OTLP collector; your identity provider's JWKS endpoint; huggingface.co when a models entry resolves an hf: reference, which kirto-gate artifacts pin turns into a one-time resolution; a Presidio analyzer you run, for the remote detector; a provider's admin usage API, for metering reconciliation; and an ACME directory, when the front door issues its own certificates. ONNX Runtime runs a telemetry uploader on Linux, and Gate turns it off by default before the runtime starts. The threat model disclosure keeps this list.

Gate does not retain prompt content. No log line carries a body, a prompt, a completion or a matched span. Guardrail decisions log entity counts, such as pii/CREDIT_CARD:1, and audit records name entity types without the text. The store holds virtual-key metadata and token aggregates, and has no column that could hold a prompt. Two exceptions are documented: a guardrail CEL rule you write can read the matched span, and the delta cache keeps annotations keyed by content hash in memory for the life of the process.

Deploy it as the front door with Helm, as the front door on VMs, or beside a gateway you already run.

Flow

Flow runs on a durable host you operate: the broker by default, or DBOS on your Postgres. Its record goes where you point it: rows in your Postgres, one object per event in your S3, GCS, Azure Blob or MinIO bucket, or OpenTelemetry logs to your collector.

Flow's record carries content. Replay re-feeds what arrived from outside the engine, so an agent step records the raw model response and a service task records its outputs. The record is as sensitive as the case data in it, and its store needs the same controls.

The outbound connections Flow makes are the model providers and the endpoints your process models call. The default network policy refuses loopback, private, link-local, CGNAT and unspecified addresses at connect time, which keeps cloud metadata endpoints out of a model author's reach. A deployment opens private ranges deliberately, and a model cannot. Flow has no licence check and no usage report.

The hosts and their configuration are in the Flow docs.

This site

The site is static files served by Cloudflare. It sets no cookies and runs no analytics, and a demo request is an email you send from your own mail client. What happens to that email is in the privacy notice.

Evidence you can check yourself

Gate: a signed chain

Every audit record is a link in a hash chain kept per node. Each entry carries a sequence number, the hash of the entry before it, its own hash, and an ed25519 signature by the node's audit key, generated on first start into cluster.data_dir/audit.key. A chain opens with audit.chain.start, which carries the public key, and a node that stops on purpose closes it with audit.chain.close.

kirto-gate audit verify reads an exported trail offline, with no gateway, cluster or credential. It reports, per chain, whether every record hashes to its entry, links to the one before it, carries a valid signature under the chain's key, and whether a sequence number is missing. It exits 1 on any finding, so it runs as a scheduled job.

kubectl logs kirto-gate-0 | kirto-gate audit verify -

A chain cannot show a trail cut at the end. Every node offers its signed head to the cluster about once a minute, the cluster keeps the last day of heads in replicated state, and verify -heads reports a trail that stops short of one. A cluster of one witnesses itself, so there the collector is the witness.

Records leave on a synchronous exporter, and a record the collector refuses is counted in kirto_gate_audit_export_failures_total. Every record is also written to the node's own output, whether or not a collector is configured.

The trail proves what the key signed. Keeping the key where only the node can reach it is the deployment's part. Verify the audit trail walks through each finding, and the audit trail explains the design.

Flow: a replayable record

Every case records what it decided and why: the pinned model and version, each event that arrived, each command dispatched and its result, each condition and DMN decision, each agent turn and each human approval. The durable host writes the record with the state change it describes, so the record and the engine cannot disagree.

kirto-flow-replay takes the pinned model and a case's history, re-feeds the recorded inputs through a fresh engine, and diffs the decisions it reaches against the stored ones. It exits 0 on a match, 1 on a divergence or a version skew, and 2 when the replay cannot run. The same check is served at GET /v1/cases/{kind}/{id}/replay.

kirto-flow-replay -model order.bpmn -history case-1.json

Replay holds within one MAJOR.MINOR line: the verdict names the version that recorded the case and the version that replayed it, and flags a skew.

Documented limits, not findings

A control that does less than its documentation says is the thing to report. A report of one of the limits below is a documentation question. Report anything that is worse than documented, or reaches further.

For Gate, findings in credential handling, key storage, the admin plane's default-deny, or the inspector's separation from routing are security-relevant whatever their severity looks like.

Gate

The full list is what Gate does not defend against, and threats and limits sets it beside what Gate is asked to stop.

Flow

Certifications

Listed only once a report exists, or with its date once an audit is booked (for example “SOC 2 Type I: audit in progress, report expected …”). Until then, this section stays off the page.