Skip to content

Nothing here depends on trusting the workspace.

The workspace is where untrusted things happen: an agent following a prompt it read in an issue, a package with an install script, a contractor's session. Kodela puts the credentials and the exits outside it, on your host, and writes down what passes. If your organisation turns on members’ own computers as workspace hosts, the credentials still stay on the platform there, but internet access is observed, not enforced.

Nine layerspick a layer
  1. 01 Front door host edge

    Every request to a workspace is authenticated before it reaches the container.

    Refuses
    an unauthenticated request to any workspace
    Default
    on · sessions 24 h, revocable
    Check
    sign-in and session settings in the operator console

    Limit. While “require identity” is off, which is the default, the shared front-door password is authenticated but not tied to a person. Plain HTTP unless you put a TLS front end in front.

  2. 02 Workspace workspace

    A container running as a non-root user, with no-new-privileges and memory, CPU and process limits.

    Refuses
    root and sudo inside the container; privilege gain through setuid
    Default
    uid 1000 · 2 GB · 2 CPUs · 512 processes
    Check
    workspace-info

    Limit. Containers are not VMs. No cap-drop, custom seccomp, read-only root or user-namespace remap yet. Docker in a workspace is off until your organisation allows it (workspace_docker_allowed: off, managed or full). Managed Docker runs every call through a per-workspace broker that refuses privileged containers, host namespaces, outside binds and unlisted registries; containers get no internet by default (docker_egress). Pulled images are one shared cache on the host, so a workspace can tell an image was already pulled. Full Docker needs a platform administrator and a supported runtime (Sysbox); under privileged the firewall and no-credentials guarantees no longer hold for that workspace. Not available on members’ computers.

  3. 03 Organisation network org network

    Each organisation's workspaces sit on their own Docker network and cannot reach another organisation's.

    Refuses
    a workspace create, unless the firewall verifies the network and a DNS gateway exists
    Default
    on · one network per organisation
    Check
    egress-coverage

    Limit. Organisations share one host and one control plane. The boundary is a network, not a separate machine. A workspace on a member’s own computer, if your organisation turns that on, uses that computer’s network instead.

  4. 04 Firewall host

    iptables rules per organisation send traffic to the proxy and drop the rest. If the proxy is down, the firewall drops outbound traffic rather than letting it through.

    Refuses
    any direct connection that skips the proxy
    Default
    on · fails closed · survives a reboot
    Check
    egress-firewall verify

    Limit. Anyone with root on the host, or in its Docker group, can change the rules. Who holds those stays your decision.

  5. 05 Egress proxy and DNS filter org gateway

    Decisions by hostname against your allowlist. The DNS filter answers REFUSED for names not on it (all names resolve when file transfer is set to both). Observe mode logs and allows; deny mode refuses.

    Refuses
    in every mode: direct GitHub, unlisted DNS names, copy-tool ports, and ssh, rsync and ftp recognised by their opening bytes on any other port (unless file transfer is set to both). In deny: any host off the allowlist
    Default
    observe
    Check
    egress-proxy summary --days 14

    Limit. Egress ships in observe: it logs and allows until you switch to deny. The proxy does not terminate TLS or read payloads, so an allowed host is still a way out, including a copy tool hidden inside an ordinary HTTPS connection to it. On a member’s own computer, if your organisation turns that on, egress is observed, not enforced, and DNS filtering is not enforced.

  6. 06 Brokers host

    Git through a broker that holds your GitHub App key and identifies the workspace by its socket; model calls through a proxy that holds your key.

    Refuses
    a GitHub credential inside the container; a model key that works off your host
    Default
    on under the guarded profile
    Check
    the workspace's Tools & Info panel

    Limit. Under the open or metered profile the git token is mounted in the container. The per-workspace model key is readable by its developer. The OpenAI, Codex and Antigravity broker is partial and off by default.

  7. 07 Approvals and profiles host

    How much the agent asks first, per member. Settings only get stricter.

    Refuses
    a command or out-of-project write until someone approves it
    Default
    assisted · self-approval · push and PR off
    Check
    the Self-approval and Agent grants cards in the organisation console

    Limit. You approve your own agent's cards by default. Second-person approval exists, off until an admin turns it on.

  8. 08 Validation gate host

    An optional refusal of any push without a passing check for that exact commit.

    Refuses
    a push whose commit has no host-produced passing verdict
    Default
    off until an admin turns it on
    Check
    the organisation's Checks tab in the console

    Limit. Not yet exercised with a real GitHub push.

  9. 09 Audit host disk

    A hash-chained record of identity, workspace, policy, git, egress and model events, plus a label on every push.

    Refuses
    a silent edit: verify names the stream and line of any break
    Default
    on · 90-day retention, raise-only
    Check
    audit-log verify

    Limit. Tamper-evident against anyone short of the host's root user. Nothing ships off the host for you. The push label is signed with a host-held key, so third parties cannot verify it.

