Configuration

An hermes application will look for its YAML configuration file on current working directory.

The configuration file must be named with APPNAME-config.yml, e.g.:

  • hermes-server-config.yml for server and server-cli
  • hermes-client-usersgroups_null-config.yml for client-usersgroups_null and client-usersgroups_null-cli

Settings are separated in several YAML sections:

For security reasons, it may be desirable to allow certain users to use the CLI without granting them read access to the configuration file. To do this, simply create an optional CLI configuration file named APPNAME-cli-config.yml, e.g.:

  • hermes-server-cli-config.yml for server-cli
  • hermes-client-usersgroups_null-cli-config.yml for client-usersgroups_null-cli

This file should only contain the following directives :

hermes:
  cli_socket:
    path: /path/to/cli/sockfile.sock

Boris Lechner 2025-05-05 e022507882f1c7d53ec4dc72b08922261dfdd25f

Subsections of Configuration

hermes

Settings shared by server and all clients.

Main subsections:


hermes.umask

  • Description: Set up the default umask for each file or directory created by the application : cache dirs, cache files and log files. Warning as it is an octal value, it must be prefixed by a 0.
  • Mandatory: No
  • Type: integer
  • Valid values: 0000 - 0777
  • Default value: 0027

hermes.cache

Mandatory section to define cache settings.

hermes.cache.dirpath

  • Description: Path of an existing directory where cache files will be stored.
  • Mandatory: Yes
  • Type: string

hermes.cache.enable_compression

  • Description: If true, all cache files will be gzipped.
  • Mandatory: No
  • Type: boolean
  • Default value: true

hermes.cache.backup_count

  • Description: At each save, if the file content has changed, Hermes will keep previous cache content up to specified backup_count.
  • Mandatory: No
  • Type: integer
  • Valid values: 0 - 999999
  • Default value: 1

hermes.cli_socket

Enable CLI socket that will allow communication between app and its CLI.

hermes.cli_socket.path

  • Description: Path to CLI socket file to create/use. When left unspecified, CLI will be disabled.
  • Mandatory: No
  • Type: string

hermes.cli_socket.owner

  • Description: Name of the user that should own the socket file when created, as would be fed to chown.
    When left unspecified, it uses the current hermes-server running user.
  • Mandatory: No
  • Type: string
  • Ignored when: dont_manage_sockfile is true

hermes.cli_socket.group

  • Description: Name of the group that should own the socket file when created, as would be fed to chown.
    When left unspecified, it uses the current group of hermes-server running user.
  • Mandatory: No
  • Type: string
  • Ignored when: dont_manage_sockfile is true

hermes.cli_socket.mode

  • Description: The permissions to apply to the socket file when created, as would be fed to chmod.
    For those used to /usr/bin/chmod remember that modes are octal numbers and should be prefixed by a 0.
    If mode is not specified and the socket file does not exist, the default umask on the system will be used when setting the mode for the newly created socket file.
    If mode is not specified and the socket file does exist, the mode of the existing socket file will be used.
  • Mandatory: No
  • Type: integer
  • Default value: 00600
  • Valid values: 0 - 07777
  • Ignored when: dont_manage_sockfile is true

hermes.cli_socket.dont_manage_sockfile

  • Description: Indicates that Hermes shouldn’t handle the socket file creation, and use the socket file descriptor provided by its parent process (typically SystemD).
    The created socket must be a listening AF_UNIX stream socket. One and only one socket must be provided : Hermes will ensure this by checking that the SystemD env var LISTEN_FDS is set to 1, and will fail otherwise.
  • Mandatory: No
  • Type: boolean
  • Default value: false

hermes.logs

Mandatory section to define log settings.

hermes.logs.logfile

  • Description: Path of an existing directory where log files will be stored. When left unspecified, no log file will be stored on disk.
  • Mandatory: Yes
  • Type: string

hermes.logs.backup_count

  • Description: Hermes will rotate its log every day at midnight and keep up to specified backup_count values of previous log files.
  • Mandatory: No
  • Type: integer
  • Default value: 7
  • Valid values: 0 - 999999

hermes.logs.verbosity

  • Description: Log verbosity.
  • Mandatory: No
  • Type: string
  • Default value: warning
  • Valid values:
    • critical
    • error
    • warning
    • info
    • debug

hermes.logs.long_string_limit

  • Description: Define the limit (max size) of string attributes content to show in logs.
    If a string attribute content is greater than this limit, it will be truncated to this limit and marked as a LONG_STRING in logs.
    Can be set to null to disable this feature and always show full string content in logs.
  • Mandatory: No
  • Type: integer
  • Default value: 512
  • Valid values: [1 - 999999] or null

hermes.mail

Mandatory section to define mail settings to allow Hermes to notify errors to admins.

The email will contain 3 attachments when possible: previous.txt, current.txt, and diff.txt, containing the previous state, the current state, and the diff between previous and current states.

hermes.mail.server

  • Description: DNS name or IP address of SMTP relay.
  • Mandatory: Yes
  • Type: string

hermes.mail.from

  • Description: E-mail address that will be set as from address in the mail syntax User name <name@example.com>
  • Mandatory: Yes
  • Type: string

hermes.mail.to

  • Description: Recipient address or list of addresses.
  • Mandatory: Yes
  • Type: string | string[]

hermes.mail.compress_attachments

  • Description: Indicate if attachments must be gzipped or sent raw.
  • Mandatory: No
  • Type: boolean
  • Default value: true

hermes.mail.mailtext_maxsize

  • Description: Max size in bytes for mail content. If content size is greater than mailtext_maxsize, then a default fallback message will be set instead.
  • Mandatory: No
  • Type: integer
  • Default value: 1048576 (1 MB)
  • Valid values: >= 0

hermes.mail.attachment_maxsize

  • Description: Max size in bytes for a single mail attachment. If the attachment size is greater than attachment_maxsize, it will not be attached to the email and a message indicating this will be added to the mail content.
  • Mandatory: No
  • Type: integer
  • Default value: 5242880 (5 MB)
  • Valid values: >= 0

hermes.plugins

Mandatory section to declare which plugins must be loaded, with their settings.

It is divided into subsections by plugin type.

hermes.plugins.attributes

Facultative section to declare the attributes plugins to load, and their settings.

It must contain a subsection named with the plugin name containing a facultative settings subsection with the plugin settings to fill according to the plugin documentation.

Example with the ldapPasswordHash plugin:

hermes:
  # (...)
  plugins:
    attributes:
      ldapPasswordHash:
        settings:
          default_hash_types:
            - SMD5
            - SSHA
            - SSHA256
            - SSHA512
  # (...)

hermes.plugins.datasources

Mandatory section on hermes-server to declare the datasource(s), and their settings. If set on hermes-clients, it will be silently ignored.

A same datasource plugin can be used for several datasources, so for each datasource needed, you must declare a subsection with your desired datasource name (that will be used in datamodel), containing two mandatory entries:

  • type (string): the datasource plugin to use for this datasource.
  • settings (subsection): the datasource plugin settings for this datasource according to the plugin documentation.

Example:

hermes:
  # (...)
  plugins:
    datasources:
      my_oracle1_datasource:
        type: oracle
        settings:
          login: HERMES_DUMMY
          password: "DuMmY_p4s5w0rD"
          port: 1234
          server: dummy.example.com
          sid: DUMMY
      
      my_oracle2_datasource:
        type: oracle
        settings:
          login: HERMES_DUMMY2
          password: "DuMmY2_p4s5w0rD"
          port: 1234
          server: dummy.example.com
          sid: DUMMY2

      my_ldap_datasource:
        type: ldap
        settings:
          uri: ldaps://dummy.example.com:636
          binddn: cn=binddn,dc=example,dc=com
          bindpassword: DuMmY_p4s5w0rD
          basedn: dc=example,dc=com
  # (...)

hermes.plugins.messagebus

Mandatory section to declare the messagebus plugin to load, and its settings. Obviously, you must set up exactly one message bus plugin.

  • On hermes-server, it will look up for Message bus producer plugin in plugins/messagebus_producers/ directory.
  • On hermes-client, it will look up for Message bus consumer plugin in plugins/messagebus_consumers/ directory.

It must contain a subsection named with the plugin name containing a facultative settings subsection with the plugin settings to fill according to the messagebus producers or messagebus consumers plugin documentation.

Example with the sqlite producer plugin:

hermes:
  # (...)
  plugins:
    messagebus:
      sqlite:
        settings:
          uri: /path/to/hermes/sqlite/message/bus.sqlite
          retention_in_days: 30
  # (...)

Boris Lechner 2025-05-05 e022507882f1c7d53ec4dc72b08922261dfdd25f

hermes-server

Server settings.

Main subsections:


hermes-server

hermes-server.updateInterval

  • Description: Interval between two data updates, in seconds.
  • Mandatory: Yes
  • Type: integer
  • Valid values: >= 0

hermes-server.datamodel

Mandatory subsection used to configure server datamodel.

For each data types needed, a subsection with the desired data type name must be created and configured. The data type name MUST start with an alphanumerical character.

Obviously, at least one data type must be set up.

Note

The declaration order of data types is important to enforce data integrity:

  • add/modify events will be processed in the declaration order
  • remove events will be processed in the reversed declaration order

So you really should first declare data types that do not depend on any other types, and then types that have dependencies (foreign keys) to those declared above.

hermes-server.datamodel.data-type-name.primarykeyattr

  • Description: The name of the datamodel attribute used as primary key. If the primary key is a tuple, you may declare a list of names.
  • Mandatory: Yes
  • Type: string | string[]

hermes-server.datamodel.data-type-name.toString

  • Description: Jinja template to compose the way a data item will be represented in log files.
  • Mandatory: No
  • Type: string

hermes-server.datamodel.data-type-name.on_merge_conflict

  • Description: Behavior if a same attribute has different value on multiple sources.
  • Mandatory: No
  • Type: string
  • Default value: use_cached_entry
  • Valid values:
    • keep_first_value: use the first value met in source order.
    • use_cached_entry: ignore data fetched and keep using cached entry until conflict is solved.

