@fin.cx/docbox
Open-source, self-hosted document intake and management for organizations.
Docbox takes in documents — invoices, receipts, contracts, letters, statements — files them, extracts their text, finds exact duplicates and keeps them searchable and shareable for the members of an organization. People sign in through idp.global; Docbox has no accounts or passwords of its own. Document metadata lives in a MongoDB-compatible database, the files themselves in S3-compatible object storage, and the web app updates live as documents change.
Issue Reporting and Security
For reporting bugs, issues, or security vulnerabilities, please visit community.foss.global/. This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a code.foss.global/ account to submit Pull Requests directly.
Features
- Sign-in through idp.global. OIDC authorization code with PKCE, an HttpOnly cookie session with a CSRF token, and roles taken live from idp.global organization memberships. Membership is checked at idp.global on every request; a confirmed one is reused for
DOCBOX_AUTHORITY_CACHE_SECONDS. - Organizations. Every document, scan, entity, project, process, share and processing job belongs to exactly one organization, and one tenant scope narrows every read and write to the session's organization. Each organization is linked to one idp.global organization. The instance operator creates and links organizations but never sees their documents.
- Library. Inbox (the review queue), Flagged, Recent, All and Archive, with stable scope counts, facet filters (type, source, entity, tag), server-side search, review, flagging, archiving and bulk actions.
- Rich metadata with provenance. Type, language, parties, amounts, currency, references, due dates, periods, confidentiality and retention. Every field records whether it was
extracted,recognizedoredited, and by whom. Details save field by field as you type. - Durable processing. Lease-based jobs that survive restarts run in order: native PDF or plain-text extraction, SHA-256 exact-duplicate detection, and an optional recognition stage. Progress and retry are visible per document.
- Entities, projects and processes. Link documents to people, companies, categories or projects. Collect them in projects, and follow processes as ordered threads with a due date.
- Shares. Share links to a document or a project that are read-only and expire after seven days. Only a hash of the token is stored. Links can be listed and revoked, and share access is rate-limited.
- Live updates. One TypedSocket connection per app pushes document changes, processing progress and library counts. Each push carries only what the recipient may see at that moment.
- Streamed files. Uploads stream over TypedSocket and downloads and previews stream over plain HTTP, so no file is ever held whole in memory.
- Audit trail. Security-relevant actions are recorded per organization, append-only, and shown as the Activity of documents, projects and entities.
- Operations. Readiness and liveness endpoints, structured JSON logs without secrets or content, a container image, and a serve.zone deployment declaration.
Architecture
┌────────────────────────────────────────────────────────────┐
│ Browser: web app (ts_web/, dees-appui shell, prebuilt into │
│ html/bundle.js) │
├──────────────────────────────┬─────────────────────────────┤
│ /typedrequest (HTTP) │ TypedSocket (uploads, live) │
│ /auth/* · /api/content/* · /health │
├────────────────────────────────────────────────────────────┤
│ Docbox server (ts/): request guard + tenant scope, feature │
│ routers, identity, processing worker, live updates, audit │
├──────────────────────────────┬─────────────────────────────┤
│ MongoDB-compatible database │ S3-compatible bucket │
│ (@lossless.org/client │ (@lossless.org/client │
│ /nosqldb) │ /objectstorage) │
└──────────────────────────────┴─────────────────────────────┘
idp.global (OIDC, organizations, roles)
docbox/
├── ts/ # Server
│ ├── index.ts # CLI (serve, org, migrate) and configuration
│ ├── classes.docbox.ts # Server lifecycle
│ ├── persistence.ts # Model binding and index preparation at startup
│ ├── classes.s3storage.ts # Object storage
│ ├── mod_api/ # Request guard, validators, one TypedRouter per feature, content routes, live updates
│ ├── mod_identity/ # idp.global sign-in, sessions, socket binding, live membership checks
│ ├── mod_tenancy/ # Organizations, operator linking, the tenant scope every model reads through
│ ├── mod_audit/ # Audit trail
│ ├── mod_health/ # /health and /health/live
│ ├── mod_observability/ # JSON logger
│ ├── mod_processingmanager/ # Extraction, duplicate and recognition jobs
│ ├── mod_documentmanager/ # Documents and their files
│ ├── mod_entitymanager/ mod_projectmanager/ mod_processmanager/
│ ├── mod_scanmanager/ # Scan lineage
│ ├── mod_sharemanager/ # Hashed, expiring shares
│ ├── mod_usermanager/ # People who signed in, and labels of 1.x accounts
│ └── mod_eventhub/ # Domain events the managers raise
├── ts_migration/ # Versioned startup data migrations
├── ts_shared/ # Data and request interfaces shared by server and web app
├── ts_web/ # Web app (Web Components)
├── html/ # index.html and the favicon; `pnpm build` writes the bundle and its third-party notices here
├── qenv.yml # The environment the server requires
├── cli.js # Production entry
├── cli.dev.js # Development entry with embedded database and storage
└── Dockerfile_##version## # Container image
The server is Node.js and TypeScript on @api.global/typedserver. The API is TypedRequest, and sign-in uses @idp.global/sdk /relyingparty. PDF text comes from @push.rocks/smartpdf without a browser. The web app uses @design.estate/dees-element and @design.estate/dees-catalog. It is bundled at build time into html/, so the UI packages are build-time dependencies only.
Configuration
Docbox reads its configuration from the environment, or from .nogit/env.json / .nogit/env.yml in development. The database and object storage use the names that a serve.zone database and objectstorage binding injects. qenv.yml in the package declares the required names. docbox serve refuses to start while one is missing and names it, never its value. Invalid values also stop the start.
| Variable | Required | Description | Example |
|---|---|---|---|
MONGODB_URI |
yes | MongoDB connection URI whose path names the database. A URI without one is refused | mongodb://user:pass@db:27017/docbox?authSource=docbox |
S3_ENDPOINT_HOST |
yes | Object storage host, without scheme or port | s3.example.net |
S3_PORT |
yes | Object storage port | 443 |
S3_USE_SSL |
yes | true or false |
true |
S3_BUCKET |
yes | Bucket; created on first start when missing | docbox |
S3_ACCESS_KEY |
yes | Object storage access key | — |
S3_SECRET_KEY |
yes | Object storage secret key | — |
S3_REGION |
no | Region, when the storage needs one | eu-central-1 |
IDP_ISSUER |
yes | The idp.global issuer | https://idp.global |
IDP_CLIENT_ID |
yes | The OIDC client registered for this Docbox | app-… |
IDP_CLIENT_SECRET |
yes | That client's secret | — |
PUBLIC_ORIGIN |
yes | Docbox's public origin; the callback is <origin>/auth/callback |
https://docbox.example.com |
DOCBOX_SESSION_SECRET |
yes | 32 random bytes, base64: the session and CSRF key. Never reuse it elsewhere | openssl rand -base64 32 |
DOCBOX_SEALING_KEY |
yes | 32 random bytes, base64: seals secrets at rest (idp.global tokens) | openssl rand -base64 32 |
DOCBOX_OPERATORS |
no | idp.global subjects that operate this instance, separated by commas or spaces | usr_123,usr_456 |
DOCBOX_AUTHORITY_CACHE_SECONDS |
no | How long a confirmed membership is reused (0–600, default 60). Refusals are never cached | 60 |
IDP_CA_CERT_FILE |
no | PEM file of the CA that a private or local idp.global chains to. Trusted only for requests to the issuer and read once at start | /run/secrets/idp-ca.pem |
DOCBOX_PORT |
no | Listening port (default 3050) | 3050 |
DOCBOX_MAX_UPLOAD_BYTES |
no | Largest upload in bytes (default 104857600, 100 MiB) | 26214400 |
DOCBOX_CLIENT_IP_HEADER |
no | Header a trusted reverse proxy appends the client address to. The share rate limit counts its last entry; when unset, it counts the transport peer | x-forwarded-for |
DOCBOX_TLS_CERT_PATH |
no | PEM certificate chain for TLS served by Docbox itself, set together with the key | /etc/ssl/docbox.crt |
DOCBOX_TLS_KEY_PATH |
no | PEM private key, set together with the certificate | /etc/ssl/docbox.key |
The session cookies are __Host- cookies, and TypedSocket refuses insecure transport off loopback, so a deployment's PUBLIC_ORIGIN is an https:// origin. Either terminate TLS in a reverse proxy or let Docbox serve it with DOCBOX_TLS_CERT_PATH and DOCBOX_TLS_KEY_PATH.
Sign-in, organizations and roles
-
Register an OIDC client for Docbox at idp.global. It is a confidential client with the grant types
authorization_codeandrefresh_token, the scopesopenid profile email organizations roles, and exactly one redirect URI,<PUBLIC_ORIGIN>/auth/callback(idp.global accepts exact HTTPS redirect URIs only). A client is registered by an idp.global global administrator, or by an organization service principal throughPOST /machine/v1/oidc-clientsfor a domain its organization has proven by DNS TXT. See "Runtime OIDC Client Registration" in the idp.global readme. Theclient_idand secret becomeIDP_CLIENT_IDandIDP_CLIENT_SECRET. -
Name the operators in
DOCBOX_OPERATORS. An operator may sign in without belonging to any organization, and manages organizations without ever reaching their documents. -
Create an organization and link it to its idp.global organization. A link is set once and never changed to a second organization. The operator can do this in the web app (Settings › Organizations, or the page shown to a session without an organization) or on the command line:
node cli.js org create "Example GmbH" <idp.global organization id> node cli.js org list node cli.js org link <organization id> <idp.global organization id>
Members of a linked organization sign in with the role their idp.global membership grants:
| idp.global role | Docbox role | Can |
|---|---|---|
owner, admin |
admin |
Everything a member can, plus restricted documents, the member list and the audit trail |
editor |
member |
Upload, file, edit, share and organize documents |
viewer |
viewer |
Read the library |
Any other role grants nothing, and members of unlinked organizations are refused. A session with several linked organizations switches between them in the app bar.
Run it yourself
Docbox needs three things next to it: a MongoDB-compatible database, S3-compatible object storage and an OIDC client at idp.global.
The image is built from this repository (Dockerfile_##version##, linux/amd64 and linux/arm64). It runs node cli.js serve as uid 10001, listens on DOCBOX_PORT (default 3050), writes nothing to its filesystem and carries a HEALTHCHECK against /health. The health check allows a start period of 600 s because data migrations run before the server listens. When Docbox serves TLS itself, the health probe (cli.healthcheck.js) speaks HTTPS to loopback and verifies the certificate for PUBLIC_ORIGIN's hostname.
- Register the OIDC client (see above).
- Generate the two keys, each 32 random bytes in base64 or base64url, never shared with another application:
openssl rand -base64 32. - Put TLS in front. Behind a proxy, set
DOCBOX_CLIENT_IP_HEADERto the header that proxy appends the client address to. - Start the stack, for example with Compose. MongoDB and MinIO are shown, and the
${…}values come from an.envfile next to it:
services:
docbox:
build:
context: .
dockerfile: Dockerfile_##version##
restart: unless-stopped
ports:
- '127.0.0.1:3050:3050' # your TLS proxy forwards to this
environment:
MONGODB_URI: mongodb://mongo:27017/docbox
S3_ENDPOINT_HOST: minio
S3_PORT: '9000'
S3_USE_SSL: 'false'
S3_BUCKET: docbox
S3_ACCESS_KEY: docbox
S3_SECRET_KEY: ${MINIO_ROOT_PASSWORD}
IDP_ISSUER: https://idp.global
IDP_CLIENT_ID: ${IDP_CLIENT_ID}
IDP_CLIENT_SECRET: ${IDP_CLIENT_SECRET}
PUBLIC_ORIGIN: https://docbox.example.com
DOCBOX_SESSION_SECRET: ${DOCBOX_SESSION_SECRET}
DOCBOX_SEALING_KEY: ${DOCBOX_SEALING_KEY}
DOCBOX_OPERATORS: ${DOCBOX_OPERATORS}
DOCBOX_CLIENT_IP_HEADER: x-forwarded-for # only behind a proxy that appends it
depends_on:
- mongo
- minio
mongo:
image: mongo:8
restart: unless-stopped
volumes:
- mongo-data:/data/db
minio:
image: quay.io/minio/minio
command: server /data
restart: unless-stopped
environment:
MINIO_ROOT_USER: docbox
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
volumes:
- minio-data:/data
volumes:
mongo-data:
minio-data:
- Once
/healthanswers200, link an organization:docker compose exec docbox node cli.js org create "Example GmbH" <idp.global organization id>.
Back up the database and the bucket together, because they form one dataset.
Deploy on serve.zone
.smartconfig.json carries Docbox's @git.zone/tsdeploy declaration: the public domain and its route (readiness /health, expecting 200), container port 3050, no volumes, the database and objectstorage capabilities, the complete environment surface including every platform-injected name, and built-in release evidence. The platform supplies MONGODB_URI and the S3_* names through the capability bindings.
Follow Developers → Integrate a new app in the serve.zone documentation step by step. It is the canonical recipe; the steps below cover only what is specific to Docbox:
-
Deployment machine user and grant: an
organization-service-slotgrant for the chosen service id, thentsdeploy link --serviceId '<service id>'. -
Service-owned secrets:
PUBLIC_ORIGIN: thehttps://origin of the declared domain.IDP_ISSUER.DOCBOX_SESSION_SECRETandDOCBOX_SEALING_KEY: each created as a generated value, 32 bytes,base64url.DOCBOX_OPERATORS.
Never create the database or object storage names; the platform publishes them.
-
OIDC client: registered through the typed admin operation (fresh passkey) or a registration service principal, with the redirect URI
https://<domain>/auth/callback. StoreIDP_CLIENT_IDandIDP_CLIENT_SECRETas two more service-owned secrets. -
Deploy: run
tsdeploy deploy --dryRunfirst, thentsdeploy deploy --mode greenfieldas the recipe states. -
Runtime spec: once the reserve has created the service, pin it to one node (
setServiceRuntimeSpec). The bindings and the route need exactly one pinned node. -
Route and DNS: the deploy promotes them for the declared domain; never edit DNS ahead of it.
-
Access verification: from both a public and a trusted-network vantage point,
https://<domain>/healthanswers200without a redirect, and a sign-in completes.
Recovery (retry, cleanup, restore) is described under Operations → Production rollouts and recovery in the same documentation.
Upgrading from 1.6.1
Back up the database and the bucket first. There is no way back to 1.6.1.
2.0 is a breaking release:
-
Sign-in moves to idp.global. Local accounts, passwords, Docbox JWTs and
DOCBOX_BOOTSTRAP_ADMIN_PASSWORDare gone. -
The data moves into organizations.
-
The configuration uses the serve.zone names:
MONGODB_URL+MONGODB_NAMEbecomeMONGODB_URI, with the database in the path.S3_ENDPOINTbecomesS3_ENDPOINT_HOST.S3_ACCESSKEYbecomesS3_ACCESS_KEY, andS3_SECRETKEYbecomesS3_SECRET_KEY.S3_USESSLbecomesS3_USE_SSL, which is now required.
The old names are not read.
-
Request contracts lose their
tokenfield, and list pages are bounded to 1000 items. Seechangelog.mdfor every contract change.
To upgrade:
-
Stop 1.6.1, then back up the database and the bucket.
-
Set the 2.0 environment from the configuration table, including the idp.global client and the two keys.
-
Check what the migrations would change. The dry run only reads, and prints one report per step:
node cli.js migrate --dry-run -
Start 2.0, or run
node cli.js migratefirst. The versioned migrations run before the server listens:- The document model and scan lineage are updated.
- The 1.x JWT signing key is removed.
- All existing data moves into one organization,
org_initial, which is not linked yet. - The 1.x accounts become read-only name labels, and their password hashes are deleted.
- Every stored object is copied under
orgs/<organization>/, verified by size and SHA-256, switched, and only then deleted.
Every step is recorded once done. A stopped run resumes where it left off, and several instances may start at once.
-
Link the migrated organization:
node cli.js org link org_initial <idp.global organization id>.
Command line
| Command | Description |
|---|---|
node cli.js / node cli.js serve |
Run the server (checks qenv.yml's required names first) |
node cli.js org list |
Every organization and its link, as JSON |
node cli.js org create <name> [<idp.global organization id>] |
Create an organization, optionally linked right away |
node cli.js org link <organization id> <idp.global organization id> |
Link an unlinked organization |
node cli.js migrate [--dry-run] |
Bring the database and bucket to the current version without starting the server |
The org and migrate commands need only the database and object storage variables. org create and org link are recorded in the audit trail with the command line (cli) as the actor.
Health endpoints
Both endpoints are unauthenticated and reveal nothing about the deployment:
GET /health(readiness) answers200once three checks pass: the database answers a ping, the bucket answers a probe, and the startup migrations are done. Otherwise it answers503with{ "healthy": …, "checks": [{ "name": "database" | "objectStorage" | "migrations", "healthy": …, "errorMessage"?: <reason word> }] }. Each probe is bounded to 2 s and its answer is reused for 2 s. idp.global is deliberately not part of readiness.GET /health/live(liveness) answers200whenever the process serves HTTP.
API overview
The web app and any other client use TypedRequest at /typedrequest (HTTP) or over TypedSocket. The request and response interfaces live in ts_shared/. No request carries a credential:
- HTTP requests are authorized by the session cookie, sent from the public origin.
- A TypedSocket connection registers its session once with
registerSocketSession.
Lists are paged, with at most 1000 items per page.
HTTP routes
| Route | Description | Auth |
|---|---|---|
GET /auth/login?return=/path |
Start the idp.global sign-in | — |
GET /auth/callback |
The OIDC redirect target | — |
GET /auth/session |
The session and its CSRF token, or null |
— |
POST /auth/logout |
End the session ({ csrfToken }); its socket and live updates end too |
Session |
GET /api/content/documents/<id> |
Stream a document's file; restricted documents for admins only | Session cookie |
GET /api/content/shared/<id> |
Stream a file of a share (token in the x-docbox-share-token header, never in the URL) |
Share token |
With ?disposition=inline, PDFs, PNG, JPEG, GIF, WebP and plain text show in the browser. Everything else, and every request without the parameter, is served as a download with the UTF-8 file name. Responses carry Content-Length, X-Content-Type-Options: nosniff and Cache-Control: private, no-store. Byte ranges are not served yet (Accept-Ranges: none). The status codes are:
- 401 without a session or token.
- 403 for a document the role may not read.
- 404 for a document that does not exist in the caller's organization or share.
- 429 when the share rate limit is spent.
Typed requests
| Area | Methods |
|---|---|
| Session | getSession, selectOrganization, registerSocketSession |
| Operator | listOrganizations, createOrganization, linkOrganization (operators only) |
| Users | getUsers (admins), getUserLabels |
| Documents | uploadDocument (streamed over TypedSocket), getDocuments, getDocumentById, renameDocument, updateDocument, updateDocumentFields, setDocumentFlag, reviewDocument, archiveDocument, unarchiveDocument, deleteDocument, getDocumentsByEntity, createDocumentShare, getDocumentBuffer |
| Processing | getDocumentProcessingJobs, retryDocumentProcessingJob |
| Library | getLibrarySummary, getLibraryFacets, getCapabilities, getOverviewStats, getEntityDocumentCounts |
| Entities | createEntity, getEntities, getEntityById, updateEntity, deleteEntity |
| Projects | createProject, getProjects, getProjectById, updateProject, addDocumentsToProject, removeDocumentsFromProject, deleteProject, createProjectShare |
| Processes | createProcess, getProcesses, updateProcess, getProcessThread, deleteProcess |
| Shares | listShares, revokeShare, resolveShare and getSharedDocumentBuffer (share token) |
| Audit | getAuditEvents (admins) |
| Live updates | subscribeLiveUpdates, unsubscribeLiveUpdates |
getDocumentBuffer and getSharedDocumentBuffer return a file base64-encoded; prefer the streamed content routes. resolveShare, getSharedDocumentBuffer and the shared-file route share one budget per client of 120 requests a minute.
Lists that hold documents only ever show a caller the documents it may see. A caller who replaces such a list keeps the documents it cannot see. A project or process holds at most 10 000 documents, and concurrent changes to one never overwrite each other.
Live updates
After subscribeLiveUpdates, the server pushes three messages over the socket:
pushDocumentChanged: a document was created, updated, reviewed, flagged, unflagged, archived, unarchived or deleted, or becamehiddento the recipient.pushProcessingProgress: a document's complete job list.pushLibrarySummaryChanged: the recipient's scope counts.
Each push carries only what that recipient may see at the time. Clients cannot tag their connection themselves.
Audit trail and logs
The audit trail records these actions per organization:
- Sessions:
session.login,session.logout,session.select. - Organizations:
organization.create,organization.link. - Shares:
share.create,share.revoke. - Documents:
document.delete,document.archive,document.unarchive,document.confidentiality. - Other deletions:
project.delete,process.delete,entity.delete.
Each entry names who acted (a user, the operator or the command line) and when. Entries are never changed or removed, and never carry document content.
The server writes one JSON object per line. Each API request and file download is logged with its request id, method or route, organization, subject, duration and outcome, alongside startup and failure events. Payloads, file contents, tokens and configuration values are never logged, and fields named like credentials are redacted.
Recognition
The recognition stage is pluggable and off by default. Programmatic users of Docbox pass recognition: { recognizer } in IDocboxConfig. Restricted documents are withheld from a recognizer unless recognizeRestricted is set. Recognition never overwrites an edited or extracted value, and it proposes entities for review without applying them.
Web app
The web app is a dees-appui shell. Every screen has a hash route, and filters, search and the selected document live in the hash query, so Reload, Back and Forward keep your place.
| View | Route | Description |
|---|---|---|
| Library | #library/:scope? |
Inbox, Flagged, Recent, All and Archive, with filters, search and an inspector for filing, details and processing |
| Document | #doc/:id/:tab? |
Preview beside filing and details, extracted text, pages and Activity |
| Capture | #capture |
Upload several files with per-file progress and processing stages. A camera field comes first on phones |
| Entities | #entities/:id? |
Entities by kind, with one entity's documents, processes, details and Activity |
| Projects | #projects/:id? |
Active and archived projects with their documents, processes, details, share links and Activity |
| Processes | #processes/:id? |
Open, waiting and closed processes as threads |
| Settings | #settings/:section? |
Members (admins), Connections, Capabilities, Appearance, Organizations (operators) |
| Share | #share/:token |
Public, read-only page of a shared document or project |
Development
The project uses pnpm and the @git.zone toolchain.
pnpm install
pnpm build # compile ts/, ts_shared/, ts_migration/ and bundle ts_web/ into html/
pnpm test # the full test suite; needs no external services
pnpm startDev # run with an embedded database and object storage
pnpm run watch # local idp.global + server from source, restarted on changes, and the web bundle
pnpm start # run the built server (node cli.js)
pnpm startDev needs no MongoDB, no S3 and no Docker. It starts @lossless.org/nosqldb and @lossless.org/objectstorage in-process and points Docbox at them. Sign-in is idp.global in development too, so the IDP_*, PUBLIC_ORIGIN, DOCBOX_SESSION_SECRET and DOCBOX_SEALING_KEY values above are required, and DOCBOX_OPERATORS is usually set as well. A local idp.global under its own CA needs IDP_CA_CERT_FILE. State persists under .nogit/devstack; delete that folder to start over. DOCBOX_PORT sets the port, and DOCBOX_DEV_S3_PORT and DOCBOX_DEV_DB_NAME override the embedded storage defaults.
pnpm run watch
pnpm run watch runs Docbox from source, restarts it on changes under ts/, ts_migration/ and the launcher's ts_dev/devserve.*.ts, and rebuilds the web bundle. Sign-in is always idp.global: by default a local idp.global that the watch starts itself, or the public one when you configure it.
- Storage comes from
gitzone services, which starts the database and object storage and writes their connection names (MONGODB_URI,S3_*) to.nogit/env.json. Docbox reads them from there; start the services before the watch. - The local idp.global (
pnpm run devIdp,cli.devidp.js) runs@idp.global/devidp: the idp.global app image in Docker, a kernel-keyring namespacedocbox-devthat keeps its CA, client and personas stable across restarts, and TLS from its own development CA. It serveshttps://idp.localhost:8443withlogin.,app.andsuperadmin.idp.localhostbeside it (DOCBOX_DEV_IDP_PORTchanges the port) and registers Docbox ashttps://localhost:3050(DOCBOX_PORT), or atPUBLIC_ORIGINwhen that is set, which must then be an https origin with a host name, such ashttps://docbox.localhost:3050; Docbox's TLS certificate is issued for that host name. It needs Docker and a usable Linux kernel keyring. Ctrl+C gives it up to 30 seconds (stopGracePeriod) to remove its containers and networks. - The launcher (
pnpm run startTsDev,cli.devserve.js) waits up to six minutes for the local idp.global and fills in only what is unset:IDP_ISSUER,IDP_CLIENT_ID,IDP_CLIENT_SECRET,IDP_CA_CERT_FILE,PUBLIC_ORIGIN,DOCBOX_TLS_CERT_PATHandDOCBOX_TLS_KEY_PATH(Docbox serves HTTPS with a leaf from the same CA),DOCBOX_OPERATORS(thetestsuperadminpersona) and a stable developmentDOCBOX_SESSION_SECRETandDOCBOX_SEALING_KEY, generated once into.nogit/docbox-dev-secrets.json. Then it runsdocbox serve.
The local idp.global writes its handoff to .nogit/devidp/ (mode 0600) and removes it when it stops; the launcher refuses a handoff whose idp.global is gone, and a PUBLIC_ORIGIN other than the one the running local idp.global registered (restart the watch after changing it). The log names the issuer, the persona e-mail addresses and the CA file; the passwords and subjects of testuser, testmoderator and testsuperadmin are in .nogit/devidp/runtime.json.
To sign in, trust .nogit/devidp/ca.pem as a certificate authority in the browser (a separate browser profile keeps it out of your everyday one), open https://localhost:3050 and sign in as a persona. Chromium and Firefox resolve *.localhost to the loopback address themselves. On a remote development host, forward both ports: ssh -L 3050:localhost:3050 -L 8443:localhost:8443 <host>.
Setting IDP_ISSUER (with IDP_CLIENT_ID, IDP_CLIENT_SECRET and the rest of the sign-in names, in the environment or .nogit/env.json) uses that idp.global instead, for example the public idp.global: the launcher then neither waits for the local one nor fills in anything. IDP_CLIENT_ID, IDP_CLIENT_SECRET or IDP_CA_CERT_FILE without IDP_ISSUER is refused, so a configuration is never mixed with the local idp.global.
License and Legal Information
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the license.md file.
Please note: The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
Trademarks
This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.
Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.
Company Information
Task Venture Capital GmbH
Registered at District Court Bremen HRB 35230 HB, Germany
For any legal inquiries or further information, please contact us via email at hello@task.vc.
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.