.. _licensing: Licensing ========= Calyntro requires a valid license file to start. The license is verified locally — no internet connection or external server is needed. License Types ------------- .. list-table:: :header-rows: 1 :widths: 20 40 40 * - Type - Intended use - Expiry behaviour * - ``trial`` - 30-day evaluation - Hard stop when ``expires_at`` date is reached. The server refuses to start and all API calls return HTTP 402. * - ``full`` - Production deployment - Perpetual for the purchased version. Versions released *after* ``maintenance_until`` require a maintenance renewal — older versions continue to run indefinitely. Obtaining a License ------------------- Contact us at `calyntro.com/#contact `_ to receive a license file. Placing the License File ------------------------ Drop the ``calyntro.license`` file into the ``config/`` directory of your Calyntro deployment: .. code-block:: text config/ ├── calyntro.license ← license file here ├── config.yaml └── calyntro_config.yaml Alternatively, set the environment variable ``CALYNTRO_LICENSE_PATH`` to an absolute path: .. code-block:: bash CALYNTRO_LICENSE_PATH=/etc/calyntro/calyntro.license The environment variable takes precedence over the ``config/`` directory. License File Format ------------------- The license file is a signed JSON document. Do not modify any field — the signature covers all fields and any modification will be detected on startup. **Trial license example:** .. code-block:: json { "customer": "ACME Corp", "email": "admin@acme.com", "issued_at": "2026-07-22", "type": "trial", "expires_at": "2026-08-21", "signature": "" } **Full license example:** .. code-block:: json { "customer": "ACME Corp", "email": "admin@acme.com", "issued_at": "2026-07-22", "type": "full", "maintenance_until": "2027-07-22", "signature": "" } .. list-table:: License Fields :header-rows: 1 :widths: 25 15 60 * - Field - Types - Description * - ``customer`` - all - Customer or organisation name. * - ``email`` - all - Contact email used during purchase. * - ``issued_at`` - all - Issue date in ISO 8601 format (``YYYY-MM-DD``). * - ``type`` - all - ``"trial"`` or ``"full"``. * - ``expires_at`` - trial - Date after which the server refuses to start (``YYYY-MM-DD``). * - ``maintenance_until`` - full - Last date covered by the maintenance contract. Calyntro versions released after this date require a renewal (``YYYY-MM-DD``). * - ``signature`` - all - Ed25519 signature over all other fields. Tamper-evident — any modification invalidates the license. Error Behaviour --------------- .. list-table:: :header-rows: 1 :widths: 35 65 * - Condition - Result * - No license file found - Server does not start. Startup error with instructions. * - Signature invalid / file tampered - Server does not start. Startup error. * - Trial expired (``today > expires_at``) - Server does not start. All running requests return HTTP 402. * - Full license — version too new (``release_date > maintenance_until``) - Server does not start. Error message with renewal instructions. .. note:: For a **full license**, older Calyntro versions that were released *before* ``maintenance_until`` will continue to run even after the maintenance period expires. Only upgrading to a newer version requires renewal. Checking License Status ----------------------- The ``/api/health`` endpoint always returns license information regardless of license state: .. code-block:: http GET /api/health **Trial license response:** .. code-block:: json { "status": "healthy", "database": "connected", "version": "1.13.0", "license": { "customer": "ACME Corp", "type": "trial", "expires_at": "2026-08-21", "days_remaining": 29, "status": "active" } } **Full license response:** .. code-block:: json { "status": "healthy", "database": "connected", "version": "1.13.0", "license": { "customer": "ACME Corp", "type": "full", "maintenance_until": "2027-07-22", "maintenance_days_remaining": 364, "status": "active" } } Maintenance Renewals -------------------- When your maintenance contract expires, you receive a new ``calyntro.license`` file with an updated ``maintenance_until`` date. Replace the existing file in ``config/`` and restart Calyntro — no data migration required. .. code-block:: bash cp calyntro_renewed.license config/calyntro.license ./manage.sh down && ./manage.sh up For Operators: Docker Build Integration --------------------------------------- Calyntro Docker images embed a ``release_date`` at build time (stored in ``src/.release_date``). This date is compared against ``maintenance_until`` on every startup. In development environments without a ``src/.release_date`` file, the maintenance check is skipped automatically — only trial expiry is enforced. To set the release date when building a custom image: .. code-block:: dockerfile RUN echo "2026-07-22" > /app/src/.release_date