hermes-server.datamodel.data-type-name.foreignkeys

  • Description: Allow to declare foreign keys in a data type, that clients will use to enforce their foreign keys policy. See Foreign keys for details.
    The setting is a dict with current data type primary key as key, a dict with two entries as value, refering to the parent data type from_objtype and its primary key from_attr.
    Although it might seem intuitive, declaring foreign keys will not create any integrity constraint rules automatically.

    Warning

    Whether for the current data type or for the parent, attributes must be primary keys of their respective types.
    In addition, the primary key of the parent cannot be multivalued (a tuple).

    These constraints could eventually be relaxed one day, but for now no relevant use case has justified the need.

    Example:

    foreignkeys:
      group_id:
        from_objtype: SRVGroups
        from_attr: gid
      user_id:
        from_objtype: SRVUsers
        from_attr: uid
  • Mandatory: No

  • Type: dict[string, dict[string, string]]

  • Default value: {}

hermes-server.datamodel.data-type-name.integrity_constraints

  • Description: Integrity constraints between datamodel type, in Jinja.
    WARNING: it could be terribly slow, so you should keep it as simple as possible, and focus upon primary keys.

    Jinja vars available are:

    • _SELF: the current object
    • data-type-name_pkeys: a set with every primary key of specified data type.
    • data-type-name: a list of dict containing each entry of specified data type.

    Example:

    integrity_constraints:
      - "{{ _SELF.pkey_attr in OTHERDataType_pkeys }}"
  • Mandatory: No

  • Type: string[]

  • Default value: []

hermes-server.datamodel.data-type-name.sources

Mandatory subsection listing the datasource(s) used to fetch current data type data.

For each datasource used, a subsection with its name must be defined and configured.

Obviously, at least one datasource must be set up.

Note

The declaration order of datasources is important to for data merging if hermes-server.datamodel.data-type-name.on_merge_conflict is set to keep_first_value, or if hermes-server.datamodel.data-type-name.sources.datasource-name.pkey_merge_constraint is used.

hermes-server.datamodel.data-type-name.sources.datasource-name.fetch

Mandatory subsection to set up the query used to fetch data.

According to datasource plugin used, query and vars may be facultative: configure them according to your datasource plugin documentation.

hermes-server.datamodel.data-type-name.sources.datasource-name.fetch.type
  • Description: Indicate to datasource plugin which flavor of query to proceed. Should probably be fetch here.
  • Mandatory: Yes
  • Type: string
  • Valid values:
    • fetch: Indicate that plugin must fetch data, without altering dataset.
    • add: Indicate that plugin will add data to dataset.
    • delete: Indicate that plugin will delete data from dataset.
    • modify: Indicate that plugin will modify data in dataset.
hermes-server.datamodel.data-type-name.sources.datasource-name.fetch.query
  • Description: The query to send to datasource. May be a Jinja template.

    Jinja vars available are:

    • REMOTE_ATTRIBUTES: the list of remote attribute names used in attrsmapping. May be useful to generate SQL queries with required data without using wildcards or manually typing the attribute list.
    • CACHED_VALUES: the cache of previous query. A list of dictionaries, each dictionary is an entry with attrname as key, and corresponding value as value. May be useful to filter the query using a cached value.
    • data-type-name_pkeys: a set with every primary key of specified data type. The var’s datatype must be declared before the current one in the datamodel, otherwise the content of the var will always be empty as its content will be fetched after that of the current datatype.
    • data-type-name: a list of dict containing each entry of specified data type. The var’s datatype must be declared before the current one in the datamodel, otherwise the content of the var will always be empty as its content will be fetched after that of the current datatype.
  • Mandatory: No

  • Type: string

hermes-server.datamodel.data-type-name.sources.datasource-name.fetch.vars

Facultative subsection containing some vars to pass to datasource plugin.

The var name as key, and its value as value. Each value may be a Jinja template.

Jinja vars available are:

  • REMOTE_ATTRIBUTES: the list of remote attribute names used in attrsmapping. May be useful to generate SQL queries with required data without using wildcards or manually typing the attribute list.
  • CACHED_VALUES: the cache of previous query. A list of dictionaries, each dictionary is an entry with attrname as key, and corresponding value as value.
  • data-type-name_pkeys: a set with every primary key of specified data type. The var’s datatype must be declared before the current one in the datamodel, otherwise the content of the var will always be empty as its content will be fetched after that of the current datatype.
  • data-type-name: a list of dict containing each entry of specified data type. The var’s datatype must be declared before the current one in the datamodel, otherwise the content of the var will always be empty as its content will be fetched after that of the current datatype.
hermes-server.datamodel.data-type-name.sources.datasource-name.commit_one

Facultative subsection to set up a query to run each time an item of current data has been processed without errors.

According to datasource plugin used, query and vars may be facultative: configure them according to your datasource plugin documentation.

Warning

commit_one and commit_all are mutually exclusive: you can set none or one of them, but not both at the same time.

hermes-server.datamodel.data-type-name.sources.datasource-name.commit_one.type
  • Description: Indicate to datasource plugin which flavor of query to proceed.
  • Mandatory: Yes
  • Type: string
  • Valid values:
    • fetch: Indicate that plugin must fetch data, without altering dataset.
    • add: Indicate that plugin will add data to dataset.
    • delete: Indicate that plugin will delete data from dataset.
    • modify: Indicate that plugin will modify data in dataset.
hermes-server.datamodel.data-type-name.sources.datasource-name.commit_one.query
  • Description: The query to send to datasource. May be a Jinja template.

    Jinja vars available are:

    • REMOTE_ATTRIBUTES: the list of remote attribute names used in attrsmapping. May be useful to generate SQL queries with required data without using wildcards or manually typing the attribute list.
    • ITEM_CACHED_VALUES: the cache values of current item. A dictionary with attrname as key, and corresponding value as value.
    • ITEM_FETCHED_VALUES: the fetched values of current item. A dictionary with attrname as key, and corresponding value as value.
  • Mandatory: No

  • Type: string

hermes-server.datamodel.data-type-name.sources.datasource-name.commit_one.vars

Facultative subsection containing some vars to pass to datasource plugin.

The var name as key, and its value as value. Each value may be a Jinja template.

Jinja vars available are:

  • REMOTE_ATTRIBUTES: the list of remote attribute names used in attrsmapping. May be useful to generate SQL queries with required data without using wildcards or manually typing the attribute list.
  • ITEM_CACHED_VALUES: the cache values of current item. A dictionary with attrname as key, and corresponding value as value.
  • ITEM_FETCHED_VALUES: the fetched values of current item. A dictionary with attrname as key, and corresponding value as value.
hermes-server.datamodel.data-type-name.sources.datasource-name.commit_all

Facultative subsection to set up a query to run once all data have been processed with no errors.

According to datasource plugin used, query and vars may be facultative: configure them according to your datasource plugin documentation.

Warning

commit_all and commit_one are mutually exclusive: you can set none or one of them, but not both at the same time.

hermes-server.datamodel.data-type-name.sources.datasource-name.commit_all.type
  • Description: Indicate to datasource plugin which flavor of query to proceed.
  • Mandatory: Yes
  • Type: string
  • Valid values:
    • fetch: Indicate that plugin must fetch data, without altering dataset.
    • add: Indicate that plugin will add data to dataset.
    • delete: Indicate that plugin will delete data from dataset.
    • modify: Indicate that plugin will modify data in dataset.
hermes-server.datamodel.data-type-name.sources.datasource-name.commit_all.query
  • Description: The query to send to datasource. May be a Jinja template.

    Jinja vars available are:

    • REMOTE_ATTRIBUTES: the list of remote attribute names used in attrsmapping. May be useful to generate SQL queries with required data without using wildcards or manually typing the attribute list.
    • CACHED_VALUES: the cache of previous polling. A list of dictionaries, each dictionary is an entry with attrname as key, and corresponding value as value.
    • FETCHED_VALUES: the fetched entries of current polling. A list of dictionaries, each dictionary is an entry with attrname as key, and corresponding value as value.
  • Mandatory: No

  • Type: string

hermes-server.datamodel.data-type-name.sources.datasource-name.commit_all.vars

Facultative subsection containing some vars to pass to datasource plugin.

The var name as key, and its value as value. Each value may be a Jinja template.

Jinja vars available are:

  • REMOTE_ATTRIBUTES: the list of remote attribute names used in attrsmapping. May be useful to generate SQL queries with required data without using wildcards or manually typing the attribute list.
  • CACHED_VALUES: the cache of previous polling. A list of dictionaries, each dictionary is an entry with attrname as key, and corresponding value as value.
  • FETCHED_VALUES: the fetched entries of current polling. A list of dictionaries, each dictionary is an entry with attrname as key, and corresponding value as value.
hermes-server.datamodel.data-type-name.sources.datasource-name.attrsmapping

Mandatory subsection to set up attribute mapping. HERMES attributes as keys, REMOTE attributes (on datasource) as values. A list of several remote attributes can be defined as a convenience, their non-NULL values will be combined in a list. The NULL values and empty lists won’t be loaded.

A Jinja template could be set as value. If you do so, the whole value must be a template. You can’t set "{{ ATTRIBUTE.split('separator') }} SOME_NON_JINJA_ATTR". This is required to allow the software to collect the REMOTE_ATTRIBUTES

Jinja vars available are:

  • each remote attribute for current data type and datasource with its fetched value, only if its value is not NULL and not an empty list.
  • ITEM_CACHED_VALUES: the cache values of current item. A dictionary with attrname as key, and corresponding value as value.
hermes-server.datamodel.data-type-name.sources.datasource-name.secrets_attrs
  • Description: Define attributes that will contain sensitive data, like passwords.
    It will indicate Hermes to not cache them. The attribute names set here must exist as keys in attrsmapping. They’ll be sent to clients unless they’re defined in local_attrs too. As they’re not cached, they’ll be seen as added EACH TIME the server will be restarted, and the consecutive events will be sent.
  • Mandatory: No
  • Type: string[]
hermes-server.datamodel.data-type-name.sources.datasource-name.cacheonly_attrs
  • Description: Define attributes that will only be stored in cache.
    They won’t be sent in events, nor used to diff with cache. The attribute names set here must exist as keys in attrsmapping.
  • Mandatory: No
  • Type: string[]
