io7m | single-page | multi-page | epub | Cardant User Manual 1.0.0-beta0002
2. Installation
Front Matter
4. Model
1
The cardant server is configured using a single XML-formatted configuration file. The format has a fully documented schema and so configuration files can be independently validated, and benefit from autocompletion in most modern IDEs.
2
The configuration file must consist of a single top-level Configuration element in the com.io7m.cardant:configuration:1 namespace. In modern IDEs, simply creating a file containing this element will immediately fill in all the other required child elements.
1
The smallest working configuration file, assuming a database at db.example.com and an idstore server at idstore.example.com:

3.2.2. Example

<?xml version="1.0" encoding="UTF-8" ?>

<Configuration xmlns="com.io7m.cardant:configuration:1"
               xmlns:ct="com.io7m.cardant:tls:1">

  <InventoryService ListenAddress="[::]"
                    ListenPort="30000"
                    SessionExpiration="PT30M"
                    ExternalAddress="http://cardant.example.com:30000">
    <ct:TLSDisabled/>
  </InventoryService>

  <Database Kind="POSTGRESQL"
            OwnerRoleName="cardant_install"
            OwnerRolePassword="892a2b68-2ddf-478a-a8ab-37172f6ac2fe"
            WorkerRolePassword="e61135dc-1d3f-4ab2-85ef-95ef49d66285"
            ReaderRolePassword="c2026069-97e7-45b1-85c4-a2349bbb847b"
            Address="db.example.com"
            Port="5432"
            Name="cardant"
            Create="true"
            Upgrade="true"
            Language="english"/>

  <Idstore BaseURI="https://idstore.example.com:50000"
           PasswordResetURI="https://idstore.example.com:50001/reset"/>

  <Limits MaximumFileUploadSizeOctets="10000000"
          MaximumCommandSizeOctets="10000000"/>

  <Maintenance TLSReloadInterval="PT24H"/>

  <OpenTelemetry LogicalServiceName="cardant01">
    <Logs Endpoint="http://logs.example.com:4317"
          Protocol="GRPC"/>
    <Metrics Endpoint="http://metrics.example.com:4317"
             Protocol="GRPC"/>
    <Traces Endpoint="http://traces.example.com:4317"
            Protocol="GRPC"/>
  </OpenTelemetry>

</Configuration>
1
The InventoryService section of the configuration file configures the main inventory service.
2
The ListenAddress and ListenPort attributes specify the address and port to which to the HTTP service will bind.
3
The ExternalAddress attribute specifies the external address that clients will use to connect to this server.
4
By convention, the inventory service should listen on TCP port 30000.
5
The InventoryService element must contain either a TLSEnabled or TLSDisabled element specifying whether TLS should be enabled or disabled, respectively. The TLSEnabled element describes the key store and trust store. The cardant server automatically reloads certificates periodically in order to work well in environments using the ACME protocol to issue certificates.
1
An example service configuration:

3.3.2.2. Example

<?xml version="1.0" encoding="UTF-8" ?>

<InventoryService xmlns="com.io7m.cardant:configuration:1"
                  xmlns:tls="com.io7m.cardant:tls:1"
                  ListenAddress="[::]"
                  ListenPort="30000"
                  SessionExpiration="PT30M"
                  ExternalAddress="http://cardant.example.com:30000">
  <tls:TLSEnabled>
    <tls:KeyStore Type="CANONMILL"
                  Provider="CANONMILL"
                  Password="ignored"
                  File="/cardant/keystore.xml"/>
    <tls:TrustStore Type="JKS"
                    Provider="SUN"
                    Password="changeit"
                    File="/usr/lib/jvm/java-21-openjdk/lib/security/cacerts"/>
  </tls:TLSEnabled>
</InventoryService>
1
The Idstore section of the configuration file configures the external idstore server.
1
The BaseURI attribute specifies the base URI of the User API of the external idstore server. This server is used to authenticate users whenever they try to log in to the cardant server.
2
The PasswordResetURI attribute specifies the URI to which users should be redirected if they want to reset their passwords. This is the URI of the User View service on the external idstore server.
1
An example service configuration:

3.4.3.2. Example

