# Security Audit Reviewed 2026-11-04 against commit `cf0bfd4` and the current worktree. Pending relocations of earlier audit documents do not change the production baseline and were left untouched. ## Scope, Architecture, And Threat Boundary PromptKit is an in-process Go library with a public facade and internal configuration, execution, transport, validation, and observation components. ConfigKit owns source loading/composition; PromptKit interprets its final handoff and captures immutable definitions. Execution reads caller-selected artifacts, renders captured templates, resolves credentials, and contacts the selected backend. Prepared handles privately retain one execution's settings. Inspection and observation expose deliberately selected metadata. Reviewed configuration and request validation, filesystem/resource selection, template and JSON handling, credential flow, public formatting and reports, HTTP requests/redirect handling, provider responses, schema loading, repair, backend capacity, prepared ownership, and release-entrypoint wiring. The review included interactions with the selected ConfigKit and JSON Schema dependencies and an advisory scan of runtime packages. The [architecture policy](../../policy/architecture.md#repository-and-consumer-boundary) and [consumer security guidance](../../consumers/pkg-promptkit.md#protect-files-and-generated-data) place application authorization, untrusted path/endpoint admission, payload-size policy, and output disclosure with the consumer. Configuration sources, templates, and injected Go collaborators are application-selected capabilities. Upstream HTTP response bytes remain an external trust boundary. This review does not treat ordinary file selection, runtime endpoint overrides, namespace selection, or supported message roles as authorization mechanisms. No production code or repository tests were changed, no secrets were collected, and no external provider or forge was probed. Network activity was limited to obtaining the public Go vulnerability checker/database and reading official advisories. This is a source review with focused diagnostics, not a claim that every possible consumer deployment is secure. ## Evidence - Source/call-graph review and the applicable public GoDoc, framework formats, integration contract, policies, and ADR 0001. - Existing focused tests passed for credential/report formatting, sensitive configuration inspection/diffs, schema reference containment, provider-body bounds, JSON value cycles/depth, prepared ownership, and capacity boundaries. - A temporary offline public-API diagnostic used a controlled HTTP transport and a synthetic credential. It verified the authentication-body behavior in finding 2 and confirmed that credential was absent from the serialized report. - `govulncheck` v1.9.0 scanned `./...` using Go 1.27.0 and the Go vulnerability database last modified `2026-11-02T22:01:43Z`. The runtime scan covered the module, its examples, ConfigKit v1.1.0, jsonschema/v6 v6.0.2, YAML v4.0.0-rc.6, and x/text v0.14.0. It is not a complete audit of ReleaseKit's implementation or every dependency used only by the release tool. The text-mode scan reported ten symbol-level standard-library advisories, plus package/module-only matches. Those are candidate matches, not ten established PromptKit vulnerabilities. Applicability was checked against the actual operations described below rather than inferred from interface-call traces. ## 1. The Audited Go Toolchain Predates Applicable Networking Security Fixes **Priority:** P2. Build/deployment security finding, not a newly discovered PromptKit algorithm defect. **Relevant code:** [declared Go minimum](../../../go.mod:3), [default HTTP-client construction](../../../internal/llm/openai_compatible_client.go:58), [generation dispatch](../../../internal/llm/openai_compatible_client.go:211), and [diagnostic dispatch](../../../internal/llm/http_evidence.go:129). **Condition and impact:** The local toolchain used for this audit is Go 1.27.0. Applications built with that patch can exercise affected standard-library networking through PromptKit's normal outbound client: - [GO-2026-6611](https://pkg.go.dev/vuln/GO-2026-6611) describes excessive CPU consumption caused by a malicious HTTP/2 peer repeatedly changing initial stream windows. An application using HTTP/2 against a hostile or compromised backend, with enough active streams for amplification, can suffer availability loss. The Go 1.27 fix is in 1.27.2. Body-size limits do not address protocol processing below response decoding. - [GO-2026-6809](https://pkg.go.dev/vuln/GO-2026-6809) adds explicit rejection of compromised intermediate certificates. The affected conditions depend on the platform and trust-store state. When the old trust path remains accepted, an attacker able to present a matching certificate chain and intercept the connection could compromise confidentiality/integrity of prompts, responses, or bearer credentials. The Go 1.27 fix is in 1.27.3. This is not a claim that every default system trust store remains affected. **Evidence and limits:** The advisories establish affected versions and attack conditions; source review establishes use of the standard outbound HTTP/TLS path. No certificate forgery, HTTP/2 attack, or running consumer binary was tested. The scanner's surprising interface-based paths from unrelated methods are not relied upon as proof of exploitation. PromptKit is source-only: a consumer's actual compiled toolchain and transport configuration determine its exposure. The `go 1.27.0` directive is a compatibility minimum, not a record of which patch built an application. **Potential remediation:** Use an appropriate current patched Go toolchain, at least 1.27.3 within this series for these two fixes, for release validation and ReleaseKit execution; advise consumers to rebuild affected applications with patched Go. Recheck advisories against that selected toolchain. This fits the existing distinction between consumer minimum and maintainer toolchain in the [release procedure](../../release.md#prepare-the-candidate). Whether to raise the consumer minimum for the identified fixes is a separate compatibility decision under the existing policy, not an automatic consequence of this audit. These fixes do not require custom TLS verification, a blanket HTTP/2 ban, or a new recurring release gate. ## 2. Authentication Probes Permit Unbounded Remote-Body Memory Consumption **Priority:** P2. Existing availability finding, confirmed at the external response boundary. This is the same mechanism as resource-management audit finding 1, not a second independent remediation item. **Relevant code:** [authentication recognition](../../../internal/usecase/smoke_authentication.go:139), [authentication probe execution](../../../internal/usecase/smoke_authentication.go:66), and [diagnostic HTTP execution](../../../internal/llm/http_evidence.go:129). **Condition:** A consumer explicitly invokes an `openrouter_key` authentication diagnostic. The selected endpoint, a compromised provider, or an intermediary on an operator-selected plaintext connection returns HTTP 200 with a large or continuously growing body. Recognition uses unrestricted `io.ReadAll` followed by whole-document JSON unmarshalling. Unlike generation response decoding, this path has no byte budget. HTTP-only probes also do not use generation capacity admission. **Impact:** The remote peer controls memory consumption before the diagnostic returns. A fast response can cause large allocations or process termination before a deadline, and concurrent probes multiply the exposure. A configured timeout bounds time, not bytes allocated during that interval. This requires a diagnostic call; it is not an unauthenticated inbound attack on a PromptKit server, and ordinary `Run` does not execute the probe. **Evidence:** The offline diagnostic returned a minimal recognized account object and 4 MiB of irrelevant padding. PromptKit read all 4,194,374 bytes, closed the body, and concluded with credential acceptance. The body used an unknown content length. No deliberate memory exhaustion was attempted. The synthetic bearer credential was supplied to the controlled transport and was absent from the serialized diagnostic report. **Potential remediation:** Select a finite body budget for this small diagnostic protocol and enforce it for declared and streamed lengths, closing on overflow without unbounded draining. Preserve factual reporting: overflow establishes neither credential rejection nor acceptance. Agree the limit and overflow classification explicitly; no existing authentication-body byte guarantee is being enforced. The existing resource-audit remediation can own this fix; there is no need for separate global limits on prompts or artifacts. ## Other Candidates And Boundary Checks - **Scanner applicability:** Server-only advisories GO-2026-6603, 6612, 6613, and 6617 do not establish an attack on PromptKit's outbound client. ECH server parsing (6607), multipart-form parsing (6608), and Range-serving behavior (6609) likewise lack a matching operation here. The CONNECT-with-body condition in 6605 and raw HTTP/2-to-HTTP/1 header forwarding in 6610 are absent from built-in POST/GET generation and factual diagnostic reporting. Windows junction-directory creation (6604) is not established by read-only resource opens. These exclusions concern PromptKit, not all possible code in a host application. - **Module-only matches:** x/text advisories GO-2026-5970 and 6629 were not reported as called vulnerable symbols; no matching use of `norm.Iter` or `precis.Nickname` was established. html/template advisories 6599 and 6600 do not apply to the text/template renderer. No separate runtime third-party vulnerability was substantiated by this scan; that is not a general safety certification of those modules. - **Files and schemas:** Ordinary artifacts intentionally allow unrestricted caller-selected regular files. Host-backed `content_file` contexts use ConfigKit's rooted filesystem, while the standard schema loader checks canonical containment and rejects remote reference schemes. Generic `fs.FS` inputs remain caller-supplied capabilities; logical path checks do not turn an arbitrary filesystem implementation into a host sandbox. No additional confinement guarantee is proposed. - **Injection:** Variables and artifact text are rendered as data rather than reparsed as Go templates. Captured templates have the input helper and normal text/template functionality, not a shell or process-execution helper. Provider payloads use JSON encoding and reserved-field checks. Model output is data for validation/repair, not executable code or an authorization decision. Prompt injection and domain-aware interpretation remain consumer concerns. - **Credentials and disclosure:** Direct keys are request-scoped, excluded from supported JSON and public request summaries, and removed from diagnostic settings and prepared details. Provider error defaults redact details; explicit provider accessors and arbitrary application content retain the documented consumer disclosure responsibility. Inspection/diff tests protect configured sensitive provider paths. No blanket redaction of arbitrary prompt, schema, variable, error, or provider content is promised. - **Ownership and availability:** Engine snapshots and copied public values prevent ordinary cross-call mutation. Prepared handles enforce owner binding and single claim. Capacity and retry cleanup are tested. Intentionally unlimited backends, synchronous template/schema dependency calls, and application-selected large files are not newly classified as vulnerabilities. The other resource-audit findings remain maintenance items rather than independently demonstrated remote attacks. - **Release tooling:** Local launchers pass quoted arguments through `exec`; there is no PromptKit runtime command-execution surface. The delivery token path is ignored and selected for committed-file protection. Publication, token-file permission enforcement, and recovery implementation belong to ReleaseKit; no publication command was run during this audit. ## Recommended Follow-Up Use a patched Go toolchain before release preparation and address the existing authentication-body availability finding. Neither requires a new application authorization subsystem or stronger filesystem, endpoint, or semantic-output contracts. No additional PromptKit-specific confidentiality, integrity, or authorization defect was substantiated within the documented boundary.