The agent is untrusted code. We built the product around that.

An autonomous coding agent clones your repository and executes arbitrary commands against it. That is the same risk profile as a CI runner, and we treat it that way. This page describes the isolation architecture in enough detail to forward to your security team. Questions and disclosures: security@fragonstudios.com.

Threat model

Two things must never happen: an agent run touching anything outside its own sandbox, and one customer's data reaching another customer. Everything below exists to enforce those two properties, fail-closed.

One qualifying fact before you read 3,000 words of architecture: FragonForge is a hosted service and connects to your forge over the internet. An instance that is only reachable inside your VPN cannot be connected today; details in the Reachability section below. On the Enterprise tier, a deployment on your own hardware can be arranged by agreement.

  • EU residency: yes
  • Per-run isolation: yes
  • Audit log + CSV export: yes
  • TOTP 2FA: yes
  • SAML SSO: not yet
  • SOC 2 / ISO 27001: not yet
On this page
data flow, one run

your forge

calls our public webhook URL; we call its API over HTTPS

control plane

clone, push, and MR calls happen here

forge token + LLM key live here

sandbox

per-run Kubernetes job, egress: deny

zero credentials inside

gateway + LLM proxy

one door out, per-run token; your key attached on the way out

your LLM provider

your contract, your bill; bodies are never stored by us

Execution isolation

Each run executes in a dedicated Kubernetes job, created for that run and destroyed after it.

  • Hardened runtimes

    Sandboxes run under gVisor, a user-space kernel that intercepts syscalls. The Team and Business plans use Kata Containers, which put each run in its own lightweight VM with a separate guest kernel.

  • Non-root, pinned, scanned

    The sandbox image runs as a non-root user, is pinned by digest (not by tag), and is vulnerability-scanned with Trivy in CI before it can be deployed.

  • Real toolchains, no secrets

    The image ships compilers and test runners. It ships no credentials of any kind.

A note on honesty: no sandbox is escape-proof. gVisor and Kata have had CVEs over the years, like every isolation layer. That is why the design assumes the sandbox can turn hostile: no credentials inside it, default-deny networking around it, and one authenticated door out. The runtime is one layer, not the whole defense.

Network isolation

  • Default-deny egress

    A Kubernetes NetworkPolicy denies all outbound traffic from the sandbox by default, enforced by the Calico policy engine. We are aware that some CNIs silently ignore NetworkPolicy; ours does not, and our isolation tests run against a policy-enforcing CNI for exactly that reason.

  • One door out

    The only permitted destination is the platform gateway. It exposes exactly two things to the agent: repository tools (checkout and diff push, executed server-side) and an LLM egress proxy.

  • Per-run tokens

    The sandbox authenticates to the gateway with an opaque per-run token: 256-bit, stored only as a hash, time-limited, and revoked the moment the run reaches a terminal state.

  • Proxy discipline

    The LLM proxy allows only the configured provider endpoints, guards against SSRF, and strips any inbound authentication headers before forwarding.

The sandbox holds no credentials

This is the core design decision. Cloning, pushing, and opening the merge request happen on the control plane, outside the sandbox. Your forge token never enters the sandbox. Your LLM key never enters the sandbox either: the agent calls the egress proxy, and the proxy attaches your key on the way out, scoped to the provider that was fixed when the run token was minted. A compromised run has nothing to steal and nowhere to send it.

Tenant isolation

FragonForge is multi-tenant, and tenant isolation is enforced in depth, not by convention:

  1. Query-level scoping. Every tenant-scoped row carries a tenant ID, and the data layer applies a global filter to every query. Inserts are stamped centrally, not by hand.
  2. Fail-closed context. Tenant context starts empty. No tenant means zero rows, not all rows. Background jobs re-establish the tenant from the claimed work item before any data access.
  3. Compiler-enforced exceptions. Bypassing the tenant filter without a declared, categorized justification is a build error, enforced by a custom static analyzer. The list of exceptions is auditable.
  4. Leak tests as build gates. Automated two-tenant tests assert that data, credentials, clone URLs, and search indexes never cross tenants. The build fails if any tenant-scoped entity is missing its filter.

Credentials and encryption

  • Each organization has its own data encryption key. LLM API keys, forge tokens, webhook secrets, and TOTP seeds are encrypted with it (AES-GCM).
  • Inbound webhooks are verified twice: a signed per-tenant URL token and the forge's payload signature against your own webhook secret, compared in constant time.
  • Agent output is written to run logs through a secret-redaction filter.

