Skip to main content
PatentSchmiede

Data security and AI use

Data security and AI use

A statement for the firm's IT

This statement is for the IT of the firm that has to approve the installation. It describes what already holds, and it names the open points.

Base: 2026-08-19 · Support clarifications: 2026-09-22 · applies to PatentSchmiede from 0.3.0 · Ollama cloud models (section 1) and outbound channels (sections 3 to 5): as of 2026-10-03, applies from the first release after 0.3.0 · safeguards per value of the ENVIRONMENT setting and the narrower statement on the external development provider (section 4) and the data location in Model A (section 1): as of 2026-10-08, applies from the first release after 0.3.0

The support clarifications refer to package draft 0.2. It is not yet legally approved. The technical basis was checked against a fixed source revision, not against a firm installation. The other sections were not fully re-validated. The statements as of 2026-10-08 (sections 1 and 4) were checked against a later fixed source revision.

Reading note that applies to the whole paper:

Every statement below is either evidenced in code or explicitly marked as an organisational commitment. Where a property arises only from the firm’s configuration, that is stated alongside it. An assurance the software does not enforce is not an assurance — it is an intention.

01 / 09

Two supported operating models

The installation supports two operating models. The comparison sets them side by side, and the diagram shows the inference path of each.

Model B, the point that matters

The firm's contract partner is Microsoft, not us. The inference path described here runs from the firm's installation directly to its own Azure endpoint. A possible data access by us during support or maintenance must be assessed separately (section 8).

What actually leaves in Model B, in full

Not only chat prompts. For the embedding, the application assembles the title, abstract, description, and Ansprüche (claims) of a document and sends them to the provider. Anyone who uses the semantic search or the reference library thereby transmits document text, not merely questions. For section 3 this is the decisive point: the 30-day retention applies to inputs and outputs.

Model A: what “local” requires

Ollama can also run models in the cloud. An Ollama cloud model (its name ends in :cloud or -cloud, for example gemma4:cloud) runs on ollama.com, even when the Ollama server runs at the firm. The supplied Compose files therefore start Ollama with OLLAMA_NO_CLOUD=1: the server refuses cloud models and references to models on other servers. A firm that connects its own Ollama server must also set OLLAMA_NO_CLOUD=1 there. The provider posture reports a configured cloud model as a warning. It cannot detect a model with a local name that points to another server.

Explicitly not supported

Operation in the firm's cloud tenant by us, and a SaaS operated by us. Neither is a roadmap gap, but a product decision.

This is evidenced in the source: the provider selection, the services of the production stack with OLLAMA_NO_CLOUD=1, and the cloud-model check in the provider posture.

Firm infrastructureOutsideBrowserCaddyFrontendBackendNeo4jOllamaNo outboundconnections forinference
Firm infrastructureOutsideBrowserCaddyFrontendBackendNeo4jAzure OpenAIPrompt content andembedding textResponse
Comparison of the two operating models
QuestionModel A — local inferenceModel B — hosted inference
Where the language model runsOn the firm's hardware, in the ollama containerAt Microsoft, Azure OpenAI
Where the data livesPatentSchmiede stores the data exclusively on the firm's infrastructure. Section 5 names the configurations in which data can leave the firm, such as web research being switched onDocuments on the firm's infrastructure. The prompt content and the embedding text additionally go to the provider
Controller (GDPR)The firmThe firm
Processor for inferenceNo external inference providerMicrosoft, in the firm's contract with Microsoft
Contract with us required§ 203 service-provider package as soon as remote maintenance, log inspection, or updates are carried out by us (section 8)the same
Outbound connections in operationNone for inferenceTo the firm's Azure endpoint

Without JavaScript, the page shows both diagrams one below the other and the complete table.

02 / 09

Where the data lives

The local data resides on the firm's infrastructure. In Model B, content is additionally processed at the inference provider (section 1). Separately approved support files are governed by section 8.