hermes-server.datamodel.data-type-name.sources.datasource-name.local_attrs
  • Description: Define attributes that won’t be sent to clients, cached or used to diff with cache.
    They won’t be sent in events, nor used to diff with cache. The attribute names set here must exist as keys in attrsmapping.
  • Mandatory: No
  • Type: string[]
hermes-server.datamodel.data-type-name.sources.datasource-name.pkey_merge_constraint
  • Description: Constraints on primary keys during merge: will be applied during datasources merge.
    As merging will be processed in the datamodel source declaration order in config file, the first source constraint will be ignored (because it will be created and not merged). Then the first source data will be merged with the second source according to the second’s pkey_merge_constraint. Then the resulting data will be merged with the third source data according to the third’s pkey_merge_constraint, etc.
  • Mandatory: No
  • Type: string
  • Default value: noConstraint
  • Valid values:
    • noConstraint: don’t apply any merge constraint
    • mustNotExist: the primary key in current source must not exist in previous (in datasources declaration order), otherwise the data of current will be discarded
    • mustAlreadyExist: the primary key in current source must already exist in previous (in datasources declaration order), otherwise the data of current will be discarded
    • mustExistInBoth: the primary key in current source must already exist in previous (in datasources declaration order), otherwise the data of both sources will be discarded
hermes-server.datamodel.data-type-name.sources.datasource-name.merge_constraints
  • Description: Advanced merge constraints with Jinja rules.
    Warning

    Terribly slow, avoid using them as much as possible.

    Jinja vars available are:
    • _SELF: the data type item in current datasource being currently merged.
    • For each datasource declared in current data type:
      • datasource-name_pkeys: a set with every primary key of data type item in current datasource.
      • datasource-name: the fetched entries of current polling. A list of dictionaries, each dictionary is an entry with attrname as key, and corresponding value as value.
        Note

        if pkey_merge_constraint is defined, it will be enforced before merge_constraints, and Jinja vars will contains the resulting values.

  • Mandatory: No
  • Type: string[]

Boris Lechner 2025-05-05 e022507882f1c7d53ec4dc72b08922261dfdd25f

hermes-client

Settings shared by all clients.

Main subsections:


hermes-client.autoremediation

  • Description: Autoremediation policy to use in error queue for events concerning a same object.
    Warning

    Enabling this feature may break the regular processing order of events: if your data types are only linked by primary keys, it shouldn’t be problematic, but if the links between them are more complex, you really should consider what could go wrong before enabling it.

    e.g. with maximum policy, and trashbin enabled, the autoremediation will delete both events when an added event is followed by a removed event. Without error, the object would have been created and stored in trashbin, but in this case it won’t even be created.

    See how autoremediation works for more details.

  • Mandatory: No
  • Type: string
  • Default value: disabled
  • Valid values:
    • disabled: no autoremediation, events are stacked as is (default).
    • conservative: only merge added and modified events between them.
      • merge an added event with a following modified event.
      • merge two successive modified events.
    • maximum: merge every events that can be merged.
      • merge an added event with a following modified event.
      • merge two successive modified events.
      • delete both events when an added event is followed by a removed event.
      • merge a removed event followed by an added event in a modified event.
      • delete a modified event when it is followed by a removed event.

hermes-client.foreignkeys_policy

  • Description: Set up which event types that will be placed in the error queue if the object concerning them is the parent (by foreign key) of an object already present in the error queue.
    See Foreign keys for more details.
  • Mandatory: No
  • Type: string
  • Default value: on_remove_event
  • Valid values:
    • disabled: No event, policy is disabled.
    • on_remove_event: Only on removed events.
    • on_every_event: On every events types (added, modified, removed)

hermes-client.errorQueue_retryInterval

  • Description: Number of minutes between two attempts of re-processing events in error.
  • Mandatory: No
  • Type: integer
  • Default value: 60 (1 hour)
  • Valid values: 1 - 65535

hermes-client.trashbin_purgeInterval

  • Description: Number of minutes between two trashbin purge attempts.
  • Mandatory: No
  • Type: integer
  • Default value: 60 (1 hour)
  • Valid values: 1 - 65535
  • Ignored when: trashbin_retention is 0/unset

hermes-client.trashbin_retention

  • Description: Number of days to keep removed data in trashbin before permanently deleting it.
    0/unset disable the trashbin: data will be immediately deleted.
  • Mandatory: No
  • Type: integer
  • Default value: 0 (no trashbin)
  • Valid values: >= 0

hermes-client.updateInterval

  • Description: Number of seconds to sleep once no more events are available on message bus.
  • Mandatory: No
  • Type: integer
  • Default value: 5
  • Valid values: >= 0

hermes-client.useFirstInitsyncSequence

  • Description: If true, indicate to use the first/older initsync sequence available on message bus. If false, the latest/newer will be used.
  • Mandatory: No
  • Type: boolean
  • Default value: false

hermes-client.datamodel

Mandatory subsection used to configure client datamodel.

For each data types needed, a subsection with the desired data type name must be created and configured. The data type name MUST start with an alphanumerical character.

Obviously, at least one data type must be set up.

hermes-client.datamodel.data-type-name.hermesType

  • Description: Name of corresponding data type on hermes-server.
  • Mandatory: Yes
  • Type: string

hermes-client.datamodel.data-type-name.toString

  • Description: Jinja template to compose the way a data item will be represented in log files.
  • Mandatory: No
  • Type: string

hermes-client.datamodel.data-type-name.attrsmapping

Subsection to set up attribute mapping. CLIENT attributes as keys, REMOTE attributes (identified as HERMES attributes on hermes-server) as values.

A Jinja template could be set as value. If you do so, the value outside the templates will be used as raw string, and not as remote attribute name.

Jinja vars available are:

  • each remote attribute for current data type, only if its value is not NULL and not an empty list.
Note

If you won’t use their value, it is not necessary to declare a mapping for primary key(s). For some data types, you may omit the attrsmapping, which is equivalent to defining an empty one : therefore it will only contain its primary key(s).

Boris Lechner 2025-05-05 e022507882f1c7d53ec4dc72b08922261dfdd25f

Plugins

Server and clients plugins

  • attributes: custom Jinja filters to transform data

Server plugins

Clients plugins

Boris Lechner 2025-05-05 e022507882f1c7d53ec4dc72b08922261dfdd25f

Subsections of Plugins

attributes plugins

  • crypto_RSA_OAEP: encrypt/decrypt strings with asymmetric RSA keys, using PKCS#1 OAEP, an asymmetric cipher based on RSA and the OAEP padding

  • ldapPasswordHash: generate LDAP hashes of specified formats from a clear text password string

Boris Lechner 2025-05-05 e022507882f1c7d53ec4dc72b08922261dfdd25f

Subsections of attributes plugins

crypto_RSA_OAEP

Description

This plugin allows to encrypt/decrypt strings with asymmetric RSA keys, using PKCS#1 OAEP, an asymmetric cipher based on RSA and the OAEP padding.

Configuration

You can set up as many keys as you want in plugin settings. A key can be used to either encrypt or decrypt, but not both. The plugin will determine if it’s an encryption or a decryption operation upon the key type: decryption for private keys, and encryption for public keys.

hermes:
  plugins:
    attributes:
      crypto_RSA_OAEP:
        settings:
          keys:
            # Key name, you can set whatever you want
            encrypt_to_messagebus:
              # Hash type, when decrypting, you must obviously use the same value
              # that was used for encrypting
              hash: SHA3_512
              # Public RSA key used to encrypt
              # WARNING - THIS KEY IS WEAK AND PUBLIC, NEVER USE IT
              rsa_key: |-
                  -----BEGIN PUBLIC KEY-----
                  MCgCIQCy2W1bAPOa1JIeLuV8qq1Qg7h0jxpf8QCik11H9xZcfwIDAQAB
                  -----END PUBLIC KEY-----                  

            # Another key
            decrypt_from_messagebus:
              hash: SHA3_512
              # Private RSA key used to decrypt
              # WARNING - THIS KEY IS WEAK AND PUBLIC, NEVER USE IT
              rsa_key: |-
                  -----BEGIN RSA PRIVATE KEY-----
                  MIGrAgEAAiEAstltWwDzmtSSHi7lfKqtUIO4dI8aX/EAopNdR/cWXH8CAwEAAQIh
                  AKfflFjGNOJQwvJX3Io+/juxO+HFd7SRC++zBD9paZqZAhEA5OtjZQUapRrV/aC5
                  NXFsswIRAMgBtgpz+t0FxyEXdzlcTwUCEHU6WZ8M2xU7xePpH49Ps2MCEQC+78s+
                  /WvfNtXcRI+gJfyVAhAjcIWzHC5q4wzgL7psbPGy
                  -----END RSA PRIVATE KEY-----                  

Valid values for hash are:

  • SHA224
  • SHA256
  • SHA384
  • SHA512
  • SHA3_224
  • SHA3_256
  • SHA3_384
  • SHA3_512

Usage

crypto_RSA_OAEP(value: bytes | str, keyname: str)  str

Once everything is set up, you can encrypt data with encrypt_to_messagebus key like this in a Jinja filter:

password_encrypted: "{{ PASSWORD_CLEAR | crypto_RSA_OAEP('encrypt_to_messagebus') }}"
password_decrypted: "{{ PASSWORD_ENCRYPTED | crypto_RSA_OAEP('decrypt_from_messagebus') }}"

You can even decrypt and immediately re-encrypt data with another key like this:

password_reencrypted: "{{ PASSWORD_ENCRYPTED | crypto_RSA_OAEP('decrypt_from_datasource') | crypto_RSA_OAEP('encrypt_to_messagebus') }}"

Boris Lechner 2025-05-05 e022507882f1c7d53ec4dc72b08922261dfdd25f

ldapPasswordHash

Description

This plugin allows to generate LDAP hashes of specified formats from a clear text password string.

Configuration

You can set up a facultative list of default hash types in plugin settings. This list will be used if hashtypes are not specified in filter arguments, otherwise the specified hashtypes will be used.

