PostgreSQL is required for the Dashboard Host Service, Test Monitor Service, Dynamic Form Fields Service, and AI Assistant Service.

Common Requirements

Note For enhanced security, create separate database users for each SystemLink service. This least-privilege approach ensures that each service can only access its own database and own tables.

Before configuring any service to use a PostgreSQL server, ensure you have:

  • A provisioned PostgreSQL server. For best performance and security, we recommend dedicating the PostgreSQL instance to SystemLink rather than sharing it with other applications.
  • The host name of the PostgreSQL server.
  • The credentials for at least one database user.
  • PostgreSQL administrative privileges to create databases and users.
  • A TLS certificate for secure connections. (Recommended)

On initial launch and for some upgrade scenarios, each service creates the required schema and tables. After setup, you can revoke the user's CREATE privileges. The following table shows the minimum privileges required for normal operation:

Table 32. Operation Privileges
Location Privileges
Database CONNECT
Service schema CREATE, USAGE
Tables in schema SELECT, INSERT, UPDATE, DELETE
Note Schema data should be accessed through the SystemLink web application or the respective service API. The schema is considered an internal implementation and may change without notice.

Storing Data from the Dashboard Host Service on an External PostgreSQL Server

Create a database and user, making sure that the user has CREATE privileges on the database. The default database name is grafana.

If you are managing secrets with Helm, add your database credentials to systemlink-secrets.yaml:

dashboardhost:
  secrets:
    database:
      host: "<postgresql-hostname>:<port>"
      user: "systemlink"
      password: "<database-password>"

In systemlink-values.yaml, ensure that the default dashboardhost.grafana.extraSecretMounts and dashboardhost.grafana.extraConfigmapMounts configurations are enabled:

dashboardhost:
  grafana:
    extraSecretMounts:
      - name: *dashboardhostdbSecret
        secretName: *dashboardhostdbSecret
        defaultMode: 0440
        mountPath: "/etc/secrets/dashboardhost"
        readOnly: true
    extraConfigmapMounts:
      - name: *postgresCertificateConfigMap
        mountPath: "/etc/ssl/certs/dashboardhost/"
        subPath: *postgresCertificateFileName
        configMap: *postgresCertificateConfigMap
        readOnly: true

Storing Data from the Test Monitor Service on an External PostgreSQL Server

Create a database and user, making sure that the user has CREATE privileges on the database.

Future updates of the test monitor service chart may require modifications to the schema and table. To perform these modifications, the test monitor service chart must act as the user that owns the schema and tables. In addition to the user that handles day-to-day operations, you can specify a separate user with higher permissions to perform database migrations.

You can configure the PostgreSQL connection using either a connection string (recommended) or individual connection parameters.

Using a connection string (recommended):
  • Add your credentials to systemlink-secrets.yaml:
    testmonitorservice:
      secrets:
        database:
          connectionString: "Host=<postgresql-hostname>;Database=<database-name>;Username=<database-user>;Password=<database-password>;SslMode=Require"
          migrationConnectionString: "Host=<postgresql-hostname>;Database=<database-name>;Username=<migration-user>;Password=<migration-password>;SslMode=Require"
  • Then configure the connection in systemlink-values.yaml:
    testmonitorservice:
      database:
        connectionString:
          secretName: "testmonitorservicedb-connection"
          connectionStringKey: "connection-string"
          migrationConnectionStringKey: "migration-connection-string"
        tls:
          enabled: true
          existingConfigMap: *postgresCertificateConfigMap
          certificateSubPath: *postgresCertificateFileName

Using individual connection parameters:

  • Alternatively, you can specify connection parameters individually. Add your credentials to systemlink-secrets.yaml:
    testmonitorservice:
      secrets:
        database:
          connectionPassword: "<database-password>"
          migrationConnectionPassword: "<migration-password>"
  • Then configure the connection in systemlink-values.yaml. The default database name is nisystemlink and the default user is nisystemlink:
    testmonitorservice:
      database:
        connectionInfo:
          host: "<postgresql-hostname>"
          port: "5432"
          dbName: "nisystemlink"
          user: "nisystemlink"
          migrationUser: "<migration-user>"
          secretName: "testmonitorservicedb-connection"
          passwordKey: "password"
          migrationPasswordKey: "migration-password"
        tls:
          enabled: true
          existingConfigMap: *postgresCertificateConfigMap
          certificateSubPath: *postgresCertificateFileName

