Configuration
Mounting a config file
- Create a config file in JSON format in a folder of your choice.
-
Fill the config file with your desired configuration (it’s sufficient to add values you want to change; the Connector will merge your config file with the default configuration) Example:
{ "infrastructure": { "httpServer": { "enabled": true, "apiKey": "an-api-key" } } } - Mount the created config file into the Docker container (e.g. to
/config.json). See the official documentation for more information on how to mount files into a Docker container. This is also possible using docker compose. - Set the environment variable
CUSTOM_CONFIG_LOCATIONto the path you mounted your config file to (e.g.CUSTOM_CONFIG_LOCATION="/config.json").
There is also an example config file available. It sets some default values, please only use the fields you require
Environment variables
The configuration can also be done using environment variables. This feature is included in the Connector since version 2.2.1.
Parsing rules
-
Nested fields can be represented using a colon (
:) as a separator.The
:separator doesn’t work with environment variable hierarchical keys on all platforms. The double underscore (__) is supported on all platforms (e.g. bash does not support the:separator but it supports__). The Connector will therefore convert__to:so you can use it on that systems. - The parameter casing must be the same as the config file casing.
- The strings “true” and “false” are converted to the respective boolean values.
- Number strings (
"1"/"1.1") will be converted to the respective number types. - Complex structures (arrays, objects) are not supported. (=>
modules:aModule:aKey='{"a": "x", "b": "y"}'ormodules:aModule:aKey='["a", "b"]'is not valid)
Example
You want to configure the following values:
{
"infrastructure": {
"httpServer": {
"enabled": true,
"port": 8080,
"apiKey": "an-api-key"
}
}
}
- The first value can be configured using the variable
infrastructure:httpServer:enabled="true". Note that the value is represented as a string in the environment variable and the Connector will rewrite it to its boolean representation. - The second value can be configured using the variable
infrastructure:httpServer:port="8080". Note that the value is represented as a string in the environment variable and the Connector will rewrite it to its number representation. - The third value can be configured using the variable
infrastructure:httpServer:apiKey="an-api-key".
Configuration options
The Connector provides the following configuration parameters:
{
"debug": false,
"enforceCertificatePinning": false,
"pinnedTLSCertificateSHA256Fingerprints": {},
"transportLibrary": {
"baseUrl": "BASE_URL",
"platformClientId": "CLIENT_ID",
"platformClientSecret": "CLIENT_SECRET"
},
"database": {
"connectionString": "mongodb://[username:password@]host1[:port1][,...hostN[:portN]][/[defaultauthdb][?options]]",
"dbName": "a-db-name"
},
"infrastructure": { ... },
"modules": { ... }
}
You can validate the config using our schema file. This is possible for example with VSCode or online tools like jsonschemavalidator.net.
debug available since version 3.3.0
⚠️ Do not turn on debug mode in production environments.
The debug flag configures if the Connector is set to production or debug mode. Defaults to false. Can also be configured using the environment variable DEBUG.
enforceCertificatePinning available since version 6.5.0
The enforceCertificatePinning flag configures whether the Connector should enforce certificate pinning. Defaults to false.
If enabled, the Connector will only accept TLS certificates that match the SHA256 fingerprints for endpoints of outgoing requests specified in the pinnedTLSCertificateSHA256Fingerprints object. If a hostname is not configured at all, it cannot be accessed by the Connector anymore.
pinnedTLSCertificateSHA256Fingerprints available since version 6.5.0
The pinnedTLSCertificateSHA256Fingerprints object maps hostnames to TLS certificate SHA256 fingerprints of the respective hostname. If a hostname is found, the Connector only accepts a TLS connection if the server responds with a certificate of one of the given fingerprints. The fingerprints must be in a hexadecimal format and are internally stripped of separators and characters not valid for hexadecimal formats. To reduce attack vectors, wildcard domains like “*.enmeshed.eu” are not valid hostnames, you need to fill this map with every subdomain.
To increase security, please consider setting enforceCertificatePinning to true.
TLS certificates are rotated multiple times in a year for each hostname. Therefore, setting multiple fingerprints per hostname is possible. However, the config and fingerprints need to be updated regularly with the new fingerprints, otherwise the Connector will reject outgoing requests for expired certificates and cease to function.
Getting the SHA256 fingerprint of a certificate:
echo -n | openssl s_client -connect <hostname>:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > cert.pem
openssl x509 -noout -in cert.pem -fingerprint -sha256
rm cert.pem
This will output something similar to:
Connecting to <ip>
...
DONE
sha256 Fingerprint=AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA
You can simply copy the fingerprint after sha256 Fingerprint= and use it.
If you use another way to acquire the fingerprint, the Connector understands multiple formats like
AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
aa:aa:aa:aa:aa:aa:aa:aa:aa:aa:aa:aa:aa:aa:aa:aa:aa:aa:aa:aa:aa:aa:aa:aa:aa:aa:aa:aa:aa:aa:aa:aa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Sample Configuration:
{
// ...
"pinnedTLSCertificateSHA256Fingerprints": {
"example.com": [
"AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA",
"BB:BB:BB:BB:BB:BB:BB:BB:BB:BB:BB:BB:BB:BB:BB:BB:BB:BB:BB:BB:BB:BB:BB:BB:BB:BB:BB:BB:BB:BB:BB:BB"
],
"subdomain.example.com": [
"AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA:AA",
"CC:CC:CC:CC:CC:CC:CC:CC:CC:CC:CC:CC:CC:CC:CC:CC:CC:CC:CC:CC:CC:CC:CC:CC:CC:CC:CC:CC:CC:CC:CC:CC"
]
}
}
transportLibrary
-
baseUrl
requiredThe base url is used to communicate with the enmeshed platform. It can be changed to use a custom enmeshed Backbone. The base url may not contain a vertical bar
|. -
platformClientId
requiredThe client id is required to communicate with the enmeshed platform. It can be acquired from the enmeshed Support.
-
platformClientSecret
requiredThe client secret is required to communicate with the enmeshed platform. It can be acquired from the enmeshed Support.
database
-
connectionString
requiredAt this point the connection to the database can be configured. The connection string must follow the MongoDB Connection String URI Format.
-
dbName
default: "default"The
dbNamestring is used as the name of the MongoDB database, prefixed withacc-. You can use any name you like, but keep in mind that changing it later will NOT rename the database. Instead a new database will be created, together with a new enmeshed Identity. Even though the old database will still exist, the Connector will not be able to access the data until you change thedbNameback to its original value.If you would like to use multiple Connectors with distinct Identities (one Identity per Connector) running on the same database, you have to specify a unique
dbNamefor each of them.Note: If you are using the Connector in combintation with a FerretDB, you have to pay attention to the database name restrictions specified in the FerretDB documentation.
-
dbNamePrefix
default: "acc-"The
dbNamePrefixstring is used as a prefix for the MongoDB database name. It will be prepended to the string configured by thedbNameproperty.If you don’t want your database name to be prefixed, you can set this value to an empty string.
infrastructure
Each infrastructure can be enabled or disabled by passing true / false to enabled.
httpServer
The HTTP server is the base for the coreHttpApi Module. It opens an express HTTP server where Modules can register endpoints.
Sample Configuration:
{
// ...
"infrastructure": {
"httpServer": {
"enabled": true,
"cors": {
"origin": false
},
"apiKey": "an-api-key"
}
}
}
-
enabled
default: trueEnable or disable the HTTP server.
-
cors
default: { "origin": false }configure the CORS middleware. Valid options can be found here.
-
apiKey
requiredDefine the API-Key the Connector should use to authenticate requests.
The API-Key can be chosen arbitrarily and has to be sent with every request in the
X-API-KEYHTTP-Header.There are no limitations regarding the allowed characters. We recommend using an API-Key that is at least 20 characters long.
The API-Key protects your Connector from unauthorized access and should therefore be kept secret.
-
helmetOptions
default: depending on the Connector modeConfigure the helmet middleware.
Defaults to
{}inproductionmode. Indebugmode the following options are used:{ "contentSecurityPolicy": { "directives": { "defaultSrc": [], "scriptSrc": ["'self'"], "styleSrc": ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com"], "imgSrc": ["'self'", "https://enmeshed.eu", "data:"], "connectSrc": ["'self'"], "upgradeInsecureRequests": null } } }
modules
Every Module can be enabled or disabled by passing true / false to enabled. Read more about the Module by clicking on the icon in each title.
autoAcceptPendingRelationships
It is not recommended to use this Module for production scenarios.
Sample Configuration:
{
// ...
"modules": {
"autoAcceptPendingRelationships": {
"enabled": false
}
}
}
-
enabled
default: falseEnable or disable the autoAcceptPendingRelationships Module.
coreHttpApi
Sample Configuration:
{
// ...
"modules": {
"coreHttpApi": {
"enabled": true,
"docs": {
"enabled": false,
"rapidoc": {
"persistAuth": false
}
}
}
}
}
-
enabled
default: trueEnable or disable the coreHttpApi Module.
-
docs:enabled
default: falseIt is not possible to enable the docs in production mode.
Enable / disable the
/docs/jsonand/docs/yamlroutes and the rendered swagger / rapidoc documentations. -
docs:rapidoc:persistAuth
default: falseAuthentication persistence can be a security risk. Use it with caution.
If set to
truerapidoc persists the API Key in the local storage of the browser.
messageBrokerPublisher
Sample Configuration:
{
// ...
"modules": {
"messageBrokerPublisher": {
"enabled": false,
"brokers": []
}
}
}
-
enabled
default: falseEnable or disable the messageBrokerPublisher Module.
-
brokers
default: []Here you can define multiple brokers to which the Connector should publish messages.
Each broker consists of a
type(string) and aconfigurationobject. Thetypespecifies the type of the broker (e.g.AMQPorPubSub) and theconfigurationobject contains the configuration for the broker.-
type
AMQPexample
{ "type": "AMQP", "configuration": { "url": "amqp://example.com:5672", "exchange": "myExchange" } }configuration
-
url
string, required-the URL of the AMQP broker
the URL must be in the AMQP url format
-
exchange
string, default: ""-the name of the AMQP exchange to publish to
-
timeout
number-the timeout in milliseconds for the broker to respond
-
-
type
MQTTexample
{ "type": "MQTT", "configuration": { "url": "mqtt://example.com:1883" } }configuration
-
url
string, requiredthe URL of the MQTT broker
the URL can be on the following protocols:
mqtt,mqtts,tcp,tls,ws,wss,wxsoralis
-
-
type
PubSubexample
{ "type": "PubSub", "configuration": { "projectId": "myProjectId", "topicName": "myTopicName", "keyFile": "/path/to/keyfile.json" } }configuration
-
projectId
string, requiredthe project id of the Google Cloud project
-
topicName
string, requiredthe name of the PubSub topic to publish to
-
keyFile
string, requiredthe (absolute) path of the key file to authenticate with the Google Cloud project
-
-
type
Redisexample
{ "type": "Redis", "configuration": { "url": "redis://example.com:6379" } }configuration
-
url
string, requiredthe URL of the broker
the URL must be in the Redis url format:
redis[s]://[[username:]password@]host[:port][/database]
-
-
sync
Sample Configuration:
{
// ...
"modules": {
"sync": {
"enabled": false,
"interval": 60
}
}
}
-
enabled
default: falseEnable or disable the sync Module.
-
interval
default: 60The interval in seconds at which the sync Module will fetch changes from the Backbone.
webhooks
Sample Configuration:
{
// ...
"modules": {
"webhooks": {
"enabled": false,
"targets": {},
"webhooks": []
}
}
}
-
enabled
default: falseEnable or disable the webhooks Module.
-
targets
default: {}Here you can predefine targets so you can reuse them for multiple webhooks.
A target consists of a URL as well as optional arbitrary headers, which the Connector should send as part of the request. Optionally, your URL can contain the placeholder
{{trigger}}, which at runtime will be replaced with the event name that triggered the webhook (e.g. transport.messageReceived). This way, you can reuse the same target for multiple webhooks and still have different URLs for different events. See the code below for an example.The server under the URL must respond to the request with a status code between 200 and 299. Otherwise the Connector will log a warning.
If the webhook target is protected by authentication, you can configure the webhook module to authenticate itself. Currently, the available
authenticationtypes are:OAuth2andApiKey.OAuth2
The OAuth2 authentication type is used to authenticate the request to the webhook using the client credentials flow of OAuth2. The Connector will send a bearer token as part of the request in its Authentication header. The OAuth2 authentication is configured using the following parameters:
-
type
"OAuth2", requiredThe type of the authentication.
-
accessTokenUrl
string, requiredThe URL to get the access token from. This URL must be reachable from the Connector.
-
clientId
string, requiredThe client id used to authenticate to the access token server.
-
clientSecret
string, requiredThe client secret used to authenticate to the access token server.
-
scope
string, optionalThe scope of the access request. This is optional and can be omitted if not needed.
ApiKey
The ApiKey authentication type is used to authenticate the request to the webhook using an API key. The Connector will send the API key as part of the request using a header. The ApiKey authentication is configured using the following parameters:
-
type
"ApiKey", requiredThe type of the authentication.
-
headerName
string, default: "x-api-key"The name of the header to send the API key in. If not set, the default value
x-api-keywill be used. -
apiKey
string, requiredThe API key to use for authentication.
Example
{ // a target with headers "target1": { "url": "https://example.com/enmeshed/webhook2", // the following headers will be sent as part of the webhook "headers": { "a-header": "a-value", "another-header": "another-value" } }, // a target without headers "target2": { "url": "https://example.com/enmeshed/webhook" }, // a target with the {{trigger}} placeholder as part of the URL "target3": { "url": "https://example.com/enmeshed/webhook/{{trigger}}" }, // a target with an OAuth2 authentication type "target4": { "url": "https://example.com/enmeshed/webhook", "authentication": { "type": "OAuth2", "accessTokenUrl": "https://example.com/oauth2/token", "clientId": "myClientId", "clientSecret": "myClientSecret", "scope": "myScope" } }, // a target with an ApiKey authentication type "target5": { "url": "https://example.com/enmeshed/webhook", "authentication": { "type": "ApiKey", "headerName": "a-header-name", "apiKey": "my-api-key" } } } -
-
skipTlsCheck
default: falseSkip the TLS certificate check for https request to all targets.
This is a security risk and should only be used if you know what you are doing.
-
webhooks
default: []The webhooks that will be called. A webhook consists of one or more Connector Events on which the webhook should be triggered, as well as a target to which the request should be sent. The target either is an inline definition of target as described above, or a name of a target defined in the
targetsobject.Example
[ { "triggers": ["transport.messageReceived"], // inline declaration of a target "target": { // see the targets section for a description of how to configure a target } }, { "triggers": ["transport.messageReceived"], // a reference to a target defined in the 'targets' object "target": "target1" } ]
Payload
{
// the event name (e.g. transport.messageReceived) that triggered the webhook
"trigger": "transport.messageReceived",
// the data of the event
"data": {}
}
You can find type definitions of the event data in the Connector Events section.
sse (Server-Sent Events)
This Module requires additional configuration on the Backbone. Ensure that your Backbone has the required settings enabled.
Sample Configuration:
{
// ...
"modules": {
"sse": {
"enabled": false
}
}
}
-
enabled
default: falseEnable or disable the sse Module.
Troubleshooting
If you encounter any problems while configuring the Connector, head over to the Troubleshooting site.