hermes:
  plugins:
    attributes:
      ldapPasswordHash:
        settings:
          default_hash_types:
            - SMD5
            - SSHA
            - SSHA256
            - SSHA512

Valid values for default_hash_types are:

  • MD5
  • SHA
  • SMD5
  • SSHA
  • SSHA256
  • SSHA512

Usage

ldapPasswordHash(password: str, hashtypes: None | str | list[str] = None)  list[str]

Once everything is set up, you can generate your hash list like this in a Jinja filter:

# Will contain a list of hashes of PASSWORD_CLEAR according to
# default_hash_types settings: SMD5, SSHA, SSHA256, SSHA512
ldap_password_hashes: "{{ PASSWORD_CLEAR | ldapPasswordHash }}"

# Will contain a list with only the SSHA512 hashes of PASSWORD_CLEAR
ldap_password_hashes: "{{ PASSWORD_CLEAR | ldapPasswordHash('SSHA512') }}"

# Will contain a list with only the SSHA256 and SSHA512 hashes of PASSWORD_CLEAR
ldap_password_hashes: "{{ PASSWORD_CLEAR | ldapPasswordHash(['SSHA256', 'SSHA512']) }}"

Boris Lechner 2025-05-05 e022507882f1c7d53ec4dc72b08922261dfdd25f

datasources plugins

  • ldap: use a LDAP server as datasource

  • oracle: use an Oracle database as datasource

  • postgresql: use a PostgreSQL database as datasource

  • sqlite: use a SQLite database as datasource (testing only)

Boris Lechner 2025-05-05 e022507882f1c7d53ec4dc72b08922261dfdd25f

Subsections of datasources plugins

ldap

Description

This plugin allows the use of an LDAP server as datasource.

Configuration

Connection settings are required in plugin configuration.

hermes:
  plugins:
    datasources:
      # Source name. Use whatever you want. Will be used in datamodel
      your_source_name:
        type: ldap
        settings:
          # MANDATORY: LDAP server URI
          uri: ldaps://ldap.example.com:636
          # MANDATORY: LDAP server credentials to use
          binddn: cn=account,dc=example,dc=com
          bindpassword: s3cReT_p4s5w0rD
          # MANDATORY: LDAP base DN
          basedn: dc=example,dc=com

          ssl: # Facultative
            # Path to PEM file with CA certs
            cafile: /path/to/INTERNAL-CA-chain.crt # Facultative
            # Path to file with PEM encoded cert for client cert authentication,
            # requires keyfile
            certfile: /path/to/client.crt # Facultative
            # Path to file with PEM encoded key for client cert authentication,
            # requires certfile
            keyfile: /path/to/client.pem # Facultative

          # Facultative. Default: false.
          # Since the client is not aware of the LDAP schema, it cannot know whether
          # an attribute is single-valued or multi-valued. By default, it will
          # return a single value in its base type, as if it were a single-valued
          # attribute, and multiple values in a list.
          # If this setting is enabled, all values will always be returned in a list.
          always_return_values_in_list: true

Usage

Usage differs according to specified operation type

fetch

Fetch entries from LDAP server.

hermes-server:
  datamodel:
    oneDataType:
      sources:
        your_source_name: # 'your_source_name' was set in plugin settings
          fetch:
            type: fetch
            vars:
              # Facultative: the basedn to use for 'fetch' operation.
              # If unset, setting basedn will be used
              base: "ou=exampleOU,dc=example,dc=com"
              # Facultative: the operation scope for 'fetch' operation
              # Valid values are:
              # - base: to search the "base" object itself
              # - one, onelevel: to search the "base" object’s immediate children
              # - sub, subtree: to search the "base" object and all its descendants
              # If unset, "subtree" will be used
              scope: subtree
              # Facultative: the LDAP filter to use for 'fetch' operation
              # If unset, "(objectClass=*)" will be used
              filter: "(objectClass=*)"
              # Facultative: the attributes to fetch, as a list of strings
              # If unset, all the attributes of each entry are returned
              attrlist: "{{ REMOTE_ATTRIBUTES }}"

add

Add entries to LDAP server.

hermes-server:
  datamodel:
    oneDataType:
      sources:
        your_source_name: # 'your_source_name' was set in plugin settings
          fetch:
            type: add
            vars:
              # Facultative: a list of entries to add.
              # If unset, an empty list will be used (and nothing will be added)
              addlist:
                  # MANDATORY: the DN of the entry. If not specified, the entry will
                  # be silently ignored
                - dn: uid=newentry1,ou=exampleOU,dc=example,dc=com
                  # Facultative: the attributes to add to the entry
                  add:
                    # Create attribute if it doesn't exist, and add "value" to it
                    "attrnameToAdd": "value",
                    # Create attribute if it doesn't exist, and add "value1" and
                    # "value2" to it
                    "attrnameToAddList": ["value1", "value2"],
                - dn: uid=newentry2,ou=exampleOU,dc=example,dc=com
                  # ...

delete

Delete entries from LDAP server.

hermes-server:
  datamodel:
    oneDataType:
      sources:
        your_source_name: # 'your_source_name' was set in plugin settings
          fetch:
            type: delete
            vars:
              # Facultative: a list of entries to delete.
              # If unset, an empty list will be used (and nothing will be deleted)
              dellist:
                  # MANDATORY: the DN of the entry. If not specified, the entry will
                  # be silently ignored
                - dn: uid=entryToDelete1,ou=exampleOU,dc=example,dc=com
                - dn: uid=entryToDelete2,ou=exampleOU,dc=example,dc=com
                  # ...

modify

Modify entries on LDAP server.

hermes-server:
  datamodel:
    oneDataType:
      sources:
        your_source_name: # 'your_source_name' was set in plugin settings
          fetch:
            type: modify
            vars:
              # Facultative: a list of entries to modify.
              # If unset, an empty list will be used (and nothing will be modified)
              modlist:
                  # MANDATORY: the DN of the entry. If not specified, the entry will
                  # be silently ignored
                - dn: uid=entryToModify1,ou=exampleOU,dc=example,dc=com

                  # Facultative: the attributes to add to the entry
                  add:
                    # Create attribute if it doesn't exist, and add "value" to it
                    attrnameToAdd: value
                    # Create attribute if it doesn't exist, and add "value1" and
                    # "value2" to it
                    attrnameToAddList: [value1, value2]

                  # Facultative: the attributes to modify in the entry
                  modify:
                    # Create attribute if it doesn't exist, and replace all its
                    # value by "value"
                    attrnameToModify: newvalue
                    # Create attribute if it doesn't exist, and replace all its
                    # value by "newvalue1" and "newvalue2"
                    attrnameToModifyList: [newvalue1, newvalue2]

                  # Facultative: the attributes to delete from the entry
                  delete:
                    # Delete specified attribute and all of its values
                    attrnameToDelete: null
                    # Delete "value" from specified attribute. Raise an error if
                    # value is missing
                    attrnameToDeleteValue: value
                    # Delete "value1" and "value2" from specified attribute. Raise
                    # an error if a value is missing
                    attrnameToDeleteValueList: [value1, value2]

                - dn: uid=entryToModify2,ou=exampleOU,dc=example,dc=com
                  # ...

Boris Lechner 2025-05-05 e022507882f1c7d53ec4dc72b08922261dfdd25f

oracle

Description

This plugin allows using an Oracle database as datasource.

Configuration

Connection settings are required in plugin configuration.

hermes:
  plugins:
    datasources:
      # Source name. Use whatever you want. Will be used in datamodel
      your_source_name:
        type: oracle
        settings:
          # MANDATORY: the database server DNS name or IP address
          server: dummy.example.com
          # MANDATORY: the database connection port
          port: 1234
          # MANDATORY: the database service name. Cannot be set if 'sid' is set
          service_name: DUMMY.example.com
          # MANDATORY: the database SID. Cannot be set if 'service_name' is set
          sid: DUMMY
          # MANDATORY: the database credentials to use
          login: HERMES_DUMMY
          password: "DuMmY_p4s5w0rD"

Usage

Specify a query. If you’d like to provide values from cache, you should provide them in a vars dict, and refer to them by specifying the column-prefixed : var key name in the query: this will automatically sanitize the query.

The example vars names are prefixed with sanitized_ only for clarity, it’s not a requirement.

hermes-server:
  datamodel:
    oneDataType:
      sources:
        your_source_name: # 'your_source_name' was set in plugin settings
          fetch:
            type: fetch
            query: >-
              SELECT {{ REMOTE_ATTRIBUTES | join(', ') }}
              FROM AN_ORACLE_TABLE              

          commit_one:
            type: modify
            query: >-
              UPDATE AN_ORACLE_TABLE
              SET
                valueToSet = :sanitized_valueToSet
              WHERE pkey = :sanitized_pkey              

            vars:
              sanitized_pkey: "{{ ITEM_FETCHED_VALUES.pkey }}"
              sanitized_valueToSet: "{{ ITEM_FETCHED_VALUES.valueToSet }}"

Boris Lechner 2025-05-05 e022507882f1c7d53ec4dc72b08922261dfdd25f

postgresql

Description

This plugin allows using a PostgreSQL database as datasource.

Configuration

Connection settings are required in plugin configuration.

hermes:
  plugins:
    datasources:
      # Source name. Use whatever you want. Will be used in datamodel
      your_source_name:
        type: postgresql
        settings:
          # MANDATORY: the database server DNS name or IP address
          server: dummy.example.com
          # MANDATORY: the database connection port
          port: 1234
          # MANDATORY: the database name
          dbname: DUMMY
          # MANDATORY: the database credentials to use
          login: HERMES_DUMMY
          password: "DuMmY_p4s5w0rD"

Usage

Specify a query. If you’d like to provide values from cache, you should provide them in a vars dict, and refer to them by specifying the var key name encased in %()s in the query: this will automatically sanitize the query. See example below.

The example vars names are prefixed with sanitized_ only for clarity, it’s not a requirement.