Storing Data from the Dynamic Form Fields Service on an External PostgreSQL Server

Create a database and user, making sure that the user has CREATE privileges on the database.

Future updates of the dynamic form fields service chart may require modifications to the schema and table. To perform these modifications, the dynamic form fields service chart must act as the user that owns the schema and tables. In addition to the user that handles day-to-day operations, you can specify a separate user with higher permissions to perform database migrations.

You can configure the PostgreSQL connection using either a connection string (recommended) or individual connection parameters.

Using a creation string (recommended):

  • Add your credentials to systemlink-secrets.yaml:
    dynamicformfields:
      secrets:
        database:
          connectionString: "Host=<postgresql-hostname>;Database=<database-name>;Username=<database-user>;Password=<database-password>;SslMode=Require"
          migrationConnectionString: "Host=<postgresql-hostname>;Database=<database-name>;Username=<migration-user>;Password=<migration-password>;SslMode=Require"
  • Then configure the connection in systemlink-values.yaml:
    dynamicformfields:
      database:
        connectionString:
          secretName: "dynamicformfields-db-connection"
          connectionStringKey: "connection-string"
          migrationConnectionStringKey: "migration-connection-string"
        tls:
          enabled: true
          existingConfigMap: *postgresCertificateConfigMap
          certificateSubPath: *postgresCertificateFileName

Alternatively, you can specify connection parameters individually:

  • Add your credentials to systemlink-secrets.yaml:
    dynamicformfields:
      secrets:
        database:
          connectionPassword: "<database-password>"
          migrationConnectionPassword: "<migration-password>"
  • Then configure the connection in systemlink-values.yaml. The default database name is nisystemlink and the default user is nisystemlink:
    dynamicformfields:
      database:
        connectionInfo:
          host: "<postgresql-hostname>"
          port: "5432"
          dbName: "nisystemlink"
          user: "nisystemlink"
          migrationUser: "<migration-user>"
          secretName: "dynamicformfields-db-connection"
          passwordKey: "password"
          migrationPasswordKey: "migration-password"
        tls:
          enabled: true
          existingConfigMap: *postgresCertificateConfigMap
          certificateSubPath: *postgresCertificateFileName

Storing Data from the AI Assistant Service on an External PostgreSQL Server

Starting with SystemLink Enterprise 2026-10, the AI Assistant Service is enabled by default and requires PostgreSQL.

Create a database user, making sure that the user has CONNECT and CREATE privileges on the database. During installation and each upgrade, a database migration job runs CREATE SCHEMA IF NOT EXISTS ai_assistant_service as this user.

PostgreSQL checks the CREATE privilege on the database for this statement even if the schema already exists, so do not revoke this privilege after setup. Each time the service starts, it creates any tables that are missing from the ai_assistant_service schema. The service does not require extensions or superuser privileges.

The AI Assistant Service also requires data protection secrets that are not related to PostgreSQL. If you manage secrets with Helm and these values are missing, the Helm installation fails. Refer to Required Secrets for details on the aiassistant-dataprotection secret.

You can configure the PostgreSQL connection using either individual connection parameters (recommended) or a connection string.

Using Individual Connection Parameters (Recommended)

Add your credentials to systemlink-secrets.yaml:

aiassistantservice:
  secrets:
    database:
      connectionPassword: "<database-password>"
Note The AI Assistant Service places the password unencoded in a connection URL. The password cannot contain any reserved characters as defined by the IETF URL specification, such as @ : / ? # % [ ].

Then configure the connection in systemlink-values.yaml. The AI Assistant Service has no default value for host, dbName, or user. You must set these values.

aiassistantservice:
  database:
    connectionInfo:
      host: "<postgresql-hostname>"
      port: "5432"
      dbName: "<database-name>"
      user: "<database-user>"
      secretName: "aiassistant-postgres-credentials"
      passwordKey: "password"
    tls:
      enabled: true
      sslMode: "verify-full"
      existingConfigMap: *postgresCertificateConfigMap
      certificateSubPath: *postgresCertificateFileName

