From 558d7a1cc60c4691527b4008d6ca624df3484618 Mon Sep 17 00:00:00 2001 From: Marine LM Date: Fri, 19 Dec 2025 12:05:25 +0100 Subject: [PATCH 1/3] [docs] feat(composer): integration manager --- .../integration-manager/composer-required.png | Bin 0 -> 6587 bytes .../integration-manager/ee-required.png | Bin 0 -> 5851 bytes docs/deployment/ecosystem/collectors.md | 103 ++++-- docs/deployment/ecosystem/injectors.md | 113 +++--- .../integration-manager/configuration.md | 175 +++++++++ .../integration-manager/installation.md | 313 ++++++++++++++++ .../ecosystem/integration-manager/overview.md | 69 ++++ .../proxy-configuration.md | 107 ++++++ .../integration-manager/quick-start.md | 201 +++++++++++ .../registry-authentification.md | 129 +++++++ .../integration-manager/troubleshooting.md | 336 ++++++++++++++++++ mkdocs.yml | 9 + 12 files changed, 1477 insertions(+), 78 deletions(-) create mode 100644 docs/deployment/assets/integration-manager/composer-required.png create mode 100644 docs/deployment/assets/integration-manager/ee-required.png create mode 100644 docs/deployment/ecosystem/integration-manager/configuration.md create mode 100644 docs/deployment/ecosystem/integration-manager/installation.md create mode 100644 docs/deployment/ecosystem/integration-manager/overview.md create mode 100644 docs/deployment/ecosystem/integration-manager/proxy-configuration.md create mode 100644 docs/deployment/ecosystem/integration-manager/quick-start.md create mode 100644 docs/deployment/ecosystem/integration-manager/registry-authentification.md create mode 100644 docs/deployment/ecosystem/integration-manager/troubleshooting.md diff --git a/docs/deployment/assets/integration-manager/composer-required.png b/docs/deployment/assets/integration-manager/composer-required.png new file mode 100644 index 0000000000000000000000000000000000000000..283e101c126f137a407e967ac7948f82884678ce GIT binary patch literal 6587 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 literal 0 HcmV?d00001 diff --git a/docs/deployment/assets/integration-manager/ee-required.png b/docs/deployment/assets/integration-manager/ee-required.png new file mode 100644 index 0000000000000000000000000000000000000000..64aea763e9c0a7acc1b38063f31d9d73c5526928 GIT binary patch literal 5851 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