hermes-server:
  datamodel:
    oneDataType:
      sources:
        your_source_name: # 'your_source_name' was set in plugin settings
          fetch:
            type: fetch
            query: >-
              SELECT {{ REMOTE_ATTRIBUTES | join(', ') }}
              FROM A_POSTGRESQL_TABLE              

          commit_one:
            type: modify
            query: >-
              UPDATE A_POSTGRESQL_TABLE
              SET
                valueToSet = %(sanitized_valueToSet)s
              WHERE pkey = %(sanitized_pkey)s              

            vars:
              sanitized_pkey: "{{ ITEM_FETCHED_VALUES.pkey }}"
              sanitized_valueToSet: "{{ ITEM_FETCHED_VALUES.valueToSet }}"

Boris Lechner 2025-05-05 e022507882f1c7d53ec4dc72b08922261dfdd25f

sqlite

Description

This plugin allows using an SQLite database as datasource.

Configuration

Connection settings are required in plugin configuration.

hermes:
  plugins:
    datasources:
      # Source name. Use whatever you want. Will be used in datamodel
      your_source_name:
        type: sqlite
        settings:
          # MANDATORY: the database file path
          uri: /path/to/sqlite.db

Usage

Specify a query. If you’d like to provide values from cache, you should provide them in a vars dict, and refer to them by specifying the column-prefixed : var key name in the query: this will automatically sanitize the query.

The example vars names are prefixed with sanitized_ only for clarity, it’s not a requirement.

hermes-server:
  datamodel:
    oneDataType:
      sources:
        your_source_name: # 'your_source_name' was set in plugin settings
          fetch:
            type: fetch
            query: >-
              SELECT {{ REMOTE_ATTRIBUTES | join(', ') }}
              FROM AN_SQLITE_TABLE              

          commit_one:
            type: modify
            query: >-
              UPDATE AN_SQLITE_TABLE
              SET
                valueToSet = :sanitized_valueToSet
              WHERE pkey = :sanitized_pkey              

            vars:
              sanitized_pkey: "{{ ITEM_FETCHED_VALUES.pkey }}"
              sanitized_valueToSet: "{{ ITEM_FETCHED_VALUES.valueToSet }}"

Boris Lechner 2025-05-05 e022507882f1c7d53ec4dc72b08922261dfdd25f

messagebus producers plugins

  • kafka: Send produced events over an Apache Kafka server

  • sqlite: Send produced events over an SQLite database

Boris Lechner 2025-05-05 e022507882f1c7d53ec4dc72b08922261dfdd25f

Subsections of messagebus producers plugins

kafka

Description

This plugin allows hermes-server to send produced events over an Apache Kafka server.

Configuration

It is possible to connect to Kafka server without authentication, or with SSL (TLS) authentication.

hermes:
  plugins:
    messagebus:
      kafka:
        settings:
          # MANDATORY: the Kafka server or servers list that can be used
          servers:
            - dummy.example.com:9093

          # Facultative: which Kafka API version to use. If unset, the
          # api version will be detected at startup and reported in the logs.
          # Don't set this directive unless you encounter some
          # "kafka.errors.NoBrokersAvailable: NoBrokersAvailable" errors raised
          # by a "self.check_version()" call.
          api_version: [2, 6, 0]

          # Facultative: Hard limit on the size of a message sent to Kafka.
          # You should set a higher value if your Kafka messages are likely to
          # exceed the default of 1MB or if you encountered the error
          #   "MessageSizeTooLargeError: The message is xxx bytes when
          #    serialized which is larger than the maximum request size you
          #    have configured with the max_request_size configuration".
          # Default: 1048576.
          max_request_size: 1048576

          # Facultative: enables SSL authentication. If set, the 3 options below
          # must be defined
          ssl:
            # MANDATORY: hermes-server cert file that will be used for
            # authentication
            certfile: /path/to/.hermes/dummy.crt
            # MANDATORY: hermes-server cert file private key
            keyfile: /path/to/.hermes/dummy.pem
            # MANDATORY: The PKI CA cert
            cafile: /path/to/.hermes/INTERNAL-CA-chain.crt

          # MANDATORY: the topic to send events to
          topic: hermes

Boris Lechner 2025-05-05 e022507882f1c7d53ec4dc72b08922261dfdd25f

sqlite

Description

This plugin allows hermes-server to send produced events over an SQLite database.

Configuration

To emulate the behavior of other message buses that delete messages once some conditions are met, retention_in_days can be set. It will delete messages older than the specified number of days.

hermes:
  plugins:
    messagebus:
      sqlite:
        settings:
          # MANDATORY:
          uri: /path/to/.hermes/bus.sqlite
          retention_in_days: 1

Boris Lechner 2025-05-05 e022507882f1c7d53ec4dc72b08922261dfdd25f

hermes-client plugins

The client plugins are grouped by categories serving the same goal over several target types. There is currently only one plugin category:

  • usersgroups: manage users, groups, userpasswords and groups membership

Boris Lechner 2025-05-05 e022507882f1c7d53ec4dc72b08922261dfdd25f

Subsections of hermes-client plugins

usergroups

Manage users, groups, userpasswords and groups membership.

Available clients are:

Boris Lechner 2025-05-05 e022507882f1c7d53ec4dc72b08922261dfdd25f

Subsections of usergroups

adpypsrp

Description

This client will handle Users, Groups and UserPasswords events, and store data into an Active Directory through Powershell commands across pypsrp.

The settings list standardAttributes contains available cmdlet parameters used for Users (New-ADUser / Set-ADUser) and Groups (New-ADGroup / Set-ADGroup). The settings list otherAttributes may contains available LDAP display name (ldapDisplayName) attributes to manage those that are not represented by cmdlet parameters for Users and Groups.

The local Datamodel keys MUST exist in standardAttributes or otherAttributes, and will be used as cmdlet parameters with associated values, allowing to handle every AD attributes.

The GroupsMembers will only associate a User with a Group. The SubGroupsMembers will only associate a Group with a Group, allowing to handle nested groups.

To avoid security issues and corner cases with trashbin, a complex random password is set when user is created. This unknown password will be overwritten by the next UserPassword event of the User. This avoids having an enabled account with no password.

The trashbin will only disable the account.

Configuration

hermes-client-usersgroups_adpypsrp:
  WinRM:  # For options details, you may look at https://pypi.org/project/pypsrp/ - "Connection"
    # MANDATORY: AD server URI and port
    host: radon1.in.insa-strasbourg.fr
    port: 5986
    # MANDATORY: AD server credentials
    login: administrator
    password: "s3cReT_p4s5w0rD"
    # Default: true
    ssl: true
    # Default: true
    ssl_cert_validation: false
    # Default: true
    credssp_disable_tlsv1_2: true
    # Default: "auto". Valid values are [auto, always, never]
    encryption: always
    # Default: "wsman"
    path: "wsman"
    # Default: "negotiate". Valid values are [basic, certificate, negotiate, ntlm, kerberos, credssp]
    auth: kerberos
    # Default: "WSMAN". Override the service part of the calculated SPN used when authenticating the server.
    # This is only valid if negotiate auth negotiated Kerberos or kerberos was explicitly set.
    # If you obtain an error "Server not found in Kerberos database", you may try to set HTTP here.
    negotiate_service: WSMAN

  AD_domain:
    # MANDATORY: AD domain name and DN
    name: in.insa-strasbourg.fr
    dn: DC=in,DC=insa-strasbourg,DC=fr
    # MANDATORY: OUs where Users and Groups will be stored
    users_ou: OU=INSA,OU=People,DC=in,DC=insa-strasbourg,DC=fr
    groups_ou: OU=INSA,OU=Groups,DC=in,DC=insa-strasbourg,DC=fr

  # Optional, allows to force each user to be added to the specified group list.
  # Group membership is only added when the user is created: any change to this parameter's value
  # will only impact users created subsequently
  Users_mandatory_groups:
    - MandatoryGroup1
    - MandatoryGroup2

  # Defines cmdlet parameters that can be set, and the valid type of the associated value
  # You really should set it as is.
  standardAttributes:
    Users:
      AccountExpirationDate: "<DateTime>"
      AccountNotDelegated: "<Boolean>"
      AllowReversiblePasswordEncryption: "<Boolean>"
      AuthenticationPolicy: "<ADAuthenticationPolicy>"
      AuthenticationPolicySilo: "<ADAuthenticationPolicySilo>"
      AuthType: "<ADAuthType>"
      CannotChangePassword: "<Boolean>"
      ChangePasswordAtLogon: "<Boolean>"
      City: "<String>"
      Company: "<String>"
      CompoundIdentitySupported: "<Boolean>"
      Country: "<String>"
      # Credential: "<PSCredential>" # Useless: Specifies the user account credentials to use to perform this task
      Department: "<String>"
      Description: "<String>"
      DisplayName: "<String>"
      Division: "<String>"
      EmailAddress: "<String>"
      EmployeeID: "<String>"
      EmployeeNumber: "<String>"
      Enabled: "<Boolean>"
      Fax: "<String>"
      GivenName: "<String>"
      HomeDirectory: "<String>"
      HomeDrive: "<String>"
      HomePage: "<String>"
      HomePhone: "<String>"
      KerberosEncryptionType: "<ADKerberosEncryptionType>"
      LogonWorkstations: "<String>"
      Manager: "<ADUser>"
      MobilePhone: "<String>"
      Office: "<String>"
      OfficePhone: "<String>"
      Organization: "<String>"
      OtherName: "<String>"
      PasswordNeverExpires: "<Boolean>"
      PasswordNotRequired: "<Boolean>"
      POBox: "<String>"
      PostalCode: "<String>"
      # PrincipalsAllowedToDelegateToAccount: "<ADPrincipal[]>" # Won't be set
      ProfilePath: "<String>"
      SamAccountName: "<String>"
      ScriptPath: "<String>"
      # Server: "<String>" # Useless: Specifies the Active Directory Domain Services instance to connect to
      SmartcardLogonRequired: "<Boolean>"
      State: "<String>"
      StreetAddress: "<String>"
      Surname: "<String>"
      Title: "<String>"
      # TrustedForDelegation: "<Boolean>" # Won't be set
      UserPrincipalName: "<String>"

    Groups:
      AuthType: "<ADAuthType>"
      # Credential: "<PSCredential>" # Useless: Specifies the user account credentials to use to perform this task
      Description: "<String>"
      DisplayName: "<String>"
      GroupCategory: "<ADGroupCategory>"
      GroupScope: "<ADGroupScope>"
      HomePage: "<String>"
      ManagedBy: "<ADPrincipal>"
      SamAccountName: "<String>"
      # Server: "<String>" # Useless: Specifies the Active Directory Domain Services instance to connect to

  # Defines LDAP display name (ldapDisplayName) to handle, that are not handled with standardAttributes.
  # You can set your desired values. The values below are just here for example.
  otherAttributes:
    Users:
      otherMobile: "<String[]>"
      otherTelephone: "<String[]>"
      url: "<String[]>"

  # Optional random password generation settings. Default: values specified below
  # Random password is generated to initialize a user whose password is not yet available,
  # or when the user password is removed but the user still exists
  random_passwords:
    # Password length
    length: 32
    # If true, the generated password may contains some upper case letters
    with_upper_letters: true
    # The generated password will contain at least this number of upper case letters
    minimum_number_of_upper_letters: 1
    # If true, the generated password may contains some lower case letters
    with_lower_letters: true
    # The generated password will contain at least this number of lower case letters
    minimum_number_of_lower_letters: 1
    # If true, the generated password may contains some numbers
    with_numbers: true
    # The generated password will contain at least this number of numbers
    minimum_number_of_numbers: 1
    # If true, the generated password may contains some special chars
    with_special_chars: true
    # The generated password will contain at least this number of special chars
    minimum_number_of_special_chars: 1
    # If true, the generated password won't contains the chars specified in 'ambigous_chars_dictionary'
    avoid_ambigous_chars: false
    # The dictionary of ambigous chars (case sensitive) that may be forbidden in password, even if some are present in other dictionnaries
    ambigous_chars_dictionary: "lIO01"
    # The dictionary of letters (case unsensitive) allowed in password
    letters_dictionary: "abcdefghijklmnopqrstuvwxyz"
    # The dictionary of special chars allowed in password
    special_chars_dictionary: "!@#$%^&*"

