Cordon is a local credential-injection proxy. It intercepts HTTP/HTTPS traffic on the loopback interface and injects API credentials from external secret stores. This page describes the security architecture, trust boundaries, and design rationale.Documentation Index
Fetch the complete documentation index at: https://docs.codezero.io/llms.txt
Use this file to discover all available pages before exploring further.
This document describes the Community (local) deployment model. Network-facing deployment models (Team/Enterprise) extend the trust boundary and are documented separately as they ship.
Design principles
These principles govern all security decisions in the local deployment model.Structural security over configuration-dependent security
Security properties are enforced by code, not by operators setting the right flags. There are no environment variables, CLI flags, or config options that weaken the security posture. If a property matters, it is hardcoded or enforced by the type system. Examples:- The bind address is hardcoded to
127.0.0.1— there is no option to bind to another address. - For unmatched outbound traffic, the SSRF denylist is always on — there is no option to disable it. Configured HTTP credential routes are a documented v1 exemption.
- For HTTPS routes and PostgreSQL upstreams, upstream TLS verification uses the system root store — there is no option to skip certificate validation.
Credential injection, not credential management
Cordon fetches credentials from external vaults and injects them into outbound requests. It never persists, encrypts, or manages a credential store of its own. There is no Cordon-managed database to breach. The proxy’s security does not depend on defending a credential store — it depends on the security of credential sources the developer already trusts and controls.No infrastructure in the request path
The proxy runs on the developer’s machine. Outbound requests go directly from the proxy to the upstream API — no intermediate cloud services, no shared multi-tenant servers, no SaaS relay. External trust is limited to the credential source (OS keyring or vault provider), which the developer already trusts and controls. Out-of-band CLI update checks and telemetry are separate from proxied application traffic and are listed in CLI telemetry and update checks.Defense in depth through the type system
TheSecret type enforces zeroization, log prevention, and explicit access at compile time. #![forbid(unsafe_code)] prevents bypassing these guarantees. Security properties that depend on developer discipline are replaced by properties that depend on compilation.
Trust boundaries
Credential lifecycle
Credentials pass through five stages. There is no “at rest in Cordon” stage for API credentials — the proxy holds no credential database, no encrypted store, and no API credential material on disk.| Stage | Location | Protection |
|---|---|---|
| At rest | External vault (1Password) or OS keyring | Vault/OS-managed encryption |
| In transit (vault → proxy) | 1Password CLI stdout or D-Bus session bus | Process-scoped; no network exposure |
| In memory | Secret type on the proxy’s task stack | Zeroize on drop, no Debug/Display, token-gated boundary access |
| In transit (proxy → upstream) | HTTPS request, plain HTTP request, or PostgreSQL connection | HTTPS and PostgreSQL use TLS with system root CA validation; plain HTTP routes remain cleartext and should only be configured intentionally |
| After use | Zeroed | Guaranteed by Rust Drop implementation |
Explicit trust dependencies
Cordon trusts the following components. Compromise of any of these is outside the proxy’s trust boundary.- The local operating system — process isolation, memory protection, keyring access control. A compromised OS is outside the trust boundary.
- The credential source — 1Password or OS keyring returns the correct secret. Cordon does not verify secret correctness, only that resolution succeeded. When using the
opCLI backend, the pre-authenticated session may be accessible to other same-user processes depending on the authentication method — see 1Password security considerations. - The upstream TLS PKI — for HTTPS routes and PostgreSQL upstreams, system root certificates validate upstream identity. Cordon uses the system trust store and provides no mechanism to override or disable certificate validation.
- The developer’s route configuration — configured HTTP routes are an explicit trust decision. Cordon uses matched routes to authorize credential injection and upstream selection; in v1, matched HTTP routes bypass private/link-local/loopback denylist blocking while still using origin-bound host checks and DNS pinning. Misconfigured routes can direct credentials to unintended destinations.
- The installed agent skill file —
cordon setupwrites an agent skill file to disk that tells the AI agent how to use Cordon. The authoritative content is embedded in the binary, but the installed copy is a plain text file that a same-user process could modify. Installed files are set to read-only (0444) andcordon doctordetects content mismatches, but there is no cryptographic integrity check at agent read time. See the threat model for details.
CLI telemetry and update checks
Cordon does not send proxied application requests through Codezero infrastructure. The CLI does make out-of-band HTTPS requests tohttps://api.codezero.dev/cordon/v1/check for update checks and lightweight telemetry.
| Collection point | Event | Purpose |
|---|---|---|
First cordon start update check | install | Initial install signal and update check |
Later cordon start update checks | start | Active-use signal and update check |
cordon doctor | doctor_ok, doctor_warning, or doctor_error | Troubleshooting signal bucketed by diagnostic result |
cordon_version, os, arch, and event. When telemetry is enabled, cordon start creates and sends an opaque install ID stored under the Cordon config directory. cordon doctor sends that install ID when it already exists, but does not create it before the first cordon start install event. Cordon does not send route hosts, config paths, service names, secret source names, credential values, Authorization headers, or individual doctor check messages.
Telemetry and update checks can be disabled with environment variables:
| Environment variable | Effect |
|---|---|
CORDON_NO_TELEMETRY=1 | Disables the install ID. cordon start still checks for updates without the ID; cordon doctor does not send telemetry. |
DO_NOT_TRACK=1 | Same telemetry opt-out behavior as CORDON_NO_TELEMETRY=1. Only the value 1 is treated as enabled. |
CORDON_NO_UPDATE_CHECK=1 | Disables all update-check and telemetry network calls. |
Credential storage
Cordon delegates credential storage entirely to external providers. The proxy holds no credential database, no encrypted store, and no API credential material on disk. HTTP route secrets exist in the proxy’s memory only during active request injection; PostgreSQL listener credentials are resolved at startup and held while the listener runs.| Source | Config value | Storage | Encryption |
|---|---|---|---|
| OS keyring | keyring | macOS Keychain / Linux Secret Service | OS-managed (encrypted at rest) |
| 1Password | 1password | 1Password vault | 1Password-managed |
Platform differences
macOS Keychain encrypts entries at rest and enforces per-application access control. Only the binary that created an entry can read it without triggering an authorization dialog. Linux Secret Service (GNOME Keyring, KDE Wallet) encrypts entries on disk and unlocks them with the user’s login session. There are no per-application ACLs — any process running as the user can read entries. Security relies on Unix user isolation. On Linux, secrets are transmitted to the Secret Service provider over the D-Bus session bus without transport-layer encryption (no DH key exchange). This is a deliberate trade-off: the session bus is a Unix socket restricted to the current user, so any process that could observe bus traffic already has same-user code execution and could query the Secret Service directly. The trust boundary is the session bus access control, not encryption on top of it.In-memory secret handling
Secrets in memory are protected with multiple layers:- Zeroized on drop — secret values are overwritten with zeros when no longer needed, reducing the window for memory scraping
- No Debug or Display — the
Secrettype has noDebugorDisplayimpl. Attempts to log or format a secret fail at compile time, not at runtime. - Token-gated boundary access — plaintext is accessible only through callback methods that require a capability token. Each protocol boundary module defines its own token with a private constructor, confining plaintext access to the specific module that needs it. Compile-fail tests enforce this from external crates.
- No unsafe code — the core library forbids unsafe code at compile time
Network security
Loopback-only binding
The proxy always binds to127.0.0.1. The config only accepts a port number, not a bind address — it is structurally impossible to configure a non-loopback address. This ensures the proxy is only accessible from the local machine.
Auth header stripping
For matched routes, Cordon unconditionally strips inboundAuthorization, Proxy-Authorization, and the configured credential header, then replaces auth with the credential from the configured secret source. This is not conditional — the proxy does not check whether the inbound header matches a placeholder, is empty, or contains a real credential. Strip-and-replace is always applied.
This prevents credential passthrough attacks where a manipulated agent sends a valid credential in the Authorization header hoping the proxy will forward it unchanged to an unintended destination.
SSRF protection
All unmatched HTTP forwarding is subject to SSRF validation. Configured HTTP credential routes are exempt from private/link-local/loopback denylist blocking in v1: a route is an explicit trust decision by the developer and is allowed to target internal APIs, VPN/private endpoints, PrivateLink services, staging environments, and localhost development services. For traffic that does not match a configured route, there is no way to bypass the IP denylist. Cordon acts as a credential oracle — any process that can reach it can cause authenticated requests to configured upstream APIs. For untrusted runtimes (AI agents, LLM-generated code), this creates a potential SSRF exposure if left unmitigated. For unmatched traffic, Cordon addresses this with an always-on IP denylist that blocks connections to internal infrastructure (cloud metadata, private networks, localhost services) before they leave the proxy. For unmatched HTTP traffic, blocked ranges include:- Private networks:
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 - Loopback:
127.0.0.0/8 - Link-local / cloud metadata:
169.254.0.0/16(blocks AWS/GCP/Azure metadata endpoints) - CGNAT:
100.64.0.0/10 - IPv6 equivalents:
::1,fc00::/7,fe80::/10, and more - IPv6 transition addresses (IPv4-mapped, NAT64, 6to4, Teredo, ISATAP) have their embedded IPv4 extracted and re-checked
Configured HTTP credential routes skip private/link-local/loopback denylist checks in v1. They authorize credential injection and upstream selection for the configured host, but they are not a general protection against malicious same-user callers. Post-v1 policy work will revisit the default and likely require explicit private-upstream opt-ins.
TLS interception
For HTTPS routes, Cordon performs TLS MITM using a locally-generated CA certificate. See TLS configuration for details.- The CA private key is stored with
0600permissions - The CA cert must be explicitly trusted by the user
- Per-host certificates use
SubjectAltName(not CN) as required by modern clients - Upstream TLS verification uses the system root certificate store. There is no environment variable, CLI flag, or configuration option to disable certificate validation.