Local storage locations
LocationContent
Volume neo4j-dataAnmeldungen (patent applications), Erfindungsmeldungen (invention disclosures), Ansprüche (claims), descriptions, draft versions, features, embeddings
Volume uploads-dataUploaded documents in the original
Volume ollama-dataModel weights (no client data)
Volume logs-dataApplication logs (see section 6)
Volumes neo4j-logs, neo4j-import, neo4j-pluginsDatabase logs, import directory, plugins
Volumes caddy-data, caddy-configTLS material, including the private key of the internal CA
Host Docker log storeA duplicate of the application logs. Logging additionally writes to stderr, which Docker stores under the data root
Backup target PS_BACKUP_DIRNightly copies of the database and uploads

All these locations sit under the firm's Docker data root or in the selected backup target. This list of local storage locations describes neither the processing at the inference provider nor separately approved support copies. The production file defines nine volumes. The assignment and the encryption obligation are described in the documentation on encryption at rest.

What the backup does not include

The backup copies the volumes neo4j-data and uploads-data. Logs, TLS material, and the environment file .env are explicitly excluded. Anyone who wants to start up again after a total loss needs the environment file and the Caddy material from separate safekeeping.

03 / 09

Azure OpenAI — the often-overlooked section

Azure OpenAI does not train on customer data. That is the part most statements name. The part that matters for a professional secrecy holder is a different one:

Azure OpenAI stores inputs and outputs by default for up to 30 days for abuse monitoring. A human review of this stored content is possible.

For a law firm, precisely this review is the problem case, not the training.

Remedy

Modified Abuse Monitoring or Zero Data Retention. Both eliminate the storage, but they are

  • subject to approval at Microsoft (an application, not a portal setting) and
  • tied to an Enterprise Agreement or a Microsoft Customer Agreement.

EU DataZone deployments

EU DataZone deployments keep processing and storage in Europe. That is a separate question from retention: an EU deployment without an approved retention posture still stores for 30 days — in Europe.

The product asks about it and warns

This question is not only documented, but built. Under System → AI provider and data posture, the installation shows which provider is active, where it stands, and which retention posture the firm has declared. If none is declared, or the endpoint lies outside the EU, a warning appears in the header of every page and cannot be dismissed. In addition, a line in the sidebar footer says where AI processing runs. It is green (“Processed locally · no cloud channels configured”) only when every configured provider is confirmed to run inference locally, no outbound channel is switched on and no warning applies. Otherwise it is amber and names the cause.

The display visibly separates what is measured from what is declared. The application reads the endpoint host from its own configuration. Whether Microsoft has granted the firm Modified Abuse Monitoring it cannot know — that is a declaration by the firm and is marked as such, never as a verified result. The region is also only sometimes derivable: an endpoint of the form resource.openai.azure.com names none.

This is set through the parameters AZURE_DATA_RETENTION_POSTURE and AZURE_DEPLOYMENT_REGION. The rationale and the limits are recorded in an architecture decision.

04 / 09

What does not happen

Assurances and what they rest on
AssuranceWhat makes it hold
No training on client dataModel A: there is no recipient. Model B: Microsoft's commitment in the firm's contract — not enforced by us
No telemetry to usThe checked production stack defines no telemetry service of its own. This alone does not prove the absence of all outbound connections or externally installed tools
No logging of document contentA house rule in the Security-first architecture principle, implemented in the services: retry paths log only the error type and count, diagnose and backtrace are switched off on both sinks, and a length-based mechanism catches an over-long message, an over-long logged value, or an over-long exception on both sinks. See section 6 with the limitation that belongs to it
The external development provider is blocked outside a development environmentDirect OpenAI access (api.openai.com, for development and tests only, not Azure OpenAI) is refused outside a development environment (fail-closed, refused when in doubt). The check takes effect when the application sets up the provider. That happens at startup, so a misconfigured installation does not start. This is not a general assurance that nothing leaves the firm: this block does not cover, among others, web research, the EPO channel, a hosted fallback provider, or an Ollama cloud model. Section 5 names these configurations. The block depends on the ENVIRONMENT setting (see the following rows)
Four safeguards depend on the ENVIRONMENT settingWith ENVIRONMENT=production, four safeguards apply. First: the start is refused when the session signing key (JWT_SECRET_KEY) or the database password (NEO4J_PASSWORD) is empty, a default value shipped in earlier versions, or an unchanged placeholder from the shipped example configuration. The same applies to an initial password for the first admin (ADMIN_INITIAL_PASSWORD), if one is set. A signing key shorter than 32 bytes is also refused. The application checks the strength of these values no further, only the signing key has a minimum length. Second: the session cookie carries the Secure flag (the browser sends it only over HTTPS). Third: if no active admin exists at startup and the email address (ADMIN_EMAIL) or the initial password for the first admin is missing, the start aborts. Fourth: the external development provider (direct OpenAI access) is refused, see the row above
The start with an empty or unknown ENVIRONMENT value is refusedIf ENVIRONMENT is set but empty or unknown (for example prod or staging), the start is refused and the error message names the accepted values. If ENVIRONMENT is not set, or is development, dev, local, test or testing, the development environment applies and none of the four safeguards takes effect. This is also the default of the shipped example configuration. The production stack sets production, a hand-built deployment must do so itself
The optional EPO channel is offThe EPO option is false by default. If it is on, a validator at startup checks that the target URL is ops.epo.org
Web research can be switched off and needs explicit permission for each runThe web research switch is on by default, and the air-gap package switches it off. When it is off, the application refuses research runs, web searches and retrievals. When it is on, the attorney must explicitly allow web access for each run

