What "headless" has to mean before it means anything else
A headless component is not a product with its front end removed. It is a program that takes an input, produces an output, and exits — with no window, no console anyone has to watch, no service it phones, and no assumption that a network exists at all. The distinction matters because most software described as headless is really a client with the interface detached: it still checks a license server, still emits usage metrics, still resolves a package from a public index the first time it runs. Inside an environment someone else has accredited, each of those behaviors is a finding waiting to be written up.
What we build is narrow: small models that read through a body of data and produce a written conclusion, with every statement traced back to the exact record it came from. When that has to run inside somebody else's boundary, the model is the easy part. The packaging, the interface contract, and the evidence trail are the work — and they are the part that decides whether the thing ever gets to run at all.
The three refusals that define the artifact
No UI. The component has no window and no interactive prompt, because the accredited system already has one — or has none, because the job runs on a schedule with nobody watching. A useful consequence follows from how the rule is scoped. The Revised 508 Standards at 36 CFR Part 1194 — issued under Section 508 of the Rehabilitation Act (29 U.S.C. § 794d), incorporating WCAG 2.0 Level AA — apply Chapter 5 to software that has a user interface or transmits information (E207.1). A component with neither carries no user-interface conformance duty of its own; the host application carries it. What does still reach us is the content the component emits, so we emit it structured well enough for the host to render accessibly: real headings, real lists, no meaning carried by color alone.
No callback. Zero outbound connections at runtime — not for licensing, not for updates, not for weights, not for a public package registry. NIST SP 800-53 Rev. 5 control SC-7 governs boundary protection, and unattributed egress from a vendor component is precisely what an assessor goes looking for. Designing for zero egress makes the answer to "what does it talk to?" a single word, which is worth more in a review than any feature we could have spent that effort on.
No telemetry. We do not get the logs. The component writes them to a filesystem path the customer designates, in a format the customer can read without our tooling, and that is the end of our visibility. Debugging then has to work from an artifact the customer may choose to send us — a run manifest, not a stream. It is slower for us. It is also the only version a customer operating at a high impact level can say yes to.
This is a methods piece written from public standards and published vendor documentation. It describes how we package and hand off software, not any specific customer environment, program, or dataset.
What actually crosses the boundary
The handoff should be a small, fixed set of files with a stated hash for each one. Anything that has to be fetched later is a dependency the customer inherits without agreeing to it.
| Artifact | Form | Why it is separate |
|---|---|---|
| Runtime image | OCI image, referenced by sha256 digest | The Open Container Initiative image spec is content-addressed. A digest names exactly one artifact; a tag names whatever was pushed last. |
| Model weights | safetensors, ONNX, or GGUF, hashed separately | Kept out of the image so the customer can inspect, replace, or re-verify them without rebuilding anything. |
| SBOM | CycloneDX or SPDX | Executive Order 14028 §4 directs software providers to furnish a bill of materials; NTIA's Minimum Elements for an SBOM (July 2021) defines what has to be in it. |
| Signature | Detached signature over image and weights | Sigstore's cosign signs OCI artifacts. It lets the customer prove the bytes they are running are the bytes we built. |
| Interface schema | Versioned JSON Schema | The contract. It changes on its own cadence and its version number is not the model's version number. |
| Run manual | Plain text, offline | Install, verify, run, read the output, uninstall — with no step that requires reaching us or reaching the internet. |
The interface contract
Three shapes are worth considering, and the choice is usually the customer's, not ours. Files in, files out is the most portable and the easiest to schedule; it also leaves an artifact on disk that an auditor can pick up later. stdin/stdout with a JSON envelope is the cleanest to embed in another program and leaves nothing behind, which is sometimes the point. A loopback HTTP server bound to 127.0.0.1 is appropriate when the host needs many calls in one session; binding to loopback keeps it a local socket, not a network service, and that distinction is worth stating explicitly in the documentation because a reviewer will ask.
Whichever shape, the contract needs the same three parts. A schema, versioned independently of the model. Exit codes that mean something — non-zero with a machine-readable error object, never a partial result that looks complete. And an explicit statement of what the component does with an input it cannot handle, because "it produced nothing and returned zero" is the failure mode that hurts most six months later.
Dependency discipline
The base image is the first real decision. Minimal images — Google's distroless family, or Red Hat's Universal Base Image where the customer's scanning tooling expects RPM metadata — reduce the surface a scanner has to argue about. In DoD contexts, Platform One's Iron Bank publishes hardened container images, and DISA's Cyber Exchange publishes STIGs and a Container Platform Security Requirements Guide against which a customer's platform team is likely to be measured. Starting from something they already recognize saves a review cycle you cannot get back.
Nothing installs at runtime. If a build needs the internet, that happens on our side, before the handoff. Every layer is pinned by digest, and the build should be reproducible enough that we can rebuild the same image from the same inputs months later — the practices catalogued by the Reproducible Builds project are the reference here.
GPU coupling is where most of these handoffs actually break. A container that runs on our bench and not on theirs is usually a CUDA driver ABI mismatch, not a model problem. State the minimum driver version in the manual, state whether the NVIDIA Container Toolkit is required, and always ship a CPU path that works — slower — when the accelerated one does not. The same applies to the C library: an image built against glibc will not run on a musl-based host, and finding that out inside a closed enclave costs a full transfer cycle.
Determinism is what they will actually test
The first thing a careful reviewer does is run the same input twice and compare. If the two runs disagree, the conversation is over, regardless of how good either answer was. Getting agreement means pinning seeds, pinning thread counts (floating-point reduction order changes with them), and selecting deterministic kernels where the framework offers the option — PyTorch exposes torch.use_deterministic_algorithms for exactly this, and some cuDNN and cuBLAS paths have no deterministic implementation at all, which is a constraint to discover before you promise anything.
This is also why we tend to keep generation out of the last mile of anything that will be read as an instruction rather than as a draft. We have written up a benchmark where a frontier model out-recalled our deterministic extractor and still could not ship, including the number that goes against us. The short version: you cannot certify a function that does not agree with itself.
What the customer has to provide
This list is not a formality. Every item on it is a decision only the customer can make, and the absence of any one of them means the artifact we build has a guess baked into it.
- A named container runtime and version — Docker, Podman, containerd, or a bare OS baseline — confirmed to exist inside the enclave.
- CPU architecture, and if a GPU is in play: model, driver version, and container toolkit.
- A memory and disk ceiling stated as a number, not as "should be fine."
- A read path for input and a writable path for output and logs, both owned by the customer, with the retention and disposal rule already decided.
- A service identity to run as — non-root, with file permissions granted in advance.
- A transfer path for the artifact and the name of whoever authorizes it.
- A named person who will perform the first execution and can read a log back to us.
- A decision on whether the output is CUI, and if so, the marking it carries. NIST SP 800-171 is the control baseline for CUI on nonfederal systems — note that Revision 3 (May 2024) is the current NIST edition, while DoD contracts under DFARS 252.204-7012 remain on Revision 2 by class deviation.
What changes as the impact level rises
The DoD Cloud Computing Security Requirements Guide, published by DISA, defines the Impact Levels that govern how sensitive information may be hosted. The engineering inside the component barely changes across them. Everything around the component changes a great deal.
| Level | Information it covers | What it changes for a headless handoff |
|---|---|---|
| IL4 | Controlled Unclassified Information | Transfer is usually electronic within an authorized region. Scanning and SBOM review dominate the schedule. |
| IL5 | CUI requiring higher protection, and unclassified National Security Systems | Tighter separation and personnel requirements. Expect the artifact to be re-scanned by a platform team you never speak to. |
| IL6 | Information classified up to SECRET, in SIPRNet-connected accredited infrastructure | Transfer becomes a governed event under the customer's media-handling and cross-domain process. Every fix costs a full cycle. |
The practical design consequence sits in that last cell. When a round trip is expensive, the artifact has to be diagnosable from what is already on the inside — verbose-by-default local logs, a self-check mode that validates its own environment before it touches data, and error messages written for someone who cannot ask us a follow-up question. Related reading: STIG compliance for LLM containers and Kubernetes in the IC tier.
The evidence the component produces about itself
Every run writes a manifest beside its output: the image digest, the weights digest, the configuration actually used, a hash of the input, start and end timestamps, the schema version, and — for our work specifically — a pointer from each statement in the conclusion back to the record it came from. It is a plain file the customer owns.
It serves two purposes at once. It is how the customer reproduces a result a year later without us, which is what an auditor is really asking for. And because there is no telemetry, it is the only debugging channel we have; when something goes wrong, the manifest is the thing a customer can review, redact if needed, and choose to send.
Where we draw the line
We do not ask for accounts inside your boundary
No VPN, no credentials, no seat in your enclave as a condition of delivery. If a component only works when the vendor can log in, it is not a headless component — it is a managed service with the word "headless" on the box.
We do not take your sensitive data onto our systems to "test against something real"
Evaluation runs on synthetic fixtures we build, on public corpora, or on your side with your people executing. If a fair evaluation genuinely requires controlled technical data, that is a separate, documented arrangement under the appropriate agreement — the firm holds a DD Form 2345 certification through the Joint Certification Program (CAGE 1AYQ0) — and it happens before any file moves, not after.
We do not operate the transfer or the cross-domain path
Moving an artifact into a closed enclave is the customer's accredited process, run by their people under their authority. We build to it and document against it. We do not sponsor it, and we will not propose a schedule that quietly assumes we can.
We do not claim an authorization we do not hold
A component that runs inside someone else's boundary inherits their authorization. It does not create one for us. Any vendor telling you their software "is IL5" without naming whose authorization boundary it sits in is describing a hope, not a status — and it is the kind of claim that turns into a finding during assessment.
We do not ship weights whose provenance and license we cannot state
Every model that goes into an artifact gets a written line of origin and a license the customer's counsel can read. If we cannot produce that, the model does not go in, however well it scores.
Frequently asked questions
A component with no user interface, no outbound network calls at runtime, and no vendor telemetry. It reads an input, writes an output and a run manifest to paths the customer owns, and exits. Anything else — license checks, auto-update, usage metrics — is egress a reviewer will have to account for.
As a fixed set of files with a published hash for each: an OCI image referenced by digest, model weights, an SBOM, a signature, a versioned schema, and an offline run manual. The customer's own media-handling or cross-domain process moves them inside; the vendor does not operate that path.
No. The component inherits the customer's authorization for the environment it runs in. It does not produce an authorization for the vendor or for the software as a standalone offering. The Impact Levels themselves are defined in DISA's DoD Cloud Computing Security Requirements Guide.
Because reproducibility is what makes a result defensible. If the same input produces different output across runs, the result cannot be validated, reproduced in an audit, or certified. Pinned seeds, fixed thread counts, and deterministic kernels are the price; on GPU paths, some operations have no deterministic implementation and that limit should be stated up front.
Runtime and version, CPU/GPU and driver, memory and disk ceilings, the read and write paths, the service identity, who authorizes the transfer, who runs it first, and whether the output is CUI. Each of those is a customer decision; guessing at any of them puts an assumption inside the deliverable.