c(aIU`M^*Hg$mw zp2biTP(o%{*4DZX`Jz+oBc5HdtfqJXE1+hb{1`7<_|Q4gnF86s_uOH{i_E~~PRVgx zYg)TuA-?5+y2QF*b4Pvbr)kF0*D*cDz4ZuN7aJR6Shu zd3=)^_T*GbFdND$9zFC_#X=P(Xb3Alua+Ns*BT{UDi{EISyi<;;yhmYFzkw=tQuW; zvrE*jOx+@`4|y>*@KGFKAX*gVEC0|QL(P0HChbM4mcluHfN%7*wU03S346F`3%BJH za)BQX&-m|(UVSHoscDDOf)~^6)0dquOvyI>%HdLa*~z=!50_iqVmV}1D^u%LQKA_%G`{^+d4tcOTLeEF8!HVIrLNwqnvGf?XUyKk=79Z zR98*m0+pm*hsE!k1@EPHaL4RLfNaT4K&*;q49I#<`>WK`?iH8^da!gaR1x|)tkmnX zxzB5T`r6l9%VSr$d6Y`@V7s&bOg%d+);aD07Zd*^;RnSxh7{G4u0wV{%JKP9F4gZ+ zDeui&0;_FpTKlI4$m+Xz(lzt_CzYA%n`@hYHCVB`2fnD&s>RKxAkmR>HJ$vu)H!=U z3G5g8d<8P7T*ODu8XGbYk`#ETgd@NzLAo8$c>!tbB^myDsII(#rb)5dMUXF(K7kv8E#JQIhLYR2!H@VO}USAJz z7c^ILow~#?f++mQ(F6Rg?^11+I*#eLt2@`4W5n^h(ez!vpdG4#=RUEFvUk{Ne8bvI zyRIA@VACTST9nG@nJ@T{hPOU!4fG7-3L7GDX+npLQMWH<%{Z$tO_YyF{JZ9rTz;?e ziNl`^`#^;|{>J!UiepXn|C_?yM>FD}KK{AJ2!-D|zR&-acH5;KT z@bC!j-cUPFr(I2`QLfTOSN{LH8G1MDKM>sWTWb{O`z^i?azf)j?a collectors. You will be able to see the statistics of the RabbitMQ queue of the collector: diff --git a/docs/deployment/ecosystem/injectors.md b/docs/deployment/ecosystem/injectors.md index a224de33..9f7878c5 100644 --- a/docs/deployment/ecosystem/injectors.md +++ b/docs/deployment/ecosystem/injectors.md @@ -17,53 +17,26 @@ just add the proper configuration parameters in your platform configuration. ### External (Python) injectors -#### Configuration +There are multiple ways to deploy an external injectors from OpenAEV: -All external injectors have to be able to access the OpenAEV API. To allow this connection, they have 2 mandatory configuration parameters, the `OPENAEV_URL` and the `OPENAEV_TOKEN`. In addition to these 2 parameters, injectors have other mandatory parameters that need to be set in order to get them work. +- Integration Manager (Recommended) +- Docker deployment +- Manual deployment -!!! info "Injector tokens" +!!! info - You can use your administrator token or create another administrator service account to put in your injectors. It is not necessary to have one dedicated user for each injector. + ⚠️ All external injectors must be able to access the OpenAEV API. They require 2 mandatory configuration parameters: OPENAEV_URL and OPENAEV_TOKEN. In addition, each collector has specific mandatory parameters that need to be configured. -Here is an example of a injector `docker-compose.yml` file: -```yaml -- OPENAEV_URL=http://localhost -- OPENAEV_TOKEN=ChangeMe -- INJECTOR_ID=ChangeMe # Specify a valid UUIDv4 of your choice -- "INJECTOR_NAME=HTTP query" -- INJECTOR_LOG_LEVEL=error -``` +#### Integration Manager (Recommended) +The easiest way to deploy injectors is through the Integration Manager, which allows automatic deployment directly from the OpenAEV interface. -Here is an example in a injector `config.yml` file: +πŸ‘‰ See the [Integration Manager documentation](integration-manager/overview.md) for detailed instructions. -```yaml -openaev: - url: 'http://localhost:3001' - token: 'ChangeMe' -injector: - id: 'ChangeMe' - name: 'HTTP query' - log_level: 'info' -``` - -#### Networking - -Be aware that all injectors are reaching RabbitMQ based the RabbitMQ configuration provided by the OpenAEV platform. The injector must be able to reach RabbitMQ on the specified hostname and port. If you have a specific Docker network configuration, please be sure to adapt your `docker-compose.yml` file in such way that the injector container gets attached to the OpenAEV Network, e.g.: - -```yaml -networks: - default: - external: true - name: openaev-docker_default -``` - -## Docker activation - -You can either directly run the Docker image of injectors or add them to your current `docker-compose.yml` file. - -### Add an injector to your deployment +#### Docker Deployment +Several options are available for Docker deployment: +##### Add an injector to your existing deployment For instance, to enable the HTTP query injector, you can add a new service to your `docker-compose.yml` file: ```docker @@ -77,9 +50,9 @@ For instance, to enable the HTTP query injector, you can add a new service to yo - INJECTOR_LOG_LEVEL=error restart: always ``` +Note: Injector images and available versions can be found on Docker Hub. -### Launch a standalone injector - +##### Launch a standalone collector To launch standalone injector, you can use the `docker-compose.yml` file of the injector itself. Just download the latest [release](https://github.com/OpenAEV-Platform/injectors/releases) and start the injector: ``` @@ -94,7 +67,7 @@ Change the configuration in the `docker-compose.yml` according to the parameters $ docker compose up ``` -## Manual activation +#### Manual activation If you want to manually launch injector, you just have to install Python 3 and pip3 for dependencies: @@ -117,12 +90,66 @@ $ pip3 install -r requirements.txt $ cp config.yml.sample config.yml ``` -Change the `config.yml` content according to the parameters of the platform and of the targeted service and launch the injector: +Change the `config.yml` content according to the parameters of the platform and of the targeted service. +For example : +```yaml +openaev: + url: 'http://localhost:3001' + token: 'ChangeMe' + +injector: + id: 'ChangeMe' + name: 'HTTP query' + log_level: 'info' +``` + +Finally : launch the injector: ``` $ python3 openaev_http.py ``` +#### Configuration + +All external injectors have to be able to access the OpenAEV API. To allow this connection, they have 2 mandatory configuration parameters, the `OPENAEV_URL` and the `OPENAEV_TOKEN`. In addition to these 2 parameters, injectors have other mandatory parameters that need to be set in order to get them work. + +!!! info "Injector tokens" + + You can use your administrator token or create another administrator service account to put in your injectors. It is not necessary to have one dedicated user for each injector. + +Here is an example of a injector `docker-compose.yml` file: +```yaml +- OPENAEV_URL=http://localhost +- OPENAEV_TOKEN=ChangeMe +- INJECTOR_ID=ChangeMe # Specify a valid UUIDv4 of your choice +- "INJECTOR_NAME=HTTP query" +- INJECTOR_LOG_LEVEL=error +``` + +Here is an example in a injector `config.yml` file: + +```yaml +openaev: + url: 'http://localhost:3001' + token: 'ChangeMe' + +injector: + id: 'ChangeMe' + name: 'HTTP query' + log_level: 'info' +``` + +#### Networking + +Be aware that all injectors are reaching RabbitMQ based the RabbitMQ configuration provided by the OpenAEV platform. The injector must be able to reach RabbitMQ on the specified hostname and port. If you have a specific Docker network configuration, please be sure to adapt your `docker-compose.yml` file in such way that the injector container gets attached to the OpenAEV Network, e.g.: + +```yaml +networks: + default: + external: true + name: openaev-docker_default +``` + ## Injectors status The injector status can be displayed in the dedicated section of the platform available in Integration > injectors. You will be able to see the statistics of the RabbitMQ queue of the injector: diff --git a/docs/deployment/ecosystem/integration-manager/configuration.md b/docs/deployment/ecosystem/integration-manager/configuration.md new file mode 100644 index 00000000..19109245 --- /dev/null +++ b/docs/deployment/ecosystem/integration-manager/configuration.md @@ -0,0 +1,175 @@ +# Configuration reference + +XTM Composer uses a layered configuration system with support for YAML files and environment variables. Environment variables override file-based configuration. + +## Configuration priority + +1. Environment variables (highest priority) +2. Environment-specific config file (e.g., `production.yaml`) +3. Default config file (`default.yaml`) + +## Environment variable format + +All environment variables use double underscores (`__`) to separate nested configuration levels. + +Example: `manager.logger.level` becomes `MANAGER__LOGGER__LEVEL` + +## Platform + +### Manager + +#### Basic parameters + +| Parameter | Environment variable | Default value | Description | +|:-----------------------------------|:----------------------------------------|:------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------| +| manager:id | MANAGER__ID | default-manager-id | Unique identifier for this manager instance | +| manager:name | MANAGER__NAME | Filigran integration manager | Human-readable name for the manager | +| manager:execute_schedule | MANAGER__EXECUTE_SCHEDULE | 10 | Interval in seconds between execution cycles | +| manager:ping_alive_schedule | MANAGER__PING_ALIVE_SCHEDULE | 60 | Interval in seconds between alive ping messages | +| manager:credentials_key | MANAGER__CREDENTIALS_KEY | | RSA private key content (4096-bit recommended). Use for direct key embedding. One of `credentials_key` or `credentials_key_filepath` is required | +| manager:credentials_key_filepath | MANAGER__CREDENTIALS_KEY_FILEPATH | | Path to RSA private key file. Takes priority over `credentials_key` if both are set. One of `credentials_key` or `credentials_key_filepath` is required | + +#### Logging + +| Parameter | Environment variable | Default value | Description | +|:----------------------------|:--------------------------------|:--------------|:--------------------------------------------------------------------| +| manager:logger:level | MANAGER__LOGGER__LEVEL | info | Logging verbosity level (`trace`, `debug`, `info`, `warn`, `error`) | +| manager:logger:format | MANAGER__LOGGER__FORMAT | json | Log output format (`json`, `pretty`) | +| manager:logger:directory | MANAGER__LOGGER__DIRECTORY | `true` | Enable logging to directory/file | +| manager:logger:console | MANAGER__LOGGER__CONSOLE | `true` | Enable logging to console/stdout | + +#### Debug + +| Parameter | Environment variable | Default value | Description | +|:---------------------------------------|:-----------------------------------------|:--------------|:------------------------------------------------------------------------| +| manager:debug:show_env_vars | MANAGER__DEBUG__SHOW_ENV_VARS | `false` | Display environment variables at startup (excludes sensitive data) | +| manager:debug:show_sensitive_env_vars | MANAGER__DEBUG__SHOW_SENSITIVE_ENV_VARS | `false` | Display sensitive environment variables at startup (tokens, keys, etc.) | + +### Dependencies + +#### OpenAEV + +| Parameter | Environment variable | Default value | Description | +|:---------------------------------|:----------------------------------|:------------------------------------|:-------------------------------------------------| +| openaev:enable | OPENAEV__ENABLE | `false` | Enable OpenAEV integration (Coming Soon) | +| openaev:url | OPENAEV__URL | http://host.docker.internal:4000 | OpenAEV platform URL (Coming Soon) | +| openaev:token | OPENAEV__TOKEN | ChangeMe | OpenAEV API authentication token (Coming Soon) | +| openaev:unsecured_certificate | OPENAEV__UNSECURED_CERTIFICATE | `false` | Allow self-signed SSL certificates (Coming Soon) | +| openaev:with_proxy | OPENAEV__WITH_PROXY | `false` | Use system proxy settings (Coming Soon) | +| openaev:logs_schedule | OPENAEV__LOGS_SCHEDULE | 10 | Log report interval in seconds (Coming Soon) | + +#### Proxy configuration + +| Parameter | Environment variable | Default value | Description | +|:----------------------------------|:---------------------------------|:--------------|:--------------------------------------------------------------------------------------------------| +| http_proxy | HTTP_PROXY | | Proxy URL for HTTP requests (e.g., `http://proxy:8080`) | +| https_proxy | HTTPS_PROXY | | Proxy URL for HTTPS requests (e.g., `http://proxy:8080`) | +| no_proxy | NO_PROXY | | Comma-separated list of hosts excluded from proxy (e.g., `localhost,127.0.0.1,internal.domain`) | +| https_proxy_ca | HTTPS_PROXY_CA | | CA certificates used to validate HTTPS proxy connections | +| https_proxy_reject_unauthorized | HTTPS_PROXY_REJECT_UNAUTHORIZED | `false` | If not false, validates the proxy certificate against the provided CA list | + +!!! note "Proxy certificate separation" + + Proxy TLS certificates are **independent** from OpenAEV HTTPS server certificates. + + - For proxy connections β†’ use `https_proxy_ca` and `https_proxy_reject_unauthorized` + - For OpenAEV platform HTTPS β†’ use `app:https_cert:*` variables in the main OpenAEV configuration + +### Registry authentication + +| Parameter | Environment variable | Default value | Description | +|:------------------------------|:-----------------------------|:--------------|:----------------------------------------------------------------------------| +| registry:enable | REGISTRY__ENABLE | `false` | Enable authentication to a container registry | +| registry:url | REGISTRY__URL | | Registry endpoint (e.g., `https://registry.hub.docker.com`) | +| registry:username | REGISTRY__USERNAME | | Username for registry authentication | +| registry:password | REGISTRY__PASSWORD | | Password or token for registry authentication | +| registry:cache_ttl | REGISTRY__CACHE_TTL | 3600 | Time (in seconds) for caching registry authorization tokens | + +!!! note "Authentication cache" + + Composer caches registry authentication tokens to reduce the number of login requests. + Tokens are refreshed automatically when expired. + +### Orchestration + +#### General settings + +| Parameter | Environment variable | Default value | Description | +|:----------------------------------|:----------------------------------------|:--------------|:-----------------------------------------------------------------------| +| openaev:daemon:selector | OPENAEV__DAEMON__SELECTOR | kubernetes | Container orchestration platform (`kubernetes`, `docker`, `portainer`) | + +#### Kubernetes + +| Parameter | Environment variable | Default value | Description | +|:------------------------------------------------|:--------------------------------------------------------------|:--------------|:----------------------------------------------------------| +| openaev:daemon:kubernetes:image_pull_policy | OPENAEV__DAEMON__KUBERNETES__IMAGE_PULL_POLICY | IfNotPresent | Image pull policy (`Always`, `IfNotPresent`, `Never`) | +| openaev:daemon:kubernetes:base_deployment | Not supported for complex objects | | Base Kubernetes Deployment manifest template | +| openaev:daemon:kubernetes:base_deployment_json | OPENAEV__DAEMON__KUBERNETES__BASE_DEPLOYMENT_JSON | | Base Deployment manifest as JSON string | + +#### Docker + +| Parameter | Environment variable | Default value | Description | +|:-----------------------------------|:---------------------------------------|:--------------|:---------------------------------------------------------------| +| openaev:daemon:docker:extra_hosts | OPENAEV__DAEMON__DOCKER__EXTRA_HOSTS | | Additional hosts entries for containers (array) | +| openaev:daemon:docker:network_mode | OPENAEV__DAEMON__DOCKER__NETWORK_MODE | bridge | Docker network mode (`bridge`, `host`, `none`, or custom) | +| openaev:daemon:docker:dns | OPENAEV__DAEMON__DOCKER__DNS | | Custom DNS servers for containers (array) | +| openaev:daemon:docker:privileged | OPENAEV__DAEMON__DOCKER__PRIVILEGED | `false` | Run containers in privileged mode | +| openaev:daemon:docker:cap_add | OPENAEV__DAEMON__DOCKER__CAP_ADD | | Linux capabilities to add (array) | +| openaev:daemon:docker:cap_drop | OPENAEV__DAEMON__DOCKER__CAP_DROP | | Linux capabilities to drop (array) | +| openaev:daemon:docker:shm_size | OPENAEV__DAEMON__DOCKER__SHM_SIZE | | Shared memory size in bytes | + +#### Portainer + +| Parameter | Environment variable | Default value | Description | +|:--------------------------------------|:-----------------------------------------|:-----------------------------------|:-------------------------------------------------------| +| openaev:daemon:portainer:api | OPENAEV__DAEMON__PORTAINER__API | https://host.docker.internal:9443 | Portainer API endpoint URL | +| openaev:daemon:portainer:api_key | OPENAEV__DAEMON__PORTAINER__API_KEY | ChangeMe | Portainer API authentication key | +| openaev:daemon:portainer:env_id | OPENAEV__DAEMON__PORTAINER__ENV_ID | 3 | Portainer environment ID | +| openaev:daemon:portainer:env_type | OPENAEV__DAEMON__PORTAINER__ENV_TYPE | docker | Portainer environment type (`docker`, `kubernetes`) | +| openaev:daemon:portainer:api_version | OPENAEV__DAEMON__PORTAINER__API_VERSION | v1.41 | Docker API version for Portainer | +| openaev:daemon:portainer:stack | OPENAEV__DAEMON__PORTAINER__STACK | | Portainer stack name for deployment | +| openaev:daemon:portainer:network_mode | OPENAEV__DAEMON__PORTAINER__NETWORK_MODE | | Network mode for Portainer-managed containers | + +## Environment configuration + +| Parameter | Environment variable | Default value | Description | +|:----------|:---------------------|:--------------|:-------------------------------------------------------------------------------| +| - | COMPOSER_ENV | production | Specifies which configuration file to load (e.g., `development`, `production`) | + +## Complete configuration example + +```yaml +# config/production.yaml +manager: + id: prod-manager-001 + name: Production XTM Manager + execute_schedule: 10 + ping_alive_schedule: 60 + credentials_key_filepath: /keys/private_key_4096.pem + logger: + level: info + format: json + directory: true + console: false + +openaev: + enable: true + url: https://openaev.example.com + token: ${OPENAEV_TOKEN} # Reference env variable + unsecured_certificate: false + with_proxy: false + logs_schedule: 10 + daemon: + selector: kubernetes + kubernetes: + image_pull_policy: IfNotPresent +``` + +## Security best practices + +1. **Never commit credentials**: Use environment variables or secure secret management +2. **Use file-based keys**: Prefer `credentials_key_filepath` over embedding keys +3. **Restrict file permissions**: Set key files to `600` permissions +4. **Rotate tokens regularly**: Update API tokens periodically +5. **Use TLS/SSL**: Always use HTTPS in production +6. **Limit debug output**: Disable `show_sensitive_env_vars` in production diff --git a/docs/deployment/ecosystem/integration-manager/installation.md b/docs/deployment/ecosystem/integration-manager/installation.md new file mode 100644 index 00000000..64a038cf --- /dev/null +++ b/docs/deployment/ecosystem/integration-manager/installation.md @@ -0,0 +1,313 @@ +# Installation guide + +## System requirements + +### Runtime requirements + +#### Production environment +- **Kubernetes**: v1.24 or higher +- **Namespace**: Dedicated namespace for XTM Composer +- **RBAC**: Role-based access control for pod management + +#### Development environment +- **Docker**: v20.10 or higher +- **Portainer**: v2.0 or higher (recommended for container management) +- **Docker Compose**: v2.0 or higher (optional) + +### Security requirements + +- **RSA Private Key**: 4096-bit RSA private key for authentication +- **Network Access**: + - Connectivity to OpenCTI/OpenAEV instances + - Access to container orchestration API +- **Permissions**: + - Production: Kubernetes service account with appropriate RBAC + - Development: Docker socket access or Portainer API access + +## Installation methods + +Create a configuration file based on your environment or add extra environment variables in the following steps. +See [Configuration Reference](configuration.md) for more information on required configuration. + +## Production environment (Kubernetes) + +Note: The Kubernetes installation method described here assumes that OpenAEV is already deployed on a Kubernetes cluster. + +1. Create namespace: +```bash +kubectl create namespace xtm-composer +``` + +2. Create secret for RSA key: +```bash +# Generate key +openssl genrsa -out private_key_4096.pem 4096 + +# Create secret +kubectl create secret generic xtm-composer-keys \ + --from-file=private_key.pem=private_key_4096.pem \ + -n xtm-composer +``` + +3. Create ConfigMap for configuration: +```bash +kubectl create configmap xtm-composer-config \ + --from-file=default.yaml=config/default.yaml \ + -n xtm-composer +``` + +4. Create service account: + +XTM Composer uses a service account to have authorization to start new pods and deployments on the cluster. + +```bash +cat < Catalog** +- Use the search bar to find collectors, injectors and executors by name or description. You can also apply filters (e.g., by collector, executor or injector type). +- If a collector, injector or executor has already been deployed, a **badge** will appear on its **Deploy** button. + +## Deploying a collector, injector or executor +1. Click the **Deploy** button on an external collector, injector or executor card or from the detail view. A form will appear with required configuration fields. +2. Fill in the required options (you can also expand **Advanced options** to configure additional settings) + +!!! warning "Configuration information" + + - **Instance names**: Two instances can't share the same name + - **Validation error**: If a duplicate name is detected, a blocking error will prevent deployment until a unique name is provided + - **Confidence level**: set the desired confidence level for the service account. + - **API key** (encrypted and securely stored). + - **Additional options**: collector, injector or executor specific configuration. + +![instance form](../../assets/integration-manager/instance-form-sample.png) + +3. Click **Create**. Once the collector is created, you will be redirected to the collector instance view. + +!!! note "Instance created" + + Newly created external collectors, injectors or executors are not started automatically. + You can still update their configuration via the **Update** action. + + +5. When ready, click **Start** to run it. +6. From the instance view, you can also check the **Logs** tab. The displayed logs depend on the logging level configured. + + +## Managing the instances + +- Different injector, collector or executor types are identified in the catalog: + - External : Injector, collector or executor managed by the integration manager + - built-in : Injector, collector or executor natively integrated into the core platform no additional deployment required +- Instances statuses: + - Managed instances: *Started* or *Stopped*. +- Only **managed instances** can be started/stopped from the UI. They are also the only ones that provide logs in the interface. +- Updating the configuration of a managed instance is possible. Changes will take effect after a short delay. +- For security reasons, API keys/tokens are encrypted when saved and never displayed in the UI afterward. diff --git a/docs/deployment/ecosystem/integration-manager/proxy-configuration.md b/docs/deployment/ecosystem/integration-manager/proxy-configuration.md new file mode 100644 index 00000000..e051b21d --- /dev/null +++ b/docs/deployment/ecosystem/integration-manager/proxy-configuration.md @@ -0,0 +1,107 @@ +# Proxy Support + +## Overview + +XTM Composer can use system proxy settings for outgoing network calls. + +### YAML configuration + +```yaml +openaev: + daemon: + with_proxy: true +``` + +### Environment variable configuration + +```bash +export OPENAEV__DAEMON__WITH_PROXY="true" +export HTTP_PROXY="http://proxy.example.com:8080" +export HTTPS_PROXY="http://proxy.example.com:8080" +export NO_PROXY="localhost,127.0.0.1,.example.com" +``` + +When enabled, the Integration Manager automatically applies the proxy settings to: + +- Docker API calls +- Kubernetes image pulls +- Portainer API requests + +## HTTPS Proxy Certificate Support (optional) + +Some environments use HTTPS proxies with TLS interception (for example, corporate proxies or debugging proxies like Burp). +In these cases, additional certificate settings may be required. + +### Environment variables + +```bash +export HTTPS_PROXY_CA='["/path/to/proxy-ca.pem"]' +export HTTPS_PROXY_REJECT_UNAUTHORIZED="false" +``` + + - HTTPS_PROXY_CA β€” List of CA certificates (file paths or PEM blocks) used to validate the proxy’s certificate. + - HTTPS_PROXY_REJECT_UNAUTHORIZED β€” If set to "false", certificate validation is disabled for proxy connections (default behavior). + +### Important: Certificate Scope Clarification + +Composer distinguishes two independent certificate configurations: + +| Purpose | Keys | Description | +|-----------------------------------|-------------------------------------------------------|------------------------------------------------------------------| +| OpenAEV HTTPS server certificates | app.https_cert.ca, app.https_cert.reject_unauthorized | TLS configuration for the OpenAEV web server | +| Proxy HTTPS certificates | https_proxy_ca, https_proxy_reject_unauthorized | Validation settings for HTTPS connections made through the proxy | + +These settings must not be mixed. + +### Proxy Configuration in config.json + +Example of equivalent configuration in a JSON file: + +```json +{ + "http_proxy": "http://proxy.example.com:8080", + "https_proxy": "http://proxy.example.com:8080", + "no_proxy": "localhost,127.0.0.1,internal.domain", + "https_proxy_ca": ["/path/to/proxy-ca.pem"], + "https_proxy_reject_unauthorized": false +} +``` + + +## Certificate Separation + +⚠️ **Important**: Proxy certificates are separate from OpenAEV server certificates. + +| Purpose | Configuration Keys | Used For | +|---------------------------------|-------------------------------------------------------------|----------------------------------------------------| +| **Proxy certificates** | `https_proxy_ca`
`https_proxy_reject_unauthorized` | Validating HTTPS connections **through the proxy** | +| **OpenAEV server certificates** | `app:https_cert:ca`
`app:https_cert:reject_unauthorized` | TLS for the OpenAEV web server itself | + +**Do not confuse these two configurations.** + +--- + +### Troubleshooting - Collector, executor or injector integration + +### Automatic Injection + +When proxy is enabled, XTM Composer automatically injects these environment variables into all managed collectors, injectors and executors containers: + +- `HTTP_PROXY` +- `HTTPS_PROXY` +- `NO_PROXY` +- `HTTPS_CA_CERTIFICATES` (when `https_proxy_ca` is configured) + +### Verification + +To verify that proxy settings are correctly injected, call the following API endpoint: + +``` +GET /api/connector-instances/{instance-id} +``` + +Replace `{instance-id}` with your connector instance ID. + + + +See also: [Private Registry Authentication](registry-authentification.md) \ No newline at end of file diff --git a/docs/deployment/ecosystem/integration-manager/quick-start.md b/docs/deployment/ecosystem/integration-manager/quick-start.md new file mode 100644 index 00000000..dc39221c --- /dev/null +++ b/docs/deployment/ecosystem/integration-manager/quick-start.md @@ -0,0 +1,201 @@ +# Quick start guide + +This guide will help you get XTM Composer up and running quickly with OpenAEV. + +## Prerequisites + +Before starting, ensure you have: +- XTM Composer installed (see [Installation Guide](installation.md)) +- Access to an OpenAEV instance +- OpenAEV API token +- RSA private key (4096-bit) + +## Step 1: Generate RSA private key + +Generate a 4096-bit RSA private key for authentication: + +```bash +openssl genrsa -out private_key_4096.pem 4096 +``` + +## Step 2: Basic configuration + +Create a configuration file based on your environment. + +### Option A: Using Configuration File + +Create `config/production.yaml`: + +```yaml +manager: + id: "my-manager-001" + name: "Production Manager" + credentials_key_filepath: "/path/to/private_key_4096.pem" + logger: + level: info + format: json + +openaev: + enable: true + url: "https://openaev.example.com" + token: "your-openaev-api-token" + daemon: + selector: kubernetes # or 'docker' or 'portainer' +``` + +### Option B: Using Environment Variables + +Set configuration through environment variables: + +```bash +export COMPOSER_ENV=production +export MANAGER__ID="my-manager-001" +export MANAGER__CREDENTIALS_KEY_FILEPATH="/path/to/private_key_4096.pem" +export OPENAEV__URL="https://openaev.example.com" +export OPENAEV__TOKEN="your-openaev-api-token" +export OPENAEV__DAEMON__SELECTOR="kubernetes" +``` + +## Step 3: Choose your orchestration platform + +### For Kubernetes + +```yaml +openaev: + daemon: + selector: kubernetes + kubernetes: + image_pull_policy: IfNotPresent +``` + +### For Docker + +```yaml +openaev: + daemon: + selector: docker + docker: + network_mode: bridge +``` + +**Note**: Docker mode requires socket access: +```bash +docker run -v /var/run/docker.sock:/var/run/docker.sock ... +``` + +### For Portainer + +```yaml +openaev: + daemon: + selector: portainer + portainer: + api: "https://portainer.example.com:9443" + api_key: "your-portainer-api-key" + env_id: "3" + env_type: "docker" +``` + +## Step 4: Run XTM Composer + +### Using Docker + +```bash +docker run -d \ + --name xtm-composer \ + -v $(pwd)/config:/config \ + -v $(pwd)/private_key_4096.pem:/keys/private_key.pem \ + -e COMPOSER_ENV=production \ + filigran/xtm-composer:latest +``` + +### Using Binary + +```bash +COMPOSER_ENV=production ./xtm-composer +``` + +## Step 5: Verify connection + +Check the logs to verify XTM Composer is connected to OpenAEV: + +```bash +# Docker +docker logs xtm-composer + +# Binary/Systemd +tail -f /var/log/xtm-composer/composer.log +``` + +You should see messages like: +``` +INFO Starting XTM Composer +INFO Connecting to OpenAEV at https://openaev.example.com +INFO Successfully connected to OpenAEV +INFO Manager registered with ID: my-manager-001 +``` + +## Step 6: Verify in OpenAEV + +1. Log into your OpenAEV instance +2. Navigate to **Integrations > Catalog** +3. You should not see any alert message indicating that the Integration Manager installation is required. + +## Common configuration examples + +### Development environment + +```yaml +manager: + id: "dev-manager" + credentials_key_filepath: "./private_key_4096.pem" + logger: + level: debug + format: pretty + console: true + debug: + show_env_vars: true + +openaev: + enable: true + url: "http://localhost:4000" + token: "development-token" + daemon: + selector: docker +``` + +### Production with high availability + +```yaml +manager: + id: "prod-manager-ha" + execute_schedule: 5 # Check every 5 seconds + ping_alive_schedule: 30 # Ping every 30 seconds + logger: + level: warn + format: json + directory: true + console: false + +openaev: + enable: true + url: "https://openaev.prod.example.com" + token: "${OPENAEV_TOKEN}" # Use environment variable + logs_schedule: 5 + daemon: + selector: kubernetes + kubernetes: + image_pull_policy: Always +``` + +## Troubleshooting + +For common issues and their solutions, see the [Troubleshooting Guide](troubleshooting.md). + +## Next steps + +- Review the complete [Configuration Reference](configuration.md) +- Set up monitoring and alerting +- Configure collector, injector or executor specific settings +- Implement security best practices +- Join the OpenAEV community for support diff --git a/docs/deployment/ecosystem/integration-manager/registry-authentification.md b/docs/deployment/ecosystem/integration-manager/registry-authentification.md new file mode 100644 index 00000000..cc57a372 --- /dev/null +++ b/docs/deployment/ecosystem/integration-manager/registry-authentification.md @@ -0,0 +1,129 @@ +# Private Registry + +## Overview + +XTM Composer supports the deployment of containers from both public and private Docker registries. +Registry authentication is configured through the OpenAEV daemon settings and automatically applied by the Integration Manager during collector, injector or executor deployment. + +This page explains how to configure: + +- Configuration for private Docker registries +- Kubernetes automatic secret creation +- Registry prefix resolution + +--- + +## Configuration + +The Integration Manager automatically uses the registry configuration defined under `openaev.daemon.registry`. +No additional configuration is required inside Composer. + +```yaml +openaev: + daemon: + registry: + server: "registry.example.com" # Default: docker.io + username: "myuser" # Required for Kubernetes auto-creation + password: "mypassword" # Required for Kubernetes auto-creation + email: "user@example.com" # Optional +``` + +### Environment Variables + +```bash +export OPENAEV__DAEMON__REGISTRY__SERVER="registry.example.com" +export OPENAEV__DAEMON__REGISTRY__USERNAME="myuser" +export OPENAEV__DAEMON__REGISTRY__PASSWORD="mypassword" +export OPENAEV__DAEMON__REGISTRY__EMAIL="user@example.com" # Optional +``` + +### Required Fields + +- **server**: Registry URL (defaults to `docker.io` if not specified) +- **username**: Registry username (required for Kubernetes secret creation) +- **password**: Registry password (required for Kubernetes secret creation) +- **email**: User email (optional) + +--- + +## Kubernetes Secret Auto-Creation + +When using the **Kubernetes orchestrator**, XTM Composer automatically creates an `imagePullSecret` at startup if credentials are configured. + +### Behavior + +**With credentials configured:** + +1. At startup, the orchestrator deletes any existing secret named `openaev-registry-auth` +2. Creates a new secret with your credentials +3. Automatically attaches this secret to deployed collector, injector or executor pods + +**Without credentials:** + +- No secret is created +- You can manually create and configure your own secret if needed + +### Secret Details + +- **Name**: `openaev-registry-auth` (hardcoded) +- **Type**: `kubernetes.io/dockerconfigjson` +- **Lifecycle**: Recreated on each startup if credentials present + +### Expected Startup Logs + +``` +INFO orchestrator="kubernetes" secret="openaev-registry-auth" Deleting existing imagePullSecret if present +INFO orchestrator="kubernetes" secret="openaev-registry-auth" server="registry.example.com" Creating imagePullSecret for private registry +INFO orchestrator="kubernetes" secret="openaev-registry-auth" Successfully created imagePullSecret +``` + +### Required Kubernetes Permissions + +Your ServiceAccount must have these permissions: + +```yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: xtm-composer-role +rules: +- apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list", "create", "delete"] +``` + +### Troubleshooting + +**Secret creation fails:** + +- Check that your ServiceAccount has the required RBAC permissions +- Verify credentials are correct +- Check startup logs for error messages + +**Pods can't pull images:** + +- Verify the secret exists: `kubectl get secret openaev-registry-auth` +- Check secret is attached to pods: `kubectl describe pod ` +- Ensure registry server is accessible from the cluster + +--- + +## Registry Prefix Resolution + +The Integration Manager automatically handles registry prefixes in image names: + +- If the image name already includes the registry, it will not prepend anything. +- If no registry is included, the `server` from the registry configuration is automatically prefixed. +- This prevents double-prefixing and ensures images are pulled from the correct registry. + +Example: + +```yaml +# Image without prefix +image: "openaev/collector-example:1.0.0" + +# After resolution +image: "registry.example.com/openaev/collector-example:1.0.0" +``` + +See also: [Proxy Support](proxy-configuration.md) \ No newline at end of file diff --git a/docs/deployment/ecosystem/integration-manager/troubleshooting.md b/docs/deployment/ecosystem/integration-manager/troubleshooting.md new file mode 100644 index 00000000..f29879e1 --- /dev/null +++ b/docs/deployment/ecosystem/integration-manager/troubleshooting.md @@ -0,0 +1,336 @@ +# Troubleshooting guide + +This guide provides solutions to common issues you may encounter while installing, configuring, and running XTM Composer. + +## Installation issues + +### Post-installation verification + +After installing XTM Composer, verify the installation is successful by checking these components based on your environment. + +#### Development environment + +##### Docker verification +```bash +# Check container status +docker ps | grep xtm-composer + +# View logs +docker logs xtm-composer + +# Test connectivity +docker exec xtm-composer curl -s http://localhost:8080/health +``` + +##### Portainer verification +1. Access Portainer dashboard +2. Navigate to Containers or Stacks +3. Check XTM Composer status (should show as "running") +4. Click on the container to view logs and statistics + +#### Production environment + +##### Kubernetes verification +```bash +# Check pod status +kubectl get pods -n xtm-composer + +# View deployment status +kubectl get deployment -n xtm-composer + +# Check logs +kubectl logs -n xtm-composer deployment/xtm-composer + +# Verify service account permissions +kubectl auth can-i --list --as=system:serviceaccount:xtm-composer:xtm-composer -n xtm-composer +``` + +#### Common verification steps + +Regardless of environment, verify: + +1. **RSA Key**: Ensure the private key is properly mounted and accessible +2. **Configuration**: Confirm configuration files are loaded correctly +3. **Network**: Test connectivity to OpenCTI/OpenAEV instances +4. **Logs**: Check for any error messages or warnings + +## Connection issues + +If XTM Composer cannot connect to OpenAEV: + +### 1. Verify URL and token + +Test the connection directly using curl: +```bash +curl -H "Authorization: Bearer YOUR_TOKEN" https://openaev.example.com/api/settings/version +``` + +If this fails, check: +- The URL is correct and accessible +- The token is valid +- No proxy or firewall is blocking the connection + +### 2. Check network connectivity + +Verify basic network connectivity: +```bash +# Test DNS resolution +ping openaev.example.com + +# Test port connectivity +nc -zv openaev.example.com 443 +``` + +If connectivity fails: +- Check DNS configuration +- Verify firewall rules +- Ensure the service is running on the expected port + +### 3. SSL certificate issues + +For self-signed certificates, you can temporarily set `unsecured_certificate: true` in your configuration: + +```yaml +openaev: + unsecured_certificate: true +``` + +**Warning**: This is not recommended for production environments. Instead: +- Add the certificate to your trusted store +- Use a valid certificate from a trusted CA + +## Authentication failures + +### 1. Verify RSA key + +Check that your RSA key is valid: +```bash +openssl rsa -in private_key_4096.pem -check +``` + +Expected output: +``` +RSA key ok +``` + +If the key is invalid: +- Regenerate the key: `openssl genrsa -out private_key_4096.pem 4096` +- Ensure it's in PKCS#8 PEM format +- Verify the key size is 4096 bits + +### 2. Check file permissions + +Ensure proper permissions on the private key file: +```bash +chmod 600 private_key_4096.pem +ls -la private_key_4096.pem +``` + +The file should be readable only by the owner. + +### 3. Verify key path + +Confirm the path in your configuration matches the actual key location: + +```yaml +manager: + credentials_key_filepath: "/path/to/private_key_4096.pem" +``` + +For Docker deployments, ensure the volume mount is correct: +```bash +docker run -v /local/path/key.pem:/keys/private_key.pem ... +``` + +## Orchestration issues + +### Kubernetes issues + +#### Verify cluster access +```bash +# Check cluster connectivity +kubectl cluster-info + +# Verify permissions +kubectl auth can-i create deployments +``` + +If access is denied: +- Check RBAC configuration +- Verify service account permissions +- Ensure the kubeconfig is properly configured + +#### Common Kubernetes errors + +**"pods is forbidden"**: The service account lacks necessary permissions +- Solution: Apply the correct RBAC configuration (see Installation Guide) + +**"no such host"**: Kubernetes API server cannot be reached +- Solution: Check the cluster endpoint configuration + +### Docker issues + +#### Check socket permissions +```bash +# Verify Docker is accessible +docker info + +# Check socket permissions +ls -la /var/run/docker.sock +``` + +If permission denied: +- Add user to docker group: `sudo usermod -aG docker $USER` +- For container access, mount the socket: `-v /var/run/docker.sock:/var/run/docker.sock` + +#### Common Docker errors + +**"Cannot connect to Docker daemon"**: Docker socket not accessible +- Solution: Ensure Docker is running and socket is properly mounted + +**"Network not found"**: Specified network doesn't exist +- Solution: Create the network or update configuration + +### Portainer issues + +#### Test API access +```bash +curl -H "X-API-Key: YOUR_KEY" https://portainer.example.com/api/endpoints +``` + +If this fails: +- Verify the API key is correct +- Check the Portainer URL and port +- Ensure the environment ID is correct + +## Runtime issues + +### Container health monitoring + +XTM Composer monitors container health and can detect various runtime issues: + +#### Reboot loop detection + +If a container restarts more than 3 times within 5 minutes, XTM Composer detects a reboot loop. Check: + +1. **Container Logs**: Review logs for startup errors + ```bash + # Docker + docker logs container_name + + # Kubernetes + kubectl logs pod_name -n namespace + ``` + +2. **Configuration Issues**: Verify all required environment variables are set +3. **Resource Limits**: Check if the container has sufficient resources +4. **Image Availability**: Ensure the Docker image exists and is accessible + +### Log collection issues + +XTM Composer collects logs every `logs_schedule` interval. If logs are missing: + +1. Verify the schedule configuration: + ```yaml + openaev: + logs_schedule: 10 # seconds + ``` + +2. Check container log availability: + ```bash + # Docker + docker logs --tail 50 container_name + + # Kubernetes + kubectl logs --tail 50 pod_name + ``` + +3. Ensure the orchestrator has permissions to read logs + +## Configuration issues + +### Environment variable problems + +If configuration via environment variables isn't working: + +1. **Check Variable Format**: Use double underscores for nested values + - Correct: `MANAGER__LOGGER__LEVEL=debug` + - Incorrect: `MANAGER.LOGGER.LEVEL=debug` + +2. **Verify Variable Loading**: Enable debug mode to see loaded variables + ```yaml + manager: + debug: + show_env_vars: true + ``` + +3. **Priority Issues**: Remember environment variables override file configuration + +### Configuration file not loading + +If your configuration file isn't being loaded: + +1. **Check COMPOSER_ENV**: Ensure it matches your file name + ```bash + export COMPOSER_ENV=production # Loads config/production.yaml + ``` + +2. **Verify File Location**: Configuration files should be in `/config` directory +3. **Check YAML Syntax**: Validate your YAML file for syntax errors + +## Logging and debugging + +### Enable debug logging + +For detailed troubleshooting, enable debug logging: + +```yaml +manager: + logger: + level: debug + console: true + format: pretty +``` + +Or via environment variable: +```bash +export MANAGER__LOGGER__LEVEL=debug +``` + +### View logs + +Check logs to identify issues: + +```bash +# Docker +docker logs -f xtm-composer + +# Kubernetes +kubectl logs -f deployment/xtm-composer -n xtm-composer + +# Binary/File-based +tail -f /var/log/xtm-composer/composer.log +``` + +### Common log messages + +**"Successfully connected to OpenAEV"**: Connection established successfully + +**"Failed to connect to platform"**: Check connection settings and network + +**"Manager registered with ID"**: XTM Composer successfully registered + +**"Invalid authentication"**: Check API token and credentials + +**"Reboot loop detected"**: Container is continuously restarting + +## Getting help + +If you continue to experience issues: + +1. **Check the logs** with debug level enabled +2. **Review the configuration** for any misconfigurations +3. **Verify network connectivity** between all components +4. **Consult the openAEV community** for additional support + +For bug reports and feature requests, visit the [GitHub repository](https://github.com/FiligranHQ/xtm-composer.git). diff --git a/mkdocs.yml b/mkdocs.yml index 900af519..16a2d8f9 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -122,6 +122,15 @@ nav: - Executors: deployment/ecosystem/executors.md - Injectors: deployment/ecosystem/injectors.md - Collectors: deployment/ecosystem/collectors.md + - Integration Manager: + - Overview: deployment/ecosystem/integration-manager/overview.md + - Quick start: deployment/ecosystem/integration-manager/quick-start.md + - Installation guide: deployment/ecosystem/integration-manager/installation.md + - Configuration: + - Configuration reference : deployment/ecosystem/integration-manager/configuration.md + - Proxy : deployment/ecosystem/integration-manager/proxy-configuration.md + - Private Registry : deployment/ecosystem/integration-manager/registry-authentification.md + - Troubleshooting: deployment/ecosystem/integration-manager/troubleshooting.md - Advanced: - Platform managers: deployment/managers.md - Breaking changes: From 3d23764afdf0aabd1407c062fdc53660f8683033 Mon Sep 17 00:00:00 2001 From: Marine LM Date: Mon, 12 Jan 2026 11:57:12 +0100 Subject: [PATCH 2/3] [docs] feat(composer): improve --- .../instance-form-sample.png | Bin 0 -> 46913 bytes .../ecosystem/integration-manager/overview.md | 26 ++++++++---------- 2 files changed, 12 insertions(+), 14 deletions(-) create mode 100644 docs/deployment/assets/integration-manager/instance-form-sample.png diff --git a/docs/deployment/assets/integration-manager/instance-form-sample.png b/docs/deployment/assets/integration-manager/instance-form-sample.png new file mode 100644 index 0000000000000000000000000000000000000000..df20b45abb09fdc9bdde2e0486f83b1370df63a3 GIT binary patch literal 46913 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 U Date: Mon, 12 Jan 2026 12:31:10 +0100 Subject: [PATCH 3/3] [docs] feat(composer): rename confidence level by log level --- docs/deployment/ecosystem/integration-manager/overview.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/deployment/ecosystem/integration-manager/overview.md b/docs/deployment/ecosystem/integration-manager/overview.md index d8bd1c24..4e9b2000 100644 --- a/docs/deployment/ecosystem/integration-manager/overview.md +++ b/docs/deployment/ecosystem/integration-manager/overview.md @@ -40,8 +40,7 @@ To learn more about Xtm Composer architecture, refer to the [dedicated documenta - **Instance names**: Two instances can't share the same name - **Validation error**: If a duplicate name is detected, a blocking error will prevent deployment until a unique name is provided - - **Confidence level**: set the desired confidence level for the service account. - - **API key** (encrypted and securely stored). + - **Log level**: set the desired confidence log level for the service account. - **Additional options**: collector, injector or executor specific configuration. 3. Click **Create**. Once the collector is created, you will be redirected to the collector instance view.