<?xml version="1.0" encoding="UTF-8" ?>

<Idstore xmlns="com.io7m.cardant:configuration:1"
         BaseURI="https://idstore.example.com:50000"
         PasswordResetURI="https://idstore.example.com:50001/reset"/>
1
The Maintenance section of the configuration file configures the maintenance service.
1
The TLSReloadInterval attribute specifies how frequently the server will reload the TLS certificates for the HTTP services; the server will reload certificates every time this interval elapses. The attribute must be formatted as an ISO 8601 duration string.
1
An example maintenance configuration:

3.5.3.2. Example

<Maintenance TLSReloadInterval="PT30M"/>
1
The Limits section of the configuration file configures various limits for the server.
1
The MaximumFileUploadSizeOctets attribute specifies the maximum size allowed for files uploaded the server. Requests to upload files larger than this limit will be rejected.
1
The MaximumCommandSizeOctets attribute specifies the maximum size allowed for commands sent to the server. Commands larger than this limit will be rejected.
1
An example configuration:

3.6.4.2. Example

<Limits MaximumFileUploadSizeOctets="10000000"
        MaximumCommandSizeOctets="10000000"/>
1
The Database section of the configuration file configures the database.
2
The OwnerRoleName attribute specifies the name of the role that owns the database. Conventionally, this should be cardant_install, but can be set independently by the database administrator.
3
The OwnerRolePassword attribute specifies the password of the owner role.
4
The WorkerRolePassword attribute specifies the password of the worker role used for normal database operation.
5
The ReaderRolePassword attribute specifies the password of the reader role used for read-only database access. If this attribute is not specified, logging in using this role will be prevented.
6
The MinimumPoolConnections attribute specifies the number of database connections to keep idle in the internal database connection pool. If this attribute is not specified, the default is 0.
7
The MaximumPoolConnections attribute specifies the maximum number of database connections to allow in the internal database connection pool. If this attribute is not specified, the default is 10. If the number of connections in the internal database pool reaches this value, the application will be forced to wait for a connection to become idle before it can obtain a new connection.
8
The Name attribute specifies the database name.
9
The Create attribute specifies that the database schema should be created on startup.
10
The Upgrade attribute specifies that the database schema should be upgraded on startup.
11
The Language attribute specifies the language that will be used internally for full-text searching.
1
An example database configuration:

3.7.2.2. Example

<Database Kind="POSTGRESQL"
          OwnerRoleName="cardant_install"
          OwnerRolePassword="mydatabase"
          WorkerRolePassword="willquickly"
          ReaderRolePassword="becompromised"
          Address="db.example.com"
          Port="5432"
          Name="cardant"
          Create="true"
          Upgrade="true"
          Language="english"
          MinimumPoolConnections="1"
          MaximumPoolConnections="5"/>
1
The OpenTelemetry section of the configuration file configures Open Telemetry. This section is optional and telemetry is disabled if the section is not present.
2
The logical service name should be provided in the LogicalServiceName attribute.
1
If the OpenTelemetry element contains a Traces element, OTLP traces will be sent to a specified endpoint. The Endpoint attribute specifies the endpoint, and the Protocol attribute can either be GRPC or HTTP.
1
If the OpenTelemetry element contains a Metrics element, OTLP metrics will be sent to a specified endpoint. The Endpoint attribute specifies the endpoint, and the Protocol attribute can either be GRPC or HTTP.
1
If the OpenTelemetry element contains a Logs element, OTLP logs will be sent to a specified endpoint. The Endpoint attribute specifies the endpoint, and the Protocol attribute can either be GRPC or HTTP.
1
An example Open Telemetry configuration:

3.8.5.2. Example

<OpenTelemetry LogicalServiceName="idstore">
  <Logs Endpoint="http://logs.example.com:4317"
        Protocol="GRPC"/>
  <Metrics Endpoint="http://metrics.example.com:4317"
           Protocol="GRPC"/>
  <Traces Endpoint="http://traces.example.com:4317"
          Protocol="GRPC"/>
</OpenTelemetry>
1
The XSD schema for the configuration file is as follows:

3.9.2. Configuration Schema

