2026-07-29 15:34:25 -04:00
|
|
|
# Security model
|
|
|
|
|
|
|
|
|
|
DocForge is a project-bound knowledge compiler. Its security boundary is an explicit project root,
|
2026-07-29 16:50:39 -04:00
|
|
|
closed configuration, bounded data, and exact identities. It is not a general process or
|
|
|
|
|
filesystem sandbox.
|
2026-07-29 15:34:25 -04:00
|
|
|
|
|
|
|
|
Start with [core authority](CORE_CONCEPTS_AND_AUTHORITY.md), then use
|
|
|
|
|
[policy precedence](POLICY_PRECEDENCE.md) to decide which capabilities a server should expose.
|
|
|
|
|
|
|
|
|
|
## Project and path confinement
|
|
|
|
|
|
|
|
|
|
Descriptors, reference-adapter configurations, canonical sources, authority files, templates,
|
|
|
|
|
changesets, caches, indexes, previews, and declared outputs are resolved against one project root.
|
|
|
|
|
DocForge rejects absolute paths where only project-relative paths are allowed, parent traversal,
|
|
|
|
|
symbolic-link escapes, unsafe file types, and protected-root overlap. Important reads use
|
|
|
|
|
no-follow file descriptors and compare file identity before and after reading.
|
|
|
|
|
|
|
|
|
|
Confinement protects DocForge operations. It does not stop another process with repository access
|
|
|
|
|
from changing files. Long-running bindings revalidate descriptor and adapter implementation
|
|
|
|
|
identity and require a restart after drift.
|
|
|
|
|
|
2026-07-29 16:50:39 -04:00
|
|
|
Generic canonical application stages backups and replacements below
|
|
|
|
|
`.docforge/application/transaction-*` in mode-0700 directories. That private namespace confines
|
|
|
|
|
ordinary path access and prevents access by other users. Deliberate arbitrary tampering by another
|
|
|
|
|
process running as the same operating-system user is outside this boundary. DocForge still
|
|
|
|
|
identity-checks private files before using or removing them, but mode `0700` is not isolation from
|
|
|
|
|
the same UID.
|
|
|
|
|
|
2026-07-29 15:34:25 -04:00
|
|
|
## Untrusted project content
|
|
|
|
|
|
|
|
|
|
Documentation, source text, templates, adapter metadata, compiler-database entries, and changeset
|
|
|
|
|
content are data. They cannot redefine policy or instruct DocForge to execute a command. Generic
|
|
|
|
|
manual rendering disables raw HTML, accepts a fixed template vocabulary, and rejects script-like
|
|
|
|
|
content. Portable graph and manual workers accept validated inert packages and fixed built-in
|
|
|
|
|
renderer identities.
|
|
|
|
|
|
|
|
|
|
The C++ reference adapter reads `compile_commands.json` only as bounded translation-unit inventory
|
|
|
|
|
and fingerprint evidence. It never executes the recorded command, compiler, response file, or
|
|
|
|
|
project program.
|
|
|
|
|
|
|
|
|
|
## Adapter launcher boundary
|
|
|
|
|
|
|
|
|
|
`AdapterLauncherV1` contains one Python module name and project identity. It contains no command,
|
|
|
|
|
shell string, arbitrary argument list, working directory, environment, discovery rule, or callable
|
|
|
|
|
selector.
|
|
|
|
|
|
|
|
|
|
Custom modules must be installed top-level modules. An isolated `python -I` probe resolves the
|
|
|
|
|
module without importing it and requires its regular-file origin to remain inside the bound
|
|
|
|
|
project. The sole trusted dotted exception is the packaged `docforge.reference_mcp` module. Client
|
|
|
|
|
fragments use the exact validated interpreter and canonical fixed arguments with an empty
|
|
|
|
|
environment.
|
|
|
|
|
|
|
|
|
|
This proves that the declared module is resolvable and project-bound. It does not make arbitrary
|
|
|
|
|
module code safe. Project owners remain responsible for the implementation they install.
|
|
|
|
|
|
|
|
|
|
## Mutation boundary
|
|
|
|
|
|
|
|
|
|
Normal MCP and the fixed reference server are read-only. Proposal tools exist only when a
|
|
|
|
|
startup-bound writer is authorized by the descriptor. Canonical application exists only when a
|
|
|
|
|
matching applier is explicitly configured.
|
|
|
|
|
|
|
|
|
|
Every proposal append, rebase, abandonment, and application is hash-bound. Application requires
|
|
|
|
|
the exact changeset hash that was reviewed. Source identity, content hashes, permissions,
|
|
|
|
|
conflicts, graph validity, and serializer round trips are checked before success. DocForge never
|
|
|
|
|
turns prose approval into a fuzzy merge.
|
|
|
|
|
|
2026-07-29 16:50:39 -04:00
|
|
|
The generic applier compares exact canonical file identity immediately before each publication.
|
|
|
|
|
Create uses no-clobber publication. Update and delete use atomic exchange and no-replace moves.
|
|
|
|
|
Concurrent canonical-target mutation therefore fails closed, rolls back when the exact displaced
|
|
|
|
|
state is still provable, or retains recovery evidence without overwriting foreign data.
|
|
|
|
|
|
|
|
|
|
This compare-and-swap protection is not a process-death journal. One file publication is atomic,
|
|
|
|
|
and an in-process failure runs exact rollback, but an application spanning several canonical files
|
|
|
|
|
does not promise crash atomicity if the process or host dies between publications. Operators must
|
|
|
|
|
inspect canonical state and retained transaction evidence before retrying after such an
|
|
|
|
|
interruption.
|
|
|
|
|
|
2026-07-29 15:34:25 -04:00
|
|
|
## Derived state and publication
|
|
|
|
|
|
|
|
|
|
SQLite indexes, source-generation receipts, extraction caches, render fragments, previews, and
|
|
|
|
|
portable artifacts are disposable. Corrupt, stale, foreign, oversized, or mismatched derived
|
|
|
|
|
state is rejected or rebuilt from current project evidence.
|
|
|
|
|
|
2026-07-29 16:50:39 -04:00
|
|
|
Derived publication stages complete bounded output, flushes file and directory state, and commits
|
|
|
|
|
with atomic replacement or no-clobber compare-and-swap. It is crash-safe: an interruption leaves
|
|
|
|
|
the prior verified artifact, the complete new artifact, or explicit degraded post-commit evidence,
|
|
|
|
|
not a mixed publication. Generated command-reference publication also serializes cooperating
|
|
|
|
|
writers. A raced target is restored or retained for recovery instead of being silently discarded.
|
|
|
|
|
|
|
|
|
|
Projection and canonical-application lifecycles record when semantic content committed but later
|
|
|
|
|
private cleanup or receipt verification degraded. Canonical success closes the applied proposal
|
|
|
|
|
and persists compact `application_recovery` metadata with retained paths and remediation. A
|
|
|
|
|
completed mutation is never reported as an ordinary retryable failure.
|
2026-07-29 15:34:25 -04:00
|
|
|
|
|
|
|
|
## Limits and denial-of-service resistance
|
|
|
|
|
|
|
|
|
|
Inputs, results, traversal, context, changesets, renders, worker protocols, manifests, adapter
|
|
|
|
|
assemblies, and extraction caches have explicit count and byte limits. Incremental extraction
|
|
|
|
|
caches are capped at 10,000 sources and 64,000,000 bytes. Adapter primary nodes use the project
|
|
|
|
|
`max_nodes` limit; edges and Logic have deterministic multipliers over that limit.
|
|
|
|
|
|
|
|
|
|
Limits reduce accidental and adversarial amplification. An in-process adapter can still allocate
|
|
|
|
|
memory before returning data, so only trusted project-owned adapter code should run in the server
|
|
|
|
|
process.
|
|
|
|
|
|
|
|
|
|
## Secrets and network behavior
|
|
|
|
|
|
|
|
|
|
DocForge does not copy the parent environment into generated client fragments or detached
|
|
|
|
|
projection workers. Doctor checks never return environment values. The live viewer binds to
|
|
|
|
|
loopback, uses an unguessable URL token, supports read-only methods, and serves no arbitrary
|
|
|
|
|
filesystem tree.
|
|
|
|
|
|
|
|
|
|
Project secrets must not be placed in canonical documentation, adapter configuration, compiler
|
|
|
|
|
databases, templates, or changesets. Repository release gates include secret scanning, but that
|
|
|
|
|
scan is not a substitute for credential hygiene.
|
|
|
|
|
|
|
|
|
|
## No-AST boundary
|
|
|
|
|
|
|
|
|
|
`--no-ast` is a binding policy that preserves the selected adapter and prohibits Logic publication
|
|
|
|
|
and retrieval. It is not a parser detector, filesystem sandbox, or promise that unrelated
|
|
|
|
|
processes cannot parse source. See [legacy and no-AST operation](LEGACY_AND_NO_AST.md).
|
|
|
|
|
|
|
|
|
|
## Reporting and recovery
|
|
|
|
|
|
|
|
|
|
Do not bypass a confinement, identity, policy, hash, or limit error. Preserve the failing evidence,
|
|
|
|
|
stop the affected binding, and follow [recovery and performance](RECOVERY_AND_PERFORMANCE.md).
|