05 / 09

Network exposure — checked on the running stack

Not read from the configuration, but observed on the running development stack with docker ps (2026-08-19) — complete, without omission:

patentschmiede-neo4j      127.0.0.1:7474->7474/tcp, 127.0.0.1:7688->7687/tcp
patentschmiede-backend    0.0.0.0:8000->8000/tcp, [::]:8000->8000/tcp
patentschmiede-frontend   0.0.0.0:3000->3000/tcp, [::]:3000->3000/tcp
patentschmiede-ollama     11434/tcp

Read it like this: the database only over loopback, the language model not reachable from outside the container network at all — but the backend and frontend bind all interfaces in development and are therefore reachable on the LAN. That is a property of the development file and the reason why the security note says this state does not belong in an untrusted network. The Bolt port is 7688 on this machine instead of the 7687 of the development file — a local reassignment, not a deviation of the delivered state.

The production stack is the statement that matters

The production file gives no ports at all for neo4j, ollama, backend, and frontend. Caddy alone is reachable from the host on 80 and 443 with TLS termination.

On the statement “no outbound calls”

What the software does: the supplied configuration for Model A names no external endpoint for inference, and the external development provider is locked outside a development environment. A local endpoint alone does not prove local inference: an Ollama cloud model runs on ollama.com even when the configured endpoint is the firm's own Ollama server (section 1). The supplied Ollama therefore refuses cloud models (OLLAMA_NO_CLOUD=1).

What the software cannot do: prove that nothing actually leaves the firm. That proof is established at the network edge — a firewall rule or a separate network — and belongs to the acceptance of the installation, not to this statement. The air-gap installation path describes it.

Five configurations narrow the air-gap statement. The display from section 3 reports all five, but not with the same weight:

  1. 1A set fallback provider (LLM_FALLBACK_PROVIDER) to a hosted provider. On a repeatable failure of the local model, the same data goes outside. That is a warning and appears in the page header.
  2. 2An Ollama cloud model in OLLAMA_CHAT_MODEL or OLLAMA_EMBED_MODEL (section 1). If the Ollama server allows cloud models, every request to this model goes to ollama.com with its content. For the embedding model, this includes the text of the Erfindungsmeldung and of every source. The supplied Ollama does not allow cloud models (OLLAMA_NO_CLOUD=1). An Ollama server that the firm runs itself needs the same setting. The software recognises a cloud model only by the name ending :cloud or -cloud. That is a warning and appears in the page header.
  3. 3An OLLAMA_BASE_URL whose host the software cannot confirm as local. The software treats only three kinds of host as local. The first is an IP address in the loopback, private, or link-local range. The second is a name without a dot, for example ollama. The third is a name that ends in .local, .internal, .lan, or .home.arpa. A name such as ollama.kanzlei.example is not treated as local, even if it resolves to a private address. For any other host, the software cannot tell whether inference leaves the firm. That is a warning and appears in the page header.
  4. 4An enabled EPO channel. It transmits search queries and publication numbers to ops.epo.org and worldwide.espacenet.com — not the Erfindungsmeldung, but an outbound connection. That is a notice. It appears on the system page and, named or counted, in the sidebar line, not in the page header: it does not affect inference.
  5. 5Enabled web research in the research record (RESEARCH_WEB_ENABLED, on by default). In a run that the attorney starts with web access explicitly allowed, words from the research order go to html.duckduckgo.com as a search query, and pages from any public host are loaded. That is a notice and appears, like the EPO channel, on the system page and in the sidebar line. To rule out web access, set RESEARCH_WEB_ENABLED to false.

