Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions documentation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Use the section below to quickly find what you are looking for.

- Configuration
- [Environment variables](env.md)
- [Malware detection](malware_detection.md)
- [Object storage](s3.md)
- [Collaboration](collaboration.md)
- [Format conversion](format_conversion.md)
Expand Down
4 changes: 2 additions & 2 deletions documentation/env.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ These are the environment variables you can set for the `impress-backend` contai
| LOGIN_REDIRECT_URL | Login redirect url | |
| LOGIN_REDIRECT_URL_FAILURE | Login redirect url on failure | |
| LOGOUT_REDIRECT_URL | Logout redirect url | |
| MALWARE_DETECTION_BACKEND | The malware detection backend use from the django-lasuite package | lasuite.malware_detection.backends.dummy.DummyBackend |
| MALWARE_DETECTION_PARAMETERS | A dict containing all the parameters to initiate the malware detection backend | {"callback_path": "core.malware_detection.malware_detection_callback",} |
| MALWARE_DETECTION_BACKEND | The malware detection backend use from the django-lasuite package. See [malware detection documentation](malware_detection.md) to configure the ICAP backend | lasuite.malware_detection.backends.dummy.DummyBackend |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Fix the grammar in the description.

"The malware detection backend use from the django-lasuite package" is grammatically incorrect. Use "The malware detection backend to use, from the django-lasuite package" or similar.

📝 Proposed fix
-| MALWARE_DETECTION_BACKEND                       | The malware detection backend use from the django-lasuite package. See [malware detection documentation](malware_detection.md) to configure the ICAP backend                                                                                      | lasuite.malware_detection.backends.dummy.DummyBackend                   |
+| MALWARE_DETECTION_BACKEND                       | The malware detection backend to use, from the django-lasuite package. See [malware detection documentation](malware_detection.md) to configure the ICAP backend                                                                                  | lasuite.malware_detection.backends.dummy.DummyBackend                   |
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
| MALWARE_DETECTION_BACKEND | The malware detection backend use from the django-lasuite package. See [malware detection documentation](malware_detection.md) to configure the ICAP backend | lasuite.malware_detection.backends.dummy.DummyBackend |
| MALWARE_DETECTION_BACKEND | The malware detection backend to use, from the django-lasuite package. See [malware detection documentation](malware_detection.md) to configure the ICAP backend | lasuite.malware_detection.backends.dummy.DummyBackend |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@documentation/env.md` at line 95, In the MALWARE_DETECTION_BACKEND
environment variable description row, fix the grammatical error in the
description column. Change the phrase "backend use from the django-lasuite
package" to use proper grammar by inserting "to" before "use" and adding a comma
after "backend" to read "backend to use, from the django-lasuite package" or
similar grammatically correct phrasing that maintains the original meaning.

| MALWARE_DETECTION_PARAMETERS | A dict containing all the parameters to initiate the malware detection backend. See [malware detection documentation](malware_detection.md) | {"callback_path": "core.malware_detection.malware_detection_callback",} |
| MEDIA_BASE_URL | | |
| MEDIA_AUTH_ORIGINAL_URL_HEADER | Parameter containing the original request URL, as seen at the media auth endpoint, in CGI/WSGI form (HTTP_HEADER_NAME_ALL_CAPS_WITH_UNDERSCORES) | HTTP_X_ORIGINAL_URL |
| NO_WEBSOCKET_CACHE_TIMEOUT | Cache used to store current editor session key when only users without websocket are editing a document | 120 |
Expand Down
15 changes: 15 additions & 0 deletions documentation/examples/helm/cicap.values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
cicap:
enabled: true
name: cicap
#serviceNameOverride: cicap
registry: registry.opencode.de
repository: bmi/opendesk/components/platform-development/images/clamav-icap
tag: "0.6.4"
clamd:
image: clamav/clamav:stable
port: 1344
# MaxObjectSize limits the size of files scanned by the ICAP service
maxObjectSize: 100M
# StreamMaxLength limits the size of files scanned by clamd
streamMaxLength: 100M
resources: {}
27 changes: 27 additions & 0 deletions documentation/installation/kubernetes.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,33 @@ redis-dev-backend-redis-68c9f66786-4dgxj 1/1 Running 0 4m21s

```

### Find ICAP server connection values

Docs can scan every uploaded file with an antivirus engine exposed through the
Internet Content Adaptation Protocol (ICAP), see
[malware detection](../malware_detection.md). For development, an ICAP server
(c-icap with ClamAV) is provided by the dev dependencies chart, so you can
install a local testing environment as follow:

```
$ helm install --repo https://suitenumerique.github.io/helm-dev-backend -f documentation/examples/helm/cicap.values.yaml cicap dev-backend
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
cicap-dev-backend-cicap-xxxxx-xxxxx 1/1 Running 0 10s
```
Comment on lines +223 to +228

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a language to the fenced code block.

markdownlint (MD040) flags this block. Add a language identifier, for example shell or text, consistent with other code blocks in this file.

