Runtime and Container Architecture

Trustpoint is implemented as a Django application deployed in Docker containers. The standard deployment uses three containers: the main web application, a workflow worker, and a PostgreSQL database.

Container Architecture

        flowchart TB
    subgraph CLIENTS[Clients and devices]
        BROWSER[Web browser]
        API["API clients / JWT authentication"]
        DEVICE["Industrial devices / EST, CMP, AOKI"]
        OPC_UA[OPC UA clients]
    end

    subgraph WEB_EDGE[Web edge: NGINX]
        NGINX["NGINX / TLS termination / static assets / optional mTLS"]
    end

    subgraph TRUSTPOINT_WEB[Trustpoint web container]
        GUNICORN["Gunicorn WSGI server / 4 workers, 300s timeout"]
        DJANGO["Django application / protocol handlers / REST APIs / web UI"]
        QCLUSTER["Django-Q2 qcluster / scheduled tasks / CRL generation / notifications"]
    end

    subgraph TRUSTPOINT_WORKER[Trustpoint worker container]
        WF_WORKER["workflows2_worker / long-running jobs / approvals / webhooks"]
    end

    subgraph DATA_LAYER[Data and cryptography]
        POSTGRES[("PostgreSQL / operational state")]
        FILES["Filesystem / media, logs, backups"]
        CRYPTO_API[Crypto provider abstraction]
        PKCS11_IMPL["PKCS#11 provider / SoftHSM or hardware HSM"]
    end

    subgraph EXTERNAL_SVC[External services]
        EXTERNAL_CA["External CA / RA mode"]
        WEBHOOK_TARGET["Webhook endpoints / ERP, MES, IAM"]
        SMTP[SMTP server]
        PROMETHEUS[Prometheus metrics]
    end

    BROWSER -->|HTTPS| NGINX
    API -->|HTTPS, JWT| NGINX
    DEVICE -->|EST, CMP, AOKI| NGINX
    OPC_UA -->|GDS Push| NGINX

    NGINX -->|Proxy to :8000| GUNICORN
    NGINX -.->|Serve static files| FILES
    GUNICORN --> DJANGO

    DJANGO <--> POSTGRES
    DJANGO <--> FILES
    DJANGO --> CRYPTO_API
    QCLUSTER <--> POSTGRES

    WF_WORKER <--> POSTGRES
    WF_WORKER --> CRYPTO_API

    CRYPTO_API --> PKCS11_IMPL

    DJANGO -.->|RA requests| EXTERNAL_CA
    WF_WORKER --> WEBHOOK_TARGET
    WF_WORKER --> SMTP
    DJANGO --> PROMETHEUS
    

Container Roles

Trustpoint Web Container

Processes:

Process

Role

Details

NGINX

TLS termination, routing

Port 80 (HTTP for CMP/CRL only), Port 443 (HTTPS, TLS 1.2/1.3), proxies to Gunicorn on 127.0.0.1:8000

Gunicorn

WSGI server

4 workers, 300s timeout, handles protocol endpoints, REST API, web UI

Django

Application logic

Protocol handlers, REST API, web UI views, certificate operations

Django-Q2 qcluster

Scheduled tasks

CRL generation, certificate expiry notifications, maintenance

Entry point: /docker/trustpoint/entrypoint.sh with TRUSTPOINT_SERVICE_ROLE=web

Trustpoint Worker Container

Process: workflows2_worker - Background job processor

Responsibilities:

  • Claims jobs from database queue

  • Executes approval workflows

  • Calls external webhooks

  • Sends email notifications

  • Handles long-running certificate operations

  • Lease-based job locking (default: 30 seconds)

Entry point: /docker/trustpoint/entrypoint.sh with TRUSTPOINT_SERVICE_ROLE=worker

PostgreSQL Container

  • Stores all operational data (devices, certificates, domains, workflows, users)

  • Listens on 127.0.0.1:5432 (not exposed to external network)

  • Data persisted in postgres_data Docker volume

Bootstrap vs Operational Phases

Trustpoint operates in two distinct phases:

Phase Comparison

Aspect

Bootstrap Phase

Operational Phase

Purpose

Initial setup and configuration

Normal production operation

Active when

No operational config file, first-time deployment

Operational config exists, TRUSTPOINT_PHASE=operational/auto

Features

Setup wizard UI, bootstrap SQLite DB, TLS cert generation, minimal routes

Full functionality, protocol endpoints, REST API, workflows

Services

Web container only

All three containers (web, worker, postgres)

Database

SQLite (temporary)

PostgreSQL

Phase Transition

        stateDiagram-v2
    [*] --> AutoDetection
    AutoDetection --> Bootstrap: No operational marker
    AutoDetection --> Operational: Operational configuration present

    Bootstrap --> SetupWizard: Configure admin, database, crypto, TLS
    SetupWizard --> OperationalHandoff: Validate and persist configuration
    OperationalHandoff --> Operational: Restart or switch runtime

    Operational --> Operational: Full application active
    

Phase detection logic:

  1. Check TRUSTPOINT_PHASE environment variable

  2. If auto, check for operational marker files (/var/lib/trustpoint/bootstrap/operational.env, operational.ready)

  3. Files exist → operational phase; otherwise → bootstrap phase

Security benefit: Limits exposed endpoints until system is properly configured.