Datamodel

The following data types may be set up:

  • Users: requires the attribute SamAccountName to be set
  • UserPasswords: obviously requires Users, and requires the attribute user_pkey corresponding to the primary keys of Users, and the attribute password. All other attributes will be ignored
  • Groups: requires the attribute SamAccountName to be set
  • GroupsMembers: obviously requires Users and Groups, and requires the attributes user_pkey and group_pkey corresponding to the primary keys of Users and Groups. All other attributes will be ignored
  • SubGroupsMembers: obviously requires Groups, and requires that the subgroup_pkey and group_pkey attributes match the primary key of the subgroup to be assigned, and that of the assignment group, respectively. All other attributes will be ignored
  datamodel:
    Users:
      hermesType: your_server_Users_type_name
      attrsmapping:
        user_pkey: user_primary_key_on_server
        SamAccountName: login_on_server
        UserPrincipalName: "{{ login_on_server ~ '@YOU.AD.DOMAIN.TLD' }}"
        # Not mandatory, only for example:
        MobilePhone: "{{ (mobile | default([None]))[0] }}" # <String>
        otherMobile: "{{ (mobile | default([]))[1:]  }}" # <String[]>
        # ...

    UserPasswords:
      hermesType: your_server_UserPasswords_type_name
      attrsmapping:
        user_pkey: user_primary_key_on_server
        password: cleartext_password_on_server
        # ...

    Groups:
      hermesType: your_server_Groups_type_name
      attrsmapping:
        group_pkey: group_primary_key_on_server
        SamAccountName: group_name_on_server
        # ...

    GroupsMembers:
      hermesType: your_server_GroupsMembers_type_name
      attrsmapping:
        user_pkey: user_primary_key_on_server
        group_pkey: group_primary_key_on_server
        # ...

    SubGroupsMembers:
      hermesType: your_server_SubGroupsMembers_type_name
      attrsmapping:
        subgroup_pkey: subgroup_primary_key_on_server
        group_pkey: group_primary_key_on_server
        # ...

Boris Lechner 2025-05-05 e022507882f1c7d53ec4dc72b08922261dfdd25f

bsspartage

Description

This client will handle Users, UserPasswords, Groups, GroupsMembers, GroupsSenders and Ressources events, and store data into the PARTAGE dashboard through its API, handled by libPythonBssApi.

To avoid security issues, if no hash is available at user creation, a complex random password will be set. This unknown password will be changed when a userPassword attribute will be set to the User or to the UserPassword. This avoids having an enabled account with no password.

The trashbin will only disable the account.

Configuration

You have to configure an authentication mapping containing all domains managed by this client as keys, and their API key as values.

hermes-client-usersgroups_bsspartage:
  authentication:
    example.com: "Secret_API_key_of_example.com"
    subdomain.example.com: "Secret_API_key_of_subdomain.example.com"
  
  # When an attribute has no more value, the default behavior is to keep its latest value in place.
  # This setting allow to override this behaviour for the specified attributes, with the replacement values.
  # Please note that it is forbidden to set Users.userPassword, as the default behavior is to generate a new random password.
  # It is also forbidden to set null values, as this reverts to the default behavior. In this case, simply remove the affected attribute from this list.
  #
  # The values set below are the default values used if default_removed_values is not set
  default_removed_values:
    Users:
      co: ""
      company: ""
      description: ""
      displayName: ""
      facsimileTelephoneNumber: ""
      givenName: ""
      homePhone: ""
      initials: ""
      l: ""
      mobile: ""
      name: ""
      pager: ""
      postalCode: ""
      st: ""
      street: ""
      telephoneNumber: ""
      title: ""
      zimbraNotes: ""
      zimbraPrefMailForwardingAddress: ""
      zimbraMailCanonicalAddress: ""
      zimbraPrefFromDisplay: ""
      zimbraMailQuota: 0
    Groups:
      # Values should be set to empty strings, but a bug in API is ignoring them.
      # This bug has been notified to PARTAGE's team.
      description: "-" 
      displayName: "-"
      zimbraNotes: "-"
    Resources:
      co: ""
      description: ""
      l: ""
      postalCode: ""
      st: ""
      street: ""
      zimbraCalResBuilding: ""
      zimbraCalResContactEmail: ""
      zimbraCalResContactName: ""
      zimbraCalResContactPhone: ""
      zimbraCalResFloor: ""
      zimbraCalResLocationDisplayName: ""
      zimbraCalResRoom: ""
      zimbraCalResSite: ""
      zimbraNotes: ""
      zimbraCalResCapacity: "-1"

  # Optional random password generation settings. Default: values specified below
  # Random password is generated to initialize a user whose password is not yet available
  random_passwords:
    # Password length
    length: 32
    # If true, the generated password may contains some upper case letters
    with_upper_letters: true
    # The generated password will contain at least this number of upper case letters
    minimum_number_of_upper_letters: 1
    # If true, the generated password may contains some lower case letters
    with_lower_letters: true
    # The generated password will contain at least this number of lower case letters
    minimum_number_of_lower_letters: 1
    # If true, the generated password may contains some numbers
    with_numbers: true
    # The generated password will contain at least this number of numbers
    minimum_number_of_numbers: 1
    # If true, the generated password may contains some special chars
    with_special_chars: true
    # The generated password will contain at least this number of special chars
    minimum_number_of_special_chars: 1
    # If true, the generated password won't contains the chars specified in 'ambigous_chars_dictionary'
    avoid_ambigous_chars: false
    # The dictionary of ambigous chars (case sensitive) that may be forbidden in password, even if some are present in other dictionnaries
    ambigous_chars_dictionary: "lIO01"
    # The dictionary of letters (case unsensitive) allowed in password
    letters_dictionary: "abcdefghijklmnopqrstuvwxyz"
    # The dictionary of special chars allowed in password
    special_chars_dictionary: "!@#$%^&*"

Datamodel

The following data types may be set up:

  • Users: for users accounts. Requires the attribute name and sn to be set, a facultative aliases attribute may bet set, and the others are attributes as defined and used by libPythonBssApi and are facultative. Note that zimbraAllowFromAddress, zimbraFeatureContactsEnabled and zimbraMailForwardingAddress attributes are not supported by libPythonBssApi.
  • UserPasswords: obviously require Users, and requires that its primary keys are corresponding to the primary keys of Users, and requires the attribute userPassword that have to contain a valid LDAP hash. All other attributes will be ignored. As the userPassword attribute can also be managed by Users, you have to choose: either you manage it by Users, or by UserPasswords, but in no case should you use both at the same time for obvious reasons.
  • Groups: for groups and distribution lists. Requires the attribute name and zimbraMailStatus to be set, a facultative aliases attribute may bet set, and the others are attributes as defined and used by libPythonBssApi and are facultative.
  • GroupsMembers: to add users as group members. Obviously require Users and Groups, and requires the attributes user_pkey and group_pkey corresponding to the primary keys of Users and Groups. All other attributes will be ignored.
  • GroupsSenders: to add users as group senders. Obviously require Users and Groups, and requires the attributes user_pkey and group_pkey corresponding to the primary keys of Users and Groups. All other attributes will be ignored.
  • Resources: for resources. Requires the attribute name, zimbraCalResType and displayName to be set, and the others are attributes as defined and used by libPythonBssApi and are facultative.
Warning

If you’re setting the Users.zimbraCOSId, you should avoid setting COS-managed attributes in your datamodel, as overriding the COS default value may lead to unexpected behaviours.

Warning

Since the API does not allow renaming Groups and Resources, this operation is done by deleting the old instance and recreating the new one in the process. However, this can cause loss of links and information (e.g. resource calendars), and it is probably best to avoid these renames.

Tip

