Skip to content

Data handling

Data Where Leaves the bank?
Closing documents (PDFs) and rendered pages documents volume, content-addressed by SHA-256 never
Extracted terms, findings, approvals, boarding records, wire requests database only to the bank’s own core (jXchange) or export folder, when a person commits a boarding or exports a wire
Evidence chain database (append-only) only when the bank exports a packet
Settings, including SMTP, core and OIDC credentials and the signing key database; secrets AES-256-GCM encrypted with the master key never
Users, roles, TOTP secrets (encrypted), API-key hashes, sign-in events database never
Template-studio samples documents volume, by hash only the sample’s page text, and only if an administrator uses Suggest with ai.endpoint set; see below
Heartbeat posted to metering.endpoint install id, version, period, closed-loan count, document page count, coarse health and the license key; see Metering. Off in air-gapped mode.
Diagnostics GET /v1/diagnostics only if an operator sends it to support; it contains no loan data

There are no subprocessors for loan data.

Each is configured by the bank and can be left unset:

  • Core boarding (core.jxchange.*) or the export folder (core.file_export_path): the mapped boarding record, after checker approval.
  • SMTP (smtp.*): sign-in links, invitations and assignment notices. Emails carry links and loan references, not documents.
  • OpenID Connect (auth.oidc_*): the standard authorization-code exchange with the bank’s identity provider.
  • Metering (metering.*): the daily heartbeat above.
  • Template suggestions (ai.endpoint, ai.model, ai.api_key): when an administrator asks the template studio to Suggest a template, Bookend sends the text of the uploaded sample document, plus the field catalog and document taxonomy, to that OpenAI-compatible endpoint. It is blank by default, which disables Suggest. Point it at a model inside the bank’s network (Ollama, llama.cpp server and similar work), or use a hosted model only with a sample that contains no customer data. The model never sees production loans; pipeline extraction does not use it.
  • TLS at the bank’s terminator; inside the compose network, plain HTTP on one isolated bridge.
  • Secrets encrypted at rest with BOOKEND_MASTER_KEY (32 random bytes the bank holds). Losing the key means re-entering every secret.
  • Passwords hashed with Argon2id; sign-in link, refresh-token and API-key material stored as SHA-256 hashes.
  • Documents are immutable once stored; the chain hashes reference them.

documents.retention_days (default 2,555 days, about seven years) is enforced by a nightly sweep at 04:00 UTC. It deletes the stored PDF bytes and page renders of loans sealed longer ago than the policy. Database rows (metadata, SHA-256 hashes, extracted values, findings and the evidence chain) are kept, so a sealed packet still verifies and still names every document by hash. A file shared with a loan that is still inside the policy is kept. The last sweep’s result is shown in Diagnostics. Template-studio samples are not purged by the sweep. Backups and restores are documented in Backup and restore.

Structured logs go to stdout for the bank’s collector; loan references appear, document contents and extracted values do not. The data audit (GET /v1/audit?source=data) records row-level changes on business tables with the actor; secrets are excluded from before and after values.

Support has no access path into a deployment. Diagnostics and logs are shared by the bank; loan documents never need to leave the institution for a support case.