<?xml version="1.0" encoding="UTF-8" ?>

<!--
  Copyright © 2023 Mark Raynsford <code@io7m.com> https://www.io7m.com

  Permission to use, copy, modify, and/or distribute this software for any
  purpose with or without fee is hereby granted, provided that the above
  copyright notice and this permission notice appear in all copies.

  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
  IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-->

<schema xmlns="http://www.w3.org/2001/XMLSchema"
        targetNamespace="com.io7m.cardant:configuration:1"
        xmlns:ct="com.io7m.cardant:tls:1"
        xmlns:c="com.io7m.cardant:configuration:1">

  <import namespace="com.io7m.cardant:tls:1"/>

  <annotation>
    <documentation>
      The schema for server configuration files.
    </documentation>
  </annotation>

  <simpleType name="DatabaseKind">
    <annotation>
      <documentation>
        The kind of the target database. Currently, only PostgreSQL is supported.
      </documentation>
    </annotation>

    <restriction base="string">
      <enumeration value="POSTGRESQL">
        <annotation>
          <documentation>
            The database is PostgreSQL.
          </documentation>
        </annotation>
      </enumeration>
    </restriction>
  </simpleType>

  <element name="Idstore">
    <annotation>
      <documentation>
        Configuration for the idstore server that will be used for user identity information.
      </documentation>
    </annotation>

    <complexType>
      <attribute name="BaseURI"
                 type="anyURI"
                 use="required">
        <annotation>
          <documentation>
            The base URI of the idstore user API.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="PasswordResetURI"
                 type="anyURI"
                 use="required">
        <annotation>
          <documentation>
            The password reset URI to which to redirect users who want to reset their password.
          </documentation>
        </annotation>
      </attribute>
    </complexType>
  </element>

  <simpleType name="OpenTelemetryProtocol">
    <annotation>
      <documentation>
        The protocol used to deliver OpenTelemetry data.
      </documentation>
    </annotation>

    <restriction base="string">
      <enumeration value="GRPC">
        <annotation>
          <documentation>
            The data will be sent using gRPC.
          </documentation>
        </annotation>
      </enumeration>
      <enumeration value="HTTP">
        <annotation>
          <documentation>
            The data will be sent using HTTP(s).
          </documentation>
        </annotation>
      </enumeration>
    </restriction>
  </simpleType>

  <element name="Logs">
    <annotation>
      <documentation>
        Configuration information for OpenTelemetry logs.
      </documentation>
    </annotation>

    <complexType>
      <attribute name="Endpoint"
                 use="required"
                 type="anyURI">
        <annotation>
          <documentation>
            The endpoint to which OTLP log data will be sent.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="Protocol"
                 use="required"
                 type="c:OpenTelemetryProtocol">
        <annotation>
          <documentation>
            The protocol used to send log data.
          </documentation>
        </annotation>
      </attribute>
    </complexType>
  </element>

  <element name="Metrics">
    <annotation>
      <documentation>
        Configuration information for OpenTelemetry metrics.
      </documentation>
    </annotation>

    <complexType>
      <attribute name="Endpoint"
                 use="required"
                 type="anyURI">
        <annotation>
          <documentation>
            The endpoint to which OTLP metrics data will be sent.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="Protocol"
                 use="required"
                 type="c:OpenTelemetryProtocol">
        <annotation>
          <documentation>
            The protocol used to send metrics data.
          </documentation>
        </annotation>
      </attribute>
    </complexType>
  </element>

  <element name="Traces">
    <annotation>
      <documentation>
        Configuration information for OpenTelemetry traces.
      </documentation>
    </annotation>

    <complexType>
      <attribute name="Endpoint"
                 use="required"
                 type="anyURI">
        <annotation>
          <documentation>
            The endpoint to which OTLP trace data will be sent.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="Protocol"
                 use="required"
                 type="c:OpenTelemetryProtocol">
        <annotation>
          <documentation>
            The protocol used to send trace data.
          </documentation>
        </annotation>
      </attribute>
    </complexType>
  </element>

  <element name="OpenTelemetry">
    <annotation>
      <documentation>
        Configuration information for OpenTelemetry.
      </documentation>
    </annotation>

    <complexType>
      <sequence>
        <element ref="c:Logs"
                 minOccurs="0"
                 maxOccurs="1"/>
        <element ref="c:Metrics"
                 minOccurs="0"
                 maxOccurs="1"/>
        <element ref="c:Traces"
                 minOccurs="0"
                 maxOccurs="1"/>
      </sequence>

      <attribute name="LogicalServiceName"
                 use="required"
                 type="string">
        <annotation>
          <documentation>
            The logical name of the service as it will appear in OpenTelemetry.
          </documentation>
        </annotation>
      </attribute>
    </complexType>
  </element>

  <element name="Database">
    <annotation>
      <documentation>
        Configuration information for the database.
      </documentation>
    </annotation>

    <complexType>
      <attribute name="Kind"
                 type="c:DatabaseKind"
                 use="required"/>

      <attribute name="OwnerRoleName"
                 use="required"
                 type="string">
        <annotation>
          <documentation>
            The name of the role that owns the database. This is used for the initial database setup, and for upgrades.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="OwnerRolePassword"
                 use="required"
                 type="string">
        <annotation>
          <documentation>
            The password of the role that owns the database.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="WorkerRolePassword"
                 use="required"
                 type="string">
        <annotation>
          <documentation>
            The password of the role used for normal database operation. This is an unprivileged role that does not have
            the ability to perform DDL or other database-changing operations.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="ReaderRolePassword"
                 use="optional"
                 type="string">
        <annotation>
          <documentation>
            The password of the role used for read-only database operation. If this attribute is not specified, the
            read-only role is not allowed to log in.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="Address"
                 type="string"
                 use="required">
        <annotation>
          <documentation>
            The address of the database.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="Port"
                 type="integer"
                 use="required">
        <annotation>
          <documentation>
            The port used to connect to the database.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="Name"
                 type="string"
                 use="required">
        <annotation>
          <documentation>
            The name of the database.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="Create"
                 type="boolean"
                 use="required">
        <annotation>
          <documentation>
            If set to true, the database and tables will be created if they do not already exist.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="Upgrade"
                 type="boolean"
                 use="required">
        <annotation>
          <documentation>
            If set to true, the database and tables will be upgraded to the latest supported schema version.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="Language"
                 type="string"
                 use="required">
        <annotation>
          <documentation>
            The language used for database search indexes (such as 'english'). See
            https://www.postgresql.org/docs/current/locale.html.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="MinimumPoolConnections"
                 use="optional"
                 default="1"
                 type="unsignedInt">
        <annotation>
          <documentation>
            The minimum number of connections to keep idle in the database connection pool.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="MaximumPoolConnections"
                 use="optional"
                 default="10"
                 type="unsignedInt">
        <annotation>
          <documentation>
            The maximum number of connections to allow in the database connection pool. When this number of
            connections is active in the pool, the application will be forced to wait until a connection
            becomes idle upon requesting another connection.
          </documentation>
        </annotation>
      </attribute>
    </complexType>
  </element>

  <complexType name="HTTPService">
    <sequence minOccurs="1"
              maxOccurs="1">
      <group ref="ct:TLSGroup"/>
    </sequence>

    <attribute name="ListenAddress"
               type="string"
               use="required">
      <annotation>
        <documentation>
          The address upon which this HTTP service will listen.
        </documentation>
      </annotation>
    </attribute>

    <attribute name="ListenPort"
               type="integer"
               use="required">
      <annotation>
        <documentation>
          The port upon which this HTTP service will listen.
        </documentation>
      </annotation>
    </attribute>

    <attribute name="ExternalAddress"
               type="anyURI"
               use="required">
      <annotation>
        <documentation>
          The address by which this service is accessible to the outside world. The service will typically be configured
          behind a reverse proxy to provide TLS.
        </documentation>
      </annotation>
    </attribute>

    <attribute name="SessionExpiration"
               type="duration"
               use="optional">
      <annotation>
        <documentation>
          The expiration time for sessions.
        </documentation>
      </annotation>
    </attribute>
  </complexType>

  <element name="InventoryService"
           type="c:HTTPService">
    <annotation>
      <documentation>
        Configuration for the Inventory API service.
      </documentation>
    </annotation>
  </element>

  <element name="Limits">
    <annotation>
      <documentation>
        Configuration for various limits.
      </documentation>
    </annotation>

    <complexType>
      <attribute name="MaximumFileUploadSizeOctets"
                 type="unsignedLong"
                 use="required">
        <annotation>
          <documentation>
            The maximum permitted size of uploaded files (in octets).
          </documentation>
        </annotation>
      </attribute>

      <attribute name="MaximumCommandSizeOctets"
                 type="unsignedLong"
                 use="required">
        <annotation>
          <documentation>
            The maximum permitted size of ordinary commands (in octets).
          </documentation>
        </annotation>
      </attribute>
    </complexType>
  </element>

  <element name="Maintenance">
    <annotation>
      <documentation>
        Configuration for the server's periodic maintenance tasks.
      </documentation>
    </annotation>

    <complexType>
      <attribute name="TLSReloadInterval"
                     type="duration"
                     use="optional">
        <annotation>
          <documentation>
            The interval at which TLS contexts will be reloaded. If not
            specified, TLS contexts will not be reloaded.
          </documentation>
        </annotation>
      </attribute>
    </complexType>
  </element>

  <element name="Configuration">
    <annotation>
      <documentation>
        The top-level configuration element.
      </documentation>
    </annotation>

    <complexType>
      <sequence>
        <element ref="c:InventoryService"/>
        <element ref="c:Database"/>
        <element ref="c:Idstore"/>
        <element ref="c:Limits"/>
        <element ref="c:Maintenance"/>
        <element ref="c:OpenTelemetry"
                 minOccurs="0"
                 maxOccurs="1"/>
      </sequence>
    </complexType>
  </element>