What it is built against

This is the project's own threat model. Four ways a workspace goes wrong, and the layers that answer each one.

  1. Prompt injection

    The agent reads an issue, a README or a web page that tells it to do something you did not ask for.

    The injected instruction runs inside the workspace, where the credentials and exits are not.

  2. Exfiltration over allowed hosts

    Code leaves through a host you had to allow for installs, like a package registry.

    Every decision is logged. Some paths stay open today, listed with what limits each.

  3. Credential theft from the environment

    A post-install script reads the environment looking for tokens.

    Under the guarded profile there is no GitHub or model provider key in the container to find.

  4. Unattributable actions

    Something changed, and nobody can say whether a person or an agent did it.

    Each push is labelled agent, human-console or unattributed, never human.

How to check it yourself

Each control has a command that reports its real state on your host. Run them rather than take this page's word.

ControlDefaultEvidence commandWhat it tells you
Firewallon, fails closedegress-firewall verifyWhether the rules are installed and closed
Organisation networksonegress-coverageNames any organisation network without rules
Egress decisionsobserveegress-proxy summary --days 14What left, and what deny would have refused
Audit chainon, 90 daysaudit-log verifyThe stream and line of any break
Organisation postureon demandtenant-auditOrganisations looser than the floor
Evidence reporton demandcompliance-report --framework soc213 technical controls, each MET, PARTIAL or NOT MET

Each one is documented in the reference, with the output you should expect.

What goes into the build

Dependencies, editor extensions and platform skills are pinned by version and checksum. fetch-verified refuses a download whose checksum does not match. A CycloneDX SBOM and an optional gpg-signed manifest describe what shipped.

No image signing and no automated CVE image scan yet. The SBOM is incomplete without syft, and the cloudflared image is not pinned.

Supply chainas shipped
Pins
version + checksum
Mismatch
fetch-verified refuses
Extensions
curated, pinned Open VSX
Skills
pinned, read-only
SBOM
CycloneDX · partial without syft
Manifest
gpg-signed, optional
Image signing
not built yet
CVE image scan
not built yet

What stays your responsibility

Kodela runs on your host, so the host is yours to keep. None of these is done for you.

  • The host's operating system and its patches.
  • TLS in front of the front door. Without it, traffic is plain HTTP.
  • Who holds root, and who is in the Docker group. Docker group membership is root-equivalent.
  • Scheduling backups. bin/backup exists; nothing runs it for you.
  • Your identity provider, including whether it requires MFA.
  • Your SMTP relay. Outbound mail refuses every send until one is configured.

For an audit, these controls map to the evidence report. It is evidence, not a certificate: see compliance evidence.

What it does not cover yet

The short version. The known gaps list every way out we have not closed, and what limits each one today.

  • Egress ships in observe. It logs and allows until you turn on deny.
  • Some exits stay open. npm publish and some AI provider APIs. Copy tools on any port are refused on your host unless file transfer is set to both, but not on members’ computers.
  • Members’ computers are not fenced. Off by default. If a platform operator grants it and your organisation turns it on, egress there is observed, not enforced; DNS filtering is not enforced; the source on its disk is readable by whoever uses it. Tested end to end only on Windows.
  • Privileged full Docker drops the firewall and no-credentials guarantees for that workspace. Operator only, never chosen automatically, and audited.
  • Containers, not VMs. No custom seccomp, read-only root or user-namespace remap.
  • The record trusts host root. Tamper-evident, and nothing ships off the host for you.
  • No native MFA, no SAML, no SCIM. OIDC per organisation is what exists.
  • No image signing or CVE image scan. Dependencies are pinned and checksummed.

Read the gaps before you run it

Then check each layer on your own host. Report a vulnerability tells you how reports will work.