Administration
This appendix covers the administrative tasks needed to run a Quantra installation: managing users, configuring system-wide settings, registering microservice endpoints, looking after Transport Layer Security (TLS) certificates, running the microservices with the qm script, reviewing the audit log, bumping versions, and enrolling local agents. It is written for an administrator. Administrative actions require a Django superuser account (is_superuser = True).
Where Administration Lives
Most administrative configuration is done through the standard Django admin site at /admin/. There is no separate administration page in the main Quantra interface; the same Django admin site is used by an operator to manage every persistent record. The pages a superuser sees there include CustomUser, SystemSettings, ServiceEndpoint, CnoEndpoint, AuditLog, LocalAgent, and EnrolmentToken.
A handful of operational tasks — bringing microservices up and down, generating certificates, bumping versions — are done from the command line with the qm script and the helper scripts under /home/einar/quantra/scripts/. Those are described in the relevant sections below.
User Management
The user model is a custom Django model (CustomUser) that uses the email address as the unique login identifier. It exposes the standard Django auth flags — there are no custom roles.
| Field | Meaning |
|---|---|
email | The user's email address. Used as the login username; must be unique. |
first_name, last_name | Display name fields. |
is_active | If false, the user cannot sign in. Use this to disable an account without deleting it — deleting would break audit history and project ownership references. |
is_staff | Allows access to the Django admin site at /admin/. |
is_superuser | Grants full administrative privileges. A superuser can manage every record, see the audit log, change SystemSettings, and so on. |
Creating Users
Two paths exist:
- Django admin — sign in at
/admin/, open CustomUsers, click Add user, set the email, password, and the appropriate flags. - Command line — the standard Django
createsuperusermanagement command creates an administrator account interactively:python3.10 manage.py createsuperuser
Disabling and Re-Enabling Accounts
Toggle the is_active flag on the user record. A disabled user cannot sign in and is hidden from user-selection dropdowns (for example, project sharing) but their audit history and project ownership remain intact. Re-enabling restores access immediately.
Multi-Factor Authentication
Multi-Factor Authentication (MFA) is implemented with the django-otp library. End-user authentication uses the Time-based One-Time Password (TOTP) algorithm via a TOTPDevice; recovery codes are stored as one-shot tokens on a StaticDevice.
System-Wide MFA Mode
The platform exposes a mfa_mode field on SystemSettings with three values:
- enforced — every user must enrol in MFA before they can use the platform. Users without an enrolled
TOTPDeviceare forced through the enrolment flow on next sign-in. - optional — users can enrol if they wish, from their account settings.
- disabled — the MFA flow is bypassed entirely.
A second setting, mfa_max_attempts, sets how many consecutive bad MFA codes are tolerated before the session is rejected (default: 5).
Recovery Codes
When a user enrols, a batch of single-use recovery tokens is generated (8 hexadecimal characters each) and stored as StaticToken objects on the user's StaticDevice. Each token can be used once in place of a TOTP code; on use, the token is consumed and removed. The user is shown the codes once at enrolment and must save them. If the codes run out, an administrator can regenerate the static device for that user.
System Settings
SystemSettings is a singleton model — its save() method pins the primary key to 1, so there is exactly one row. Edit it through the Django admin (/admin/quantra/systemsettings/1/change/). Changes take effect immediately.
| Field | Type | Default | Description |
|---|---|---|---|
session_timeout_value + session_timeout_unit |
integer + choice | — | Inactivity timeout. The unit is one of minutes, hours, or days; the value is the number of those units. |
splash_page_enabled |
boolean | false |
Show a splash page (used for legal notices, demo banners, or environment markers) before the dashboard. |
splash_page_html |
text | — | The HyperText Markup Language (HTML) shown on the splash page. |
mfa_mode |
choice (enforced, optional, disabled) | enforced |
Platform-wide MFA policy (see above). |
mfa_max_attempts |
integer | 5 |
Bad MFA codes tolerated per session before rejection. |
login_max_attempts |
integer | 5 |
Failed sign-ins tolerated before lockout. |
login_lockout_minutes |
integer | 15 |
How long an account is locked after exceeding login_max_attempts. |
Service Endpoint Registry
ServiceEndpoint is the registry the Central Node Orchestrator (CNO) and platform use to find each microservice. It has four fields:
| Field | Description |
|---|---|
name | Unique short name (for example, OCRTool, BoxCom). Plugins look up their microservice endpoint by this name. |
category | One of datasource, tool, or ai. |
host | Hostname or IP address where the microservice listens. |
port | The Transmission Control Protocol (TCP) port the microservice listens on. |
Manage these records through the Django admin at /admin/quantra/serviceendpoint/. There is no separate management page in the main interface, and there is no automatic health-check column on this model — if you need to confirm that a service is running, use qm status (described below).
ServiceEndpoint records, register the new name, and add the microservice to the qm script so it can be started by the operator.
Port Assignments
The default ports each microservice listens on, taken from /home/einar/quantra/ms/qm:
| Port | Service | Category |
|---|---|---|
| 50050 | SnowFlake | Datasource |
| 50051 | WindowsShare (Network Drives) | Datasource |
| 50052 | MsSql (Microsoft SQL Server) | Datasource |
| 50053 | BoxCom (Box) | Datasource |
| 50054 | SharePoint | Datasource |
| 50055 | Outlook | Datasource |
| 50056 | MFiles | Datasource |
| 50058 | Postgres | Datasource |
| 50060 | MetaDataTool | Tool |
| 50061 | CSVGatewayTool | Tool |
| 50063 | PIITool | Tool |
| 50064 | OCRTool | Tool |
| 50065 | NHSSummaryTool | Tool |
| 50068 | FingerprintTool | Tool |
| 50070 | SummaryTool | Tool |
| 50071 | FaceBioTool | Tool |
| 50072 | HashTool | Tool |
| 50073 | ArchiverTool | Tool |
| 50074 | OpenAI | AI helper |
| 50075 | Textract | AI helper |
| 50076 | Mistral | AI helper |
| 50077 | MistralOnprem | AI helper |
| 50078 | Exasol | Datasource |
| 50079 | SapHana | Datasource |
| 50080 | AlephAlpha | AI helper |
| 50081 | Claude | AI helper |
| 50082 | AgentBroker (CNO-facing) | Infrastructure |
| 50090 | RedactorTool | Tool |
| 8444 | CNO blob store | Infrastructure |
| 8445 | CNO content cache | Infrastructure |
| 8447 | AgentBroker (agent-facing) | Infrastructure |
Mutual TLS Certificate Management
The platform secures gRPC traffic between the CNO and every microservice with mutual Transport Layer Security (mTLS). Certificates are stored on the filesystem at /home/einar/quantra/ms/certs/:
| File | Role |
|---|---|
ca.crt | The Certificate Authority (CA) root certificate. Trusted by every party. |
ca.key | The CA private key. Required only on the host that issues new certificates. |
server.crt | Server certificate presented by each microservice and by the platform's gRPC services. |
server.key | Server private key paired with server.crt. |
Permissions on this directory should restrict it to the Quantra service account; private keys must not be world-readable. There is no certificate-management page in the user interface — certificate generation, rotation, and distribution are filesystem operations.
CNO Endpoints
The platform also keeps a CnoEndpoint table (visible in the Django admin) that records each CNO instance the platform talks to, the certificates it presents, and a claim/release lifecycle. The admin page exposes Claim, Release, and Rotate actions for each endpoint.
The qm Script
The qm script at /home/einar/quantra/ms/qm is the canonical way to start, stop, and check the status of every microservice in the deployment. Each microservice writes a run.pid file when it starts so qm can find and stop it again.
| Command | Effect |
|---|---|
qm start | Launches every enabled microservice. |
qm stop | Stops every running microservice by sending a termination signal to the Process Identifier (PID) recorded in its run.pid file. |
qm restart | A stop followed by a start. |
qm status | Reports which microservices are currently running. |
Enabling Mutual TLS
Pass --tls to qm start (or qm restart) to launch every microservice in mTLS mode using the certificates in /home/einar/quantra/ms/certs/. Without --tls, microservices launch in plain-text mode — this is intended only for local development.
Selecting Components
The file /home/einar/quantra/components.ini lets the operator turn individual microservices on or off without removing them from the deployment. Setting a service to disabled in this file causes qm start to skip it.
qm restart only stops the processes whose Process Identifier (PID) it finds in the run.pid files. If a previous run was killed without qm stop, the PID file may be missing or stale; check with ps aux if a restart does not appear to take effect.
Audit Log
The AuditLog model records security-relevant and project-relevant events. Each record stores the user, the event type, a timestamp, an Internet Protocol (IP) address, and event-specific metadata.
The audit log is accessed in two places:
- Django admin (
/admin/quantra/auditlog/) — system-wide view, with filters by event type, status, and timestamp, and full-text search across user, action, project name, and IP address. Records are read-only. - Per-project audit log page — a project owner or shared-with reader can open Audit logs from the canvas toolbar to see the events recorded against that single project (see the Platform User Guide).
Event Types
| Event | What it records |
|---|---|
login | Successful sign-in. |
logout | Sign-out (explicit or session timeout). |
login_failed | Failed sign-in attempt, with reason. |
project_create | A project was created. |
project_delete | A project was deleted. |
project_share | A project was shared with another user, including the permission level. |
project_unshare | A project share was revoked. |
execution | A pipeline was executed, including which project, the execution identifier, and the result. |
release | A Subject Access Request (SAR) Release tool produced a release package. |
Audit records are read-only through the admin site; there is no built-in export action. To produce an offline audit report, query the quantra_auditlog table directly through the database.
Version Management
Quantra tracks three independent version streams:
- Platform — the version is held in
/home/einar/quantra/version.json, with fields formajor,minor,build, and a content-hash of the code that produced this build. - Plugin — each plugin's
plugin.jsonmanifest carries its ownversionstring, for example1.0.12. - Microservice — each microservice keeps its own version string in its source tree (typically a constant near the top of the server entry-point file).
The bump_versions.py Script
The script at /home/einar/quantra/scripts/bump_versions.py automates version bumps. It works by hashing each component's source code and comparing the hash to the recorded build_hash: if the hash has changed, the build number is incremented; if not, the version is left alone. This avoids accidental "no-op" bumps.
| Flag | Effect |
|---|---|
--dry-run | Reports which components would be bumped without writing any changes. |
--platform-only | Considers only the platform's own source code (quantra/, pluginhost/, root-level .py files). |
--plugins-only | Considers only plugin manifests under plugins/. |
Running the script with no flags bumps every component whose source has changed.
Local Agent Enrolment
The Local Drive datasource (see the Datasources section) reads files from a workstation that has the Quantra Local Agent installed. Each agent must be enrolled before users can pick it from the dropdown. Two Django models support this:
- EnrolmentToken — a one-time token an administrator issues to a workstation operator. Stored as a hash, scoped to a future agent name and owner, and consumed on first use. Tokens have an
expires_attimestamp. - LocalAgent — a record of an enrolled agent. Carries the agent's certificate Common Name (CN), a friendly label, the certificate fingerprint, the owning user, status (pending, active, or revoked), and timestamps for creation and last seen.
Enrolling a New Agent
- In the Django admin, open EnrolmentTokens and create a new token. Set the agent label, the owning user, and an expiry. The token value is shown once.
- On the workstation, install the Quantra Local Agent and run its enrolment command, passing the token. The agent generates a certificate, sends an enrolment request to the Agent Broker, and waits for approval.
- Back in the Django admin, open LocalAgents; the new agent appears in pending status. Verify the certificate fingerprint matches what the operator reports and set the status to active.
- The agent now appears in the Local Drive datasource dropdown for the owning user.
Revoking an Agent
Set status to revoked on the LocalAgent record. The Agent Broker rejects further connections from the agent's certificate immediately.
Datasource Group Credentials
Several datasources support shared credentials managed at platform level so that end users do not have to enter Client IDs, Client Secrets, server addresses, or sign-in details for every project. These are the entries flagged as administrator-only in the Datasources section. They are stored as encrypted records associated with each datasource plugin and managed through the Django admin under each plugin's settings page.
Group credentials are typically used for:
- Box and Outlook — the Open Authorization (OAuth) Client Identifier and Client Secret from the registered Box or Microsoft Azure Active Directory application.
- SharePoint and Snowflake — shared service credentials and a default environment.
- Microsoft SQL Server, PostgreSQL, and Network Drives — pre-registered server addresses (so users pick from a dropdown) and optionally shared service-account credentials.
- M-Files — pre-configured server URL and vault Globally Unique Identifier (GUID).
Database Configuration
Database settings live in settings.py. The platform supports SQLite, PostgreSQL, and Microsoft SQL Server back-ends.
Development: SQLite
SQLite is the default and requires no setup; the database file is created automatically when migrations run. SQLite is single-writer and not suitable for production deployments.
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
Production: PostgreSQL
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'quantra',
'USER': 'quantra_user',
'PASSWORD': 'secure_password_here',
'HOST': 'db.server.local',
'PORT': '5432',
}
}
Production: Microsoft SQL Server
DATABASES = {
'default': {
'ENGINE': 'mssql',
'NAME': 'quantra',
'USER': 'quantra_user',
'PASSWORD': 'secure_password_here',
'HOST': 'sqlserver.corp.local',
'PORT': '1433',
}
}
Migrations
After any platform update, run database migrations to apply schema changes:
python3.10 manage.py migrate
Migrations are idempotent. Always back up the database before running migrations against production data.
Backups
Quantra does not ship with a backup tool of its own. Use the standard backup mechanisms of the underlying database (pg_dump for PostgreSQL, native backup for Microsoft SQL Server, file-level snapshots for SQLite). The /home/einar/quantra/ms/certs/ directory and the contents of /home/einar/quantra/version.json should be included in the backup set so that a restore can reproduce the deployment exactly.