📝 Proposed fix
-```
+```text
 $ helm install --repo https://suitenumerique.github.io/helm-dev-backend -f documentation/examples/helm/cicap.values.yaml cicap dev-backend
 $ kubectl get pods
 NAME                                       READY   STATUS    RESTARTS   AGE
 cicap-dev-backend-cicap-xxxxx-xxxxx        1/1     Running   0          10s
</details>

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion

🧰 Tools
🪛 markdownlint-cli2 (0.23.1)

[warning] 223-223: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@documentation/installation/kubernetes.md` around lines 223 - 228, Add a
language identifier to the fenced code block containing the Helm installation
and kubectl output, using text or the file’s established convention, without
changing its contents.

Source: Linters/SAST tools


Wait for the pod to be ready. On the first start the clamd sidecar
downloads the ClamAV virus database, which takes a few minutes and requires
access to `database.clamav.net`. From here the important information you will
need are:

```yaml
MALWARE_DETECTION_BACKEND: lasuite.malware_detection.backends.icap.ICAPBackend
MALWARE_DETECTION_PARAMETERS: '{"server_address":"cicap-dev-backend-cicap","server_port":1344,"service":"avscan","callback_path":"core.malware_detection.malware_detection_callback"}'
```

You can find these values in **documentation/examples/helm/cicap.values.yaml**

## Deployment

Now you are ready to deploy Docs without AI. AI requires more dependencies (OpenAI API). To deploy Docs you need to provide all previous information to the helm chart.
Expand Down
87 changes: 87 additions & 0 deletions documentation/malware_detection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Malware detection

Docs can scan every uploaded file with an antivirus engine before making it
available to other users. Scanning is delegated to
[django-lasuite](https://github.com/suitenumerique/django-lasuite) which
provides several backend implementations. By default the `DummyBackend` is
used: every file is immediately considered safe.

To actually scan files, configure the `ICAPBackend` to use an antivirus engine
exposed through the
[Internet Content Adaptation Protocol](https://datatracker.ietf.org/doc/html/rfc3507)
(ICAP, RFC 3507), for example [c-icap](https://github.com/c-icap/c-icap) with
ClamAV or SquidClamAV.

> [!NOTE]
> The `ICAPBackend` is available in `django-lasuite` 0.0.28+. Upgrade the
> `django-lasuite` dependency in `src/backend/pyproject.toml` before enabling
> it.

## How it works

The backend runs in the Celery workers. For every uploaded file, a task sends
the file to the ICAP service using REQMOD and reads the verdict from the
response:

- `204` No Modification, or `200` without an `X-Infection-Found` header: the
file is reported `safe`.
- An `X-Infection-Found` header containing a `Threat=<name>` part: the file is
reported `unsafe`.
- Any other ICAP status or a `500` server error: the file is reported
`unknown`. Transient connection, timeout and protocol errors are retried by
the task.

The scan result is handled by the docs callback
(`core.malware_detection.malware_detection_callback`) which fails closed: only
a `safe` result makes the file `READY`, everything else removes the
attachment, deletes the file and logs a `docs.security` entry.

## Configuration

The backend is configured with two environment variables:

```bash
MALWARE_DETECTION_BACKEND=lasuite.malware_detection.backends.icap.ICAPBackend
MALWARE_DETECTION_PARAMETERS={"server_address":"icap.example.com","server_port":1344,"service":"avscan","callback_path":"core.malware_detection.malware_detection_callback"}
```

`MALWARE_DETECTION_PARAMETERS` is a JSON dict, see the
[django-lasuite documentation](https://github.com/suitenumerique/django-lasuite/blob/main/documentation/how-to-use-malware-detection-backend.md)
for all the supported parameters (`server_port`, `service`, `timeout`,
`max_processing_files`, TLS options, ...).

### Helm deployment

In a Kubernetes deployment, set these variables with the `backend.envVars`
value of the chart or with a ConfigMap referenced from `backend.envFrom`:

```yaml
backend:
envVars:
MALWARE_DETECTION_BACKEND: lasuite.malware_detection.backends.icap.ICAPBackend
MALWARE_DETECTION_PARAMETERS: '{"server_address":"icap.example.com","server_port":1344,"service":"avscan","callback_path":"core.malware_detection.malware_detection_callback"}'
```

Both the backend web deployment and the Celery worker deployment receive these
variables.

## ICAP server requirements

The ICAP server is external to Docs: you must provide and operate it yourself
(c-icap + ClamAV containers, an existing appliance, ...). For a Kubernetes
development environment, the dev dependencies chart provides one, see the
[Kubernetes installation guide](installation/kubernetes.md).

- The server must be reachable from the Celery workers on the configured port
(`1344` by default, or the `server_port` parameter). Keep it on a private
network or enable TLS with the backend `tls` parameters.
- The `service` parameter must match a REQMOD service on the server. With
c-icap, the `avscan` service maps to the `virus_scan` module backed by
`clamd`.
- The `clamd` `StreamMaxLength` setting must be high enough for the largest
files you allow, otherwise large uploads are rejected by the scanner.
- Make sure the scanning engine is monitored: c-icap can report a file as
clean when `clamd` is down. The docs callback only protects against
non-`safe` verdicts, so a scan engine outage must be detected out of band
(alerting on `unknown` statuses, on the callback logs or on the engine
itself).