06 / 09

Encryption, roles, logging, backup

Encryption in transit

The production stack terminates TLS in Caddy. Port 80 redirects to 443. Between the containers, traffic runs on the internal Docker network, which has no host binding (section 5).

Encryption at rest

The application encrypts nothing itself. The protection comes from encrypting the host drives and is an installation prerequisite. A preflight tool helps with this, but it is not an installation gate. It returns the diagnostic status ENCRYPTED, NOT_ENCRYPTED, or UNKNOWN per target, plus an aggregated exit code (0, 1, or 2). On an explicit Windows path, a NOT_ENCRYPTED is a safe BitLocker negative finding. Cloud and hardware encryption are not assessed by it. UNKNOWN means the check allows no safe conclusion. The bundle installation prints these diagnostic codes but does not treat them as an abort condition and continues warn-only. Linux checks dm-crypt/LUKS, explicit Windows paths are checked via manage-bde -status. Cloud drives and self-encrypting disks remain UNKNOWN without provider or hardware proof. It is a warning aid, not a proof. The full picture, including the trap of an encrypted data root with an unencrypted backup target, is described in the documentation on encryption at rest.

Roles and access

There are two roles, patentanwalt and admin. Every v1 route except login requires a session. The audit trail is additionally restricted to admin. The token travels in a cookie that scripts cannot read, supplemented by a CSRF header for all changing methods. The first administrator password is one-time and must be changed at first login.

Logging

Application logs sit in the volume logs-data and additionally in the Docker log store of the firm. Passing them on for support needs a separate approval and review under the service-provider package.

The audit trail is event-based, not comprehensive, and that is more important here than the reassuring sentence. It knows a fixed list of event types and covers the security- and liability-relevant actions — among them sign-in and sign-out (including failed ones), user management and password changes, uploading, changing, and deleting library documents, attaching and detaching references to an Anmeldung, DOCX export, draft generation, Freigabe (sign-off), the management of the firm’s own prompt cards, and the adoption of machine-generated text variants (with model and prompt version). The binding list is the AuditAction type, not this enumeration.

Not covered are, among others, creating an Anmeldung, recording an Erfindungsmeldung, saving a draft version, and feature maintenance. For these operations, the who can be answered afterwards only where the record itself keeps it (the creator of a draft version). Anyone who needs a gap-free attribution does not have it today — see section 9.

Deletion of an Anmeldung (Art. 17 GDPR)

The deletion request for an Anmeldung deletes the Akte (case file) and everything hanging off it (Erfindungsmeldung, draft versions with Freigaben, clarifying dialogue, references) immediately and irrevocably — no deletion period, no restore. It may be run by admin, or by the patent attorney who created the Akte. For a legacy Akte without a reconstructable owner, it stays admin-only. The proof sits in the audit trail: a deletion event names the removed counters (number of drafts, sessions, clarifications), never document content. Existing events for that Akte remain, even after the record itself is gone. Earlier versions left two kinds of records behind when an Akte was deleted: the instructions for single sections and the saved versions of the drafting plan. Only their link to the Akte was removed. The application can no longer open these leftovers, but they contain text written by the attorney. At the first start after updating to the version with this fix, an automatic cleanup deletes them. If the cleanup fails, the system tries again at the next start. The log shows only their number, never content. Backups made before a deletion or before the cleanup still contain the data until the backup retention rule removes them. The update guide for operators describes the count query and the steps.

The limitation that belongs to it

