From ae89068fc87350dba4efeecd968592df1a9877b0 Mon Sep 17 00:00:00 2001 From: Gale W Date: Mon, 11 May 2026 21:55:52 -0400 Subject: [PATCH 1/3] docs: record security audit findings --- ROADMAP.md | 51 +++++++++- .../artifacts/attack_path_analysis_report.md | 55 +++++++++++ .../artifacts/exhaustive-file-checklist.md | 53 ++++++++++ .../artifacts/finding_discovery_report.md | 61 ++++++++++++ .../artifacts/repository_coverage_ledger.md | 18 ++++ .../artifacts/runtime_inventory.md | 38 +++++++ .../artifacts/seed_research.md | 13 +++ .../artifacts/threat_model.md | 86 ++++++++++++++++ .../artifacts/validation_report.md | 74 ++++++++++++++ .../82ea49d_20260511T213956-0400/report.md | 99 +++++++++++++++++++ 10 files changed, 547 insertions(+), 1 deletion(-) create mode 100644 docs/security-audits/82ea49d_20260511T213956-0400/artifacts/attack_path_analysis_report.md create mode 100644 docs/security-audits/82ea49d_20260511T213956-0400/artifacts/exhaustive-file-checklist.md create mode 100644 docs/security-audits/82ea49d_20260511T213956-0400/artifacts/finding_discovery_report.md create mode 100644 docs/security-audits/82ea49d_20260511T213956-0400/artifacts/repository_coverage_ledger.md create mode 100644 docs/security-audits/82ea49d_20260511T213956-0400/artifacts/runtime_inventory.md create mode 100644 docs/security-audits/82ea49d_20260511T213956-0400/artifacts/seed_research.md create mode 100644 docs/security-audits/82ea49d_20260511T213956-0400/artifacts/threat_model.md create mode 100644 docs/security-audits/82ea49d_20260511T213956-0400/artifacts/validation_report.md create mode 100644 docs/security-audits/82ea49d_20260511T213956-0400/report.md diff --git a/ROADMAP.md b/ROADMAP.md index 3244b26..6ed1d35 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -8,6 +8,7 @@ - [Milestone Progress](#milestone-progress) - [Current Maintainer Priority](#current-maintainer-priority) - [V1 Readiness Checklist](#v1-readiness-checklist) +- [Security Audit Follow-Up](#security-audit-follow-up) - [Live App-Server Findings](#live-app-server-findings) - [Live Testing Expansion Plan](#live-testing-expansion-plan) - [Previous V1 Release Slice](#previous-v1-release-slice) @@ -113,6 +114,13 @@ against Codex-owned workspace, Git, file, and thread facts wherever possible, rather than making SwiftASB or a sandboxed client infer repository identity by walking the local filesystem. +The 2026-05-11 repository-wide security audit adds two patch-sized hardening +items that should land before broadening more protocol surface: preserve or +reject out-of-range numeric JSON-RPC IDs instead of narrowing through +`NSNumber.intValue`, and fail closed for unknown network-policy amendment +actions instead of representing them as `allow`. See +[`docs/security-audits/82ea49d_20260511T213956-0400/report.md`](docs/security-audits/82ea49d_20260511T213956-0400/report.md). + The package can now: - start turns through `CodexThread` @@ -136,7 +144,7 @@ The package can now: - document the supported lifecycle in the README without sending consumers into the tests -That means the current priority order is: +After those audit hardening items, the current broader priority order is: 1. Implement the feature permission policy described in [`docs/maintainers/feature-permission-policy-plan.md`](docs/maintainers/feature-permission-policy-plan.md): @@ -690,6 +698,41 @@ workflow earns them in a later feature release. - Continue tuning recent companion cache calibration, richer file previews, archive-aware retention, and rollback forensic archival. +## Security Audit Follow-Up + +The repository-wide Codex Security audit on 2026-05-11 found no critical or +high-severity issues in the reviewed SwiftASB surfaces. It did identify two +medium-severity protocol/policy hardening tasks and several deferred audit rows +that should stay visible until closed. + +Audit bundle: +[`docs/security-audits/82ea49d_20260511T213956-0400/report.md`](docs/security-audits/82ea49d_20260511T213956-0400/report.md). + +- [ ] Fix JSON-RPC numeric ID narrowing. + `CodexRPCEnvelope.parseRequestID(_:)` currently checks whole-number shape and + then uses `NSNumber.intValue`. Replace that with a range-preserving + conversion or explicit out-of-range rejection, then add boundary tests around + 32-bit and platform `Int` limits. +- [ ] Fix fail-open network-policy amendment mapping. + `CodexProtocolNetworkPolicyAmendment.publicValue` currently maps unknown + wire `action` strings to `.allow`. Preserve unknown values or fail closed so + approval UI and app logic cannot misrepresent malformed or future actions as + permission-widening approvals. +- [ ] Add a focused resource-limit review for stdio line framing and JSON + materialization. + `LineDelimitedDataBuffer` and the JSON-RPC envelope path currently do not have + a documented line-size cap. The audit deferred this because the peer is the + local Codex app-server, but bounded framing would make the transport contract + clearer. +- [ ] Complete a focused `ThreadHistoryStore` audit. + The audit identified local command, file, thread, and token history as + sensitive local metadata but did not close a full line-by-line persistence + review. +- [ ] Complete generated-wire parser/codec review when the upstream wire layer + next changes materially. + Generated models remain internal, but schema refreshes should keep parser and + conversion assumptions visible before public mapping expands. + ## Live App-Server Findings The current live Codex CLI probes have found real app-server behavior that should @@ -1342,6 +1385,8 @@ Completed apps that want Codex-like repository operations through `git` and `gh` when those tools are installed and the app has the required access grant. - [ ] Add archive-aware retention/eviction and rollback forensic archival for removed turn payloads. +- [ ] Fix repository-wide security audit findings around JSON-RPC numeric ID + parsing and network-policy amendment fail-closed behavior. - [x] Add live rollback coverage once the disposable-thread path is reliable enough to assert explicit local rollback markers. - [x] Add a local-only startup mode for recent history observables when live upstream paging is unavailable because the thread is ephemeral or not yet materialized. - [x] Confirm the Swift Package Index listing after the package is publicly indexed and tagged. @@ -1367,3 +1412,7 @@ Completed - 2026-05-08: Added a future optional macOS app-access layer for user-granted directory access and security-scoped bookmark handoff, keeping richer local repository and file-write enrichment separate from app-server-reported workspace facts. - 2026-05-08: Added future command-execution-backed Git and GitHub actions through installed `git` and optional `gh`, scoped by explicit user-reviewed command intents and the app-access permission model. - 2026-05-09: Added the feature permission policy implementation plan, shifting the next app-wide action work toward quiet read-only defaults, one-time mutation-category enablement, proactive Git observability, and human-readable mutation events. +- 2026-05-11: Added the first repository-wide Codex Security audit bundle and + tracked follow-up hardening for JSON-RPC numeric ID parsing, network-policy + amendment fail-closed behavior, transport resource limits, history-store + sensitivity, and generated-wire parser review. diff --git a/docs/security-audits/82ea49d_20260511T213956-0400/artifacts/attack_path_analysis_report.md b/docs/security-audits/82ea49d_20260511T213956-0400/artifacts/attack_path_analysis_report.md new file mode 100644 index 0000000..42d1942 --- /dev/null +++ b/docs/security-audits/82ea49d_20260511T213956-0400/artifacts/attack_path_analysis_report.md @@ -0,0 +1,55 @@ +# Attack Path Analysis + +## F1: Numeric JSON-RPC ID narrowing + +Attack path: + +1. A peer sends a JSON-RPC response or server request with a numeric `id` outside the C `int` range but still representable by `NSNumber`. +2. `CodexRPCEnvelope.parseRequestID(_:)` checks that the number is whole, then converts it with `number.intValue`. +3. The narrowed value becomes `CodexRPCRequestID.int`. +4. SwiftASB uses that parsed ID to classify a response or bind an interactive server request. +5. If two peer-provided numeric IDs collide after narrowing, SwiftASB can route or answer the wrong logical request. + +Preconditions: + +- The app-server peer must emit numeric IDs large enough to narrow or collide. +- The affected flow must involve peer-provided IDs; SwiftASB's own outgoing request IDs are UUID strings. + +Impact: + +- Request/response correlation confusion. +- Wrong interactive request identity binding in malformed or future protocol conditions. + +Severity: + +- Medium. The local app-server trust model limits exploitability, but this is a protocol boundary bug in a library whose job is to safely wrap a moving wire protocol. + +## F2: Unknown network-policy amendment actions fail open + +Attack path: + +1. Codex app-server sends a command-execution approval request with a proposed network-policy amendment. +2. The wire action is malformed, future-versioned, or otherwise not one of the current public cases. +3. SwiftASB maps the unknown value to `.allow`. +4. A downstream app displays or applies the public value as though Codex requested an allow rule. + +Preconditions: + +- App-server emits an unknown network action value. +- Downstream app trusts SwiftASB's public value for approval presentation or response construction. + +Impact: + +- Permission intent is represented fail-open. +- A user or app can approve a broader network permission than the app-server actually encoded. + +Severity: + +- Medium. This directly touches permission vocabulary and should fail closed or preserve unknown values. + +## Non-Reportable Paths + +- Error-response expected-ID mismatch is blocked by transport routing in the normal path. +- Compatibility-after-launch is not a security barrier against malicious executable selection because version probing already executes the selected binary. +- Hook/plugin inventory exposure is local trusted-app metadata exposure under the current package model. +- MCP resource reads require app-server authorization validation; no SwiftASB-side bypass was proven. diff --git a/docs/security-audits/82ea49d_20260511T213956-0400/artifacts/exhaustive-file-checklist.md b/docs/security-audits/82ea49d_20260511T213956-0400/artifacts/exhaustive-file-checklist.md new file mode 100644 index 0000000..9386a1a --- /dev/null +++ b/docs/security-audits/82ea49d_20260511T213956-0400/artifacts/exhaustive-file-checklist.md @@ -0,0 +1,53 @@ +# Exhaustive File Checklist + +The Codex Security workflow requires a file-by-file line review for every in-scope runtime file. This scan used subagents where available, but one transport subagent was blocked by the platform security classifier. Files marked checked were either read directly in this session or reported as fully read by a completed subagent. Deferred rows remain explicit coverage gaps rather than silently completed coverage. + +- [x] `Package.swift` - read for package graph and dependency provenance. +- [x] `Sources/SwiftASB/Transport/CodexAppServerTransport.swift` - directly read. +- [x] `Sources/SwiftASB/Transport/CodexCLIExecutableResolver.swift` - directly read. +- [x] `Sources/SwiftASB/Transport/LineDelimitedDataBuffer.swift` - directly read. +- [x] `Sources/SwiftASB/Transport/CodexTransportError.swift` - directly read. +- [x] `Sources/SwiftASB/Transport/CodexRPCRequestID.swift` - directly read. +- [x] `Sources/SwiftASB/Protocol/CodexAppServerProtocol.swift` - subagent reported full read, targeted validation directly read critical decode lines. +- [x] `Sources/SwiftASB/Protocol/CodexAppServerProtocol+Types.swift` - subagent reported full read. +- [x] `Sources/SwiftASB/Protocol/CodexRPCEnvelope.swift` - subagent reported full read, targeted validation directly read full file. +- [x] `Sources/SwiftASB/Protocol/CodexProtocolError.swift` - subagent reported full read. +- [x] `Sources/SwiftASB/Public/CodexAppServer.swift` - subagent reported full read; critical areas directly read. +- [x] `Sources/SwiftASB/Public/CodexAppServer+Bootstrap.swift` - subagent reported full read. +- [x] `Sources/SwiftASB/Public/CodexAppServer+Compatibility.swift` - subagent reported full read. +- [x] `Sources/SwiftASB/Public/CodexConfig.swift` - subagent reported full read. +- [x] `Sources/SwiftASB/Public/CodexErrors.swift` - subagent reported full read. +- [x] `Sources/SwiftASB/Public/CodexAppServer+CommandExecution.swift` - subagent reported full read. +- [x] `Sources/SwiftASB/Public/CodexAppServer+ThreadLifecycle.swift` - subagent reported full read. +- [x] `Sources/SwiftASB/Public/CodexAppServer+TurnLifecycle.swift` - subagent reported full read. +- [x] `Sources/SwiftASB/Public/CodexTurnHandle.swift` - subagent reported full read. +- [x] `Sources/SwiftASB/Public/CodexInteractiveRequests.swift` - subagent reported full read. +- [x] `Sources/SwiftASB/Public/CodexAppServer+Library.swift` - subagent reported full read. +- [x] `Sources/SwiftASB/Public/CodexAppServer+LoadedThreads.swift` - subagent reported full read. +- [x] `Sources/SwiftASB/Public/CodexAppServer+ThreadManagement.swift` - subagent reported full read. +- [x] `Sources/SwiftASB/Public/CodexAppServer+GitObservability.swift` - subagent reported full read; critical command path directly read. +- [x] `Sources/SwiftASB/Public/CodexWorkspace.swift` - subagent reported full read. +- [x] `Sources/SwiftASB/Public/CodexAppServer+MCP.swift` - subagent reported full read; critical resource request directly read. +- [x] `Sources/SwiftASB/Public/CodexAppServer+Models.swift` - subagent reported full read. +- [x] `Sources/SwiftASB/Public/CodexAppServer+Hooks.swift` - subagent reported full read; critical metadata path directly read. +- [x] `Sources/SwiftASB/Public/CodexAppServer+CodexExtensions.swift` - subagent reported full read; critical metadata path directly read. +- [x] `Sources/SwiftASB/Public/CodexAppServer+ProtocolPayloads.swift` - subagent reported full read; network-policy mapping directly read. +- [x] `Sources/SwiftASB/Public/CodexFS.swift` - directly read. +- [ ] `Sources/SwiftASB/Public/CodexThread.swift` - deferred full line-by-line review; covered by API/sink inventory only. +- [ ] `Sources/SwiftASB/Public/CodexThread+Dashboard.swift` - deferred full line-by-line review; covered by API/sink inventory only. +- [ ] `Sources/SwiftASB/Public/CodexThread+RecentCommands.swift` - deferred full line-by-line review; covered by API/sink inventory only. +- [ ] `Sources/SwiftASB/Public/CodexThread+RecentFiles.swift` - deferred full line-by-line review; covered by API/sink inventory only. +- [ ] `Sources/SwiftASB/Public/CodexThread+RecentTurns.swift` - deferred full line-by-line review; covered by API/sink inventory only. +- [ ] `Sources/SwiftASB/Public/CodexDiagnostics.swift` - deferred full line-by-line review; covered by API/sink inventory only. +- [ ] `Sources/SwiftASB/Public/SwiftASBFeaturePolicy.swift` - deferred full line-by-line review; covered by API/sink inventory only. +- [ ] `Sources/SwiftASB/Public/SwiftASBFeatureOperationEvent.swift` - deferred full line-by-line review; covered by API/sink inventory only. +- [ ] `Sources/SwiftASB/Public/CodexAppServer+WireMapping.swift` - deferred full line-by-line review; covered by API/sink inventory only. +- [ ] `Sources/SwiftASB/History/ThreadHistoryStore.swift` - deferred full line-by-line review; covered by API/sink inventory only. +- [ ] `Sources/SwiftASB/Generated/CodexWire/Latest/CodexLifecycleV2Batch+JSONValue.swift` - deferred generated internal code review. +- [ ] `Sources/SwiftASB/Generated/CodexWire/Latest/CodexWireInitializeResponse.swift` - deferred generated/hand-owned wire code review. +- [x] `scripts/dump-codex-schemas.sh` - directly read. +- [x] `scripts/generate-wire-types.sh` - directly read. +- [x] `scripts/repo-maintenance/release.sh` - directly read. +- [x] `scripts/repo-maintenance/lib/common.sh` - directly read. +- [x] `scripts/repo-maintenance/version-bump.sh` - directly read. +- [ ] Remaining maintainer wrapper scripts under `scripts/` and `.github/workflows/` - deferred full line-by-line review; covered by sink inventory. diff --git a/docs/security-audits/82ea49d_20260511T213956-0400/artifacts/finding_discovery_report.md b/docs/security-audits/82ea49d_20260511T213956-0400/artifacts/finding_discovery_report.md new file mode 100644 index 0000000..04b7c47 --- /dev/null +++ b/docs/security-audits/82ea49d_20260511T213956-0400/artifacts/finding_discovery_report.md @@ -0,0 +1,61 @@ +# Finding Discovery Report + +## Scope + +Repository-wide security discovery for SwiftASB at commit `82ea49d`, with artifacts stored under `docs/security-audits/82ea49d_20260511T213956-0400/`. + +Subagents were used where the Codex Security workflow suggested them. One transport subagent was blocked by the platform security classifier; transport files were reviewed directly afterward. Other completed subagents reviewed protocol, startup/config, turn/approval, library/git/workspace, and MCP/hook/plugin surfaces. + +## Promoted Candidates + +### C1: Numeric JSON-RPC IDs are narrowed before identity binding + +- Instance key: `jsonrpc-id-narrowing:Sources/SwiftASB/Protocol/CodexRPCEnvelope.swift:67` +- Affected location: `Sources/SwiftASB/Protocol/CodexRPCEnvelope.swift:67` +- Source: inbound JSON-RPC `id` value from the Codex app-server peer. +- Broken control: numeric IDs are checked only for whole-number shape, then converted with `NSNumber.intValue`. +- Sink: `CodexRPCRequestID.int(Int)` is used for response routing and server-request identity. +- Impact: large numeric peer-provided IDs can collapse, wrap, or collide before SwiftASB binds or routes a response/request. +- Closest control: boolean and fractional values are rejected; there is no range-preserving conversion or range check. +- CWE: CWE-190, CWE-681. +- Validation recommended: yes. + +### C2: Unknown network-policy amendment actions fail open to `allow` + +- Instance key: `fail-open-policy:Sources/SwiftASB/Public/CodexAppServer+ProtocolPayloads.swift:229` +- Affected location: `Sources/SwiftASB/Public/CodexAppServer+ProtocolPayloads.swift:226` +- Source: app-server wire `action` value on a network-policy amendment proposal. +- Broken control: `.init(rawValue: action) ?? .allow` maps unknown values to allow. +- Sink: public `CodexNetworkPolicyAmendment` shown to downstream apps and used when applying network-policy amendments. +- Impact: malformed or future-deny/unknown action values can be represented as an allow action in approval UI or app logic. +- Closest control: the public enum only has `allow` and `deny`; unknown values are not preserved or rejected. +- CWE: CWE-20, CWE-284. +- Validation recommended: yes. + +## Suppressed Candidates + +### S1: JSON-RPC error response missing expected-ID guard + +Suppressed after transport validation. `decodeResponse` does not re-check `expectedID` in the error branch, but `CodexAppServerTransport` classifies each inbound message first and removes/resumes only the continuation matching the top-level envelope ID. Through the normal transport path, an error response for ID B is not delivered to the decoder for pending request A. + +### S2: Compatibility enforcement after app-server launch + +Suppressed as a reportable security finding. The resolver computes version and compatibility before app-server launch by running `codex --version`; the one-call startup API currently enforces the compatibility policy after launch, but the selected executable has already run during version probing regardless. This is a design hardening topic, not an exploitable bypass under the local-operator trust model. + +### S3: Hook/plugin/skill local inventory exposure + +Suppressed as a reportable finding under the current threat model. These APIs intentionally expose local app-server inventory to the linked local app. The fields include local paths, command strings, plugin source metadata, and diagnostics, so downstream apps should treat the values as sensitive local metadata, but SwiftASB does not currently claim to redact them. + +### S4: MCP resource read as SwiftASB-side auth bypass + +Deferred rather than promoted. SwiftASB forwards server/URI/thread ID to the app-server; resource authorization belongs to app-server. A lower-trust companion UI design would need separate app-server/resource-policy validation. + +### S5: Git command injection through cwd + +Suppressed. Git observability uses fixed argv arrays: `["git", "-C", cwd] + fixedArguments`. No shell interpolation was observed, and the helper applies output and timeout limits. + +## Deferred Rows + +- `LineDelimitedDataBuffer` and JSON materialization should receive a focused resource-limit review. No concrete untrusted peer path was proven in this scan. +- `ThreadHistoryStore` should receive a follow-up line-by-line review for local sensitive-history exposure and storage growth. +- Generated wire code should receive generated-code-oriented parser/codec review if upstream payloads become a higher-trust boundary. diff --git a/docs/security-audits/82ea49d_20260511T213956-0400/artifacts/repository_coverage_ledger.md b/docs/security-audits/82ea49d_20260511T213956-0400/artifacts/repository_coverage_ledger.md new file mode 100644 index 0000000..3d4c26e --- /dev/null +++ b/docs/security-audits/82ea49d_20260511T213956-0400/artifacts/repository_coverage_ledger.md @@ -0,0 +1,18 @@ +# Repository Coverage Ledger + +| ID | Boundary / Area | Family | Files Checked | Disposition | Evidence | +| --- | --- | --- | --- | --- | --- | +| R1 | Transport process launch | executable substitution, command execution | `CodexCLIExecutableResolver.swift`, `CodexAppServerTransport.swift` | suppressed | Resolver probes discovered executable with argv `--version`; app-server launch uses `Process` argv, not shell. Explicit executable/PATH selection is local operator environment. Compatibility-after-launch recorded as hardening note, not reportable vulnerability. | +| R2 | JSON-RPC response correlation | ID mismatch / protocol confusion | `CodexAppServerTransport.swift`, `CodexRPCEnvelope.swift`, `CodexAppServerProtocol.swift`, `CodexRPCRequestID.swift` | reportable | Numeric IDs are narrowed with `NSNumber.intValue` before becoming `CodexRPCRequestID.int`, creating possible collisions for large numeric peer-provided IDs. | +| R3 | JSON-RPC error decode | response ID mismatch | `CodexAppServerTransport.swift`, `CodexAppServerProtocol.swift` | suppressed | Error branch lacks its own `expectedID` check, but real transport routes response payloads by top-level envelope ID before decode. A mismatched error payload is not delivered to a different pending continuation through the normal transport path. | +| R4 | JSON-RPC framing | memory exhaustion | `LineDelimitedDataBuffer.swift`, `CodexAppServerTransport.swift`, `CodexRPCEnvelope.swift` | deferred | Buffer has no explicit per-line cap and JSON is fully materialized. Local app-server trust and upstream output caps reduce exploitability; no final report finding without a concrete untrusted peer path. | +| R5 | Network-policy approval mapping | fail-open permission representation | `CodexAppServer+ProtocolPayloads.swift`, `CodexInteractiveRequests.swift` | reportable | Unknown network-policy amendment action maps to `.allow`, which can misrepresent malformed or future app-server action values as permission-widening approvals. | +| R6 | Approval and elicitation request identity | confused approval response | `CodexTurnHandle.swift`, `CodexInteractiveRequests.swift`, `CodexAppServer.swift` | suppressed | Public request IDs are internal; turn-handle response APIs pass expected thread and turn IDs. No public constructor for forged request IDs was observed. | +| R7 | Filesystem APIs | arbitrary local file access / traversal | `CodexFS.swift`, `CodexAppServer.swift` | suppressed | SwiftASB forwards paths to app-server-owned `fs/*` methods and does not read local disk itself. File discovery is bounded by depth and result limit but still deferred for resource-hardening review. | +| R8 | MCP resource reads | cross-thread resource exposure | `CodexAppServer+MCP.swift`, `CodexAppServer.swift` | deferred | Public API accepts server, URI, and optional thread ID; enforcement belongs to app-server. No SwiftASB-side bypass found, but downstream trust model and app-server resource authorization need separate live validation. | +| R9 | Hook/plugin/skill inventory | local metadata exposure | `CodexAppServer+Hooks.swift`, `CodexAppServer+CodexExtensions.swift` | suppressed | Sensitive-looking command/path/diagnostic fields are inventory APIs for the local trusted app. They should be documented as local inventory, but this scan did not find secret redaction promises or lower-trust export sinks in SwiftASB. | +| R10 | Git observability | command injection | `CodexAppServer+GitObservability.swift` | suppressed | Uses fixed argv arrays with `git -C ` and no shell interpolation; output cap and timeout are set. | +| R11 | Maintainer schema scripts | shell injection / unsafe output mutation | `dump-codex-schemas.sh`, `generate-wire-types.sh` | suppressed | Variables are quoted in command positions and output paths. Tools are maintainer-controlled local commands. `rm -rf` in force mode targets versioned schema dir under configured schema parent after successful temp output. | +| R12 | Release tooling | unsafe branch/tag/release mutation | `release.sh`, `common.sh`, `version-bump.sh` | suppressed | Release flow checks clean worktree, branch context, SemVer tag shape, CI, review comments, and uses quoted git/gh arguments. Local maintainer workflow remains privileged by design. | +| R13 | History persistence | sensitive local history exposure / unbounded storage | `ThreadHistoryStore.swift` | deferred | Inventory identifies persisted command/file/thread data as sensitive. Full line-by-line store review was not completed in this scan. | +| R14 | Generated wire snapshot | parser/codec behavior | generated wire files | deferred | Internal generated scaffolding is large and was not line-reviewed. Public mapping and protocol controls received targeted coverage. | diff --git a/docs/security-audits/82ea49d_20260511T213956-0400/artifacts/runtime_inventory.md b/docs/security-audits/82ea49d_20260511T213956-0400/artifacts/runtime_inventory.md new file mode 100644 index 0000000..d94a8ca --- /dev/null +++ b/docs/security-audits/82ea49d_20260511T213956-0400/artifacts/runtime_inventory.md @@ -0,0 +1,38 @@ +# Runtime Inventory + +Scan target: repository-wide checked-out SwiftASB repository at commit `82ea49d`. + +## Product Runtime Areas + +- Package manifest: `Package.swift`. +- Public Swift API: `Sources/SwiftASB/Public/*.swift`. +- Internal protocol layer: `Sources/SwiftASB/Protocol/*.swift`. +- Internal transport layer: `Sources/SwiftASB/Transport/*.swift`. +- Local history storage: `Sources/SwiftASB/History/ThreadHistoryStore.swift`. +- Internal generated Codex wire snapshot: `Sources/SwiftASB/Generated/CodexWire/Latest/*.swift`. +- DocC public usage docs: `Sources/SwiftASB/SwiftASB.docc/*.md`. + +## Privileged Or Sensitive Boundaries + +- Process launch: `CodexCLIExecutableResolver` and `CodexAppServerTransport`. +- JSON-RPC framing and ID correlation: `LineDelimitedDataBuffer`, `CodexRPCEnvelope`, `CodexAppServerProtocol`, `CodexRPCRequestID`. +- Command execution via Codex app-server: `executeCommand(_:)`, Git observability helpers, and live probe scripts. +- Filesystem access through app-server: `CodexFS` and `fs/*` request wrappers. +- Permission and approval flow: `CodexInteractiveRequests`, `CodexTurnHandle.respond`, and `CodexAppServer.respond`. +- MCP resource/status surfaces: `CodexAppServer+MCP.swift`. +- Hook/plugin/skill/app inventory: `CodexAppServer+Hooks.swift`, `CodexAppServer+CodexExtensions.swift`. +- Local persistence: `ThreadHistoryStore`. +- Maintainer tooling: `scripts/*.sh`, `scripts/*.py`, `scripts/repo-maintenance/**`. + +## Source And Sink Search Summary + +- Process/shell sinks: `Process` in transport resolver, app-server launch, `command/exec` wrappers, shell scripts. +- Filesystem sinks: app-server `fs/read*` wrappers, schema dump/generation scripts, release/version-bump scripts. +- Network/resource sinks: MCP resource read, marketplace/plugin metadata, GitHub release tooling through `gh`. +- Parser/deserializer sinks: JSON-RPC envelope classification, generated wire decode, Python schema derivation/patching. +- Auth/permission controls: approval requests/responses, permissions approval scope, network policy amendments, sandbox/approval fields. + +## Exclusions + +- `Tests/` was used for targeted validation evidence but excluded from primary runtime coverage because test code is not shipped runtime code. +- `docs/`, media files, schema dumps under `codex-schemas/`, `tmp/`, `.build/`, and generated build outputs were excluded from primary runtime coverage unless they informed shipped behavior or maintainer workflow. diff --git a/docs/security-audits/82ea49d_20260511T213956-0400/artifacts/seed_research.md b/docs/security-audits/82ea49d_20260511T213956-0400/artifacts/seed_research.md new file mode 100644 index 0000000..9eae013 --- /dev/null +++ b/docs/security-audits/82ea49d_20260511T213956-0400/artifacts/seed_research.md @@ -0,0 +1,13 @@ +# Seed Research + +No CVE, GHSA, advisory, issue, release, package-version, or named vulnerability-family seed was provided with this scan request. + +Local seed pass instead used repository-specific high-impact areas from the runtime inventory: + +- JSON-RPC ID and response-correlation controls. +- Permission and network-policy mapping. +- Process launch and Codex CLI executable discovery. +- App-server filesystem, MCP, hook, plugin, command, and local history surfaces. +- Maintainer scripts that launch external tools or mutate release/schema output. + +No external advisory lookup was required for this scan. diff --git a/docs/security-audits/82ea49d_20260511T213956-0400/artifacts/threat_model.md b/docs/security-audits/82ea49d_20260511T213956-0400/artifacts/threat_model.md new file mode 100644 index 0000000..251cc3a --- /dev/null +++ b/docs/security-audits/82ea49d_20260511T213956-0400/artifacts/threat_model.md @@ -0,0 +1,86 @@ +# SwiftASB Security Threat Model + +## Overview + +SwiftASB is a Swift Package Manager library that wraps a locally launched Codex app-server subprocess for Swift, SwiftUI, and macOS clients. Its main runtime value is a typed Swift API over the Codex JSON-RPC app-server protocol, observable thread and turn companions, app-server-owned filesystem/config/MCP/plugin/hook surfaces, and local history reconciliation. + +The package does not expose a network service of its own. The most important security boundary is therefore local and process-oriented: a downstream app links SwiftASB, SwiftASB launches or talks to a local Codex CLI app-server over stdio, and Codex owns the effective sandbox, approval, filesystem, command execution, plugin, hook, and MCP policies. + +Primary runtime code lives under `Sources/SwiftASB/`. Generated Codex wire models under `Sources/SwiftASB/Generated/CodexWire/Latest/` are internal scaffolding and should not be treated as the final public API. Maintainer scripts under `scripts/` are privileged developer tooling for schema refreshes, validation, live probes, and releases. + +## Threat Model, Trust Boundaries, and Assumptions + +Trusted or high-trust actors: + +- The local user/operator who installs Codex, links SwiftASB into an app, chooses the Codex executable, and grants filesystem or network permissions. +- The local Codex app-server subprocess selected by SwiftASB's executable resolver. +- Maintainers running schema generation, validation, and release scripts from the repository checkout. + +Potentially attacker-controlled or lower-trust inputs: + +- App-server JSON-RPC envelopes and event payloads, especially because SwiftASB tracks a moving Codex CLI/app-server surface. +- Prompt text, local-image paths, mentions, skill/plugin names, cwd values, thread IDs, turn IDs, MCP server names, MCP resource URIs, hook/plugin inventory strings, and filesystem paths passed by downstream apps. +- Environment and PATH values used during executable discovery when a downstream app does not pin an explicit Codex executable. +- Repository contents, hook config, plugin metadata, generated schema dumps, and local git metadata when a user opens an untrusted project. + +Important assumptions: + +- SwiftASB itself should preserve straight data flow and avoid silently widening Codex permissions. +- Codex app-server remains responsible for sandbox enforcement, permission prompts, command execution policy, filesystem authorization, MCP resource authorization, and plugin/hook loading. +- Downstream SwiftASB clients may display sensitive local metadata. SwiftASB should preserve enough source/type information for clients to make safe UI decisions, but it is not a redaction layer unless explicitly documented as one. +- Maintainer scripts are run by trusted maintainers in a trusted checkout. They should still avoid shell injection, unsafe unquoted variables, and accidental deletion outside repo-owned temp/output directories. + +## Attack Surface, Mitigations, and Attacker Stories + +Primary attack surfaces: + +- `CodexAppServerTransport` launches Codex, frames JSON-RPC payloads over stdio, stores pending continuations by request ID, and broadcasts server events. +- `CodexRPCEnvelope` and `CodexAppServerProtocol` classify and decode inbound JSON-RPC responses, requests, and notifications. +- `CodexAppServer` exposes thread, turn, filesystem, config, MCP, hook, model, extension, plugin, and history APIs. +- `CodexFS` routes filesystem metadata, directory, file-read, watch, and local fuzzy discovery requests through the app-server. +- `ThreadHistoryStore` persists and reconciles local thread, turn, command, file, and token history. +- Maintainer scripts launch tools including `codex`, `quicktype`, `uv`, `swiftc`, `git`, and `gh`. + +Existing mitigations observed: + +- Public request IDs for interactive approvals are internal, and turn-handle response APIs pass expected thread and turn IDs before delegating. +- `CodexAppServerTransport` routes responses by top-level JSON-RPC envelope ID before protocol-specific decode. +- Command-exec helpers use argv arrays, not shell-interpolated command strings. +- Git observability uses fixed `git -C ...` argv shapes with output caps and timeouts. +- Feature-owned mutation surfaces such as plugin marketplace upgrade are gated by `SwiftASBFeaturePolicy`. +- Compatibility diagnostics distinguish supported, outside-window, and unknown Codex CLI versions. + +Realistic attacker stories: + +- A malformed or future Codex app-server response uses surprising JSON-RPC ID shapes, unknown policy enum values, or very large payloads and causes SwiftASB to misrepresent state to a downstream app. +- A lower-trust SwiftASB client displays or acts on hook/plugin/MCP/filesystem metadata without treating it as sensitive local inventory. +- A local environment or explicit configuration selects an unexpected Codex executable. +- A maintainer runs schema/release tooling in a checkout where local environment variables point tools at unexpected executables or output paths. + +Out-of-scope or lower-severity stories: + +- A fully trusted downstream app intentionally granting session-wide permissions is not a SwiftASB vulnerability by itself. +- The local user explicitly choosing a malicious executable path is operator-controlled configuration, though SwiftASB should make diagnostics clear. +- Codex app-server enforcement failures are upstream Codex issues unless SwiftASB misrepresents or bypasses the app-server-owned boundary. + +## Severity Calibration + +Critical: + +- SwiftASB directly bypasses Codex's sandbox or approval layer and executes attacker-controlled commands, reads arbitrary local files, or writes executable/startup files without Codex policy. +- SwiftASB accepts a forged approval/request identity and answers a different pending request than the UI displayed. + +High: + +- A malformed JSON-RPC or policy payload causes SwiftASB to grant or represent broader permissions than the app-server requested. +- Downstream apps can read MCP resources, filesystem bytes, or thread history across a meaningful thread/workspace boundary because SwiftASB drops or rewrites the app-server's scoping fields. + +Medium: + +- SwiftASB misclassifies malformed permission/policy fields, accepts lossy protocol IDs, or exposes sensitive local inventory to lower-trust UI surfaces without source classification or documentation. +- Stdio framing accepts unbounded single-line app-server messages that can exhaust memory in normal local app use. + +Low: + +- Diagnostics leak local paths to the same trusted local app that requested diagnostics. +- Maintainer scripts have developer-experience hardening gaps that require a trusted maintainer to run them in an already-controlled local environment. diff --git a/docs/security-audits/82ea49d_20260511T213956-0400/artifacts/validation_report.md b/docs/security-audits/82ea49d_20260511T213956-0400/artifacts/validation_report.md new file mode 100644 index 0000000..eacdefe --- /dev/null +++ b/docs/security-audits/82ea49d_20260511T213956-0400/artifacts/validation_report.md @@ -0,0 +1,74 @@ +# Validation Report + +## V1: Numeric JSON-RPC ID narrowing + +Disposition: reportable hardening finding. + +Evidence: + +- `CodexRPCRequestID` stores numeric IDs as Swift `Int`. +- `CodexRPCRequestID.init(from:)` decodes `Int` directly when the decoder is used. +- `CodexRPCEnvelope.parseRequestID(_:)` uses `JSONSerialization`, receives numeric IDs as `NSNumber`, rejects booleans and fractional values, then uses `number.intValue`. +- On macOS, `NSNumber.intValue` is a C `int` conversion, which is narrower than Swift `Int` on the supported platform. + +Validation result: + +The lossy conversion exists at the boundary where inbound JSON-RPC envelope IDs are classified for both responses and server requests. The practical severity is limited because SwiftASB-generated client request IDs are UUID strings and the local Codex app-server is the expected peer. The finding remains valid as protocol hardening because server-request IDs are peer-provided and approval/elicitation response identity is bound from this parsed value. + +Severity: Medium. + +## V2: Unknown network-policy amendment actions fail open + +Disposition: reportable finding. + +Evidence: + +- `CodexProtocolNetworkPolicyAmendment.publicValue` maps `action` with `.init(rawValue: action) ?? .allow`. +- Public `CodexNetworkPolicyAmendment.Action` supports `.allow` and `.deny`. +- Approval UI or downstream logic may use the public action value when deciding whether to apply a proposed network policy amendment. + +Validation result: + +This is a direct fail-open representation bug. Unknown app-server action values should not become `allow`. A safer shape would preserve `unknown(String)` or fail closed. + +Severity: Medium. + +## V3: JSON-RPC error responses do not enforce expected ID + +Disposition: suppressed. + +Evidence: + +- `CodexAppServerProtocol.decodeResponse` checks success response IDs after successful decode. +- The JSON-RPC error branch throws `rpcError` without checking `rpcError.id` against `expectedID`. +- `CodexAppServerTransport.handleStandardOutputLine` classifies the top-level envelope first, removes `pendingResponses[id]`, and only resumes the continuation associated with that same envelope ID. + +Validation result: + +The missing guard is locally inconsistent and worth test coverage, but the normal transport path already routes by the same top-level ID before decode. No cross-continuation failure or approval confusion was proven. + +Severity: Not reportable in this scan. + +## V4: Compatibility validation after app-server launch + +Disposition: suppressed as security finding; keep as design hardening. + +Evidence: + +- `CodexCLIExecutableResolver.resolve()` probes `--version`, computes compatibility, and returns a `Resolution`. +- `CodexAppServerTransport.start()` stores the resolution, then launches `codex app-server --listen stdio://`. +- `CodexAppServer.start(_:)` calls `startTransport()` before `cliExecutableDiagnostics()` and `validateStartupCompatibility(...)`. + +Validation result: + +The selected executable is already executed during `--version` probing before any policy rejection can happen. Under the local operator trust model, delaying app-server initialization is not a meaningful security barrier against a malicious executable path. This remains a useful product-hardening note: one-call startup could enforce stored compatibility before app-server launch for clearer behavior. + +Severity: Not reportable in this scan. + +## V5: Hook/plugin/MCP inventory exposure + +Disposition: suppressed/deferred depending on downstream app trust model. + +Validation result: + +Hook and plugin APIs expose local metadata by design. MCP resource reads delegate authorization to the app-server. No SwiftASB-side redaction promise or lower-trust export sink was found in this scan. If SwiftASB later supports a remote or lower-trust companion, these surfaces should be revisited as explicit data-classification boundaries. diff --git a/docs/security-audits/82ea49d_20260511T213956-0400/report.md b/docs/security-audits/82ea49d_20260511T213956-0400/report.md new file mode 100644 index 0000000..133ad26 --- /dev/null +++ b/docs/security-audits/82ea49d_20260511T213956-0400/report.md @@ -0,0 +1,99 @@ +# SwiftASB Repository-Wide Security Audit + +Scan ID: `82ea49d_20260511T213956-0400` +Commit: `82ea49d` +Date: 2026-05-11 +Tooling workflow: Codex Security repository-wide scan phases: threat model, finding discovery, validation, attack-path analysis, final report. + +## Summary + +The audit found two medium-severity protocol/policy hardening findings and no critical or high-severity findings in the reviewed surfaces. + +One subagent was blocked by the platform security classifier, so transport files were reviewed directly. Several large or lower-priority areas remain explicitly deferred in the coverage ledger rather than marked complete. + +## Findings + +### F1: Numeric JSON-RPC IDs are narrowed before identity binding + +Severity: Medium +Status: Reportable +CWE: CWE-190, CWE-681 + +Affected location: + +- `Sources/SwiftASB/Protocol/CodexRPCEnvelope.swift:67` + +SwiftASB classifies inbound JSON-RPC envelope IDs by parsing Foundation JSON, checking numeric values for whole-number shape, then converting `NSNumber` with `intValue`. On the supported macOS platform this is narrower than Swift `Int`, so large numeric peer-provided IDs can wrap or collide before becoming `CodexRPCRequestID.int`. + +This matters because SwiftASB uses parsed request IDs to route responses and bind app-server interactive requests. SwiftASB's own outgoing request IDs are UUID strings, which limits normal exploitability, but peer-provided server-request IDs still cross this boundary. + +Recommended fix: + +- Convert numeric IDs with a range-preserving path, such as decoding through `Int64` or `Int` with explicit exactness checks. +- Reject out-of-range numeric IDs with `invalidJSONRPCEnvelope`. +- Add boundary tests around 32-bit and 64-bit limits. + +### F2: Unknown network-policy amendment actions fail open to `allow` + +Severity: Medium +Status: Reportable +CWE: CWE-20, CWE-284 + +Affected location: + +- `Sources/SwiftASB/Public/CodexAppServer+ProtocolPayloads.swift:226` + +`CodexProtocolNetworkPolicyAmendment.publicValue` maps unknown wire action strings with `.init(rawValue: action) ?? .allow`. If the app-server sends a malformed or future action value, SwiftASB represents it to downstream apps as an allow action. + +This is a fail-open permission representation bug. Network-policy amendment values should preserve unknown data or fail closed so approval UI and app logic do not accidentally widen permissions. + +Recommended fix: + +- Change the public enum to include `unknown(String)` or throw during conversion. +- Prefer fail-closed behavior for approval and permission surfaces. +- Add tests proving unknown action values are not represented as allow. + +## Suppressed Or Deferred Items + +- JSON-RPC error-response expected-ID mismatch was suppressed because transport routing resumes continuations by the same top-level envelope ID before protocol decode. +- Compatibility enforcement after app-server launch was suppressed as a security finding. The selected executable already runs during `--version` probing, so this is product hardening rather than a meaningful malicious-executable barrier. +- Hook/plugin/skill metadata exposure was suppressed under the current local trusted-app threat model. Downstream apps should still treat this as sensitive local inventory. +- MCP resource reads were deferred to app-server authorization validation; no SwiftASB-side bypass was proven. +- Stdio line/message size limits and JSON materialization were deferred as resource-hardening work. +- `ThreadHistoryStore`, generated wire code, and some observable companion files remain deferred for full line-by-line audit coverage. + +## Evidence + +Primary artifacts: + +- `artifacts/threat_model.md` +- `artifacts/runtime_inventory.md` +- `artifacts/exhaustive-file-checklist.md` +- `artifacts/repository_coverage_ledger.md` +- `artifacts/finding_discovery_report.md` +- `artifacts/validation_report.md` +- `artifacts/attack_path_analysis_report.md` + +Subagent-assisted reviewed areas: + +- Protocol decode and JSON-RPC envelope files. +- Startup, compatibility, config, and error files. +- Turn lifecycle, approval, elicitation, and turn handle files. +- Library, loaded thread, thread management, Git observability, and workspace files. +- MCP, hooks, models, extensions, and protocol-payload files. + +Directly reviewed areas: + +- Transport launch and line-buffer files. +- Filesystem access surface. +- Key app-server methods around thread, filesystem, config, MCP, extensions, and turn start. +- Schema dump/generation and release-maintenance scripts. + +Validation commands: + +- No build or test suite was run because this task was an audit/report artifact pass with no code behavior changes. +- `git diff --check` should be run before commit if this docs artifact is committed. + +## Residual Risk + +This scan did not claim exhaustive closure for every source file. The coverage ledger preserves deferred areas explicitly. The strongest next pass would be a focused fix branch for F1 and F2, followed by targeted Swift tests, then a second audit slice for `ThreadHistoryStore`, generated wire parsing, and resource limits. From df075b7ccaf209e45686a044359df68c601fb3bd Mon Sep 17 00:00:00 2001 From: Gale W Date: Mon, 11 May 2026 21:55:57 -0400 Subject: [PATCH 2/3] release: bump versions for v1.3.2 --- README.md | 4 ++-- ROADMAP.md | 20 ++++++++++---------- docs/maintainers/v1-public-api-audit.md | 6 +++--- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index ef6f281..0987bea 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Listen to the SwiftASB Codex apps promo clip: ### Status -SwiftASB is actively maintained and supported by Gale. Our current API is v1, and `v1.3.1` is the current and latest release. +SwiftASB is actively maintained and supported by Gale. Our current API is v1, and `v1.3.2` is the current and latest release. ### What This Project Is @@ -38,7 +38,7 @@ I built SwiftASB because I saw so many others building and forking existing Apps Add SwiftASB to your `Package.swift` dependencies: ```swift -.package(url: "https://github.com/gaelic-ghost/SwiftASB", from: "1.3.1"), +.package(url: "https://github.com/gaelic-ghost/SwiftASB", from: "1.3.2"), ``` Then add the library product to your target dependencies: diff --git a/ROADMAP.md b/ROADMAP.md index 6ed1d35..a5dc5d8 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -78,7 +78,7 @@ | Non-UI local history-reading helpers | `Partially shipped` | `CodexThread` now exposes a lightweight `HistoryWindow` page shape for recent local history, older or newer local windows around a known boundary turn id, centered `windowAroundTurn(...)` reads, centered `windowAroundItem(...)` reads, direct `ClosedTurn` reads for one turn, and convenience array helpers over those same windows. This gives non-UI callers an intentional path into the local history store without binding a UI-oriented observable, while still deferring a broader public cursor model, transcript search surface, and richer history-query helpers. | | Public API curation | `Shipped / ongoing` | The source-organization pass has split app-wide model, MCP, thread-management, history, and observable companion values into focused public files while preserving `CodexAppServer`, `CodexThread`, and `CodexTurnHandle` as the three real owners. The connected public-surface review closed the v1 ownership model; post-v1 curation now includes app-server-owned project identity and thread source facts for launcher UI without exposing generated wire models. Future curation should stay tied to concrete public API additions. | | DocC documentation | `Shipped / ongoing` | `Sources/SwiftASB/SwiftASB.docc/` contains a package landing page, public-handle extension pages, conceptual articles for app-wide capabilities, interactive lifecycle, thread management, history/observable companions, generated-wire boundary notes, and copy-pasteable walkthroughs for startup, progress/approval handling, diagnostics/history, and SwiftUI observable companions. The catalog is validated through Xcode `docbuild`; future work is ordinary stale-link, prose, and symbol-comment refinement as the public API grows. | -| Swift Package Index readiness | `Shipped` | `.spi.yml` declares `SwiftASB` as the documentation target, and Swift Package Index lists `gaelic-ghost/SwiftASB` with a documentation link, compatibility/build results, Package ID `9B5839D9-9551-473F-A939-841534A3FC55`, and a 2026-05-06 update timestamp for the latest confirmed indexed release. Recheck SPI after the `v1.3.1` tag is published. | +| Swift Package Index readiness | `Shipped` | `.spi.yml` declares `SwiftASB` as the documentation target, and Swift Package Index lists `gaelic-ghost/SwiftASB` with a documentation link, compatibility/build results, Package ID `9B5839D9-9551-473F-A939-841534A3FC55`, and a 2026-05-06 update timestamp for the latest confirmed indexed release. Recheck SPI after the `v1.3.2` tag is published. | | Contributor documentation split | `Shipped` | `README.md` is now focused on Swift and SwiftUI package users, while `CONTRIBUTING.md` owns contributor setup, validation, DocC, live-test flags, generated-wire refresh, and PR expectations. | | `CodexTurnHandle` live observable companion | `Partially shipped` | `CodexTurnHandle` owns a live `Minimap` companion that is attached when the handle is created and maintains current-state call snapshots for command, file-edit, dynamic-tool, collab-tool, and MCP item activity. It also now mirrors whether thread context compaction is active for the turn and supports explicit `complete()` handoff into a caller-owned sealed turn snapshot. | | Additional turn event mapping | `Partially shipped` | The public event layer covers the current interactive lifecycle plus the item-start and item-complete events needed for observable call-state mirrors. Raw command-output and file-change-output deltas now stay internal as transport detail but drive the shipped `RecentCommands` and `RecentFiles` companions, and streamed or patch-updated payloads are preserved when later completed snapshots are thinner. Richer MCP-progress detail still remains internal, while warning, guardian-warning, config-warning, deprecation, MCP-server-status, remote-control-status, model-reroute, and model-verification notifications now surface through hand-owned diagnostic events. | @@ -106,7 +106,7 @@ The next meaningful package step is no longer proving the v1 interactive lifecycle, SPI visibility, basic history hydration, first-pass reconciliation, or command-approval completion. Those slices now exist and shipped in the -`v1.3.1` baseline. +`v1.3.2` baseline. The next meaningful work is to widen the reviewed app-server schema and protocol coverage before adding more public query descriptors. Descriptors should compile @@ -224,7 +224,7 @@ After those audit hardening items, the current broader priority order is: ## V1 Readiness Checklist -This checklist records the work that made `SwiftASB` ready for the `v1.3.1` +This checklist records the work that made `SwiftASB` ready for the `v1.3.2` tag. The goal was not to make every possible app-server feature public before v1. The goal was to make the supported lifecycle honest, durable, well documented, and intentionally shaped. @@ -424,8 +424,8 @@ workflow earns them in a later feature release. ### Documentation And Examples -- [x] Update stale release references after the `v1.3.1` release. - Decision: README now names `v1.3.1` as the current released baseline and no +- [x] Update stale release references after the `v1.3.2` release. + Decision: README now names `v1.3.2` as the current released baseline and no longer describes the package as early development. - [x] Finish DocC symbol comments for the supported lifecycle, not just the conceptual articles. @@ -610,10 +610,10 @@ workflow earns them in a later feature release. the `release/v1.0.0` branch on 2026-05-02 and on the `release/v1.0.1-prep` branch on 2026-05-02. - [x] Decide whether another targeted `v0.9.x` patch release is needed before - `v1.3.1`, or whether the remaining work should go straight into the v1 + `v1.3.2`, or whether the remaining work should go straight into the v1 release branch. Decision: no additional `v0.9.x` patch is needed. The remaining work should go - straight into the `v1.3.1` release branch. + straight into the `v1.3.2` release branch. - [x] Prepare v1 release notes with explicit sections for public surface, intentionally internal surfaces, compatibility window, migration notes, validation performed, and known post-v1 work. @@ -667,7 +667,7 @@ workflow earns them in a later feature release. #### Migration Notes - Existing `v0.9.x` consumers should update the SwiftPM dependency to - `from: "1.3.1"` once the tag is published. + `from: "1.3.2"` once the tag is published. - The v1 API surface has removed stale pre-v1 compatibility shims and phantom fields that no longer exist in the reviewed `v0.128.0` schema. - Same-thread overlapping turns are rejected client-side with @@ -692,7 +692,7 @@ workflow earns them in a later feature release. - Keep an eye on future Swift Package Index builds after compatibility-window or DocC changes; the `v1.1.1` listing and documentation link are live, and - `v1.3.1` should be rechecked after the patch tag is indexed. + `v1.3.2` should be rechecked after the patch tag is indexed. - Add broader live server-request coverage for permissions and MCP elicitation if those become stronger public runtime guarantees. - Continue tuning recent companion cache calibration, richer file previews, @@ -1302,7 +1302,7 @@ Completed - [x] Add version-compatibility policy notes for the local Codex binary. - [x] Refresh the compatibility window and promoted generated snapshot against the current `v0.124.0` schema dump once the added endpoint, notification, and field families have been classified. - [x] Curate the public API before v1 by splitting large source files along existing responsibility boundaries where still helpful, tightening public names/defaults, and finishing targeted source-level symbol documentation for the supported lifecycle. - Decision: completed for the `v1.3.1` boundary through the public API audit, + Decision: completed for the `v1.3.2` boundary through the public API audit, symbol inventory, source-comment pass, and focused public file organization. - [x] Add the first DocC documentation catalog before v1, including a package landing page, public-handle topic groups, and conceptual articles for the interactive lifecycle, history companions, and generated-wire boundary. - [x] Validate the DocC catalog through Xcode `docbuild` and document the maintainer command. diff --git a/docs/maintainers/v1-public-api-audit.md b/docs/maintainers/v1-public-api-audit.md index a19a448..ed96921 100644 --- a/docs/maintainers/v1-public-api-audit.md +++ b/docs/maintainers/v1-public-api-audit.md @@ -2,7 +2,7 @@ This document is the working checklist for the `SwiftASB` v1 public API curation pass. The goal is to freeze a compact, Swift-native surface for the -supported app-server lifecycle before `v1.3.1`, not to expose every generated +supported app-server lifecycle before `v1.3.2`, not to expose every generated wire family. ## Current Public Source Inventory @@ -429,7 +429,7 @@ Use these decisions for every public symbol: - [x] Add symbol comments for every stable v1 public type and method that is not self-explanatory from its declaration. - Decision: complete for the `v1.3.1` release boundary. Default-bearing public + Decision: complete for the `v1.3.2` release boundary. Default-bearing public initializers and methods now document whether omission delegates to Codex, chooses a SwiftASB local-history/UI default, or applies an explicit safety default such as `.turn` or `.unchanged`. The source-level pass also covers the @@ -508,7 +508,7 @@ Use these decisions for every public symbol: Decision: covered by the startup, progress/approval, diagnostics/history, and SwiftUI observable companion walkthroughs in `Sources/SwiftASB/SwiftASB.docc/`. - [x] Update stale README release references before the next release. - Decision: README now names `v1.3.1` as the current released baseline. + Decision: README now names `v1.3.2` as the current released baseline. - [x] Confirm README, DocC, and this audit use the same v1 release boundary. Decision: README, DocC, and this audit now describe the same narrow v1 promise: app-server lifecycle, app-wide capability reads, stored-thread From 0b06f55fb6883e5557fc68b2f25e9ec115156c9d Mon Sep 17 00:00:00 2001 From: Gale W Date: Mon, 11 May 2026 23:02:51 -0400 Subject: [PATCH 3/3] docs: align security finding line references --- .../artifacts/finding_discovery_report.md | 2 +- docs/security-audits/82ea49d_20260511T213956-0400/report.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/security-audits/82ea49d_20260511T213956-0400/artifacts/finding_discovery_report.md b/docs/security-audits/82ea49d_20260511T213956-0400/artifacts/finding_discovery_report.md index 04b7c47..aafc4d3 100644 --- a/docs/security-audits/82ea49d_20260511T213956-0400/artifacts/finding_discovery_report.md +++ b/docs/security-audits/82ea49d_20260511T213956-0400/artifacts/finding_discovery_report.md @@ -23,7 +23,7 @@ Subagents were used where the Codex Security workflow suggested them. One transp ### C2: Unknown network-policy amendment actions fail open to `allow` - Instance key: `fail-open-policy:Sources/SwiftASB/Public/CodexAppServer+ProtocolPayloads.swift:229` -- Affected location: `Sources/SwiftASB/Public/CodexAppServer+ProtocolPayloads.swift:226` +- Affected location: `Sources/SwiftASB/Public/CodexAppServer+ProtocolPayloads.swift:229` - Source: app-server wire `action` value on a network-policy amendment proposal. - Broken control: `.init(rawValue: action) ?? .allow` maps unknown values to allow. - Sink: public `CodexNetworkPolicyAmendment` shown to downstream apps and used when applying network-policy amendments. diff --git a/docs/security-audits/82ea49d_20260511T213956-0400/report.md b/docs/security-audits/82ea49d_20260511T213956-0400/report.md index 133ad26..6560a8a 100644 --- a/docs/security-audits/82ea49d_20260511T213956-0400/report.md +++ b/docs/security-audits/82ea49d_20260511T213956-0400/report.md @@ -41,7 +41,7 @@ CWE: CWE-20, CWE-284 Affected location: -- `Sources/SwiftASB/Public/CodexAppServer+ProtocolPayloads.swift:226` +- `Sources/SwiftASB/Public/CodexAppServer+ProtocolPayloads.swift:229` `CodexProtocolNetworkPolicyAmendment.publicValue` maps unknown wire action strings with `.init(rawValue: action) ?? .allow`. If the app-server sends a malformed or future action value, SwiftASB represents it to downstream apps as an allow action.