Using a Connection String

Alternatively, you can specify a connection string. The connection string must be a PostgreSQL URI. The AI Assistant Service does not support the Host=...;Username=...; key-value format. Percent-encode any special characters in the password. Configure TLS with the tls values rather than in the URI.

Add your credentials to systemlink-secrets.yaml:

aiassistantservice:
  secrets:
    database:
      connectionString: "postgresql://<database-user>:<database-password>@<postgresql-hostname>:5432/<database-name>"

Then configure the connection in systemlink-values.yaml. When set, the connection string takes precedence over connectionInfo.

aiassistantservice:
  database:
    connectionString:
      secretName: "aiassistant-postgres-connection-string"
      connectionStringKey: "connection-string"
    tls:
      enabled: true
      sslMode: "verify-full"
      existingConfigMap: *postgresCertificateConfigMap
      certificateSubPath: *postgresCertificateFileName

Using a Separate Migration User (Optional)

By default, the database migration job connects as the service user. To run migrations as a separate user, complete the following steps before you install or upgrade.

  1. Grant the migration user CONNECT and CREATE privileges on the database. The migration user must keep the CREATE privilege.
  2. As a database administrator, create the schema with the migration user as the owner. Then grant the service user access to the schema and to the tables that the migration user creates.
    CREATE SCHEMA IF NOT EXISTS ai_assistant_service AUTHORIZATION <migration-user>;
    GRANT USAGE, CREATE ON SCHEMA ai_assistant_service TO <database-user>;
    ALTER DEFAULT PRIVILEGES FOR ROLE <migration-user> IN SCHEMA ai_assistant_service
      GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO <database-user>;

    The service user needs CREATE on the schema because the service creates its own tables at startup.

  3. Add the migration credentials. If you use individual connection parameters, add the migration password to systemlink-secrets.yaml.
    aiassistantservice:
      secrets:
        database:
          migrationConnectionPassword: "<migration-password>"
  4. Add the migration user to systemlink-values.yaml.
    aiassistantservice:
      database:
        connectionInfo:
          migrationUser: "<migration-user>"
          migrationPasswordKey: "migration-password"
  5. If you use a connection string, add the migration connection string to systemlink-secrets.yaml.
    aiassistantservice:
      secrets:
        database:
          migrationConnectionString: "postgresql://<migration-user>:<migration-password>@<postgresql-hostname>:5432/<database-name>"
  6. Add the migration connection string key to systemlink-values.yaml.
    aiassistantservice:
      database:
        connectionString:
          migrationConnectionStringKey: "migration-connection-string"
Note If you manage secrets outside of Helm, the database secret must contain the key that migrationPasswordKey or migrationConnectionStringKey references. Otherwise, the migration job cannot start and the AI Assistant Service pods do not start. For more information, refer to Required Secrets.

TLS Configuration for the AI Assistant Service

TLS is enabled by default for the AI Assistant Service. The service uses the certificate in the shared PostgreSQL certificate ConfigMap to verify the PostgreSQL server certificate. During installation, provide the certificate of the certificate authority (CA) that issued your server certificate with --set-file database.postgresCertificate=postgres.pem.

If your server uses a certificate from a public CA, provide the root certificate of that CA, such as the CA bundle that your cloud provider publishes. If TLS is enabled and the ConfigMap does not exist, the AI Assistant Service pods do not start.

The AI Assistant Service defaults to verify-full, which verifies both the certificate authority and the host name. Set aiassistantservice.database.tls.sslMode to one of the following values:

  • verify-full (default): Verifies the certificate authority and that the server certificate contains the configured host.
  • verify-ca: Verifies the certificate authority only. Use this value if the server certificate does not contain the configured host name, for example when you connect through a private endpoint or an IP address.
  • require: Requires an encrypted connection. Use verify-ca or verify-full to verify the server certificate.
Note If your PostgreSQL server does not support TLS, set aiassistantservice.database.tls.enabled to false. After disabling TLS, the service does not verify the server certificate and does not require an encrypted connection.