</schema>

3.9.3. TLS Schema

<?xml version="1.0" encoding="UTF-8" ?>

<!--
  Copyright © 2023 Mark Raynsford <code@io7m.com> https://www.io7m.com

  Permission to use, copy, modify, and/or distribute this software for any
  purpose with or without fee is hereby granted, provided that the above
  copyright notice and this permission notice appear in all copies.

  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
  IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-->

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="com.io7m.cardant:tls:1"
            xmlns:nt="com.io7m.cardant:tls:1">

  <xsd:complexType name="StoreType"
                   abstract="true">
    <xsd:attribute name="Type"
                   type="xsd:string"
                   use="required"/>
    <xsd:attribute name="Provider"
                   type="xsd:string"
                   use="required"/>
    <xsd:attribute name="Password"
                   type="xsd:string"
                   use="required"/>
    <xsd:attribute name="File"
                   type="xsd:string"
                   use="required"/>
  </xsd:complexType>

  <xsd:complexType name="KeyStoreType">
    <xsd:complexContent>
      <xsd:extension base="nt:StoreType"/>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:complexType name="TrustStoreType">
    <xsd:complexContent>
      <xsd:extension base="nt:StoreType"/>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:element name="KeyStore"
               type="nt:KeyStoreType"/>

  <xsd:element name="TrustStore"
               type="nt:TrustStoreType"/>

  <xsd:complexType name="TLSType"
                   abstract="true"/>

  <xsd:complexType name="TLSDisabledType">
    <xsd:complexContent>
      <xsd:extension base="nt:TLSType"/>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:element name="TLSDisabled"
               type="nt:TLSDisabledType"/>

  <xsd:complexType name="TLSEnabledType">
    <xsd:complexContent>
      <xsd:extension base="nt:TLSType">
        <xsd:sequence>
          <xsd:element ref="nt:KeyStore"/>
          <xsd:element ref="nt:TrustStore"/>
        </xsd:sequence>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:element name="TLSEnabled"
               type="nt:TLSEnabledType"/>

  <xsd:group name="TLSGroup">
    <xsd:choice>
      <xsd:element ref="nt:TLSDisabled"/>
      <xsd:element ref="nt:TLSEnabled"/>
    </xsd:choice>
  </xsd:group>

</xsd:schema>
2. Installation
Front Matter
4. Model
io7m | single-page | multi-page | epub | Cardant User Manual 1.0.0-beta0002