“No logging of document content” was an enforced house rule and review practice without a mechanism behind it. Since then, a length-based filter in the logging catches every rendered message, every value set via logger.bind(), and the text of an attached exception that exceeds a fixed character limit, and replaces it with a redaction note — before either sink (stderr, rotation file, also in JSON format) sees the value. A separate cap on the exception summary ensures that the error-identifier mapping always survives this filter, even for a very long exception. That is a mechanism, but deliberately not a content classifier: a document fragment below the character limit on a single channel — for instance several individually short logged values that only read together form a document — is not caught by the length check and remains dependent on the house rule. One already known exception: the validation library pydantic carries the rejected value in its own text representation regardless of its length, so it is always summarised on the exception channel and in an additional value down to one nesting level — but not when it is embedded in the log message itself, and not from the second nesting level on. Both remaining gaps are recorded with dedicated tests as known-not-covered, not silently assumed fixed. An exceptional case below the limit that does not match a known pattern of this kind would still be a defect — not a state prevented by the system. Anyone who needs a harder assurance samples the logs in operation.

Backup and restart

The backup backs up the database and uploads and is intended for a nightly run. The firm’s IT sets the schedule itself (a crontab entry). The product plans nothing on its own, the same situation as with encryption. Restore with a documented drill, incident patterns and restart, and the upgrade are described in the operations runbooks.

07 / 09

Who needs which access

In the intended normal operation, the provider gets no access. For support, maintenance, or update, the purpose, people, rights, and duration are fixed per engagement. Synthetic examples and the guidance of the firm’s IT are used first.

The checked production stack defines no dedicated remote-maintenance service. That does not prove which additional accesses are set up on the host. The firm checks actual accesses and support tools before the first session. An access is opened by it and closed after completion.

The access description separates technical possibilities and organisational limits. In particular, logs, screen sharing, migrations, and admin recovery are not categorically free of secrets. Privileged host or database access is not limited to a single Akte by the application roles.

08 / 09

Confidentiality in support and maintenance

Patent attorney services are subject in particular to § 39c PAO and § 203 StGB. For lawyers, § 43e BRAO may be decisive. What matters is the concrete involvement of the service provider and the secret access opened, not the operating model alone. Even with a local installation, maintenance, log inspection, or on-site support can make secrets accessible. A pure software delivery without access is not the same thing.

The § 203 service-provider package contains a contract draft, a personal undertaking with instruction, an access description, and templates for approval and completion. Package version 0.2 is a draft. Before customer use, approval by the provider's legal advisors is missing.

A possible processing agreement for support is assessed separately from the direct Azure use. A required support data-processing agreement must be in place before the corresponding access. The Microsoft contract does not answer this question.

A fully network-separated installation can be supported on site. A remote connection, by contrast, means a break in the full network separation. It needs a separate approval and documented proof of the separation restored afterwards.

The sources and technical evidence name the legal bases as well as the limits of the source review.

09 / 09

Open points, honestly named

These points are open and are not glossed over here.

No certification

That is a decision, not a gap in the schedule. With an on-premise delivery, we run no service that an auditor could audit. A SOC 2 statement about us would be irrelevant to the firm’s installation, because it assesses an operating organisation that nobody runs here. And in German procurement, ISO 27001 is the sought-after standard anyway, not SOC 2. The burden of proof is carried instead by this statement and the service-provider contract from section 8.

Encryption at rest is an installation prerequisite

It is not a property of the application (section 6). Anyone who does not establish it does not have it. The preflight classifies the demonstrable local cases but cannot attest cloud or hardware encryption. These cases remain UNKNOWN and need proof from the provider or the firm’s IT.

No logging of document content — a mechanism, but not a complete one

The length-based filter from section 6 catches an over-long message on both sinks. A fragment below the character limit remains a house rule, not a mechanism.

The declared retention posture in Model B is a declaration

The product shows it and marks it as unverified. It cannot ask Microsoft. There is nothing to fix about that — it is the plainest form of this statement.

The audit trail does not cover every changing action

Section 6 names the limit. Taking stock and closing it is an open task.

The posture page knows the session-scoped choice

The per-session switchable provider of the claim agent is recorded on the session after every run. The posture query reads it when a session parameter is passed, and the claims page links the session as soon as one exists. It shows the path on which the last executed run of that session actually ran — not necessarily the path of a mode selected afterwards but not yet executed. An unknown session ID is explicitly shown as “unknown”, never as “runs on the default path”. These are two different statements, and the display does not confuse them. Without a linked session, the page stays on the configured default path and continues to show that limit visibly. The evaluation judge is a global, not a session-scoped setting — the default path above already describes it fully.