The Core Container uses and exposes several APIs for interaction with the Core Container as well as for Connector-to-Connector and Data App-to-Connector communication.
The following default ports are used to expose the different APIs:
The Inter Connector API is based around the Information Model Messages and follows this basic structure:
header
: An ids:Message
subclass.payload
: Optional arbitrary payload, might be scoped given the header
class.IDS allows three communication protocols: HTTP MIME Multipart, IDSCPv2, IDS REST.
In cases where the connector can’t provide a suitable response, a RejectionMessage
(or ContractRejectionMessage
in case of a contract negotiation) is returned with a limited set of information to prevent attacks based on the response of the connector. The logs of the connector often provide a more detailed explanation that can be used for root-cause analysis.
All requests based on the IDS Information Model are validated against the SHACL shapes defined in the Information Model. Errors in the messages always result in a RejectionMessage
.
The HTTP MIME Multipart protocol follows the RFC1341 7.2 standard, with either mixed (multipart/mixed
) or form-data (multipart/form-data
). This is the default protocol used by the Core Container.
The HTTP messages are composed out of a header
part with a JSON-LD represenstation of the ids:Message
subclasses and optional payload
part.
An example of an HTTP MIME Multipart message containing a ConnectorUpdateMessage
as header
together with a self-description as payload
:
POST /router HTTP/1.1
Host: localhost:8080
Content-Type: multipart/form-data; boundary=VWo5W0Rmj8P8IHyC84CxRYpQNM62IP
Accept: */*
--VWo5W0Rmj8P8IHyC84CxRYpQNM62IP
Content-Disposition: form-data; name="header"
Content-Type: application/ld+json
{
"@context" : {
"ids" : "https://w3id.org/idsa/core/",
"idsc" : "https://w3id.org/idsa/code/"
},
"@type" : "ids:ConnectorUpdateMessage",
"@id" : "https://w3id.org/idsa/autogen/connectorUpdateMessage/5d84ce59-0b34-4483-81f5-7126976fa482",
"ids:modelVersion" : "4.1.0",
"ids:issued" : {
"@value" : "2021-11-19T12:55:50.046+01:00",
"@type" : "http://www.w3.org/2001/XMLSchema#dateTimeStamp"
},
"ids:issuerConnector" : {
"@id" : "urn:ids:test"
},
"ids:recipientConnector" : [ {
"@id" : "urn:ids:broker"
} ],
"ids:senderAgent" : {
"@id" : "urn:ids:test"
},
"ids:recipientAgent" : [ {
"@id" : "urn:ids:broker"
} ],
"ids:securityToken" : {
"@type" : "ids:DynamicAttributeToken",
"@id" : "https://w3id.org/idsa/autogen/dynamicAttributeToken/1368e56a-5f13-44fb-95d3-c9577c96a134",
"ids:tokenValue" : "DUMMY",
"ids:tokenFormat" : {
"@id" : "https://w3id.org/idsa/code/JWT"
}
},
"ids:affectedConnector" : {
"@id" : "urn:ids:test"
}
}
--VWo5W0Rmj8P8IHyC84CxRYpQNM62IP
Content-Disposition: form-data; name="payload"
Content-Type: application/ld+json
{
"@context" : {
"ids" : "https://w3id.org/idsa/core/",
"idsc" : "https://w3id.org/idsa/code/"
},
"@type" : "ids:TrustedConnector",
"@id" : "urn:ids:test",
"ids:maintainer" : {
"@id" : "urn:ids:test"
},
"ids:resourceCatalog" : [ ],
"ids:description" : [ {
"@value" : "Test",
"@type" : "http://www.w3.org/2001/XMLSchema#string"
} ],
"ids:curator" : {
"@id" : "urn:ids:test"
},
"ids:inboundModelVersion" : [ "4.1.0", "4.1.1" ],
"ids:outboundModelVersion" : "4.1.0",
"ids:hasAgent" : [ ],
"ids:securityProfile" : {
"@id" : "https://w3id.org/idsa/code/TRUST_SECURITY_PROFILE"
},
"ids:extendedGuarantee" : [ ],
"ids:hasDefaultEndpoint" : {
"@type" : "ids:ConnectorEndpoint",
"@id" : "https://w3id.org/idsa/autogen/connectorEndpoint/bfcb03d5-8724-4c7b-af16-7b4174a6e419",
"ids:endpointInformation" : [ ],
"ids:endpointDocumentation" : [ ],
"ids:accessURL" : {
"@id" : "https://test"
}
},
"ids:hasEndpoint" : [ {
"@type" : "ids:ConnectorEndpoint",
"@id" : "https://w3id.org/idsa/autogen/connectorEndpoint/bfcb03d5-8724-4c7b-af16-7b4174a6e419",
"ids:endpointInformation" : [ ],
"ids:endpointDocumentation" : [ ],
"ids:accessURL" : {
"@id" : "https://test"
}
} ],
"ids:title" : [ {
"@value" : "Test",
"@type" : "http://www.w3.org/2001/XMLSchema#string"
} ]
}
--VWo5W0Rmj8P8IHyC84CxRYpQNM62IP--
By default, the following HTTP MIME Multipart endpoints are configured for the connector:
/selfdescription
: Exposes the self description of the connector. With by default support for POST messages containing an ids:DescriptionRequestMessage
message for requesting either the complete self description or only a sub-part of it. These messages must be sent from another connector with a valid DAT. Support for simple GET requests can be configured, which results in non-restricted access to the self description (without any means of requesting specific parts of the self description)./router/artifacts
: Exposes the endpoint for artifact request handling, with support for: ids:ArtifactRequestMessage
s, ids:DescriptionRequestMessage
s, and contract negotiation related messages.The IDS Communication Protocol version 2 (IDSCPv2) is a custom TLS-based stateful protocol. It consists of a transport layer protocol responsible for setting up a mutual authenticated, encrypted and integrity protected communication channel, and an application layer protocol that allows for the actual data exchange to be exchanged over the session.
The application layer uses Protobuf for the serialization of the header
and payload
parts. The message definition is as follows:
syntax = "proto3";
message IdsMessage {
// Arbitrary header string
string header = 1;
// The actual, generic message payload
bytes payload = 2;
}
The header
part should be represented in JSON-LD format and the payload
part can contain an arbitrary byte array.
Disclaimer: The Core Container does not support IDS REST at this moment.
The IDS REST protocol is intended to be the replacement of the HTTP MIME Multipart protocol, by following more closely the Linked Data Platform W3C recommendation.
The IDS REST protocol deviates from the Multipart and IDSCPv2 protocols with respect to the representation of the header
part, since it doesn’t use the JSON-LD representation for the header
. Instead, a combination of HTTP method, HTTP URL, and HTTP headers is used to represent the header.
The protocol is not finalized and published yet, as soon as it is it will be linked here. This also is the reason the TSG components do not support IDS REST at this moment.
The current implementations of Data Apps use the HTTP MIME Multipart protocol for exchanging information with the Core Container. At this moment, this is not standardized yet and might be subject to change in the future.
Next to the standard IDS communication, a Data App can also use the Admin API to manipulate the Core Container. For instance, to provide resource descriptions to the Resource Manager module using the /api/resources
endpoints.
Both the Multipart and the Admin API endpoints can be secured with API keys, as is detailed below in Security.
Metrics are exposed via the Spring Boot Actuator that allows to expose information that might be required for production-ready deployments of the core container.
By default the metrics are exposed on a seperate port (8081
) to allow for easily exposing the metrics only within a Kubernetes cluster and not to the outside world.
Also, the actuator endpoints are not secured with any credentials, to allow for easy configuration within Kubernetes, Prometheus, and any other tooling that might use the actuators for monitoring and orchestration.
The base URL of the actuators is: http://localhost:8081/actuator
The actuators that are configured are:
/actuator/health
: Simple health check to check whether Spring is successfully started and running/actuator/prometheus
: Metric endpoint formatted to be used directly within Prometheus/actuator/metrics
: Metric endpoint for extracting single metrics (see: Spring Boot Docs)The available metrics are generic process & JVM metrics, combined with the following Camel metrics (per route):
CamelExchangesTotal
: Counter of total exchanges (i.e. messages) per Camel routeCamelExchangesFailed
: Counter of failed exchanges (i.e. messages) per Camel routeCamelExchangesFailuresHandled
: Counter of failed exchanges that are handled (i.e. messages) per Camel routeCamelExchangesSucceeded
: Counter of succeeded exchanges (i.e. messages) per Camel routeCamelRoutePolicy
: Processing time per Camel routeCamelMessageHistory
: Processing time per node per Camel routeThe internal API of the Core Container is meant to be used for administration of the Core Container by either users or deployed Data Apps. It follows largely the structure of the modules of the Core Container.
The API is used by the Web User Interface that allows users to interact with the Core Container. As well as, by Data Apps that are able to communicate with API keys with the endpoints of the API. See the Security section for more information on the security of the API.
All inputs towards the administrative API are validated against Kotlin Data Classes that ensure that there is no malformed input allowed, this includes the messages returned by the API.
The Artifact Management API is used to interact with the built-in Artifact handling of the Core Container.
Method | Endpoint | Required Role | Description | Params/body |
---|---|---|---|---|
GET | /api/artifacts/consumer/artifact |
ARTIFACT_CONSUMER |
Retrieve an artifact from an external connector | artifact : String containing the requested artifact ID. connectorId : String containing the Connector ID that should be fetched. agentId (optional): String containing the agent ID that should be used when requesting the artifact. accessUrl : String containing the accessUrl where the artifact is located. transferContract (Optional): String containing the Transfer Contract to obtain the artifact. |
POST | /api/artifacts/consumer/contractRequest |
ARTIFACT_CONSUMER |
Initiate the Contract negotiation process | connectorId : String containing the connectorId where the contractRequest should be posted to. agentId (Optional): String containing the agent ID where the contractRequest should be routed to. contractOffer : String containing the Contract Offer for the request. accessUrl : String containing the accessURL where the contractRequest should be posted to. |
GET | /api/artifacts/provider |
ARTIFACT_PROVIDER_READER |
List provided artifacts | - |
POST | /api/artifacts/provider |
ARTIFACT_PROVIDER_MANAGER |
Upload a new artifact | artifact : MultipartFile title : String containing the title of the artifact. description : String containing the description of the artifact. artifactId (Optional): String containing the id you want to give the artifact. contractOffer (Optional): String containing the contract offer you want to add to your artifact. |
GET | /api/artifacts/provider/{artifactId} |
ARTIFACT_PROVIDER_MANAGER |
Retrieve artifact metadata | artifactId : String containing the identifier of the artifact. |
GET | /api/artifacts/provider/{artifactId}/data |
ARTIFACT_PROVIDER_MANAGER |
Retrieve artifact data | artifactId : String containing the identifier of the artifact. |
PUT | /api/artifacts/provider/{artifactId} |
ARTIFACT_PROVIDER_MANAGER |
Update an existing artifact | artifactId : String containing the identifier of the artifact. artifact (Optional): MultipartFile title (Optional): String containing the title of the artifact. description (Optional): String containing the description of the artifact. contractOffer (Optional): String containing the contract offer you want to add to your artifact. |
DELETE | /api/artifacts/provider/{artifactId} |
ARTIFACT_PROVIDER_MANAGER |
Delete an artifact | artifactId : String containing the identifier of the artifact. |
The Clearing controller API is used to retrieve information on cleared messages.
Method | Endpoint | Required Role | Description | Params/Body |
---|---|---|---|---|
GET | /api/clearing |
ADMIN |
Retrieve cleared messages, with optional from and to query parameters in UNIX epoch milliseconds format |
from : Long containing start in UNIX epoch milliseconds to : Long containing end in UNIX epoch milliseconds. |
GET | /api/clearing/filter |
ADMIN |
Retrieve filtered cleared messages, with query parameters to filter | filter : Map of properties to filter with. e.g. context and direction . |
The Orchestration Management API is used to interact with the orchestration manager that allows for orchestration of data apps and helper containers.
Method | Endpoint | Required Role | Description | Params/Body |
---|---|---|---|---|
GET | /api/orchestration |
ORCHESTRATION_MANAGER |
Retrieve all running containers managed by the OrchestrationManager | - |
POST | /api/orchestration |
ORCHESTRATION_MANAGER |
Retrieve detailed information for a specific container | Body: {name: string, image: {name: string, tag: string, pullSecretName (optional): string }, ports: String[], configuration: {filename: string, content: string}[], configMountPath: string, environment: Map<string, string>, healthEndpoint: string, initialDelaySeconds: int, healthProbe: HealthProbe<STARTUP,LIVENESS,READINESS>} |
GET | /api/orchestration/{containerName} |
ORCHESTRATION_MANAGER |
Add a new container using the given container configuration | containerName : String containing the name of the container |
DELETE | /api/orchestration/{containerName} |
ORCHESTRATION_MANAGER |
Delete a container from the OrchestrationManager | containerName : String containing the name of the container |
The Policy Enforcement Management API is used to interact with the built-in Policy Enforcement Framework. More specifically, the API is used to interact with the Policy Administration Point to manage agreed upon contracts and contract offers.
Method | Endpoint | Required Role | Description | Params/Body |
---|---|---|---|---|
GET | /api/pap/contracts |
PEF_READER |
List agreed upon contracts | - |
POST | /api/pap/contracts |
PEF_MANAGER |
Insert agreed upon contract | Body in JSONLD containing a contract according to the IDS Information model. |
GET | /api/pap/contracts/{contractId} |
PEF_MANAGER |
Get agreed upon contract details | contractId : String containing the contract identifier |
DELETE | /api/pap/contracts/{contractId} |
PEF_MANAGER |
Delete agreed upon contract | contractId : String containing the contract identifier |
GET | /api/pap/offers |
PEF_READER |
List contract offers | - |
POST | /api/pap/offers |
PEF_MANAGER |
Insert contract offer | Body in JSONLD containing a contract offer according to the IDS Information model. |
GET | /api/pap/offers/{offerId} |
PEF_MANAGER |
Get contract offer details | offerId : String containing the identifier of the offer |
DELETE | /api/pap/offers/{offerId} |
PEF_MANAGER |
Delete contract offer | offerId : String containing the identifier of the offer |
The Resource Management API is used to interact with the Resource Management of the Core Container, which is used to generate the self-description of the Connector. These endpoints are primarily used by Data Apps that provide resources for the Connector.
Method | Endpoint | Required Role | Description | Params/Body |
---|---|---|---|---|
GET | /api/resources |
RESOURCE_READER |
List offered resource catalogs | - |
GET | /api/resources/{catalogId} |
RESOURCE_READER |
List offered resources in a resource catalog | catalogId : String containing the identifier of the catalog. |
GET | /api/resources/{catalogId}/ids |
RESOURCE_READER |
List identifiers of offered resources in a resource catalog | catalogId : String containing the identifier of the catalog. |
POST | /api/resources/{catalogId} |
RESOURCE_MANAGER |
Insert a resource into a resource catalog, the resource catalog will be created if it does not exist | catalogId : String containing the identifier of the catalog. Body in JSONLD containing a resource according to the IDS Information model. |
POST | /api/resources/{catalogId}/batch |
RESOURCE_MANAGER |
Insert a batch of resources into a resource catalog, the resource catalog will be created if it does not exist | catalogId : String containing the identifier of the catalog. replaceAll (Optional): Whether all resources in the catalog should be replaced. Defaults to true . Body in JSONLD containing a resource catalog according to the IDS Information model. |
PUT | /api/resources/{catalogId} |
RESOURCE_MANAGER |
Update a resource in a resource catalog | catalogId : String containing the identifier of the catalog. Body in JSONLD containing a resource according to the IDS Information model. |
DELETE | /api/resources/{catalogId} |
RESOURCE_MANAGER |
Delete offered resource catalog | catalogId : String containing the identifier of the catalog. |
DELETE | /api/resources/{catalogId}/{resourceId} |
RESOURCE_MANAGER |
Delete a resource in a resource catalog | catalogId : String containing the identifier of the catalog. resourceId : String containing the identifier of the resource. |
The Route Management API is used to interact with the Camel Route Manager to administrate Camel routes and view metrics of the routes.
Method | Endpoint | Required Role | Description | Params/Body |
---|---|---|---|---|
GET | /api/routes |
ROUTE_READER |
List Apache Camel routes | - |
POST | /api/routes |
ROUTE_MANAGER |
Insert a new Camel route | Body containing a String with the route information. |
GET | /api/routes/{routeId} |
ROUTE_READER |
Get details of a Camel route, including metrics | routeId : String containing the identifier of the Camel route. |
DELETE | /api/routes/{routeId} |
ROUTE_MANAGER |
Delete a Camel route | routeId : String containing the identifier of the Camel route. |
The Authentication Management API is used to interact with the Authentication Manager to administrate users and API keys that have access to the Admin API.
Method | Endpoint | Required Role | Description | Params/body |
---|---|---|---|---|
GET | /api/auth/roles |
ADMIN |
List roles that can be assigned | - |
GET | /api/auth/users |
ADMIN |
List administrative users | - |
POST | /api/auth/users |
ADMIN |
Insert administrative user | Body: {id: string, password: string(bcrypt), roles:string[], locked: boolean, lockedUntil: long, nexPasswordChangeBefore: long} |
PUT | /api/auth/users/{userId} |
ADMIN |
Update existing administrative user. Please note that it is possible to change other administrators. | userId : String containing the identifier of the user. Body: {id: string, password: string(bcrypt), roles:string[], locked: boolean, lockedUntil: long, nexPasswordChangeBefore: long} |
DELETE | /api/auth/users/{userId} |
ADMIN |
Delete administrative user. Please note that it is possible to delete other administrators. | userId : String containing the identifier of the user. |
GET | /api/auth/apikeys |
ADMIN |
List API keys | - |
POST | /api/auth/apikeys |
ADMIN |
Insert API key | Body: {id: string, key: string, roles: string[], nextApiKeyChangeBefore: long} |
PUT | /api/auth/apikeys/{apiKeyId} |
ADMIN |
Update existing API key | {apiKeyId} : String containing the identifier of the API key. Body: {id: string, key: string, roles: string[], nextApiKeyChangeBefore: long} |
DELETE | /api/auth/apikeys/{apiKeyId} |
ADMIN |
Delete API key | {apiKeyId} : String containing the identifier of the API key. |
The Self Description API is used to request metadata from other connectors or from the Broker.
Method | Endpoint | Required Role | Description | Params/body |
---|---|---|---|---|
GET | /api/description |
DESCRIPTION_READER |
Send a DescriptionRequestMessage to another connector. With optional validate (true /false ) query parameter to validate the other connector’s self description. |
accept (Optional): String containing accepted content type. connectorId : String containing the identifier of the connector. agentId (Optional): String containing the identifier of the agent. accessUrl : String containing the access url of the hosted self description. requestedElement : String containing the element that is requested. validate : Boolean whether the response should be validated by your own connector. |
POST | /api/description/query |
DESCRIPTION_READER |
Send a QueryMessage to a broker, by default to the configured broker | accept (Optional): String containing accepted content type. connectorId (Optional): String containing the identifier of the connector. agentId (Optional): String containing the identifier of the agent. accessUrl (Optional): String containing the access url of the hosted self description. queryLanguage (Optional): String containing the query language. queryScope (Optional): String containing the query scope. recipientScope (Optional): String containing the recipientScope. |
GET | /api/broker/registrations |
DESCRIPTION_MANAGER |
Retrieve the active Broker registrations of this connector | - |
POST | /api/broker/update |
DESCRIPTION_MANAGER |
Manually update the registration of this connector at the specified Broker or the default configured Broker. With optional brokerId and brokerAddress query parameters to define a non-standard Broker |
brokerId (Optional): String containing the identifier of the broker. brokerAddress (Optional): String containing the address of the broker. |
POST | /api/broker/unavailable |
DESCRIPTION_MANAGER |
Indicate the unavailability of this connector at the specified Broker or the default configured Broker. With optional brokerId , brokerAddress and affectedConnector query parameters to define a non-standard Broker |
brokerId (Optional): String containing the identifier of the broker. brokerAddress (Optional): String containing the address of the broker. affectedConnector (Optional): String containing the identifier of the connector that is affected. |
The Workflow Management API is used to interact with the Workflow Manager.
Method | Endpoint | Required Role | Description | |
---|---|---|---|---|
GET | /api/workflow |
WORKFLOW_READER |
List workflows | - |
POST | /api/workflow |
WORKFLOW_MANAGER |
Insert and start a new workflow | Body: {parties: {id: string, name: string, accessUrl: string} |
POST | /api/workflow/group |
WORKFLOW_MANAGER |
Insert and start a group of workflows | Body: {capabilities: Capability[], workflows: Workflow[]} |
GET | /api/workflow/{networkId} |
WORKFLOW_READER |
Get details and status of a workflow | networkId : String that contains the identifier of the network. |
POST | /api/workflow/invoke/{workflowId}/{stepName}/{inputIndex} |
WORKFLOW_MANAGER |
Invoke a manual input step of a workflow | workflowId : String that contains an identifier of the workflow. stepName : String that contains the name of the step. inputIndex : String that contains the index of the input. |
DELETE | /api/workflow/{networkId} |
WORKFLOW_MANAGER |
Delete a workflow | networkId : String that contains the identifier of the network. |
GET | /api/workflow/{networkId}/results |
WORKFLOW_READER |
Get the intermediate results of a workflow. Requires the workflow.saveIntermediateResults property to be true |
networkId : String that contains the identifier of the network. |
Access to the public endpoints of the connector are handled via the IDS protcols, but access to the internal endpoints (both Admin API and Data App API) can be secured via a token-based approach. At this moment, the security feature is disabled by default (security.enabled
property), which allows any request to be handled without authentication. When this feature is enabled, there is an option to either authenticate with user credentials or with API keys.
For user-based authentication, a user must request a token from the Core Container at the /auth/signin
endpoint with its credentials (userid and password). When successfully authenticated, the user receives a JSON Web Token (JWT) that it must use in further requests to the Admin API as Bearer Authentication HTTP header. Tokens of users are valid for 1 hour.
A user can provide 10 wrong credentials within 15 minutes before the user account is locked for 15 minutes. No detailed information is shown in the error messages indicating that the user account is locked, as well as, no additional information is provided what might be wrong with the request. All failed attempts will be containing non-descriptive message like “Invalid username/password supplied”.
For API keys, the configured API key can be used directly in the Bearer Authentication HTTP header and is primarily intended for Data Apps or applications interacting with the Core Container. API keys are valid until they are deleted via the Admin API.
Each user and API key can be assigned to roles to only allow access to specific API endpoints. The list of valid roles is:
Role | Description |
---|---|
ADMIN |
Administrator role for the primary administrator that has full access and inherits all of the other roles |
DATA_APP |
Data App role that can be given to Data Apps for managing the resources that they offer |
READER |
Reader role that is allowed to read all resources in the core container but not modify them |
ARTIFACT_PROVIDER_MANAGER |
Artifact Provider Manager role that is allowed to administrate provided artifact |
ARTIFACT_PROVIDER_READER |
Artifact Provider Reader role that is allowed to list provided artifacts |
ARTIFACT_CONSUMER |
Artifact Consumer role that is allowed to request artifacts from other connectors in the network |
ORCHESTRATION_MANAGER |
Orchestration Manager role that is allowed to orchestrate containers |
ORCHESTRATION_READER |
Orchestration Reader role that is allowed to list orchestrated containers |
PEF_MANAGER |
Policy Enforcement Manager role that is allowed to initiate new contracts and contract negotiations |
PEF_READER |
Policy Enforcement Reader role that is allowed to list agreed upon contracts and contract offers |
RESOURCE_MANAGER |
Resource Manager role that is allowed to modify the resources provided by the core container and data apps |
RESOURCE_READER |
Resource Reader role that is allowed to list resources provided by the core container and data apps |
ROUTE_MANAGER |
Route Manager role that is allowed to modify Camel routes offered by the Core Container |
ROUTE_READER |
Route Reader role that is allowed to list Camel routes offered by the Core Container |
DESCRIPTION_READER |
Description Reader role that is allowed to send Description Request messages to other connectors in the network |
DESCRIPTION_MANAGER |
Description Manager role that is allowed to modify the registration at Metadata Broker(s) in the network |
WORKFLOW_MANAGER |
Workflow Manager role that is allowed to initiate new workflows |
WORKFLOW_READER |
Workflow Reader role that is allowed to list workflows and show the results and status of the workflow |
Especially for API keys, it is wise to limit the scope of the key to just the API endpoints a Data App will use, since API keys do not have an expiration date which increases the impact of leaked API keys.
Passwords for users are encrypted using BCrypt, in both the configuration files and via the API passwords must be presented in BCrypt encoded form. It is required to use a cost factor of 12 or higher when hashing the password with the BCrypt hash function. BCrypt cost factors result in a number of hashing round equal to 2 ^ COST_FACTOR
, for a cost factor of 12 this results in 4096 hashing rounds. Next to this, there is an option to perform password rotation. With the password rotation, it is not possible to verify whether two passwords are the same because of the bcrypt hashing. In the UI password strength is enforced via the forms, where a password policy of: at least 12 characters, at least 1 uppercase character, at least 1 lowercase character, at least one special character. In the UI also a requirement for API keys is enforced, which ensures all API keys are at least 20 characters long (not including APIKEY-
). Both minimum required lengths can be configured by applying environment variables to the UI, for the password length the variable PASSWORD_LENGTH
is used and for the API key length APIKEY_LENGTH
is used. If these variables are set lower than the default values of respectively 12 and 20, the default values are used instead.