Network isolation¶
complydoc makes no outbound network connections of its own. This is enforced at runtime. Two things a caller can switch on send data out, and both are named below and recorded in the report.
complydoc/offline.py replaces the standard library's outbound entry points —
socket.socket.connect, connect_ex, socket.create_connection and
socket.getaddrinfo — with functions that raise. It is armed before any file is
opened, in the parent process and in every worker, because a guard that held
only in the parent would be no guard at all.
Local AF_UNIX sockets are allowed, because they cannot leave the machine.
Every AF_INET/AF_INET6 connection and every DNS lookup is refused.
Every report records whether the guard was active, and the test suite runs a full audit with it armed.
Rationale¶
The intended input is documents that cannot be uploaded to a third party.
A stated policy covers first-party code only. Replacing the socket entry points
also covers transitive dependencies: a library that opens a connection during a
run raises NetworkAccessError.
There are three exceptions, and none happens unless a caller asks for it.
inspect_documents(..., allow_network=True) lets the loader being inspected
call connect. The connections are recorded, the report states it, and
complydoc's own processing stays guarded.
A registered instruction classifier can be backed by a hosted service, which
complydoc.integrations.typesafe.jev_classifier is. That sends the text of
the passages it judges to a third party, so the premise at the top of this
page does not hold for a run using one. Building it requires allow_network=True
— there is no default that turns it on — each call is let through the guard one
at a time rather than the guard being lowered for the run, and the hosts are
recorded. A report that sent text somewhere names the hosts in
run.content_sent_to, states it as an important limitation, and the CLI says so
above the summary. A run without such a classifier registered reports nothing
there, because nothing left.
--classifier hands the name to every worker process, which resolves its own,
so a parallel run judges every document and a hosted classifier opens a
connection from each worker rather than only from this one. A classifier
registered in Python cannot cross a process boundary, and
run.classifier_missed_workers counts the documents it therefore never saw.
run.classifier_calls and run.classifier_failures record what was asked and
what could not be answered. A call that fails is no score and so no finding, so
without the second number a run that reached nothing looked like a run that
found nothing.
complydoc assist sends a finished report to a hosted chat model, which drafts
quick wins from it. That report describes documents, and it leaves the
machine: the findings, the readiness signals, the loaders, the cost totals and
the limitations, with masked identifiers and document paths among them. The page
pictures and the text read off each page are held back, and
Drafting quick wins says exactly what goes.
It is a command of its own. No audit, check or policy run calls it, so a run
that never types assist sends nothing; the quick_wins[] in every report are
computed here, on this machine, without a model. The guard is armed as it is for
any other command, the one call is let through offline.permitted() and
recorded, and anything else the model client tries is refused.
Consequences¶
The model catalogue and prices are vendored: data files updated with
make prices and read from disk at runtime. Each price carries its provenance: a
handful verified against a provider's own page, the rest marked imported, and a
report that prices against an imported figure says so.
OCR and name detection are local models, shipped as optional extras because of
their download size. complydoc doctor says what is installed.
Library use¶
The command line arms the guard for the life of the process. The library entry points arm it for the duration of the audit and restore the socket module afterwards, including on exception, so unrelated network calls in the host process are unaffected.
import complydoc as cd
report = cd.security_audit("~/contracts") # guarded
# your own HTTP calls still work here
Pass offline_guard=False only if you know your process needs the network while
the audit runs. The report records that you did.