To handle Users.zimbraCOSId, it is likely that your data source provides a name rather than the COSId. It is possible to declare a mapping table in Jinja directly in your configuration:

  datamodel:
    Users:
      hermesType: your_server_Users_type_name
      attrsmapping:
        # ...
        zimbraCOSId: >-
          {{
              {
                'name_of_cos1': '11111111-1111-1111-1111-111111111111',
                'name_of_cos2': '22222222-2222-2222-2222-222222222222',
                'name_of_cos3': '33333333-3333-3333-3333-333333333333',
              }[zimbraCOSName_value_from_server | default('name_of_cos1') | lower]
              | default('11111111-1111-1111-1111-111111111111')
          }}          
        # ...
  datamodel:
    Users:
      hermesType: your_server_Users_type_name
      attrsmapping:
        # User primary email address <Valid email address>
        name: name_value_from_server
        # User last name <String>
        sn: sn_value_from_server

        # List of aliases for this user <String[]>
        aliases: aliases_value_from_server
        # User EPPN number <String>
        carLicense: carLicense_value_from_server
        # Country name <String>
        co: co_value_from_server
        # Company or institution name <String>
        company: company_value_from_server
        # Account description <String>
        description: description_value_from_server
        # Name displayed in emails <String>
        displayName: displayName_value_from_server
        # User fax <String>
        facsimileTelephoneNumber: facsimileTelephoneNumber_value_from_server
        # User first name <String>
        givenName: givenName_value_from_server
        # User home phone <String>
        homePhone: homePhone_value_from_server
        # Initial (Mr. or Mrs.) <String>
        initials: initials_value_from_server
        # User city <String>
        l: l_value_from_server
        # User mobile number <String>
        mobile: mobile_value_from_server
        # User shortcut number <String>
        pager: pager_value_from_server
        # Postal code <String>
        postalCode: postalCode_value_from_server
        # User state <String>
        st: st_value_from_server
        # User street <String>
        street: street_value_from_server
        # User phone <String>
        telephoneNumber: telephoneNumber_value_from_server
        # User title <String>
        title: title_value_from_server
        # Password hash <String>
        userPassword: userPassword_value_from_server
        # Account status (default active) <String(active, closed, locked)>
        zimbraAccountStatus: zimbraAccountStatus_value_from_server
        # Class of service Id <String>
        zimbraCOSId: zimbraCOSId_value_from_server
        # Briefcase tab <String (TRUE, FALSE)>
        zimbraFeatureBriefcasesEnabled: zimbraFeatureBriefcasesEnabled_value_from_server
        # Calendar tab <String (TRUE, FALSE)>
        zimbraFeatureCalendarEnabled: zimbraFeatureCalendarEnabled_value_from_server
        # Mail tab <String (TRUE, FALSE)>
        zimbraFeatureMailEnabled: zimbraFeatureMailEnabled_value_from_server
        # Allow user to specify forward address <String (TRUE, FALSE)>
        zimbraFeatureMailForwardingEnabled: zimbraFeatureMailForwardingEnabled_value_from_server
        # Options tab <String (TRUE, FALSE)>
        zimbraFeatureOptionsEnabled: zimbraFeatureOptionsEnabled_value_from_server
        # Tasks tab <String (TRUE, FALSE)>
        zimbraFeatureTasksEnabled: zimbraFeatureTasksEnabled_value_from_server
        # Hide in GAL <String (TRUE, FALSE)>
        zimbraHideInGal: zimbraHideInGal_value_from_server
        # 0=unlimited <Integer (bytes)>
        zimbraMailQuota: zimbraMailQuota_value_from_server
        # Free notes <String>
        zimbraNotes: zimbraNotes_value_from_server
        # Must change password at next login <String (TRUE, FALSE)>
        zimbraPasswordMustChange: zimbraPasswordMustChange_value_from_server
        # Forward address entered by user <Valid email address>
        zimbraPrefMailForwardingAddress: zimbraPrefMailForwardingAddress_value_from_server
        # Do not keep a copy of mails on the local client <String (TRUE, FALSE)>
        zimbraPrefMailLocalDeliveryDisabled: zimbraPrefMailLocalDeliveryDisabled_value_from_server
        # Email address visible for outgoing messages <String>
        zimbraMailCanonicalAddress: zimbraMailCanonicalAddress_value_from_server
        # Display name visible for outgoing messages <String>
        zimbraPrefFromDisplay: zimbraPrefFromDisplay_value_from_server

    UserPasswords:
      hermesType: your_server_UserPasswords_type_name
      attrsmapping:
        # Password hash <String>
        userPassword: userPassword_value_from_server

    Groups:
      hermesType: your_server_Groups_type_name
      attrsmapping:
        # Group primary email address <Valid email address>
        name: name_value_from_server
        # Discriminant distribution list/group <String (enabled, disabled)>
        zimbraMailStatus: zimbraMailStatus_value_from_server
        
        # List of aliases for this group <String[]>
        aliases: aliases_value_from_server
        # Group description <String>
        description: description_value_from_server
        # Display name <String>
        displayName: displayName_value_from_server
        # Report available shares to new members <String (TRUE, FALSE)>
        zimbraDistributionListSendShareMessageToNewMembers: zimbraDistributionListSendShareMessageToNewMembers_value_from_server
        # Hide group in GAL <String (TRUE, FALSE)>
        zimbraHideInGal: zimbraHideInGal_value_from_server
        # Free notes <String>
        zimbraNotes: zimbraNotes_value_from_server

    GroupsMembers:
      hermesType: your_server_GroupsMembers_type_name
      attrsmapping:
        user_pkey: user_pkey_value_from_server
        group_pkey: group_pkey_value_from_server

    GroupsSenders:
      hermesType: your_server_GroupsSenders_type_name
      attrsmapping:
        user_pkey: user_pkey_value_from_server
        group_pkey: group_pkey_value_from_server
    
    Resources:
      hermesType: your_server_Resources_type_name
      attrsmapping:
        # Resource primary email address <Valid email address>
        name: name_value_from_server
        # Display name <String>
        displayName: displayName_value_from_server
        # Resource type <String (Location, Equipment)>
        zimbraCalResType: zimbraCalResType_value_from_server
        
        # Country name <String>
        co: co_value_from_server
        # Description <String>
        description: description_value_from_server
        # Resource city <String>
        l: l_value_from_server
        # Postal code <String>
        postalCode: postalCode_value_from_server
        # Resource state <String>
        st: st_value_from_server
        # Resource street <String>
        street: street_value_from_server
        # Password hash <String>
        userPassword: userPassword_value_from_server
        # Resource status (default active) <String (active, closed)>
        zimbraAccountStatus: zimbraAccountStatus_value_from_server
        # Automatically accept or decline invitations <String (TRUE, FALSE)>
        zimbraCalResAutoAcceptDecline: zimbraCalResAutoAcceptDecline_value_from_server
        # Automatically decline invitations if there is a risk of conflict <String (TRUE, FALSE)>
        zimbraCalResAutoDeclineIfBusy: zimbraCalResAutoDeclineIfBusy_value_from_server
        # Automatically decline recurring invitations <String (TRUE, FALSE)>
        zimbraCalResAutoDeclineRecurring: zimbraCalResAutoDeclineRecurring_value_from_server
        # Building <String>
        zimbraCalResBuilding: zimbraCalResBuilding_value_from_server
        # Capacity <Integer>
        zimbraCalResCapacity: zimbraCalResCapacity_value_from_server
        # Contact email address <String>
        zimbraCalResContactEmail: zimbraCalResContactEmail_value_from_server
        # Contact name <String>
        zimbraCalResContactName: zimbraCalResContactName_value_from_server
        # Contact phone <String>
        zimbraCalResContactPhone: zimbraCalResContactPhone_value_from_server
        # Floor <String>
        zimbraCalResFloor: zimbraCalResFloor_value_from_server
        # Name of the displayed location <String>
        zimbraCalResLocationDisplayName: zimbraCalResLocationDisplayName_value_from_server
        # Room <String>
        zimbraCalResRoom: zimbraCalResRoom_value_from_server
        # Site <String>
        zimbraCalResSite: zimbraCalResSite_value_from_server
        # Free notes <String>
        zimbraNotes: zimbraNotes_value_from_server
        # Forward calendar invitations to this address <Array>
        zimbraPrefCalendarForwardInvitesTo: zimbraPrefCalendarForwardInvitesTo_value_from_server

Boris Lechner 2025-05-05 e022507882f1c7d53ec4dc72b08922261dfdd25f

flatfiles_emails_of_groups

Description

This client will generate a flat txt file by Groups, containing the e-mail addresses of its members (one by line).

Configuration

hermes-client-usersgroups_flatfiles_emails_of_groups:
  # MANDATORY
  destDir: "/path/where/files/are/stored"

  # Facultative: if set, will generate a file only for the specified group names in list
  onlyTheseGroups:
    - group1
    - group2

Datamodel

The following data types must be set up:

  • Users, requires the following attribute names:
    • user_pkey: the user primary key
    • mail: the user email address
  • Groups, requires the following attribute names:
    • group_pkey: the group primary key
    • name: the group name, that will be compared to those in onlyTheseGroups, and used to name the destination file “groupName.txt”
  • GroupsMembers, requires the following attribute names:
    • user_pkey: the user primary key
    • group_pkey: the group primary key
  datamodel:
    Users:
      hermesType: your_server_Users_type_name
      attrsmapping:
        user_pkey: user_pkey_on_server
        mail: mail_on_server

    Groups:
      hermesType: your_server_Groups_type_name
      attrsmapping:
        group_pkey: group_pkey_on_server
        name: group_name_on_server

    GroupsMembers:
      hermesType: your_server_GroupsMembers_type_name
      attrsmapping:
        user_pkey: user_pkey_on_server
        group_pkey: group_pkey_on_server

Boris Lechner 2025-05-05 e022507882f1c7d53ec4dc72b08922261dfdd25f

kadmin_heimdal

Description

This client will handle Users and UserPassword, and store data in an Heimdal Kerberos server.

Configuration

