65 lines
3.3 KiB
Markdown
65 lines
3.3 KiB
Markdown
# Pre-release security review
|
|
|
|
## Scope
|
|
|
|
Manual source review of the project installer, JSONC configuration edits, CLI,
|
|
and packaged content before the first release. The review focused on path
|
|
containment, symlink handling, file ownership, preserving user changes, and
|
|
partial failures. This is not an independent audit, a guarantee against local
|
|
filesystem attackers, or a review of provider/model behavior.
|
|
|
|
## Result
|
|
|
|
No release-blocking issue was identified for the documented project-local use
|
|
on a trusted filesystem. The installer resolves the project root, restricts
|
|
manifest paths to toolkit asset locations, rejects symlinked install paths and
|
|
non-regular files, refuses unmanaged collisions, and verifies hashes before
|
|
replacing or removing managed content. Configuration changes use JSONC edits
|
|
and preserve unrelated entries. Deterministic tests cover collisions, modified
|
|
files, symlinked install directories, and a tampered manifest.
|
|
|
|
## Limitations and operational guidance
|
|
|
|
- The installer does not defend against a concurrent process replacing a path
|
|
after it has been checked (a filesystem time-of-check/time-of-use race). Run it
|
|
only where another actor cannot concurrently manipulate the project tree.
|
|
- The ownership manifest is ordinary project-local JSON, not an authenticated
|
|
record. It protects against accidental overwrite/removal, not a malicious
|
|
project owner who can edit both the manifest and files.
|
|
- Uninstall removes managed files incrementally. If an I/O failure interrupts
|
|
it, the manifest is retained for recovery in normal mid-operation failures;
|
|
resolve the filesystem problem and rerun uninstall. Transactional rollback
|
|
for uninstall remains future work.
|
|
- Provider-backed agent delegation and skill invocation have not been reviewed
|
|
or verified. The runtime smoke test only covered plugin activation and the
|
|
read-only status tool with a local mock provider.
|
|
|
|
## Checks run
|
|
|
|
- `npm run typecheck` — passed.
|
|
- `npm test` — passed, 16 tests.
|
|
- `npm run test:coverage` — passed; 87.4% lines, 95.23% functions, and 81.86%
|
|
branches.
|
|
- `npm pack --dry-run` — passed; included runtime files, selected content,
|
|
licenses, notice, and README.
|
|
|
|
## Optional memory review (2026-10-08)
|
|
|
|
Memory tools are not registered unless `memory.enabled` is explicitly true.
|
|
Session keys include hashes of the OpenCode project identity and session ID;
|
|
project-scope access additionally requires `memory.project: true` and is keyed
|
|
to the canonical project. Each operation checks the session's project ID. Data
|
|
is only stored or returned through explicit tool calls; list previews and
|
|
retrieval become ordinary tool output visible to the active provider. The
|
|
package does not encrypt storage, capture session content, or background-upload
|
|
memory. Retention is lazy: expired entries are rejected and removed on access,
|
|
not by a scheduled purge. Provider-backed learning and persistence across live
|
|
OpenCode restarts have not been verified, so this is not a security audit or a
|
|
claim about the underlying storage implementation.
|
|
|
|
Deterministic checks cover disabled-by-default behavior, session separation,
|
|
project opt-in, project separation, cross-project rejection, explicit deletion,
|
|
and expiry. A plugin config object containing user options is preserved during
|
|
uninstall; users must remove that entry themselves if they converted the
|
|
installer-added string to configure memory.
|