Where your code lives, and for how long

  • The LLM proxy is a pass-through

    It forwards the agent's requests to your configured provider and streams the responses back. It does not log or persist request or response bodies. The flip side, stated as one fact rather than two scattered caveats: because nothing is stored, these calls are not metered in our cost dashboard either. Your provider's logs and bill are the complete record of what the agent sent to the model.

  • Sandbox workspaces are ephemeral

    The repository clone inside the sandbox lives on a pod-local volume that dies with the pod; finished jobs are reaped within minutes. The control plane's own working clone is deleted after every run.

  • Run logs hold agent output, not your repository

    The tenant-visible run log stores the agent's own output, passed through a secret-redaction filter and capped at 64 KiB.

  • The code search index is the deliberate exception

    On paid plans, the optional code index stores chunked source text and embeddings so the agent can search your codebase. It is tenant-isolated at both the database and the vector store, and it is deleted together with everything else when you offboard.

  • Telemetry carries no content

    Traces and metrics record IDs, durations, and token counts. Emails we send never contain repository content.

Account security

  • TOTP two-factor authentication, with recovery codes. Enrollment renders the QR code locally, so the secret does not leave the page.
  • Scoped personal access tokens for API and CLI use, bounded by the owner's live role.
  • Session management: list and revoke sessions, revocation on password change, server-side logout. Refresh tokens live in HttpOnly cookies, not in JavaScript-readable storage.
  • Role-based access control (Owner, Admin, Member, Viewer), fail-closed.
  • Sensitive actions (logins, credential and role changes, run and billing events) are written to a tenant-scoped audit log, with filtering and CSV export in the dashboard.
  • Sign-in is email and password, or Google. SAML SSO does not exist today, and we will not imply otherwise. If SAML gates your rollout, tell us at office@fragonstudios.com; it directly affects prioritization.

Data residency and lifecycle

Two data paths, stated separately. Platform data - the repositories we process, the code index, run logs, keys and tokens - lives on our EU infrastructure, detailed below. Model traffic is different by design: the code the agent sends to a model goes to the LLM provider you chose, under your contract and that provider's region and data terms. BYOK means that boundary is your choice to make; we never route it anywhere else.

  • The platform runs on dedicated bare-metal servers in the EU (Hetzner, Germany). Data at rest stays in the EU.
  • Databases have point-in-time-recovery backups to EU object storage with a 30-day retention window.
  • Run history retention follows your plan (30 days to 1 year).
  • Offboarding is a real purge: database rows, the code search index, stored keys and tokens, and billing links. Self-serve from the app.

Reachability

FragonForge is a hosted service. It connects to your forge's API from our infrastructure, over HTTPS, with the per-organization token you provide. That means your GitLab, GitHub Enterprise, Gitea, or Forgejo instance must be reachable from outside your network. An instance that is only reachable inside a VPN or private network cannot be connected today. A quick self-check: if curl -sI https://your-instance/ answers from a machine outside your network (a phone hotspot works), the instance is reachable. On the Enterprise tier, a deployment on your own hardware can be arranged by agreement; on every other plan there is no workaround today. If that constraint rules you out, tell us; it moves the priority.

Webhooks flow the other way: your forge calls our public webhook URL, the same as any other webhook integration. Nothing connects into your network.

Supply chain

  • Dependency audits gate the build: a moderate-or-higher advisory in any dependency fails compilation.
  • Container images are scanned before deployment; critical findings block the release.

Independent verification

We hold no SOC 2 or ISO 27001 certification today, and we will not pretend otherwise. What we can offer your review now: this architecture description, answers to your vendor security questionnaire, and direct access to the people who built the system. If your process needs a specific document, ask: security@fragonstudios.com.

What we ask of you

Honest boundaries, because they matter more to a reviewer than promises:

  • Review the merge request

    FragonForge never merges its own work. The MR review is a designed-in safety valve, not a missing feature.

  • Scope the forge token

    Connect a token scoped to the repositories you actually want automated, and rotate it on your normal schedule.

  • Set a spending limit with your provider

    Your LLM provider's console can enforce a hard spending limit; use it. Our in-app cost dashboard meters planning and indexing calls today, not the agent's in-sandbox calls, so the provider's numbers are the authoritative ones.

Found something? security@fragonstudios.com. We answer.