hermes-client-usersgroups_kadmin_heimdal:
  # MANDATORY: Principal with required rights to manage users and passwords in kadmin
  kadmin_login: root/admin
  # MANDATORY: Password of principal above
  kadmin_password: "s3cReT_p4s5w0rD"
  # MANDATORY: Name of Kerberos realm
  kadmin_realm: KERBEROS_REALM

  # Service principal name to get ticket for. Default: kadmin/admin
  kinit_spn: kadmin/admin
  # kinit command to use. Default: kinit.heimdal
  kinit_cmd: kinit.heimdal
  # kadmin command to use. Default: kadmin.heimdal
  kadmin_cmd: kadmin.heimdal
  # kdestroy command to use. Default: kdestroy.heimdal
  kdestroy_cmd: kdestroy.heimdal

  # kadmin additional args to use when adding a user. Must be a list of strings. Default:
  #   - "--max-ticket-life=1 day"
  #   - "--max-renewable-life=1 week"
  #   - "--attributes="
  #   - "--expiration-time=never"
  #   - "--policy=default"
  #   - "--pw-expiration-time=never"
  kadmin_user_add_additional_options:
    - "--max-ticket-life=1 day"
    - "--max-renewable-life=1 week"
    - "--attributes="
    - "--expiration-time=never"
    - "--policy=default"
    - "--pw-expiration-time=never"
  
  # Set to true to start with an already filled Kerberos database. Default: false
  dont_fail_on_existing_user: false

  # Optional random password generation settings. Default: values specified below
  # Random password is generated to initialize a user whose password is not yet available,
  # or when the user password is removed but the user still exists
  random_passwords:
    # Password length
    length: 32
    # If true, the generated password may contains some upper case letters
    with_upper_letters: true
    # The generated password will contain at least this number of upper case letters
    minimum_number_of_upper_letters: 1
    # If true, the generated password may contains some lower case letters
    with_lower_letters: true
    # The generated password will contain at least this number of lower case letters
    minimum_number_of_lower_letters: 1
    # If true, the generated password may contains some numbers
    with_numbers: true
    # The generated password will contain at least this number of numbers
    minimum_number_of_numbers: 1
    # If true, the generated password may contains some special chars
    with_special_chars: true
    # The generated password will contain at least this number of special chars
    minimum_number_of_special_chars: 1
    # If true, the generated password won't contains the chars specified in 'ambigous_chars_dictionary'
    avoid_ambigous_chars: false
    # The dictionary of ambigous chars (case sensitive) that may be forbidden in password, even if some are present in other dictionnaries
    ambigous_chars_dictionary: "lIO01"
    # The dictionary of letters (case unsensitive) allowed in password
    letters_dictionary: "abcdefghijklmnopqrstuvwxyz"
    # The dictionary of special chars allowed in password
    special_chars_dictionary: "!@#$%^&*"

Datamodel

The following data types must be set up:

  • Users, requires the following attribute names:
    • login: the user login, that will be used as principal
  • UserPasswords, requires the following attribute names:
    • password: the password of the user

Obviously, the primary keys of Users and UserPasswords must match to be able to link login with password.

  datamodel:
    Users:
      hermesType: your_server_Users_type_name
      attrsmapping:
        login: login_on_server

    UserPasswords:
      hermesType: your_server_UserPasswords_type_name
      attrsmapping:
        password: password_on_server

Boris Lechner 2025-05-05 e022507882f1c7d53ec4dc72b08922261dfdd25f

ldap

Description

This client will handle Users, Groups and UserPasswords events, and store data in an LDAP directory.

The local Datamodel keys will be used as LDAP attributes names, without any constraints, and it is possible to specify some Datamodel keys to ignore (typically the primary keys) that won’t be stored in LDAP directory with the attributesToIgnore setting.

The GroupMembers will only store data (typically LDAP member attribute) in LDAP group entries as it is possible to use LDAP overlays (dynlist or the deprecated memberOf) to dynamically generate the corresponding data in user entries. You should consider reading the propagateUserDNChangeOnGroupMember setting documentation.

LDAP password hashes generation

If you need to generate LDAP password hashes, you may consider looking at ldapPasswordHash attribute plugin.

Configuration

hermes-client-usersgroups_ldap:
    # MANDATORY: LDAP server URI
    uri: ldaps://ldap.example.com:636
    # MANDATORY: LDAP server credentials to use
    binddn: cn=account,dc=example,dc=com
    bindpassword: s3cReT_p4s5w0rD
    # MANDATORY: LDAP base DN
    basedn: dc=example,dc=com
    users_ou: ou=users,dc=example,dc=com
    groups_ou: ou=groups,dc=example,dc=com

    ssl: # Facultative
      # Path to PEM file with CA certs
      cafile: /path/to/INTERNAL-CA-chain.crt # Facultative
      # Path to file with PEM encoded cert for client cert authentication, requires keyfile
      certfile: /path/to/client.crt # Facultative
      # Path to file with PEM encoded key for client cert authentication, requires certfile
      keyfile: /path/to/client.pem # Facultative

    # MANDATORY: Name of DN attribute for Users, UserPasswords and Groups
    # You have to set up values for the three, even if you don't use some of the types
    dnAttributes:
      Users: uid
      UserPasswords: uid
      Groups: cn

    # Depending on group and group membership settings in LDAP, you may use another
    # attribute than the default 'member' attribute to store the DN of group member
    # Facultative. Default value: "member"
    groupMemberAttribute: member

    # Depending on group and group membership settings in LDAP, you usually may want
    # to propagate a user DN change on group member attributes. But sometimes, it
    # may be handled by an overlay, e.g. with memberOf overlay and the
    # memberof-refint/olcMemberOfRefint setting to TRUE
    # If set to true, it requires 'groupsObjectclass' to be defined
    # Facultative. Default value: true
    propagateUserDNChangeOnGroupMember: true

    # If you've set 'propagateUserDNChangeOnGroupMember' to true,
    # you MUST indicate your group objectClass that will be used to search
    # your groups entries
    # Mandatory only if 'propagateUserDNChangeOnGroupMember' is true
    groupsObjectclass: groupOfNames

    # It is possible to set a default value for some attributes for Users, UserPasswords and Groups
    # The default value will be set on added and modified events if the local attribute has no value
    defaultValues:
      Groups:
        member: "" # Hack to allow creation of an empty group, because of the "MUST member" in schema

    # The local attributes listed here won't be stored in LDAP for Users, UserPasswords and Groups
    attributesToIgnore:
      Users:
        - user_pkey
      UserPasswords:
        - user_pkey
      Groups:
        - group_pkey

Datamodel

The following data types may be set up:

  • Users
  • UserPasswords: obviously require Users, and requires the following attribute names user_pkey corresponding to the primary keys of Users
  • Groups
  • GroupsMembers: obviously require Users and Groups, and requires the following attribute names user_pkey group_pkey corresponding to the primary keys of Users and Groups
  datamodel:
    Users:
      hermesType: your_server_Users_type_name
      attrsmapping:
        user_pkey:  user_primary_key_on_server
        uid: login_on_server
        # ...

    UserPasswords:
      hermesType: your_server_UserPasswords_type_name
      attrsmapping:
        user_pkey:  user_primary_key_on_server
        userPassword:  ldap_pwd_hash_list_on_server
        # ...

    Groups:
      hermesType: your_server_Groups_type_name
      attrsmapping:
        group_pkey:  group_primary_key_on_server
        cn:  group_name_on_server
        # ...

    GroupsMembers:
      hermesType: your_server_GroupsMembers_type_name
      attrsmapping:
        user_pkey:  user_primary_key_on_server
        group_pkey:  group_primary_key_on_server
        # ...

Boris Lechner 2025-05-05 e022507882f1c7d53ec4dc72b08922261dfdd25f

null

Description

This client will handle Users, Groups and UserPasswords events, but does nothing but logging.

Configuration

Nothing to configure for the plugin.

hermes-client-usersgroups_null:

Datamodel

The following data types may be set up, without any specific constraint as nothing will be processed.

  • Users
  • UserPasswords
  • Groups
  • GroupsMembers
  datamodel:
    Users:
      hermesType: your_server_Users_type_name
      attrsmapping:
        attr1_client:  attr1_server
        # ...

    UserPasswords:
      hermesType: your_server_UserPasswords_type_name
      attrsmapping:
        attr1_client:  attr1_server
        # ...

    Groups:
      hermesType: your_server_Groups_type_name
      attrsmapping:
        attr1_client:  attr1_server
        # ...

    GroupsMembers:
      hermesType: your_server_GroupsMembers_type_name
      attrsmapping:
        attr1_client:  attr1_server
        # ...

Boris Lechner 2025-05-05 e022507882f1c7d53ec4dc72b08922261dfdd25f

messagebus consumers plugins

  • kafka: Receive events from an Apache Kafka server

  • sqlite: Receive events from an SQLite database

Boris Lechner 2025-05-05 e022507882f1c7d53ec4dc72b08922261dfdd25f

Subsections of messagebus consumers plugins

kafka

Description

This plugin allows hermes-client to receive events from an Apache Kafka server.

Configuration

It is possible to connect to Kafka server without authentication, or with SSL (TLS) authentication.

hermes:
  plugins:
    messagebus:
      kafka:
        settings:
          # MANDATORY: the Kafka server or servers list that can be used
          servers:
            - dummy.example.com:9093

          # Facultative: which Kafka API version to use. If unset, the
          # api version will be detected at startup and reported in the logs.
          # Don't set this directive unless you encounter some
          # "kafka.errors.NoBrokersAvailable: NoBrokersAvailable" errors raised
          # by a "self.check_version()" call.
          api_version: [2, 6, 0]

          # Facultative: enables SSL authentication. If set, the 3 options below
          # must be defined
          ssl:
            # MANDATORY: hermes-client cert file that will be used for
            # authentication
            certfile: /path/to/.hermes/dummy.crt
            # MANDATORY: hermes-client cert file private key
            keyfile: /path/to/.hermes/dummy.pem
            # MANDATORY: The PKI CA cert
            cafile: /path/to/.hermes/INTERNAL-CA-chain.crt

          # MANDATORY: the topic to send events to
          topic: hermes
          # MANDATORY: the group_id to assign client to. Set what you want here.
          group_id: hermes-grp

Boris Lechner 2025-05-05 e022507882f1c7d53ec4dc72b08922261dfdd25f

sqlite

Description

This plugin allows hermes-client to receive events from an SQLite database.

Configuration

hermes:
  plugins:
    messagebus:
      sqlite:
        settings:
          # MANDATORY:
          uri: /path/to/.hermes/bus.sqlite