# open-appsec Documentation

open-appsec documentation includes several sections. You can easily navigate between them using the menu on the left (on a mobile device click <img src="/files/Rdn3Av5YHVf5yMea5vpQ" alt="" data-size="line">):

* [**Getting Started** ](/getting-started/getting-started)- Allows you to jump right into setup. We recommend following the pages in the Getting Started section one after the other to quickly set up a working system.
* [**Concepts**](/concepts/agents) - In-depth overview of key topics and concepts. Read the ones you find interesting or read them all to get fully acquainted with how the product works.
* [**How To's**](/how-to/configuration-and-learning) - Step-by-step guides for day-to-day operations and advanced features.
* [**References**](/references/agent-cli) - Detailed description of the Agent CLI, Management API and Event Query language.


# What is open-appsec?

**open-appsec** is an **open-source** fully automated Web Application and API Security solution. It is powered by a machine learning engine which continuously analyzes users' HTTP/S requests as they visit the website or API.&#x20;

The analysis includes the application structure and how users interact with the content in order to identify patterns and automatically stop and block malicious requests and bad actors.

open-appsec provides pre-emptive threat protection against OWASP Top-10- and zero-day attacks. Thanks to machine learning, there is no threat signature upkeep and exception handling, like common in many WAF solutions.&#x20;

It can be deployed as add-on to many platforms and solutions, e.g.:\
\
**NGINX**\
**Ingress NGINX**\
**NGINX Proxy Manager**\
**NPMplus**\
**Kong API Gateway**\
**Apache APISIX API Gateway** \
**Envoy** \
**Istio Ingress Gateway**

The project GitHub is available [here](https://github.com/openappsec).

In addition to the free open-appsec "Community Edition" there's also an Enterprise WAF solution available, which is built on and significantly extends the same core technology as open-appsec\
\
**Check Point WAF** (open-appsec's "enterprise edition") offers **enterprise-grade support SLAs**, many more **advanced security capabilities**, much **higher scalability**, and **additional deployment options**, including **virtual machine images** and a **full SaaS offering** option.\
\
A **comprehensive overview and comparison of what's included in the different editions** is available [here](https://www.openappsec.com/pricing).&#x20;

## Main features of open-appsec

* **Machine Learning-based Application Firewall** - stop application layer attacks including OWASP Top 10 with very minimal tuning and no false positives. Pre-emptive (no signature updates required) protection for zero-days such as Log4Shell and Spring4Shell.
* **API Security**&#x20;
  * stop malicious API access and abuse&#x20;
  * and enforce API schema (requires Check Point WAF or open-appsec Premium Edition \[deprecated])
* **Bot Prevention** - Identify and stop automated attacks before they negatively impact the bottom line or customer experience (requires Check Point WAF or open-appsec Premium Edition \[deprecated])
* **Intrusion Prevention**
  * Full IPS Engine with support for custom Snort 3.0 signatures.
  * Protections for over 2,800 WEB CVEs, based on Check Point award winning NSS-Certified IPS (requires Check Point WAF or open-appsec Premium Edition \[deprecated])
* **File Security -** Prevent malicious files from being uploaded into web apps and APIs servers. The engine scans the HTTP traffic analyses any files uploaded and consults a huge cloud repository as to the file's reputation (requires Check Point WAF or open-appsec Premium Edition \[deprecated])
* **Rate Limiting** - Safeguard your websites and API by setting a cap on how many requests. can be made within a certain period, based on identifiers such as IP address (Community Edition) or keys within JWT, cookies or headers (requires Check Point WAF or open-appsec Premium Edition \[deprecated])
* **HTTPS Traffic inspection** - SSL certificate and private keys can be stored locally or in public cloud secrets storage (AWS/Azure)
* **Integration into modern environments** and workloads (public cloud & Kubernetes) and CI/CD workflows, supporting **NGINX Ingress Controller, NGINX, NGINX Proxy Manager, NPMplus, Envoy, APISIX and Kong API Gateways, Istio Ingress Gateway** on **Kubernetes, Linux Servers and Containers (Docker).**
* **Ease of ongoing management and maintenance** – Enterprise Grade SaaS Web UI, GraphQL API and Infrastructure-as-code using Terraform
* **GitOps-CD-ready** - alternatively to using the central WebUI manage open-appsec locally, declaratively using local configuration file (Docker/Linux) or CRDs/annotations (Kubernetes)


# open-appsec Video Tutorials

{% embed url="<https://youtu.be/ZmFrA2ibdog>" %}

{% embed url="<https://www.youtube.com/watch?v=IUgPHjLrJR8>" %}

{% embed url="<https://www.youtube.com/watch?v=VKSGPN1TnHY>" %}

{% embed url="<https://www.youtube.com/watch?t=1s&v=R45V8YbPasI>" %}

{% embed url="<https://www.youtube.com/watch?t=9s&v=al0Cua8FPp8>" %}


# Release Notes

## Releases

| Release      | Date       | Notes                                                                                                                                        |
| ------------ | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| 1.1.32       | 2025-11-26 | [release notes](https://github.com/openappsec/openappsec/releases)                                                                           |
| 1.1.30       | 2025-10-08 | [release notes](https://github.com/openappsec/openappsec/releases)                                                                           |
| 1.1.29       | 2025-08-12 | [release notes](https://github.com/openappsec/openappsec/releases)                                                                           |
| 1.1.27       | 2025-06-30 | [release notes ](https://github.com/openappsec/openappsec/releases)                                                                          |
| 1.1.26       | 2025-06-15 | [release notes ](https://github.com/openappsec/openappsec/releases)                                                                          |
| 1.1.25       | 2025-04-24 | [release notes](https://github.com/openappsec/openappsec/releases/tag/1.1.25)                                                                |
| 1.1.24       | 2025-03-23 | [release notes](https://github.com/openappsec/openappsec/releases/tag/1.1.24)                                                                |
| 1.1.23       | 2025-03-30 | [release notes ](https://github.com/openappsec/openappsec/releases/tag/1.1.23)                                                               |
| 1.1.22       | 2025-02-19 | [release notes ](https://github.com/openappsec/openappsec/releases/tag/1.1.22)                                                               |
| 1.1.21       | 2025-01-21 | [release notes](https://github.com/openappsec/openappsec/releases/tag/1.1.21)                                                                |
| 1.1.20       | 2024-12-01 | [release notes](https://github.com/openappsec/openappsec/releases/tag/1.1.20)                                                                |
| 1.1.19       | 2024-11-10 | [release notes](https://github.com/openappsec/openappsec/releases/tag/1.1.19)                                                                |
| 1.1.18       | 2024-10-01 | [release notes](https://github.com/openappsec/openappsec/releases/tag/1.1.18)                                                                |
| 1.1.17       | 2024-09-24 | [release notes](https://github.com/openappsec/openappsec/releases/tag/1.1.17)                                                                |
| 1.1.16       | 2024-08-25 | [release notes](https://github.com/openappsec/openappsec/releases/tag/1.1.16)                                                                |
| 1.1.15       | 2024-08-01 | [release notes](https://github.com/openappsec/openappsec/releases/tag/1.1.15)                                                                |
| 1.1.14       | 2024-07-08 | [release notes](https://github.com/openappsec/openappsec/releases/tag/1.1.14)                                                                |
| 1.1.13       | 2024-07-02 | [release notes](https://github.com/openappsec/openappsec/releases/tag/1.1.14)                                                                |
| 1.1.12       | 2024-06-07 | [release notes](https://github.com/openappsec/openappsec/releases/tag/1.1.12)                                                                |
| 1.1.11       | 2024-06-03 | [release notes ](https://github.com/openappsec/openappsec/releases/tag/1.1.11)                                                               |
| 1.1.10       | 2024-05-27 | [release notes](https://github.com/openappsec/openappsec/releases/tag/1.1.10)                                                                |
| 1.1.9        | 2024-04-18 | [release notes](https://github.com/openappsec/openappsec/releases/tag/1.1.9)                                                                 |
| 1.1.8        | 2024-04-10 | [release notes](https://github.com/openappsec/openappsec/releases)                                                                           |
| 1.1.7        | 2024-03-11 | [release notes](https://github.com/openappsec/openappsec/releases/tag/1.1.7)                                                                 |
| 1.1.6        | 2024-02-20 | [release notes](https://github.com/openappsec/openappsec/releases/tag/1.1.6)                                                                 |
| 1.1.5        | 2024-02-12 | [ ](https://github.com/openappsec/openappsec/releases/tag/1.1.5)[release notes](https://github.com/openappsec/openappsec/releases/tag/1.1.3) |
| 1.1.4        | 2024-02-04 | [release notes](https://github.com/openappsec/openappsec/releases/tag/1.1.3)                                                                 |
| 1.1.3        | 2023-12-28 | [release notes](https://github.com/openappsec/openappsec/releases/tag/1.1.3)                                                                 |
| 1.1.2        | 2023-12-03 | [release notes](https://github.com/openappsec/openappsec/releases/tag/1.1.2)                                                                 |
| 1.1.0        | 2023-09-10 | [release notes](https://github.com/openappsec/openappsec/releases/tag/1.1.0)                                                                 |
| 1.0.1        | 2023-08-24 | [release notes](https://github.com/openappsec/openappsec/releases/tag/1.0.1)                                                                 |
| 1.0.0        | 2023-07-25 | <p>first "stable" release<br>"latest"<br><a href="https://github.com/openappsec/openappsec/releases/tag/1.0.0">release notes</a></p>         |
| 0.9.1-rc     | 2023-06-02 | [release notes](https://github.com/openappsec/openappsec/releases/tag/0.9.1-rc)                                                              |
| 0.9.0-rc     | 2023-05-06 | [release notes](https://github.com/openappsec/openappsec/releases/tag/0.9.0-rc)                                                              |
| 0.8.0-rc     | 2023-05-02 | [release notes](https://github.com/openappsec/openappsec/releases/tag/0.8.0-rc)                                                              |
| 1.2242.1-rc1 | 2022-10-25 | initial open-source release                                                                                                                  |

## Limitations

We are constantly working on resolving the limitations listed here and adding enhanced functionality.

{% hint style="info" %}
Let us know via the open-appsec [GitHub](https://www.github.com/openappsec) or our Website [Chat](https://www.openappsec.io) if you identified a potential issue/limitation or via our Website [Chat](https://www.openappsec.io) as well if you have any ideas/requirements for additional features.\
\
If resolving one of the issues below is of critical importance for you, please let us know via email to <info@openappsec.io> .
{% endhint %}

#### Declarative Management:

**All environments:**

* **Exceptions:** only the operator "=" is supported.

**General**:

* **Log Trigger Response body**: In the log trigger setting "Response body" to true can affect traffic. &#x20;
* **Only one exception is supported per asset**&#x20;
* **SELinux**: open-appsec  Linux servers: SELinux in “Enforced” mode is not supported. When SELinux is used in “Enforced” mode on the machine running the reverse proxy server and the agent, deployment of the agent might fail during registration. SELinux in “Enforced” mode, blocks the registration attempt.
* **Country-based Exception rules:** When configuring exceptions in Asset edit->Exceptions Tab, an exception rule using the keys Country Name or Country Code cannot be defined with additional conditions based on other keys in the same exception.&#x20;
  * There’s an implicit OR logic between different exception rules, so it is possible to define different exception rules, some using country code/name, and others using other keys.
* **Source Ip Exception rules:** When configuring exceptions in Asset edit->Exceptions Tab, an exception rule using the key Source IP cannot be defined with additional conditions based on other keys in the same exception.&#x20;
  * There’s an implicit OR logic between different exception rules, so it is possible to define different exception rules, some using Source IP and others using other keys.
* **Parameter Name / Value Exceptions rules:** Drop Rules With Parameter Name and / or Parameter Value are not supported.&#x20;
* **Country-based Exception rules:** are only supported in managed tenants (Declarative / Management)&#x20;
* **Containerized agents running version 1.1.9 or earlier cannot be upgraded directly to version 1.1.21 or newer**
  * As a best practice, we recommend periodically upgrading the agent container to ensure you have the latest software updates.
* **View Logs from Tuning:**
  * When managing open-appsec in declarative mode with wildcard assets, the “View Logs” option for tuning suggestions will not display event data. To view associated logs, use non-declarative mode or define explicit assets instead of wildcards.<br>

#### SaaS Management (WebUI):

* **Creating a second tenant using the same email address is not supported**\
  (the user can be added to another tenant with another main email address as an additional user)
* **WildCard asset**: you can only have a single asset using wildcard resource for each HTTP as well as HTTPS (e.g.: http\://\* and https\://\* ) per tenant. This will be resolved soon.
* **Social log-in:** Adding Google or GitHub users as additional users to a tenant is not supported\
  (use regular users with email addresses instead)
* **Log trigger and web user response settings in rate limiting practice:**

  Currently, setting log trigger and web user reponse in rate limiting subpractice, which are different from the settings in Web subpractice, is unsupported. The configuration of the Web Attacks subpractice will instead apply to the rate limiting subpractice. This will be resolved soon.

#### Platform support:

* Temporarily Fedora is not supported for Linux-embedded installations\
  (consider using Docker-based deployment instead)
* Ambassador support is not available yet


# Getting Started

{% content-ref url="/pages/XzPA7UFoksUJscLSZUHf" %}
[Start With Kubernetes](/getting-started/start-with-kubernetes)
{% endcontent-ref %}

{% content-ref url="/pages/pYtU2ANNgakFm2heJDfd" %}
[Start With Linux](/getting-started/start-with-linux)
{% endcontent-ref %}

{% content-ref url="/pages/lDQro0xuNxZzJgHABh5l" %}
[Start with Docker](/getting-started/start-with-docker)
{% endcontent-ref %}

{% content-ref url="/pages/VqydbuHwuQn4aKZm1kUU" %}
[Using the Web UI (SaaS)](/getting-started/using-the-web-ui-saas)
{% endcontent-ref %}


# Start With Linux

## Overview

open-appsec can be deployed as an add-on for NGINX, Kong Gateway or APISIX Gateway to provide protection to any applications and APIs served by NGINX Reverse Proxy, NGINX Webserver, Kong API Gateway or APISIX API Gateway.&#x20;

{% tabs %}
{% tab title="NGINX" %}

<figure><img src="/files/A5PMdMLCT550SCWq5Nnc" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Kong Gateway" %}

<figure><img src="/files/wccmlFrXEVQxyeG5fMmo" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="APISIX Gateway" %}

<figure><img src="/files/2eluzKgtAgXlhgnfeOmp" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}

### Proxy vs. locally-served applications

{% hint style="info" %}
The open-appsec agent attaches itself to the traffic being **proxied** by the Proxy Server or API server.
{% endhint %}

If the server serves applications locally, and does not serve as a proxy between an exposed domain and an internal one - open-appsec can still inspect the traffic if you change the port for the local applications to a higher port, and add a proxy rule between the exposed listening domain and port, to the same local machine at a higher port.

{% content-ref url="/pages/ongBhoz9sKZqGzExmUEn" %}
[Install open-appsec for Linux](/getting-started/start-with-linux/install-open-appsec-for-linux)
{% endcontent-ref %}


# Install open-appsec for Linux

The fastest and easiest way to deploy and configure open-appsec is using an interactive CLI tool which will guide you through the most commonly required customizations.

## Prerequisites

* &#x20;Root permissions&#x20;
* `wget` command-line tool installed on your linux machine
* Execution permissions on the `/tmp` directory.&#x20;
* Linux machine with:
  * &#x20;A supported OS and NGINX, Kong, or APISIX version already installed.\
    Here you find lists of all supported/pre-compiled attachments per supported OS versions for each available integration:\
    \- [NGINX attachment compatibility](https://downloads.openappsec.io/packages/supported-nginx.txt)\
    \- [APISIX attachment compatibility](https://downloads.openappsec.io/packages/supported-apisix.txt)\
    \- [Kong attachment compatibility](https://downloads.openappsec.io/packages/supported-kong.txt)

{% hint style="info" %}
**For Kong a new type of attachment plugin based on Lua is now available in beta!**\
Installation is done using `luarocks` command with a `.rockspec`  file.\
You find all instructions below on this page.\
When using this, the attachment compatibility list for Kong above isn't relevant anymore,\
as there's no need anymore for providing precompiled attachments.

Let us know if you have any feedback regarding this beta program or require technical assistance: [mailto://info@openappsec.io](mailto:info@openappsec.io)
{% endhint %}

In case your version is not supported yet, you can also build the attachment yourself from source code, see [here](/deployment-and-upgrade/build-open-appsec-based-on-source-code).

## Installation

Download the installer for Linux using these commands:

```bash
wget https://downloads.openappsec.io/open-appsec-install && chmod +x open-appsec-install 
```

You can show the installer version and available options by running the following command to show the help info:

```
./open-appsec-install -h
```

This interactive installer provides 2 alternative modes for automatic vs. manual installation:

### **Mode 1: Automatic installation of open-appsec and adding attachment (plugin) to NGINX/Kong/APISIX**

{% hint style="success" %}
This is the recommended deployment mode for deploying open-appsec on Linux for most deployments, as this is fully automatic and compatible with most, typically used environments.
{% endhint %}

In this mode open-appsec will automatically be installed with all required components and the attachment will be added and activated in the existing configuration for NGINX/Kong (traditional integration)/APISIX.

{% hint style="info" %}
When using the new Kong integration based on the Lua attachment plugin you are responsible for first deploying the plugin yourself and configuring Kong to load it, steps are included in the installation instructions below.
{% endhint %}

The resulting configuration will be locally, declaratively managed using `local_policy.yaml` configuration file.

{% hint style="info" %}
If you want to directly connect your deployment to the open-appsec Web UI (SaaS) for central management this is also possible by providing the optional `--token` parameter to specify a deployment profile from Web UI to associate this new deployment with. For more details see [Using the Web UI (SaaS)](/getting-started/using-the-web-ui-saas)
{% endhint %}

Run this command to start the installation:

{% tabs %}
{% tab title="Linux, APISIX, Kong (traditional Kong plugin)" %}
The following command will automatically install the open-appsec attachment to the NGINX, APISIX or Kong proxy, configure it to be loaded and also install the open-appsec agent with default local declarative configuration.

```
./open-appsec-install --auto
```

{% endtab %}

{% tab title="Kong Lua plugin (beta)" %}
{% hint style="info" %}
Using the Lua-based plugin for the open-appsec attachment is the more modern approach for deployment of the attachment when using Kong, compared to the traditional attachment plugin. It is fully aligned with Kong's plugin standards and will eventually replace the current, traditional attachment plugin for Kong in the future.
{% endhint %}

For deployment of the open-appsec attachment using the Kong Lua-based plugin:

1. **Install dependencies:** Make sure to have all required dependencies installed on your system, as shown in the command below:\
   (This command is for Ubuntu, make sure to adjust it, if you are using a different OS.)

```bash
sudo apt-get install libbrotli-dev build-essential git curl zlib1g-dev ca-certificates 
```

2. **Compile and install the Kong Lua plugin:** Run the following `luarocks` command to compile and install the Kong Lua plugin for the open-appsec attachment:

```bash
luarocks install https://raw.githubusercontent.com/openappsec/attachment/main/attachments/kong/plugins/open-appsec-waf-kong-plugin/open-appsec-waf-kong-plugin-1.0.0-1.rockspec
```

3. **Install open-appsec agent:** Run the following command to automatically install the open-appsec agent with default local declarative configuration.\
   Make sure to add the  `--kong-plugin` flag, this will make the installer skip the installation of the traditional attachment on NGINX level, which is not required, as the Lua-based attachment plugin was already installed in the above step using the `luarocks` command.

```
./open-appsec-install --auto --kong-plugin
```

4. **Load the open-appsec attachment plugin** in the Kong Gateway (note there's multiple ways to do this in Kong), here are examples for some **alternative** options:\
   \
   Option 1 — *If you use Kong Konnect for central management of Kong:*\
   Add the Kong Konnect plugin schema for the open-appsec attachment custom plugin to your Kong Konnect tenant, you can download it from here and import in Kong Konnect web UI:\
   <https://github.com/openappsec/attachment/raw/main/attachments/kong/plugins/open-appsec-waf-kong-plugin/schema.lua>\
   Then activate the plugin from the Kong Konnect web UI.\
   Full instructions for using Kong Konnect for managing the open-appsec attachment plugin can be found here: [Using Kong Konnect (Kong only)](/getting-started/using-the-web-ui-saas/using-kong-konnect-kong-only)\
   \
   Option 2 — Include the following line in the `kong.conf` file (usually located in `/etc/kong/` ):\
   `plugins = bundled,open-appsec-waf-kong-plugin`\
   \
   Option 3 — Run this command to activate the plugin using an env variable:\
   (This also loads the included bundled plugins, you can remove `bundled`, if you are not using those.)\
   `export KONG_PLUGINS="bundled,open-appsec-waf-kong-plugin"`\
   \
   Make sure to restart Kong to apply the changes: `kong restart`  also make sure to actually enable the plugin, see following step:
5. **Enable the plugin in the Kong Gateway**, here are examples for some **alternative** options:\
   *Note all examples below are for **globally** enabling the attachment so that the open-appsec agent can inspect all traffic, you can also enable it more specifically per consumer, per route or per service, follow the Kong documentation for further details how to configure this.*\
   \
   Option 1 — *If you use Kong Konnect for central management of Kong:*\
   After you activated the attachment plugin in Kong Konnect, leave Service, Route and Consumer fields empty to enable it globally.\
   \
   Option 2 — To globally enable the attachment plugin when using Kong with database:

```bash
curl -i -X POST http://localhost:8001/plugins --data "name=open-appsec-waf-kong-plugin"
```

&#x20;      Option 3 — To globally enable the attachment plugin when using Kong in DB-less mode:\
&#x20;         Load the plugin by specifying it in your `kong.yml`  file:

```yaml
plugins:
  - name: open-appsec-waf-kong-plugin
```

6. **Reload Kong configuration** to make sure all changes are applied:

```bash
kong reload
```

{% endtab %}
{% endtabs %}

<figure><img src="/files/CkQk1ol7wwnbhLzZV2XE" alt=""><figcaption><p>Example screenshot open-appsec installer (latest installer version will look different)</p></figcaption></figure>

{% hint style="info" %}
The steps shown below for "Mode 2" (manual installation) are the exact steps which are also performed when running the automatic installation described here as "Mode 1".
{% endhint %}

As part of the installation, a default configuration file for declarative, local management of open-appsec will be created in the following path:

```bash
/etc/cp/conf/local_policy.yaml
```

{% hint style="info" %}
This default local configuration file created by the open-appsec installer uses configuration file schema version [v1beta1](/getting-started/start-with-linux/local-policy-file-advanced). You can also replace it with a newer version of the configuration file schema, e.g. to use [v1beta2](/getting-started/start-with-linux/local-policy-file-v1beta2-beta).
{% endhint %}

#### Optional open-appsec installer parameters

* `--token` allows connecting directly to SaaS management, to get the token please follow the instructions [here](/getting-started/using-the-web-ui-saas/create-a-profile).
* `--prevent` will set the default rule in the default policy file to `prevent-learn` instead of `detect-learn`, but the recommendation is to keep `detect-learn` as the default rule.&#x20;
* `--kong-plugin`  ONLY use this when deploying open-appsec with the Lua-based open-appsec attachment, this will skip the automatic installation of the traditional attachment, which is not required in this case.&#x20;

### **Mode 2: Download of software components and presenting manual installation instructions**

In this mode all required components based on your NGINX, Kong or APISIX version, OS version, Platform will be downloaded to your machine and instructions are presented for manual installation.

```
./open-appsec-install --download
```

Optionally you can add a `--tmpdir <path>` option to specify an alternative path for the downloaded software components (default path is /tmp/openappsec/ )

<figure><img src="/files/I6CmSFCg9SJAN6AaHYdH" alt=""><figcaption></figcaption></figure>

Once the download has finished, follow these steps for manual installation:

#### **Step 1:** Deploying the attachment on an existing alpine NGINX/Kong server

{% tabs %}
{% tab title="NGINX" %}

* Copy the associated libraries **as shown in the output** of the script&#x20;
* Copy the nginx attachment file **as shown in the output** for Step 1
* Load the attachment on your NGINX by adding the following line to your `nginx.conf`
  {% endtab %}

{% tab title="Kong Gateway" %}
{% hint style="info" %}
Please note that the traditional Kong is built on top of OpenResty, which again is based on NGINX. The open-appsec attachment is technically integrating in the OpenResty-layer of a Kong installation as a module (very similar to the NGINX integration).

The new Kong Plugin for integrating with open-appsec is based on Lua and integrating natively with Kong.
{% endhint %}

* Deploy the attachment by following the commands in the script's output.
  {% endtab %}

{% tab title="APISIX" %}
{% hint style="info" %}
Please note that APISIX is built on top of OpenResty, which again is based on NGINX. The open-appsec attachment is technically integrating in the OpenResty-layer of a APISIX installation as a module (very similar to the NGINX integration).
{% endhint %}

* Deploy the attachment by following the commands in the script's output
  {% endtab %}
  {% endtabs %}

#### Step 2: Installing open-appsec agent

* Run the following commands:

```
/tmp/open-appsec/openappsec/install-cp-nano-agent.sh --install --hybrid_mode
/tmp/open-appsec/openappsec/install-cp-nano-service-http-transaction-handler.sh --install
/tmp/open-appsec/openappsec/install-cp-nano-attachment-registration-manager.sh --install
```

#### Step 3 Validate configuration

{% tabs %}
{% tab title="NGINX" %}

* Run the following command to validate the nginx configuration:

```
nginx -t
```

You should see an output confirming that the syntax is "ok" similar to this:\
`nginx: the configuration file /etc/nginx/nginx.conf syntax is ok`

`nginx: configuration file /etc/nginx/nginx.conf test is successful`

* Restart the NGINX service so that the updated nginx configuration is applied and the open-appsec attachment module is loaded:&#x20;

```
service nginx restart
```

{% endtab %}

{% tab title="Kong (traditional plugin)" %}

* Run the following command to validate the OpenResty configuration:

```
/usr/local/openresty/nginx/sbin/nginx -t
```

You should see an output confirming that the syntax is "ok" similar to this:\
`nginx: the configuration file /usr/local/openresty/nginx/conf/nginx.conf syntax is ok`

`nginx: configuration file /usr/local/openresty/nginx/conf/nginx.conf test is successful`

Restart the Kong service so that the updated OpenResty configuration in OpenResty's nginx.conf is applied and the open-appsec attachment module is loaded:&#x20;

```
kong restart
```

{% endtab %}

{% tab title="APISIX" %}

* Run the following command to validate the OpenResty configuration:

```
/usr/local/openresty/nginx/sbin/nginx -t
```

You should see an output confirming that the syntax is "ok" similar to this:\
`nginx: the configuration file /usr/local/openresty/nginx/conf/nginx.conf syntax is ok`

`nginx: configuration file /usr/local/openresty/nginx/conf/nginx.conf test is successful`

Restart the APISIX service so that the updated OpenResty configuration in OpenResty's nginx.conf is applied and the open-appsec attachment module is loaded:&#x20;

```
apisix restart
```

{% endtab %}

{% tab title="Kong Lua plugin (beta)" %}

* Run the following command to validate the Kong Gateway configuration:\
  \
  \- When using Kong with database:\
  `kong check` \
  \
  \- When using Kong in DB-less mode:\
  `kong check /path/to/kong.conf`\
  `kong config parse /path/to/kong.yml`
  {% endtab %}
  {% endtabs %}

### Congratulations, you successfully installed and activated open-appsec integrated with your existing NGINX, Kong or APISIX installation.

{% hint style="info" %}
For Production usage you might want to switch from using the Basic to the more accurate Advanced Machine Learning model, as described here:&#x20;

[Using the Advanced Machine Learning Model](/getting-started/using-the-advanced-machine-learning-model)
{% endhint %}

Now you might want to have a look at our interactive CLI tool:

{% content-ref url="/pages/AirlOPWdonj6luaItR6H" %}
[Using the open-appsec-ctl Tool](/getting-started/start-with-linux/using-the-open-appsec-ctl-tool)
{% endcontent-ref %}


# Using the open-appsec-ctl Tool

The interactive CLI tool `open-appsec-ctl` allows you to perform various tasks related to your open-appsec for NGINX/Kong/APISIX installation.\
\
The tool will be automatically installed with the agent and can be used as follows:

#### List all available policies:

`open-appsec-ctl --list-policies`

`open-appsec-ctl -lp`

<figure><img src="/files/QJadi4EtjZ5pdrXcLItY" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Currently only a single configuration file is supported, support for multiple configuration files will be added soon.&#x20;

By default the following policy file is used when no \[policy-file] is explicitly specified in the commands listed below: \
`/etc/cp/conf/local_policy.yaml`
{% endhint %}

#### View policy:

`open-appsec-ctl --view-policy [policy-file]`

`open-appsec-ctl -vp [policy-file]`

This will show either the policy file at the default location which is automatically created during installation or the specified policy file `[policy-file]`

#### Edit policy

`open-appsec-ctl --edit-policy [policy-file]`

`open-appsec-ctl -ep [policy-file]`\
\
Edit the policy file at the default location which is automatically created during installation or the specified policy file `[policy-file]`

Here you can find all details regarding the structure of the Local Policy File:&#x20;

[Configuration Using Local Policy File (Linux)](/getting-started/start-with-linux/configuration-using-local-policy-file-linux)

#### Apply policy

`open-appsec-ctl --apply-policy [policy-file]`

`open-appsec-ctl -ap [policy-file]`

Apply the policy file at the default location which is automatically created during installation or the specified policy file `[policy-file]`

#### Show agent status

`open-appsec-ctl --status [--extended]`

`open-appsec-ctl -s [--extended]`

Shows the agent status and versions, you can get extended output by also adding the flag\
`--extended`

#### View logs

`open-appsec-ctl --view-logs`

`open-appsec-ctl -vl`

Show the open-appsec logs

#### Start/Stop the agent

`open-appsec-ctl --start-agent`

`open-appsec-ctl -r`

Starts the agent

`open-appsec-ctl --stop-agent`

`open-appsec-ctl -q`

Stops the agent

#### Uninstall the agent

`open-appsec-ctl --uninstall`

`open-appsec-ctl -u`

Uninstalls the agent

### For debugging purposes only

#### Start/stop individual agent services

Start the selected service

`open-appsec-ctl --start-service <orchestration|attachment-registrator|http-transaction-handler>`

`open-appsec-ctl -rs <orchestration|attachment-registrator|http-transaction-handler>`

Stop the selected service

`open-appsec-ctl --stop-service <orchestration|attachment-registrator|http-transaction-handler>`

`open-appsec-ctl -qs <orchestration|attachment-registrator|http-transaction-handler>`

#### View and change debug information

`open-appsec-ctl -d`

Can be used for viewing and changing the debug configuration.\
This command will present you with all available options when run without any additional parameters.


# Configuration Using Local Policy File (Linux)

When using open-appsec for NGINX, Kong or APISIX on Linux the configuration can be done in a declarative way using a single YAML file which holds all the relevant configuration objects. \
This way it is compatible with integration in GitOps CD-based processes.

Alternatively management can also soon be done centrally via the open-appsec WebUI (SaaS): [Using the Web UI (SaaS)](/getting-started/using-the-web-ui-saas)

### Location of the declarative configuration file

The default location of the declarative configuration file is here:

`/etc/cp/conf/local_policy.yaml`

You find syntax and schema of the declarative configuration file explained here:\
[Local Policy File (Advanced)](/getting-started/start-with-docker/local-policy-file-advanced)

You can show and edit the full default declarative configuration file with the following command:

`vi /etc/cp/conf/local_policy.yaml`&#x20;

or by using the interactive CLI tool `open-appsec-ctl` : [Using the open-appsec-ctl Tool](/getting-started/start-with-linux/using-the-open-appsec-ctl-tool)

### Basic configuration

The default policy within the default configuration file, which is created during the installation, contains the following setting which sets the mode to `detect-learn` for all web resources provided by the NGINX or Kong Gateway:

`policies.default.mode: detect-learn`

If you want attacks instead to be prevented by default for all web resources you can change this as follows:

`policies.default.mode: prevent-learn`

The specific rules section `policies.specific-rules` (v1beta1) / `policies.specificRules` (v1beta2) allows you to create specific rule entries for specific hostnames, hostname-path combinations or paths which override the default policy.

{% hint style="danger" %}
The mode settings defined in the policy for default or specific rules will only have an effect on the actual enforcement for specific security features when the `override-mode` setting in the referenced practice is set to `as-top-level` as this will cause it to inherited the mode setting from the policy.
{% endhint %}

**It is recommended to configure a specific rule for each of your protected web applications and web APIs assets** (starting with `detect-learn` mode, later move to `prevent-learn`).\
\
This allows you to apply a separate enforcement mode setting for each of these protected assets as well as to customize many other settings like selecting the logging configuration, the threat prevention and access control (introduced in v1beta2) practices configuration or selecting a custom-response like a specific response code or a custom block page.

Also the real-time contextual machine learning will be done individually per each configured specific rule representing a protected asset.\
\
Note that the actual configuration settings are all configured by referencing other elements which are defined separately in the configuration file as well, so that you can reuse them multiple times in a kind of object-oriented way, see examples below:

{% tabs %}
{% tab title="v1beta1" %}

```yaml
policies:
  default:
  ...
  ...
  specific-rules:
  - host: "www.my-specific-host.com/my-specific-path"
    triggers:
    - appsec-default-log-trigger
    mode: detect-learn
    practices:
    - webapp-default-practice
    custom-response: appsec-default-web-user-response
```

It is recommended that once sufficient confidence was gained in `detect-learn` mode for an asset which has a specific rule (review the logs) to change the mode for this specific rule to `prevent-learn` mode:

```yaml
policies:
  default:
  ...
  ...
  specific-rules:
  - host: "www.my-specific-host.com/my-specific-path"
    triggers:
    - appsec-default-log-trigger
    mode: prevent-learn
    practices:
    - webapp-default-practice
    custom-response: appsec-default-web-user-response
```

{% endtab %}

{% tab title="v1beta2" %}

```yaml
policies:
  default:
  ...
  ...
  specificRules:
  - host: "www.my-specific-host.com/my-specific-path"
    triggers:
    - appsec-default-log-trigger
    mode: detect-learn
    threatPreventionPractices:
    - webapp-default-practice
    accessControlPractices:
    - webapp-default-practice
    customResponse: appsec-default-web-user-response
```

It is recommended that once sufficient confidence was gained in `detect-learn` mode for an asset which has a specific rule (review the logs) to change the mode for this specific rule to `prevent-learn` mode:

```yaml
policies:
  default:
  ...
  ...
  specificRules:
  - host: "www.my-specific-host.com/my-specific-path"
    triggers:
    - appsec-default-log-trigger
    mode: prevent-learn
    threatPreventionPractices:
    - webapp-default-practice
    accessControlPractices:
    - webapp-default-practice
    customResponse: appsec-default-web-user-response
```

{% endtab %}
{% endtabs %}

### Applying a changed local declarative configuration file&#x20;

Once you did any changes to the local declarative configuration file `local_policy.yaml` in order to become active you must apply the new policy:

Use the open-appsec-ctl tool to apply the changes in the policy as follows:

```
open-appsec-ctl --apply-policy
```

### Configuring the local declarative configuration file

On the next page you find the full description for the different configuration sections and elements that can be part of the declarative configuration file:

{% content-ref url="/pages/KokD6qvwxDg2XFok6k8D" %}
[Local Policy File (Advanced)](/getting-started/start-with-linux/local-policy-file-advanced)
{% endcontent-ref %}


# Local Policy File (Advanced)

{% hint style="warning" %}
The local configuration schema explained below is based on the schema version v1beta1. The latest available, significantly enhanced local configuration schema version is v1beta2,\
documentation for v1beta2 is available here: [Local Policy File v1beta2 (beta)](/getting-started/start-with-linux/local-policy-file-v1beta2-beta)
{% endhint %}

Here you find the full specification for the different configuration sections and elements that can be part of the declarative configuration file including an example for each:

### Policies

The policies section defines the default behaviors that will apply to all web resources exposed by the NGINX server, Kong Gateway or APISIX Gateway as well as specific rules for overriding the default behaviour for specific hostname/path combinations.&#x20;

<details>

<summary> Example</summary>

```yaml
policies:
  default:
    triggers:
    - appsec-special-log-trigger
    mode: detect-learn
    practices:
    - webapp-default-practice
    source-identifiers: appsec-source-identifiers-sourceip-example
    trusted-sources: appsec-trusted-source-example
    custom-response: appsec-web-user-response-example
    exceptions:
    - appsec-exception-example
  specific-rules:
  - host: web.server.com/example
    triggers:
    - appsec-special-log-trigger
    mode: prevent-learn
    practices:
    - webapp-best-practice
    source-identifiers: appsec-source-identifiers-sourceip-example
    trusted-sources: appsec-trusted-source-example
    custom-response: appsec-web-user-response-example
    exceptions:
    - appsec-exception-example
  - host: web.server.com/another-example
    triggers:
    - appsec-special-log-trigger
    mode: prevent-learn
    practices:
    - webapp-best-practice
    source-identifiers: appsec-source-identifiers-sourceip-example
    trusted-sources: appsec-trusted-source-example
    custom-response: appsec-web-user-response-example
    exceptions:
    - appsec-exception-example
```

</details>

<details>

<summary>Specification</summary>

**default**

* **mode** *string enum* - security engines operation mode. Blocking will only happen in prevent-learn mode
  * prevent-learn / detect-learn / prevent / detect / inactive\
    (note that prevent and detect are just aliases for prevent-learn and detect-learn)
* **practices** *array of strings* - defines which security engines to activate and their specific settings (Although this is an array already there cannot be multiple practices of the same kind specified here for now!)
  * reference to Practice resource(s)
* **triggers** *array of strings* - defines logging verbosity and destination (stdout, syslog, cloud, etc) (Although this is an array for now only a single trigger is supported!)
  * reference to LogTrigger resource(s)
* **custom-response** *string* - defines prevent mode behaviors upon decision to block: HTTP response code, block page, http redirect
  * reference to CustomResponse resource
* **source-identifiers** *string* - defines how ML engine will  distinguish between sources based on IP address, X-Foward-For, Key in Header/Cookie/JWT
  * reference to SourcesIdentifier resource
* **trusted-sources** *string -* defines which traffic sources are very unlikely to be malicious. Used for Machine Learning engine.
* **exceptions** *arrays of strings* - defines exceptions to be applied based on e.g. countryCode, countryName, sourceIP, URL, hostName, sourceIdentifier
  * reference to Exception resource(s)

**specific-rules** list\
list of one or more per-host (ingress rule) policies that will override the defaults above

* **host** *string -* policy will apply to this host
  * network path (exactly as appear in ingress rules)
* *All other keys can be used same as decribed above for default.*

</details>

### Practices

Practice resources define which security engines will be active and what their settings are.

<details>

<summary>Example </summary>

```yaml
practices:
  - name: webapp-best-practice
    openapi-schema-validation:
      files: []
      override-mode: 'prevent'
    snort-signatures:
      files: []
      override-mode: 'prevent'
    web-attacks:
      max-body-size-kb: 1222
      max-header-size-bytes: 44343
      max-object-depth: 2111
      max-url-size-bytes: 34434
      minimum-confidence: high
      override-mode: 'prevent'
      protections:
        csrf-enabled: prevent
        error-disclosure-enabled: prevent
        non-valid-http-methods: true
        open-redirect-enabled: prevent
    anti-bot:
      injected-URIs: []
      validated-URIs: []
      override-mode: 'prevent'
```

</details>

<details>

<summary>Specification</summary>

* **web-attacks - open-appsec ML engine settings**
  * **override-mode** *string enum* - allows overriding the mode defined at the Policy level for this specific engine (when set to as-top-level the value will be inherited from mode setting in the policy)
    * prevent-learn / detect-learn / prevent / detect / inactive / as-top-level
  * **minimum-confidence** *string* *enum, default: high* - defines which security engines to activate and their specific settings
    * medium / high / critical
  * **max-url-size-bytes** *integer,* default: 32768
  * **max-object-depth** *integer,* default: 40
  * **max-body-size-kb** *integer,* default: 102400
  * **max-header-size-bytes** *integer,* default: 32768
  * **protections** *- settings for various advanced protections:*
    * **csrf-enabled** *string, default: inactive -* Cross Site Request Forgery protection
      * prevent-learn / detect-learn / prevent / detect / inactive
    * **error-disclosure-enabled** *string, default: inactive -* Prevent disclosure of technical information to the attacker in server error messages
      * prevent-learn / detect-learn / prevent / detect / inactive
    * **open-redirect-enabled** *string, default: inactive* - Protect against URL redirection to untrusted sites
      * prevent-learn / detect-learn / prevent / detect / inactive
    * **non-valid-http-methods** *boolean, default: false* - Prevent attacker from sending requests with unsafe HTTP methods
      * true / false
* **open-api-schema-validation (currently not supported yet, will be added soon)**
  * **configmap** *array of strings* - specify configmap(s) containing the OpenAPI schema definitions
  * **override-mode** *enum* - allows overriding the mode defined at the Policy level for this specific engine (when set to as-top-level the value will be inherited from mode setting in the policy)
    * prevent-learn / detect-learn / prevent / detect / inactive / as-top-level
* **anti-bot (currently not supported yet, will be added soon)**
  * **override-mode** *enum* - allows overriding the mode defined at the Policy level for this specific engine (when set to as-top-level the value will be inherited from mode setting in the policy)&#x20;
    * prevent-learn / detect-learn / prevent / detect / inactive / as-top-level
  * **injected-URIs** *array of strings* - Provide URL(s) where Anti-Bot check is injected with GET request
  * **validated-URIs** *array of strings -* Provide URL(s) where result of Anti-Bot check is received from with POST request
* **snort-signatures (currently not supported yet, will be added soon)**
  * **override-mode** *enum* - allows overriding the mode defined at the Policy level for this specific engine (when set to as-top-level the value will be inherited from mode setting in the policy)
    * prevent-learn / detect-learn / prevent / detect / inactive / as-top-level
  * **configmap** *array of strings* - specify configmap(s) containing snort signatures

</details>

### Custom Response

Optional custom responses can be configured to return in prevent mode either a customizable block page or the desired response code only. The custom responses than can be referenced within one or more policy elements.&#x20;

<details>

<summary>Examples </summary>

```yaml
custom-responses:
  - name: appsec-default-web-user-response
    mode: response-code-only
    http-response-code: 403
  - name: appsec-web-user-response-example
    mode: block-page
    http-response-code: 403
    message-title: Block page title
    message-body: "<h1>Access blocked by open-appsec.</h1><p>Your access will be logged.</p>"
```

</details>

<details>

<summary>Specification</summary>

* **mode** *enum -* engine will take one of these actions upon decision to block request
  * block-page - send HTML with text to client + HTTP response code
  * response-code-only - send only response code
* **message-title** *string* - title of block page that will be displayed only in case mode is block page and engine decided to block
* **message-body** *string* - content of block page that will be displayed only in case mode is block page and engine decided to block
* **http-response-code** *integer between 100-599* - http code that will be returned to client upon engine decision to block; default is 403 - HTTP Forbidden

</details>

### Log Trigger

Optional log trigger elements can be used to configure custom logging requirements. They can then be referenced within one or more policy elements.

<details>

<summary>Example </summary>

```yaml
logtriggers:
  - name: appsec-special-log-trigger
    access-control-logging:
      allow-events: false
      drop-events: true
    additional-suspicious-events-logging:
      enabled: true
      minimum-severity: high
      response-body: false
    appsec-logging:
      all-web-requests: false
      detect-events: true
      prevent-events: true
    extended-logging:
      http-headers: false
      request-body: false
      url-path: false
      url-query: false
    log-destination:
      cloud: false
      file: "/a/b/c"
      stdout:
        format: json
      syslog-service:
      - address: 1.2.3.4
        port: 514
      cef-service:
        address: 5.6.7.8
        port: 514
        proto: tcp

```

</details>

<details>

<summary>Specification</summary>

* **access-control-logging** - configure logging for Access Control events
  * **allow-events** *boolean, default: false* - log access control allow eve*nts*
    * true / false
  * **drop-events** *boolean, default: true* - log access control drop event*s*
    * true / false
* **additional-suspicious-events-logging** configure additional logging for suspicious events based on a selectable minimum severity-level
  * **enabled** *boolean default: true* - enable/disable additional suspicious events logging
    * true / false
  * **minimum-severity** *string enum, default: high* - select minimum severity level
    * high / critical
* **appsec-logging** configure logging for open-appsec events (threat prevention, machine learning)
  * **detect-events** *boolean, default: true* - log detected events
    * true / false
  * **prevent-events** *boolean, default: true* - log prevented events
    * true / false
  * **all-web-requests** *boolean, default: false* - log all web requests (has performance impact!)
    * true / false
  * **extended-logging**
    * **url-path** *boolean, default: true* - log URL path
      * true / false
    * **url-query** *boolean, default: true* - log URL query
      * true / false
    * **http-headers** *boolean, default: false* - log the HTTP headers (has performance impact!)
      * true / false
    * **request-body** *boolean, default: false* - log the request body (has performance impact)
      * true / false
* **log-destination**
  * **cloud** *boolean, default: false* - enable or disable logging to the appsec-open Cloud Service (relevant when being connected to SaaS Mgmt WebUI)
    * true / false
  * **file** *string* - define file path to save logs to (local path from root directory of the open-appsec container, could also refer to a mountPath for a mounted Persistent Volume in the container)
  * **stdout** - configure logging to standard-out
    * **format** *string enum* - define the desired log format
      * json / json-formatted - select between formatted or standard json
  * **syslog-service** *objects array* - define one or more syslog servers and corresponding ports to send logs to
    * **address** *string* - Syslog server IP address
    * **port** *integer* - Syslog server port
  * **cef-service** - allows sending files to a log destination in CEF format
    * **address** *string -* CEF server IP address
    * **port** *integer -* CEF server port
    * **proto** *string enum* Select the correct protocol
      * tcp / udp - Chose TCP or UDP protocol

</details>

### Exceptions

Optional exception elements can be used to configure custom exceptions. They can then be referenced within one or more policy elements.

<details>

<summary>Example </summary>

```yaml
exceptions:
  - name: appsec-exception-example
    action: skip
    comment: This is an example exception comment
    countryCode:
    - CA
    - IL
    countryName:
    - Israel
    - Canada
    hostName:
    - fff
    paramName:
    - key
    paramValue:
    - rrr
    protectionName:
    - cveee
    sourceIdentifier:
    - david
    sourceIp:
    - 1.2.3.4
    - '3,3,3,3'
    url:
    - "/rrr"
  - name: exception-example-2
    action: accept
    hostName:
    - fff
    url:
    - "/rrr"
  - name: exception-example-3
    action: drop
    comment: This is an example exception comment
    countryName:
    - Israel
    - Canada
    protectionName:
    - cveee
    sourceIdentifier:
    - david
    sourceIp:
    - 1.2.3.4
    - 2.3.4.5
    url:
    - "/rrr"
  - name: exception-example-4
    action: suppressLog
    comment: This is an example exception comment
    countryCode:
    - CA
    - IL
    countryName:
    - Israel
    - Canada
    hostName:
    - fff
    url:
    - "/rrr"
```

</details>

<details>

<summary>Specification</summary>

Define a list of actions-objects with the corresponding parameters to match to configure flexible custom exceptions/rules, each having the following configurable keys:

* **action** *string enum* - Action to be performed when exception matches
  * skip / accept / drop / suppressLog
* **sourceIp** *string array* - Source IP(s)&#x20;
* **url** *string array* - URL(s)
* **sourceIdentifier** *string array* - Identified source(s)
* **protectionName** *string arr*ay - Protection(s)
* **paramValue** *string array* - Parameter value(s)
* **paramName** s*tring array* - Parameter name(s)
* **hostName** *string array* - Host name(s)
* **countryCode** *string array* - Country code(s)
* **countryName** *string array* - Country name(s)
* **comment** st*ring* - Comment for the exception

</details>

### Trusted Sources

Optional trusted sources can be defined, for which the machine learning engine will assume, that the traffic originating from them is benign and learn accordingly.

Trusted sources elements can then be referenced within the policies section.

<details>

<summary>Example </summary>

```yaml
trustedsources:
  - name: appsec-trusted-source-example
    minNumOfSources: 3
    sourcesIdentifiers: [0.0.0.0, 1.1.1.1, 2.2.2.2]
```

</details>

<details>

<summary>Specification</summary>

Define trusted sources by referencing the source identifiers custom resources as well as setting the minimum amount of sources that need to be observed by the behavioural ML engine sending certain identical traffic patterns in order to learn this behaviour as being benign.

* **minNumOfSources** *integer* - Minimum amount of sources having to be observed sending same traffic patterns to learn behaviour as benign.
* **sourcesIdentifiers** *string array* - Specify one or more source identifiers

</details>

### Source Identifiers

Source Identifiers can be used to define how open-appsec distinguishes between different sources, e.g. based on source IP addresses, x-forwarded-for header content, etc.&#x20;

<details>

<summary>Examples </summary>

```yaml
source-identifiers:
  - name: appsec-source-identifiers-sourceip-example
    identifiers:
    - sourceIdentifier: sourceip
```

</details>

<details>

<summary>Specification</summary>

Define list of one or more specific source identifiers that can be used in trusted sources custom resources.

* **identifiers** objects array - provide single **source identifier**\
  **Note:** Although this is an array currently only adding single source identifier here is supported.\
  (Later an option is planned to be added to provide multiple source-identifiers here, so that if the first one is not found in an http request then the next one would be checked.)
* **source-identifier** *string enum* - Specify the source identifier type of which the content shall be matched
  * headerkey, JWTKey, cookie, sourceip, x-forwarded-for
* **value** *string array* - Content to match the specified sourceIdentifier type
  * For types headerkey, cookie and JWTKey provide the fieldname that designates user&#x20;
  * For type Source IP no value is required
  * For type x-forwarded-for provide previous proxy hops if there are any

</details>

## Schema file

Here you find the full schema file for the local declarative configuration yaml file.\
This also shows you which fields are required and which are optional

<details>

<summary>Schema file for local policy file</summary>

```yaml
type: object
properties:
  policies:
    type: object
    properties:
      default:
        type: object
        properties:
          custom-response:
            type: string
          exceptions:
            items:
              type: string
            type: array
          mode:
            enum:
              - prevent-learn
              - detect-learn
              - prevent
              - detect
              - inactive
            type: string
          practices:
            items:
              type: string
            type: array
          source-identifiers:
            type: string
          triggers:
            items:
              type: string
            type: array
          trusted-sources:
            type: string
        required:
          - mode
          - practices
          - triggers
      specific-rules:
        type: array
        items:
          properties:
            host:
              type: string
            custom-response:
              type: string
            exceptions:
              items:
                type: string
              type: array
            mode:
              enum:
                - prevent-learn
                - detect-learn
                - prevent
                - detect
                - inactive
              type: string
            practices:
              items:
                type: string
              type: array
            source-identifiers:
              type: string
            triggers:
              items:
                type: string
              type: array
            trusted-sources:
              type: string
          required:
            - mode
            - host
            - practices
            - triggers
          type: object
  practices:
    type: array
    items:
      properties:
        name:
          type: string
        anti-bot:
          properties:
            injected-URIs:
              items:
                properties:
                  uri:
                    type: string
                type: object
              type: array
            override-mode:
              enum:
                - prevent-learn
                - detect-learn
                - prevent
                - detect
                - inactive
                - as-top-level
              type: string
              default: "inactive"
            validated-URIs:
              items:
                properties:
                  uri:
                    type: string
                type: object
              type: array
          type: object
        openapi-schema-validation:
          properties:
            files:
              items:
                type: string
              type: array
            override-mode:
              enum:
                - prevent-learn
                - detect-learn
                - prevent
                - detect
                - inactive
                - as-top-level
              type: string
          type: object
        snort-signatures:
          properties:
            files:
              items:
                type: string
              type: array
            override-mode:
              enum:
                - prevent-learn
                - detect-learn
                - prevent
                - detect
                - inactive
                - as-top-level
              type: string
          type: object
        web-attacks:
          properties:
            max-body-size-kb:
              type: integer
            max-header-size-bytes:
              type: integer
            max-object-depth:
              type: integer
            max-url-size-bytes:
              type: integer
            minimum-confidence:
              enum:
                - medium
                - high
                - critical
              type: string
            override-mode:
              enum:
                - prevent-learn
                - detect-learn
                - prevent
                - detect
                - inactive
                - as-top-level
              type: string
            protections:
              properties:
                csrf-enabled:
                  enum:
                    - prevent-learn
                    - detect-learn
                    - prevent
                    - detect
                    - inactive
                  type: string
                error-disclosure-enabled:
                  enum:
                    - prevent-learn
                    - detect-learn
                    - prevent
                    - detect
                    - inactive
                  type: string
                non-valid-http-methods:
                  type: boolean
                open-redirect-enabled:
                  enum:
                    - prevent-learn
                    - detect-learn
                    - prevent
                    - detect
                    - inactive
                  type: string
              type: object
          type: object
      required:
        - name
  custom-responses:
    type: array
    minItems: 0
    items:
      type: object
      properties:
        name:
          type: string
        http-response-code:
          maximum: 599
          minimum: 100
          default: 403
          type: integer
        message-body:
          type: string
          default: "Attack blocked by web application protection"
        message-title:
          type: string
          default: "Openappsec's <b>Application Security</b> has detected an attack and blocked it."
        mode:
          enum:
            - block-page
            - response-code-only
          type: string
      required:
        - name
  log-triggers:
    type: array
    minItems: 0
    items:
      type: object
      properties:
        name:
          type: string
        access-control-logging:
          properties:
            allow-events:
              type: boolean
              default: false
            drop-events:
              type: boolean
              default: false
          type: object
        additional-suspicious-events-logging:
          properties:
            enabled:
              type: boolean
              default true:
            minimum-severity:
              enum:
                - high
                - critical
              type: string
              default: "high"
            response-body:
              type: boolean
              default: false
            response-code:
              type: boolean
              default: true
          type: object
        appsec-logging:
          properties:
            all-web-requests:
              type: boolean
              default: false
            detect-events:
              type: boolean
              default: false
            prevent-events:
              type: boolean
              default: true
          type: object
        extended-logging:
          properties:
            http-headers:
              type: boolean
              default: false
            request-body:
              type: boolean
              default: false
            url-path:
              type: boolean
              default: false
            url-query:
              type: boolean
              default: false
          type: object
        log-destination:
          properties:
            cef-service:
              minItems: 0
              items:
                properties:
                  address:
                    type: string
                  port:
                    type: integer
                  proto:
                    enum:
                      - tcp
                      - udp
                    type: string
                type: object
              type: array
            cloud:
              type: boolean
              default: false
            stdout:
              properties:
                format:
                  enum:
                    - json
                    - json-formatted
                  type: string
                  default: json
              type: object
            syslog-service:
              minItems: 0
              items:
                properties:
                  address:
                    type: string
                  port:
                    type: integer
                type: object
              type: array
          type: object
      required:
        - name
  exceptions:
    type: array
    minItems: 0
    items:
      type: object
      properties:
        name:
          type: string
        action:
          enum:
            - skip
            - accept
            - drop
            - suppressLog
          type: string
        comment:
          type: string
        countryCode:
          items:
            type: string
          type: array
        countryName:
          items:
            type: string
          type: array
        hostName:
          items:
            type: string
          type: array
        paramName:
          items:
            type: string
          type: array
        paramValue:
          items:
            type: string
          type: array
        protectionName:
          items:
            type: string
          type: array
        sourceIdentifier:
          items:
            type: string
          type: array
        sourceIp:
          items:
            type: string
          type: array
        url:
          items:
            type: string
          type: array
      required:
        - name
        - action
  trusted-sources:
    type: array
    minItems: 0
    items:
      type: object
      properties:
        name:
          type: string
        minNumOfSources:
          type: integer
          minimum: 1
          default: 3
        sources-identifiers:
          items:
            type: string
          type: array
      required:
        - name
        - sources-identifiers
  source-identifiers:
    type: array
    minItems: 0
    items:
      type: object
      properties:
        name:
          type: string
        identifiers:
          type: array
          minItems: 1
          items:
            type: object
            source-identifier:
              enum:
                - headerkey
                - JWTKey
                - cookie
                - sourceip
                - x-forwarded-for
              type: string
            value:
              items:
                type: string
              type: array
          required:
            - source-identifier
      required:
        - name
        - identifiers
additionalProperties: false
```

</details>


# Local Policy File v1beta2 (beta)

{% hint style="warning" %}
**Beta Feature Notice**\
This feature is currently in beta and may undergo changes based on user feedback and testing. please note that some functionality may be subject to updates or improvements in future releases.

We encourage you to explore this feature and share your feedback to help us enhance it. If you encounter any issues or have suggestions, please contact us at <info@openappsec.io>
{% endhint %}

{% hint style="info" %}
In order to use the v1beta2 CRDs simply replace the existing configuration file on your agent&#x20;

* For Linux deployments use

```bash
open-appsec-ctl --edit-policy
```

* For Docker Deployment replace the mounted local configuration file&#x20;

\
Make sure to apply policy once done.&#x20;

```bash
open-appsec-ctl --apply-policy
```

Example configurations can be found [here](https://github.com/openappsec/openappsec/tree/main/config/linux/v1beta2).&#x20;
{% endhint %}

## Local Policy Configuration&#x20;

You can download all the configuration segments examples shown below in a single file here:

```bash
wget https://raw.githubusercontent.com/openappsec/openappsec/main/config/linux/v1beta2/example/local_policy.yaml
```

{% embed url="<https://raw.githubusercontent.com/openappsec/openappsec/main/config/linux/v1beta2/example/local_policy.yaml>" %}

{% hint style="warning" %}
When creating your own local configuration file based on the v1beta2 configuration schema:\
\
Make sure to add `apiVersion: v1beta2` at the top of the file to specify using v1beta2 of our local configuration.&#x20;
{% endhint %}

### Policies

The policies section defines the default behaviors that will apply to all web resources exposed as well as specific rules for overriding the default behavior for specific hostname/path combinations.&#x20;

<details>

<summary> Example</summary>

```yaml
policies:
  default:
    mode: detect-learn
    accessControlPractices: [access-control-practice-example]
    threatPreventionPractices: [threat-prevention-practice-example]
    triggers: [log-trigger-example]
    customResponse: web-user-response-example
    sourceIdentifiers: ""
    trustedSources: ""
    exceptions:
      - exception-example
  specificRules:
    - host: "example.com"
      mode: prevent-learn
      threatPreventionPractices: [threat-prevention-practice-example]
      accessControlPractices: [access-control-practice-example]
      triggers: [log-trigger-example]
      customResponse: web-user-response-example
      sourceIdentifiers: ""
      trustedSources: ""
      exceptions:
        - exception-example
```

</details>

<details>

<summary>Specification</summary>

* **default** (`object,` required): The default configuration for the policy. This field is required.
  * **mode** (`string`, required): Specifies the mode of the entire policy.
    * Possible values: `prevent-learn`, `detect-learn`, `prevent`, `detect`, `inactive`.
    * Default: `detect-learn`.
  * **threatPreventionPractices** (`array<string>`, required): A list of threat prevention practices.
    * Minimum items: 0.
  * **accessControlPractices** (`array<string>`, required): A list of access control practices.
    * Minimum items: 0.
  * **customResponse** (`string`, optional): Specifies a custom response code.
    * Default: `403`.
  * **triggers** (`array<string>`, required): Specifies additional triggers for the policy.
  * **sourceIdentifiers** (`string`, optional): Specifies source identifiers for the policy.
  * **trustedSources** (`string`, optional): Specifies trusted sources for the policy.
  * **exceptions** (`array<string>`, optional): Specifies exception rules for the policy.
* **specificRules** (`array<object>`, optional): Specifies rules tailored to specific hosts.
  * **host** (`string`, required): Specifies the host for the rule.
  * **mode** (`string`, required): Mode for the specific rule.
    * Possible values: `prevent-learn`, `detect-learn`, `prevent`, `detect`, `inactive`.
    * Default: `detect-learn`.
  * **threatPreventionPractices** (`array<string>`, required): Threat prevention practices for the specific rule.
  * **accessControlPractices** (`array<string>`, required): Access control practices for the specific rule.
  * **triggers** (`array<string>`, required): Triggers for the specific rule.
  * **customResponse** (`string`, optional): Custom response code for the specific rule.
  * **sourceIdentifiers** (`string`, optional): Source identifiers for the specific rule.
  * **trustedSources** (`string`, optional): Trusted sources for the specific rule.
  * **exceptions** (`array<string>`, optional): Exception rules for the specific rule.

</details>

### Threat Prevention Practice <a href="#custom-response" id="custom-response"></a>

Practice resources define which threat prevention security engines will be active and what their settings are.

<details>

<summary>Example </summary>

```yaml
threatPreventionPractices:
  - name: threat-prevention-practice-example
    practiceMode: inherited
    webAttacks:
      overrideMode: inherited
      minimumConfidence: high
    intrusionPrevention:
    # intrusion prevention (IPS) requires "Premium Edition"
      overrideMode: inherited
      maxPerformanceImpact: medium
      minSeverityLevel: medium
      minCveYear: 2016
      highConfidenceEventAction: inherited
      mediumConfidenceEventAction: inherited
      lowConfidenceEventAction: detect
    fileSecurity:
    # file security requires "Premium Edition"
      overrideMode: inherited
      minSeverityLevel: medium
      highConfidenceEventAction: inherited
      mediumConfidenceEventAction: inherited
      lowConfidenceEventAction: detect
    snortSignatures:
      # you must specify snort signatures in configmap or file to activate snort inspection
      overrideMode: inherited
      configmap: []
      # relevant for deployments on kubernetes
      # 0 or 1 configmaps supported in array
      files: []
      # relevant for docker and linux embedded deployments
      # 0 or 1 files supported in array
    schemaValidation: # schema validation requires "Premium Edition" 
      overrideMode: inherited
      configmap: []
      # relevant for deployments on kubernetes
      # 0 or 1 configmaps supported in array
      files: []
      # relevant for docker and linux embedded deployments
      # 0 or 1 files supported in array
    antiBot: # antibot requires "Premium Edition" 
      overrideMode: inherited
      injectedUris: []
      validatedUris: []
```

</details>

<details>

<summary>Specification</summary>

* **name** (`string` ,required) Unique name for the threat prevention practice.
* **practiceMode** (`string` ,optional) Defines the mode of operation for the practice. Possible values: `inherited, prevent-learn, detect-learn, prevent, detect, inactive`
  * Default: `inherited` from mode set in policy.
* **webAttacks** (`object` ,required)
  * **overrideMode** (`string` ,optional) The override mode for web attacks.  Possible values: `prevent-learn, detect-learn, prevent, detect, inactive, inherited`  #inherited from threatPreventionPractice mode set in policy
    * Default: `inherited`&#x20;
  * **minimumConfidence** (`string` ,optional) The minimum confidence level for web attacks. Possible values: `medium, high, critical`
    * Default: `high`
  * **maxUrlSizeBytes** (`integer` ,optional) Maximum URL size in bytes.
    * Default: `32768`
  * **maxObjectDepth** (`integer` ,optional)Maximum object depth.
    * Default: `40`
  * **maxBodySizeKb** (`integer` ,optional) Maximum body size in KB.
    * Default: `1000000`
  * **maxHeaderSizeBytes** (`integer` ,optional) Maximum header size in bytes.
    * Default: `102400`
  * **protections** (`object,` optional)
    * **csrfProtection** (`string` ,optional) CSRF protection mode. Possible values: `prevent-learn, detect-learn, prevent, detect, inactive, inherited` #inherited from overrideMode
      * Default: `inactive`
    * **errorDisclosure** (`string` ,optional) Error disclosure mode. Possible values: `prevent-learn, detect-learn, prevent, detect, inactive, inherited` #inherited from overrideMode
      * Default: `inactive`
    * **openRedirect** (`string` ,optional) Open redirect protection mode. Possible values: `prevent-learn, detect-learn, prevent, detect, inactive, inherited` #inherited from overrideMode
      * Default: `inactive`
    * **nonValidHttpMethods** (`bollean`,optional)
      * Default: `false`&#x20;
* **antiBot** (`object`, optional)
  * **overrideMode** (`string` ,required) Override mode for bot prevention. Possible values: `prevent-learn, detect-learn, prevent, detect, inactive, inherited` #inherited from threatPreventionPractice mode set in policy
    * Default: `inactive`
  * **injectedUris** (`array<string>`, optional) List of injected URIs to be checked for bot prevention.
  * **validatedUris** (`array<string>`, optional) List of validated URIs to be checked for bot prevention.
* **snortSignatures**  (`object`, optional)
  * **overrideMode** (`string` ,required) Override mode for Snort signatures.  Possible values:`prevent-learn, detect-learn, prevent, detect, inactive, inherited`
    * Default: `inherited` inherited from threatPreventionPractice mode set in policy
  * **configmap** (`array<string>` ,optional) List of configuration maps related to Snort signatures.
  * **files** (`array<string>` ,optional)List of files related to Snort signatures.
* **schemaValidation** (`object`, optional)
  * **overrideMode** (`string` ,required) Override mode for schema validation. Possible values: `prevent-learn, detect-learn,prevent, detect, inactive, inherited`
    * Default: `inherited` inherited from threatPreventionPractice mode set in policy
  * **enforcementLevel** (`string` ,optional) Level of enforcement for schema validation.
  * **configmap** (`array<string>` ,optional) List of configuration maps related to schema validation.
  * **files** (`array<string>` ,optional) List of files related to schema validation
* **intrusionPrevention**  (`object`, optional)
  * **overrideMode** `string`: (required) Override mode for intrusion prevention. Possible values: `prevent-learn, detect-learn, prevent, detect, inactive, inherited`  inherited from threatPreventionPractice mode set in policy
    * Default: `inactive`
  * **maxPerformanceImpact** (`string` ,optional) ) Maximum acceptable performance impact. Possible values: `low, medium, high`
    * Default: `medium`
  * **minSeverityLevel** (`string` ,optional) Minimum severity level for intrusion prevention events. Possible values: `low, medium, high, critical`
    * Default: `medium`
  * **minCveYear** (`integer`, optional) ) Minimum year of CVE for inclusion in intrusion prevention events.
    * Default: `2016`
  * **highConfidenceEventAction** (`string` ,optional)  Action for high confidence events. Possible values: `prevent, detect, inactive, inherited`
    * Default: `inherited` as set in overrideMode for intrusionPrevention
  * **mediumConfidenceEventAction** (`string` ,optional) Action for medium confidence events. Possible values:`prevent, detect, inactive, inherited`
    * Default: `inherited` as set in overrideMode for intrusionPrevention
  * **lowConfidenceEventAction** (`string` ,optional) Action for medium confidence events. Possible values:`prevent, detect, inactive, inherited`
  * Default: `detect`&#x20;
* **fileSecurity** (`object`, optional)
  * **overrideMode** `string`: (required) Override mode for intrusion prevention. Possible values: `prevent-learn, detect-learn, prevent, detect, inactive, inherited` inherited from threatPreventionPractice mode set in policy
    * Default: `inactive`
  * **minSeverityLevel** (`string` ,optional) Minimum severity level for file secuirty events. Possible values: `low, medium, high, critical`
    * Default: `medium`
  * **highConfidenceEventAction** (`string` ,optional)  Action for high confidence events. Possible values: `prevent, detect, inactive, inherited`
    * Default: `inherited` as set in overrideMode for intrusionPrevention
  * **mediumConfidenceEventAction** (`string` ,optional) Action for medium confidence events. Possible values:`prevent, detect, inactive, inherited`
    * Default: `inherited` as set in overrideMode for intrusionPrevention
  * **lowConfidenceEventAction** (`string` ,optional) Action for medium confidence events. Possible values:`prevent, detect, inactive, inherited`
    * Default: `detect`&#x20;
  * **archiveInspection** (`object`, optional):
    * **extractArchiveFiles** (`boolean`, optional): Whether to extract files from archives for inspection.&#x20;
      * Default: `false`.
    * **scanMaxFileSize** (`integer`, optional): Maximum file size to scan within archives. Default: 10.
    * **scanMaxFileSizeUnit** (`string`, optional): Unit of the maximum file size for scanning. Possible values: `bytes, KB, MB, GB.`&#x20;
      * Default: `MB`.
    * **archivedFilesWithinArchivedFiles** (`string`, optional): Action for archived files nested within other archived files. Possible values: `prevent, detect, inactive, inherited`.&#x20;
      * Default: inherited, as set in overrideMode for fileSecurity.
    * **archivedFilesWhereContentExtractionFailed** (`string`, optional): Action when content extraction from archived files fails. Possible values: `prevent, detect, inactive, inherited`.&#x20;
      * Default: inherited, as set in overrideMode for fileSecurity.
  * **largeFileInspection** (`object`, optional):
    * **fileSizeLimit** (`integer`, optional): Maximum file size limit for inspection.
      * Default: `10`.
    * **fileSizeLimitUnit** (`string`, optional): Unit of the file size limit. Possible values: `bytes, KB, MB, GB`.&#x20;
      * Default: `MB`.
    * **filesExceedingSizeLimitAction** (`string`, optional): Action for files exceeding the size limit. Possible values: `prevent, detect, inactive, inherited.`
      * Default: `inherited`, as set in overrideMode for fileSecurity.
  * **unnamedFilesAction** (`string`, optional): Action for unnamed files. Possible values: `prevent, detect, inactive, inherited`.&#x20;
    * Default: `inherited`, as set in overrideMode for fileSecurity.
  * **threatEmulationEnabled** (`boolean`, optional): Whether threat emulation is enabled for file security.&#x20;
    * Default: `false`.

</details>

### **Access Control Practice**

Practice resources define which Access Control security engines will be active and what their settings are.

<details>

<summary>Examples </summary>

```yaml
accessControlPractices:
  - name: access-control-practice-example
    practiceMode: inherited
    rateLimit:
    # specify one or more rules below to use rate limiting
      overrideMode: inherited
      rules: []
```

</details>

<details>

<summary>Specification</summary>

* **name** (`string`, required): The name of the access control policy.
* **practiceMode** (`string`, optional): Defines the mode for the access control policy. Possible values: `prevent, detect, inactive, inherited (inherited values are determined by the mode set in the policy)`.&#x20;
  * Default: `inherited` .
* **rateLimit** (`object`, required):
  * **overrideMode** (`string`, optional): Allows overriding the mode defined at the policy level for this specific engine. Possible values: `prevent, detect, inactive, inherited (inherited values are determined by the mode set in the practice)`.&#x20;
    * Default: `inactive`.
  * **rules** (`array<objects>`, optional): List of rate-limiting rules.
    * **action** (`string`, optional): Action to take when a rate limit is exceeded. Possible values: `inherited, prevent, detect (inherited values are determined by the mode set in the rate limiting overide mode)`.&#x20;
      * Default: `inherited`.
    * **condition** (`array<objects>`, optional): List of conditions for rate limiting (currently not supported).
      * **key** (`string`, required): The key for the condition.
      * **value** (`string`, required): The value for the condition.
    * **uri** (`string`, optional): URI pattern for the rate limit rule.
    * **limit** (`integer`, optional): The rate limit threshold.
    * **unit** (`string`, optional): The time unit for the rate limit. Possible values: `minute, second`.&#x20;
      * Default: `minute`.
    * triggers (`array<objects>`, optional): List of triggers that activate the rule.
    * comment (`string`, optional): A comment explaining the rate limit.

</details>

### Custom Response

Optional custom responses can be configured to return in prevent mode either a customizable block page or the desired response code only. The custom responses than can be referenced within one or more policy elements.&#x20;

<details>

<summary>Examples </summary>

```yaml
customResponses:
  - name: web-user-response-example
    mode: response-code-only
    httpResponseCode: 403
```

</details>

<details>

<summary>Specification</summary>

* **name** (`string`, required): A unique name for the custom response configuration.
* **mode** (`string`, required): Defines the response mode for blocked requests. Possible values: blo`ck-page, redirect, response-code-only`.&#x20;
  * Default: `response-code-only`.
* **messageTitle** (`string`, optional): Title displayed on the block page (relevant when mode is block-page).
* **messageBody** (`string`, optional): Body message displayed on the block page (relevant when mode is block-page).
* **httpResponseCode** (`integer`, required): HTTP response code returned when blocking. Minimum: 100. Maximum: 599.&#x20;
  * Default: `403`.
* **redirectUrl** (`string`, optional): URL to redirect the blocked requests to (relevant when mode is redirect).
* **redirectAddXEventId** (`boolean`, optional): Adds an X-Event-ID header to redirected requests.&#x20;
  * Default: `false`.

</details>

### Log Trigger

Optional log trigger elements can be used to configure custom logging requirements. They can then be referenced within one or more policy elements.

<details>

<summary>Example </summary>

```yaml
logTriggers:
  - name: log-trigger-example
    accessControlLogging:
      allowEvents: false
      dropEvents: true
    appsecLogging:
      detectEvents: true
      preventEvents: true
      allWebRequests: false
    extendedLogging:
      urlPath: true
      urlQuery: true
      httpHeaders: false
      requestBody: false
    additionalSuspiciousEventsLogging:
      enabled: true
      minSeverity: high
      responseBody: false
      responseCode: true
    logDestination:
      cloud: true
      logToAgent: false
      stdout:
        format: json
```

</details>

<details>

<summary>Specification</summary>

* **name** (`string`, required): The unique name identifying the log trigger.
* **accessControlLogging** (`object`, required): Configuration for access control logs.
  * **allowEvents** (`boolean`, optional): Log allowed events.&#x20;
    * Default: `false`.
  * **dropEvents** (`boolean`, optional): Log dropped events.&#x20;
    * Default: `true`.
* **appsecLogging** (**object**, required): Configuration for application security logs.
  * **detectEvents** (`boolean`, optional): Log detection events.
    * Default: `true`.
  * **preventEvents** (`boolean`, optional): Log prevention events.&#x20;
    * Default: `true`.
  * **allWebRequests** (`boolean`, optional): Log all web requests, regardless of action.
  * Default: `false`.
* **additionalSuspiciousEventsLogging** (`object`, required): Configuration for logging suspicious events.
  * **enabled** (`boolean`, optional): Enable or disable logging for suspicious events. Default: `true`.
  * **minSeverity** (`string`, optional): Minimum severity level to log. Options: `high, critical`.&#x20;
    * Default: `high`.
  * **responseBody** (`boolean`, optional): Include response body in logs.&#x20;
    * Default: `false`.
  * **responseCode** (`boolean`, optional): Include response code in logs.&#x20;
    * Default: `true`.
* **extendedLogging** (`object`, required): Configuration for extended logging details.
  * **urlPath** (`boolean`, optional): Log URL path.&#x20;
    * Default: `false`.
  * **urlQuery** (`boolean`, optional): Log URL query parameters.&#x20;
    * Default: `false`.
  * **httpHeaders** (`boolean`, optional): Log HTTP headers.&#x20;
    * Default: `false`.
  * **requestBody** (`boolean`, optional): Log HTTP request body.&#x20;
    * Default: `false`.
* **logDestination** (`object`, required): Configuration for log destinations.
  * **cloud** (`boolean`, optional): Send logs to the cloud.&#x20;
    * Default: `false`.
  * **syslogService** (`array`, optional): List of syslog services.
    * **address** (`array<string>`, required): Syslog server address.
    * **port** (`integer`, required): Syslog server port.
  * **logToAgent** (`boolean`, optional): Send logs to the agent.&#x20;
    * Default: **true**.
  * **stdout** (`object`, optional): Configuration for logs sent to standard output.
    * **format** (`string`, optional): Log format. Options: `json, json-formatted`.
      * Default: `json`.
* **k8s-service** (`boolean`, optional): Enable logging to Kubernetes service (default depends on environment type).
* **cefService** (`array`, optional): List of CEF (Common Event Format) services.
  * **address** (`string`, required): CEF server address.
  * **port** (`integer`, required): CEF server port.
  * **proto** (`string`, optional): Protocol for CEF. Options: tcp, udp.

</details>

### Exceptions

Optional exception elements can be used to configure custom exceptions. They can then be referenced within one or more policy elements.

<details>

<summary>Example </summary>

```yaml
exceptions:
  - name: exception-example
    action: "accept"
    condition:
      - key: "countryCode"
        value: "US"
```

</details>

<details>

<summary>Specification</summary>

* **name**: (`string` ,required) - The unique name identifying the exception.
* **action**: (`string` ,required) - Action to take when the exception is triggered. Possible options: `skip`, `accept`, `drop`, `suppressLog`.&#x20;
  * Default: `accep`t.
* **condition**: (`array<object>` ,required) - List of one or more conditions that must be met for the exception to apply.
  * **key**: (`string` ,required) - The key to evaluate, such as `sourceIP`, `countryCode`, or `URL.` find full list [here](/setup-instructions/setup-custom-rules-and-exceptions).
  * **value**: (`string` ,required) - The value associated with the key to match.

</details>

### Trusted Sources

Optional trusted sources can be defined, for which the machine learning engine will assume, that the traffic originating from them is benign and learn accordingly.

Trusted sources elements can then be referenced within the policies section.

<details>

<summary>Example </summary>

<pre class="language-yaml"><code class="lang-yaml"><strong>trustedsources:
</strong>  - name: trusted-sources-example
    minNumOfSources: 3
    sourcesIdentifiers:
    - 1.0.0.27
    - 1.0.0.28
    - 1.0.0.29
</code></pre>

</details>

<details>

<summary>Specification</summary>

* **name**: (`string`). A unique identifier for the trusted source configuration.
* **minNumOfSources**: (`integer` , required) - The minimum number of trusted sources needed to apply the configuration.
  * Default: `3`.
* **sourcesIdentifiers**: (`array<stri`

</details>

### Source Identifiers

Source Identifiers can be used to define how open-appsec distinguishes between different sources, e.g. based on source IP addresses, x-forwarded-for header content, etc.&#x20;

<details>

<summary>Examples </summary>

```yaml
sourcesIdentifiers:
  - name: sources-identifier-example
    - identifier: sourceip
      value:
        - "0.0.0.0"
```

</details>

<details>

<summary>Specification</summary>

* **name**: (`string` ,required) A unique identifier for the sources configuration.
* **sourcesIdentifiers**: (`array<object>`,  required)  A list of source identifiers to distinguish between sources based on the selected type and values. Each item is an `object` with the following properties:
  * **identifier**: (`string enum`, required) - The type of identifier. Possible options: `headerkey, JWTKey, cookie, sourceip, x-forwarded-for`
    * Default: `sourceip`.
  * **value**: (`array<string>`,  required) - A list of values associated with the identifier. Each item is a `string`.

</details>

## Schema file

Here you find the full schema file for the local declarative configuration yaml file.\
This also shows you which fields are required and which are optional

<details>

<summary>Schema file for local policy file</summary>

```yaml
type: object
properties:
  apiVersion:
    type: string
    enum:
    - v1beta1
    - v1beta2
  policies:
    type: object
    properties:
      appsecClassName:
        type: string
      default:
        type: object
        required:
        - mode
        - threatPreventionPractices
        - accessControlPractices
        properties:
          mode:
            type: string
            enum:
            - prevent-learn
            - detect-learn
            - prevent
            - detect
            - inactive
            default: detect-learn
          threatPreventionPractices:
            type: array
            items:
              type: string
          accessControlPractices:
            type: array
            items:
              type: string
          customResponse:
            type: string
            default: "403"
          triggers:
            type: array
            items:
              type: string
          sourceIdentifiers:
            type: string
          trustedSources:
            type: string
          exceptions:
            type: array
            items:
              type: string
      specificRules:
        type: array
        items:
          type: object
          properties:
            name:
              type: string
            host:
              type: string
            mode:
              type: string
              enum:
              - prevent-learn
              - detect-learn
              - prevent
              - detect
              - inactive
              default: detect-learn
            threatPreventionPractices:
              type: array
              items:
                type: string
            accessControlPractices:
              type: array
              items:
                type: string
            triggers:
              type: array
              items:
                type: string
            customResponse:
              type: string
            sourceIdentifiers:
              type: string
            trustedSources:
              type: string
            exceptions:
              type: array
              items:
                type: string
  logTriggers:
    type: array
    items:
      type: object
      required:
      - accessControlLogging
      - appsecLogging
      - additionalSuspiciousEventsLogging
      - extendedLogging
      - logDestination
      properties:
        appsecClassName:
          type: string
        name:
          type: string
        accessControlLogging:
          type: object
          properties:
            allowEvents:
              type: boolean
              default: false
            dropEvents:
              type: boolean
              default: true
        appsecLogging:
          type: object
          properties:
            detectEvents:
              type: boolean
              default: true
            preventEvents:
              type: boolean
              default: true
            allWebRequests:
              type: boolean
              default: false
        additionalSuspiciousEventsLogging:
          type: object
          properties:
            enabled:
              type: boolean
              default: true
            minSeverity:
              type: string
              enum:
              - high
              - critical
              default: high
            responseBody:
              type: boolean
              default: false
            responseCode:
              type: boolean
              default: true
        extendedLogging:
          type: object
          properties:
            urlPath:
              type: boolean
              default: false
            urlQuery:
              type: boolean
              default: false
            httpHeaders:
              type: boolean
              default: false
            requestBody:
              type: boolean
              default: false
        logDestination:
          type: object
          properties:
            cloud:
              type: boolean
              default: false
            local-tuning:
              type: boolean
              default: false
            syslogService:
              type: array
              items:
                type: object
                properties:
                  address:
                    type: string
                  port:
                    type: integer
            logToAgent:
              type: boolean
              default: true
            stdout:
              type: object
              properties:
                format:
                  type: string
                  enum:
                  - json
                  - json-formatted
                  default: json
            cefService:
              type: array
              items:
                type: object
                properties:
                  address:
                    type: string
                  port:
                    type: integer
                  proto:
                    type: string
                    enum:
                    - tcp
                    - udp
  threatPreventionPractices:
    type: array
    items:
      type: object
      required:
      - webAttacks
      - intrusionPrevention
      - fileSecurity
      - snortSignatures
      properties:
        appsecClassName:
          type: string
        name:
          type: string
        practiceMode:
          type: string
          enum:
          - inherited
          - prevent-learn
          - detect-learn
          - prevent
          - detect
          - inactive
          default: inherited
        webAttacks:
          type: object
          required:
          - overrideMode
          properties:
            overrideMode:
              type: string
              enum:
              - prevent-learn
              - detect-learn
              - prevent
              - detect
              - inactive
              - inherited
              default: inactive
            minimumConfidence:
              type: string
              enum:
              - medium
              - high
              - critical
              default: high
            maxUrlSizeBytes:
              type: integer
              default: 32768
            maxObjectDepth:
              type: integer
              default: 40
            maxBodySizeKb:
              type: integer
              default: 1000000
            maxHeaderSizeBytes:
              type: integer
              default: 102400
            protections:
              type: object
              properties:
                csrfProtection:
                  type: string
                  enum:
                  - prevent-learn
                  - detect-learn
                  - prevent
                  - detect
                  - inactive
                  - inherited
                  default: inactive
                errorDisclosure:
                  type: string
                  enum:
                  - prevent-learn
                  - detect-learn
                  - prevent
                  - detect
                  - inactive
                  - inherited
                  default: inactive
                openRedirect:
                  type: string
                  enum:
                  - prevent-learn
                  - detect-learn
                  - prevent
                  - detect
                  - inactive
                  - inherited
                  default: inactive
                nonValidHttpMethods:
                  type: boolean
                  default: false
        antiBot:
          type: object
          required:
          - overrideMode
          properties:
            overrideMode:
              type: string
              enum:
              - prevent-learn
              - detect-learn
              - prevent
              - detect
              - inactive
              - inherited
              default: inactive
            injectedUris:
              type: array
              items:
                type: object
                properties:
                  uri:
                    type: string
            validatedUris:
              type: array
              items:
                type: object
                properties:
                  uri:
                    type: string
        snortSignatures:
          type: object
          required:
          - overrideMode
          properties:
            overrideMode:
              type: string
              enum:
              - prevent-learn
              - detect-learn
              - prevent
              - detect
              - inactive
              - inherited
              default: inactive
            configmap:
              type: array
              items:
                type: string
            files:
              type: array
              items:
                type: string
        schemaValidation:
          type: object
          required:
          - overrideMode
          properties:
            overrideMode:
              type: string
              enum:
              - prevent-learn
              - detect-learn
              - prevent
              - detect
              - inactive
              - inherited
              default: inactive
            enforcementLevel:
              type: string
            configmap:
              type: array
              items:
                type: string
            files:
              type: array
              items:
                type: string
        intrusionPrevention:
          type: object
          required:
          - overrideMode
          properties:
            overrideMode:
              type: string
              enum:
              - prevent-learn
              - detect-learn
              - prevent
              - detect
              - inactive
              - inherited
              default: inactive
            maxPerformanceImpact:
              type: string
              enum:
              - low
              - medium
              - high
              default: medium
            minSeverityLevel:
              type: string
              enum:
              - low
              - medium
              - high
              - critical
              default: medium
            minCveYear:
              type: integer
              default: 2016
            highConfidenceEventAction:
              type: string
              enum:
              - prevent
              - detect
              - inactive
              - inherited
              default: inherited
            mediumConfidenceEventAction:
              type: string
              enum:
              - prevent
              - detect
              - inactive
              - inherited
              default: inherited
            lowConfidenceEventAction:
              type: string
              enum:
              - prevent
              - detect
              - inactive
              - inherited
              default: detect
        fileSecurity:
          type: object
          required:
          - overrideMode
          properties:
            overrideMode:
              type: string
              enum:
              - prevent-learn
              - detect-learn
              - prevent
              - detect
              - inactive
              - inherited
              default: inactive
            minSeverityLevel:
              type: string
              enum:
              - low
              - medium
              - high
              - critical
              default: medium
            highConfidenceEventAction:
              type: string
              enum:
              - prevent
              - detect
              - inactive
              - inherited
              default: inherited
            mediumConfidenceEventAction:
              type: string
              enum:
              - prevent
              - detect
              - inactive
              - inherited
              default: inherited
            lowConfidenceEventAction:
              type: string
              enum:
              - prevent
              - detect
              - inactive
              - inherited
              default: detect
            archiveInspection:
              type: object
              properties:
                extractArchiveFiles:
                  type: boolean
                  default: false
                scanMaxFileSize:
                  type: integer
                  default: 10
                scanMaxFileSizeUnit:
                  type: string
                  enum:
                  - bytes
                  - KB
                  - MB
                  - GB
                  default: MB
                archivedFilesWithinArchivedFiles:
                  type: string
                  enum:
                  - prevent
                  - detect
                  - inactive
                  - inherited #as set in overrideMode for fileSecurity
                  default: inherited
                archivedFilesWhereContentExtractionFailed:
                  type: string
                  enum:
                  - prevent
                  - detect
                  - inactive
                  - inherited #as set in overrideMode for fileSecurity
                  default: inherited
            largeFileInspection:
              type: object
              properties:
                fileSizeLimit:
                  type: integer
                  default: 10
                fileSizeLimitUnit:
                  type: string
                  enum:
                  - bytes
                  - KB
                  - MB
                  - GB
                  default: MB
                filesExceedingSizeLimitAction:
                  type: string
                  enum:
                  - prevent
                  - detect
                  - inactive
                  - inherited #as set in overrideMode for fileSecurity
                  default: inherited
            unnamedFilesAction:
              type: string
              enum:
              - prevent
              - detect
              - inactive
              - inherited #as set in overrideMode for fileSecurity
              default: inherited
            threatEmulationEnabled:
              type: boolean
              default: false
  accessControlPractices:
    type: array
    items:
      type: object
      required:
      - rateLimit
      properties:
        appsecClassName:
          type: string
        name:
          type: string
        practiceMode:
          type: string
          enum:
          - inherited #inherited from mode set in policy
          - prevent
          - detect
          - inactive
          default: inherited
        rateLimit:
          type: object
          required:
          - overrideMode
          properties:
            overrideMode:
              type: string
              enum:
              - prevent
              - detect
              - inactive
              - inherited
              default: inactive
            rules:
              type: array
              items:
                type: object
                properties:
                  action: # currently not supported
                    type: string
                    enum:
                    - inherited
                    - prevent
                    - detect
                    default: inherited
                  condition: # currently not supported
                    type: array
                    items:
                      type: object
                      required:
                      - key
                      - value
                      properties:
                        key:
                          type: string
                        value:
                          type: string
                  uri:
                    type: string
                  limit:
                    type: integer
                  unit:
                    type: string
                    enum:
                    - minute
                    - second
                    default: minute
                  triggers:
                    type: array
                    items:
                      type: string
                  comment:
                    type: string
  customResponses:
    type: array
    items:
      type: object
      required:
      - mode
      properties:
        appsecClassName:
          type: string
        name:
          type: string
        mode:
          type: string
          enum:
          - block-page
          - redirect
          - response-code-only
          default: response-code-only
        messageTitle:
          type: string
        messageBody:
          type: string
        httpResponseCode:
          type: integer
          minimum: 100
          maximum: 599
          default: 403
        redirectUrl:
          type: string
        redirectAddXEventId:
          type: boolean
          default: false
  sourcesIdentifiers:
    type: array
    items:
      type: object
      required:
      - sourcesIdentifiers
      properties:
        name:
          type: string
        sourcesIdentifiers:
          type: array
          items:
            type: object
            required:
            - identifier
            properties:
              identifier:
                type: string
                enum:
                - headerkey
                - JWTKey
                - cookie
                - sourceip
                - x-forwarded-for
                default: sourceip
              value:
                type: array
                items:
                  type: string
  exceptions:
    type: array
    items:
      type: object
      required:
      - action
      - condition
      properties:
        appsecClassName:
          type: string
        name:
          type: string
        action:
          type: string
          enum:
          - skip
          - accept
          - drop
          - suppressLog
          default: accept
        condition:
          type: array
          items:
            type: object
            required:
            - key
            - value
            properties:
              key:
                type: string
              value:
                type: string
  trustedSources:
    type: array
    items:
      type: object
      required:
      - minNumOfSources
      - sourcesIdentifiers
      properties:
        appsecClassName:
          type: string
        name:
          type: string
        minNumOfSources:
          type: integer
          default: 3
        sourcesIdentifiers:
          type: array
          items:
            type: string
  policyActivations:
    type: array
    items:
      type: object
      properties:
        appsecClassName:
          type: string
        enabledPolicies:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
              hosts:
                type: array
                items:
                  type: string
            required:
            - hosts
      required:
      - enabledPolicies
additionalProperties: false

```

</details>


# Monitor Events

## Local Logs

After installation, you may want to trigger some traffic to one of your web services which are now protected by open-appsec. You can then run this command to view logs:

```bash
open-appsec-ctl --view-logs
```

{% hint style="info" %}
By default logs are stored here:\
`/var/log/nano-agent/CP-nano-http-transaction-handler.log<number>`

You can configure flexible logging according to your requirements by using a custom log-trigger. \
See here for configuring the log trigger when using declarative configuration file:\
[Local Policy File (Advanced)](/getting-started/start-with-linux/local-policy-file-advanced)&#x20;

See here for more details on the different available options: \
[Setup Log Triggers](/setup-instructions/setup-log-triggers)
{% endhint %}

## Central Monitoring

If you connect open-appsec to the WebUI (SaaS) for central management you do Monitoring/Logging flexible from there as well.


# Start with Docker

## Overview

open-appsec can be deployed on Docker or similar containerized platforms integrating with NGINX, Kong, APISIX and Envoy containers to provide protection to any applications and APIs served by these reverse proxies or API Gateways.&#x20;

Container images are provided for NGINX, Kong, APISIX and Envoy which have been enhanced to also contain the open-appsec attachment. This attachment then sends traffic for inspection to the open-appsec agent container.

{% tabs %}
{% tab title="NGINX" %}

<figure><img src="/files/1LWaHGfsmGCoXLYhCl1w" alt=""><figcaption></figcaption></figure>

NGINX container with open-appsec attachment + open-appsec Agent container
{% endtab %}

{% tab title="NGINX unified" %}

<figure><img src="/files/x7yJNhBNdZjwQeDxKucp" alt=""><figcaption></figcaption></figure>

Single unified container with NGINX, open-appsec attachment and also open-appsec Agent included in same container
{% endtab %}

{% tab title="Kong" %}

<figure><img src="/files/ypRkm8A8v40OShvfIpBV" alt=""><figcaption></figcaption></figure>

Kong container with open-appsec attachment + open-appsec Agent container
{% endtab %}

{% tab title="APISIX" %}

<figure><img src="/files/BFOx2085Uk13Jsv0R8yk" alt=""><figcaption></figcaption></figure>

APISIX container with open-appsec attachment + open-appsec Agent container
{% endtab %}

{% tab title="Envoy" %}

<figure><img src="/files/R3EkwvFKU6sFaXHqsdbJ" alt=""><figcaption></figcaption></figure>

Envoy container with open-appsec attachment filter + open-appsec Agent container
{% endtab %}
{% endtabs %}

open-appsec also supports integration with NGINX Proxy Manager and Docker SWAG, you find more details about those here: [Integrations](/integrations/about-integrations-with-3rd-party-solutions).

{% tabs %}
{% tab title="NGINX Proxy Manager" %}

<figure><img src="/files/8C94S1xnKpxkZfQvk5kB" alt=""><figcaption></figcaption></figure>

NGINX Proxy Manager (NPM) container with open-appsec attachment and option to manage and monitor open-appsec from the NPM WebUI or from open-appsec WebUI + open-appsec Agent container
{% endtab %}

{% tab title="SWAG" %}

<figure><img src="/files/n7y5Ku42Uo6ygtWtHghH" alt=""><figcaption></figcaption></figure>

SWAG (Secure Web Application Gateway) container with open-appsec attachment filter + open-appsec Agent container
{% endtab %}

{% tab title="NPMplus" %}
open-appsec support is natively available in NPMplus project.\
NPMplus is a fork of the original NGINX Proxy Manager (NPM) project adding additional functionalities and improvements.\
\
Deployment instructions for open-appsec integration: [NPMplus](/integrations/npmplus)\
NPMplus project in Github: <https://github.com/ZoeyVid/NPMplus>
{% endtab %}
{% endtabs %}


# Deploy With Docker-Compose

## Prerequisites

* **Linux Docker Host with root permission**
* **Docker-Compose tool installed**

#### Optional (Recommended) Prerequisites:

* **Access to a SaaS tenant on my.openappsec.io (WebUI for SaaS management)**\
  Follow the instructions available here:

{% content-ref url="/pages/0ty9rMQEgnxS9LBuN7qw" %}
[Sign-Up and Login to Portal](/getting-started/using-the-web-ui-saas/sign-up-and-login-to-portal)
{% endcontent-ref %}

* **Agent profile created for open-appsec Docker deployment in SaaS tenant** \
  Follow the instructions available here.\
  Once done, don't forget to copy the profile token after policy installation as this is needed in the installation steps further below:

{% content-ref url="/pages/WMgZp7bTMiI5PD1ocIKp" %}
[Create a Profile](/getting-started/using-the-web-ui-saas/create-a-profile)
{% endcontent-ref %}

## Deployment

#### To deploy open-appsec with docker-compose and optionally connect to the central WebUI available at <https://my.openappsec.io> follow the steps below:

1. Create a folder for your new open-appsec deployment and switch to that folder, e.g.

```bash
mkdir open-appsec-deployment
cd ./open-appsec-deployment
```

2. Download the docker compose file for your desired open-appsec integration

{% tabs %}
{% tab title="NGINX" %}
{% code overflow="wrap" %}

```bash
wget https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/nginx/docker-compose.yaml
```

{% endcode %}

{% embed url="<https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/nginx/docker-compose.yaml>" %}
{% endtab %}

{% tab title="NGINX - Unified" %}
{% code overflow="wrap" %}

```bash
wget https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/nginx-unified/docker-compose.yaml
```

{% endcode %}

{% embed url="<https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/nginx-unified/docker-compose.yaml>" %}
{% endtab %}

{% tab title="Kong (traditional)" %}
{% code overflow="wrap" %}

```bash
wget https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/kong/docker-compose.yaml
```

{% endcode %}

{% hint style="warning" %}
This deployment is for the traditional open-appsec integration with Kong.\
The Kong container specified in the `.env` file already contains the traditional open-appsec attachment which integrates on NGINX level and allows the open-appsec agent to inspect **all traffic** passing through Kong. You don't have to configure anything additionally in the Kong configuration for the agent to see the traffic.

A new version of the Kong plugin based on Lua is now available as well, see separate tab. This is more flexible, as you can apply the attachment to specific traffic (e.g. selected routes only) and this is aligned with the official Kong plugin guidelines.
{% endhint %}

{% embed url="<https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/kong/docker-compose.yaml>" %}
{% endtab %}

{% tab title="Kong (Lua plugin, beta)" %}

<pre class="language-bash" data-overflow="wrap"><code class="lang-bash"><strong>wget https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/kong-lua-plugin/docker-compose.yaml
</strong></code></pre>

{% hint style="warning" %}
This deployment is for the new, more flexible version of the Kong plugin based on Lua. This is more flexible than the traditional plugin (also still available, but will be deprecated in the future) and is following the official Kong plugin guidelines.

The Kong container specified in the `.env` file does already contain the new Lua-based Kong plugin and is loading it as part of the included `kong.conf` file.&#x20;

As this is a regular Kong plugin, you must make sure to also configure the plugin to apply to your traffic (e.g. all traffic, specific routes, etc.), as otherwise the open-appsec agent will not receive the traffic for inspection.
{% endhint %}

{% embed url="<https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/kong-lua-plugin/docker-compose.yaml>" %}
{% endtab %}

{% tab title="APISIX" %}

<pre class="language-bash" data-overflow="wrap"><code class="lang-bash"><strong>wget https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/apisix/docker-compose.yaml
</strong></code></pre>

{% embed url="<https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/apisix/docker-compose.yaml>" %}
{% endtab %}

{% tab title="Envoy (beta)" %}
{% code overflow="wrap" %}

```bash
wget https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/envoy/docker-compose.yaml
```

{% endcode %}

{% embed url="<https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/envoy/docker-compose.yaml>" %}
{% endtab %}
{% endtabs %}

3. Download the `.env` file for your desired open-appsec integration and adjust the configuration to your requirements as described below:

{% tabs %}
{% tab title="NGINX" %}

* Download the default `.env` file here:

{% code overflow="wrap" %}

```bash
wget https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/nginx/.env
```

{% endcode %}

{% embed url="<https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/nginx/.env>" %}

* **If you created a deployment profile in the WebUI and copied the Token from it:**

  \
  Edit the `.env` file and add your token to the key `APPSEC_AGENT_TOKEN`.
* **If you did not create a deployment profile in the WebUI and do not want to connect your deployment to central WebUI (SaaS) at all:**

  \
  Set the value `standalone` for the key `COMPOSE_PROFILES` which will activate the deployment of additional containers which are required only when not connected to the WebUI at all (resulting in standalone, locally, declaratively managed deployment).
* Replace `user@email.com` in the .env file with your own email. (More details below.)

#### Available settings in the `.env` file allowing further customization of the deployment:

**APPSEC\_AGENT\_TOKEN:** For connecting your open-appsec deployment to central WebUI  set APPSEC\_AGENT\_TOKEN to your own deployment profile token as copied from profile settings in the open-appsec central WebUI (see section [#prerequisites](#prerequisites "mention") above).

**COMPOSE\_PROFILES:** Possible values you can set for this key:\
&#x20;(you can set multiple values, separated by comma)

`standalone` : This will activate the deployment of additional containers which are required **only** when you are not connected to the WebUI at all, resulting in standalone, locally- and  declaratively-managed deployment.

{% hint style="warning" %}
**Only** activate the `standalone` profile in case you did not set a WebUI deployment profile token as value for the APPSEC\_AGENT\_TOKEN key (see above)!
{% endhint %}

{% hint style="info" %}
The additional containers introduce some additional functionality, which is relevant for standalone deployments only (already available when connected to central management WebUI):\
\- Local syncing of learning between open-appsec processes and agents\
\- View learning progress on CLI with open-appsec-tuning-tool\
\- Receive configuration recommendations based on the learning progress using the open-appsec-tuning-tool\
\- Receive tuning suggestions and manage them (approve/reject) using the open-appsec-tuning-tool\
\
More details on the open-appsec-tuning-tool here: [Track Learning and Local Tuning in Standalone Deployments](/how-to/configuration-and-learning/track-learning-and-local-tuning-in-standalone-deployments)
{% endhint %}

`juiceshop` : This will deploy an additional, vulnerable juiceshop-backend container that can be used for demo and testing purposes.\
In the .env file you also find a download link for the proxy-specific configuration allowing you to access the juiceshop backend via the proxy. More info on the OWASP juiceshop project: <https://owasp.org/www-project-juice-shop/>

{% hint style="warning" %}
Do not activate the juiceshop profile in production environments as the juiceshop container is intentionally highly vulnerable and meant for testing in lab environments only!
{% endhint %}

**USER\_EMAIL:** (Optional) Associate your email address with your specific deployment by replacing `user@email.com` with your own email address.

This allows the open-appsec team to provide you easy assistance in case of any issues you might have with your specific deployment in the future and also to provide you information proactively regarding open-appsec in general or regarding your specific deployment. This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future.

**APPSEC\_HTTPS\_PROXY**: (Optional) Configure an HTTP(S) proxy server to be used by the agent.&#x20;

**APPSEC\_AUTO\_POLICY\_LOAD**: (Optional) When set to `true`, allows you to set the open-appsec agent to automatically apply any new changes in the local\_policy.yaml file without having to restart the agent container or applying the changes with `open-appsec-ctl -ap` (note that this can take up to 30 seconds). This is useful especially in DevOps scenarios with continuous deployment scenarios.

**APPSEC\_VERSION**: Allows you to specify a specific version for deployment instead of using the default `latest` version for the containers provided by open-appsec (not relevant for postgres container).

**APPSEC\_POSTGRES\_VERSION**: Allows you to set the postgres database version by specifying the postgres container tag. E.g. `APPSEC_POSTGRES_VERSION=18`\
It is not recommended to set this to latest, as changing the postgres major version does require an upgrade of the postgres database to be performed first.\
You find the steps to upgrade you postgres version used in your open-appsec deployment on docker here: [Upgrade Postgres version (Docker-Compose)](/deployment-and-upgrade/upgrade-postgres-version-docker-compose)

**Additional configuration available specifically for this integration type:**

**NGINX\_CONFIG**: Set the directory on the docker host used for the volume mount to the NGINX `conf.d` directory. Make sure to have a valid NGINX configuration file default.conf in the mounted directory.\
\
For testing purposes in a lab environment you can activate the deployment of the vulnerable juiceshop-backend container via `COMPOSE_PROFILES` key (see above) and then deploy the available configuration example for exposing it via the proxy, which is provided by the open-appsec team (download link is provided in the .env file).

{% hint style="info" %}
You find some additional advanced configuration options described within the `docker-compose.yaml` file as comments.
{% endhint %}
{% endtab %}

{% tab title="NGINX - Unified" %}

* Download the default `.env` file here:

{% code overflow="wrap" %}

```bash
wget https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/nginx-unified/.env
```

{% endcode %}

{% embed url="<https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/nginx-unified/.env>" %}

* **If you created a deployment profile in the WebUI and copied the Token from it:**

  \
  Edit the `.env` file and add your token to the key `APPSEC_AGENT_TOKEN`.
* **If you did not create a deployment profile in the WebUI and do not want to connect your deployment to central WebUI (SaaS) at all:**

  \
  Set the value `standalone` for the key `COMPOSE_PROFILES` which will activate the deployment of additional containers which are required only when not connected to the WebUI at all (resulting in standalone, locally, declaratively managed deployment).
* Replace `user@email.com` in the .env file with your own email. (More details below.)

#### Available settings in the `.env` file allowing further customization of the deployment:

**APPSEC\_AGENT\_TOKEN:** For connecting your open-appsec deployment to central WebUI  set APPSEC\_AGENT\_TOKEN to your own deployment profile token as copied from profile settings in the open-appsec central WebUI (see section [#prerequisites](#prerequisites "mention") above).

**COMPOSE\_PROFILES:** Possible values you can set for this key:\
&#x20;(you can set multiple values, separated by comma)

`standalone` : This will activate the deployment of additional containers which are required **only** when you are not connected to the WebUI at all, resulting in standalone, locally- and  declaratively-managed deployment.

{% hint style="warning" %}
**Only** activate the `standalone` profile in case you did not set a WebUI deployment profile token as value for the APPSEC\_AGENT\_TOKEN key (see above)!
{% endhint %}

{% hint style="info" %}
The additional containers introduce some additional functionality, which is relevant for standalone deployments only (already available when connected to central management WebUI):\
\- Local syncing of learning between open-appsec processes and agents\
\- View learning progress on CLI with open-appsec-tuning-tool\
\- Receive configuration recommendations based on the learning progress using the open-appsec-tuning-tool\
\- Receive tuning suggestions and manage them (approve/reject) using the open-appsec-tuning-tool\
\
More details on the open-appsec-tuning-tool here: [Track Learning and Local Tuning in Standalone Deployments](/how-to/configuration-and-learning/track-learning-and-local-tuning-in-standalone-deployments)
{% endhint %}

`juiceshop` : This will deploy an additional, vulnerable juiceshop-backend container that can be used for demo and testing purposes.

{% hint style="warning" %}
Do not activate the juiceshop profile in production environments as the juiceshop container is intentionally highly vulnerable and meant for testing in lab environments only!
{% endhint %}

**USER\_EMAIL:** (Optional) Associate your email address with your specific deployment by replacing `user@email.com` with your own email address.

This allows the open-appsec team to provide you easy assistance in case of any issues you might have with your specific deployment in the future and also to provide you information proactively regarding open-appsec in general or regarding your specific deployment. This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future.

**APPSEC\_HTTPS\_PROXY**: (Optional) Configure an HTTP(S) proxy server to be used by the agent.&#x20;

**APPSEC\_AUTO\_POLICY\_LOAD**: (Optional) When set to `true`, allows you to set the open-appsec agent to automatically apply any new changes in the local\_policy.yaml file without having to restart the agent container or applying the changes with `open-appsec-ctl -ap` (note that this can take up to 30 seconds). This is useful especially in DevOps scenarios with continuous deployment scenarios.

**APPSEC\_VERSION**: Allows you to specify a specific version for deployment instead of using the default `latest` version for the containers provided by open-appsec (not relevant for postgres container).

**Additional configuration available specifically for this integration type:**

**NGINX\_CONFIG**: Set the directory on the docker host used for the volume mount to the NGINX `conf.d` directory. Make sure to have a valid NGINX configuration file default.conf in the mounted directory.

For testing purposes in a lab environment you can activate the deployment of the vulnerable juiceshop-backend container via `COMPOSE_PROFILES` key (see above) and then deploy the available configuration example for exposing it via the proxy, which is provided by the open-appsec team (download link is provided in the .env file).

{% hint style="info" %}
You find some additional advanced configuration options described within the `docker-compose.yaml` file as comments.
{% endhint %}
{% endtab %}

{% tab title="Kong (traditional)" %}

* Download the default `.env` file here:

{% code overflow="wrap" %}

```bash
wget https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/kong/.env
```

{% endcode %}

{% embed url="<https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/kong/.env>" %}

* **If you created a deployment profile in the WebUI and copied the Token from it:**

  \
  Edit the `.env` file and add your token to the key `APPSEC_AGENT_TOKEN`.
* **If you did not create a deployment profile in the WebUI and do not want to connect your deployment to central WebUI (SaaS) at all:**

  \
  Set the value `standalone` for the key `COMPOSE_PROFILES` which will activate the deployment of additional containers which are required only when not connected to the WebUI at all (resulting in standalone, locally, declaratively managed deployment).
* Replace `user@email.com` in the .env file with your own email. (More details below.)

#### Available settings in the `.env` file allowing further customization of the deployment:

**APPSEC\_AGENT\_TOKEN:** For connecting your open-appsec deployment to central WebUI  set APPSEC\_AGENT\_TOKEN to your own deployment profile token as copied from profile settings in the open-appsec central WebUI (see section [#prerequisites](#prerequisites "mention") above).

**COMPOSE\_PROFILES:** Possible values you can set for this key:\
&#x20;(you can set multiple values, separated by comma)

`standalone` : This will activate the deployment of additional containers which are required **only** when you are not connected to the WebUI at all, resulting in standalone, locally- and  declaratively-managed deployment.

{% hint style="warning" %}
**Only** activate the `standalone` profile in case you did not set a WebUI deployment profile token as value for the APPSEC\_AGENT\_TOKEN key (see above)!
{% endhint %}

{% hint style="info" %}
The additional containers introduce some additional functionality, which is relevant for standalone deployments only (already available when connected to central management WebUI):\
\- Local syncing of learning between open-appsec processes and agents\
\- View learning progress on CLI with open-appsec-tuning-tool\
\- Receive configuration recommendations based on the learning progress using the open-appsec-tuning-tool\
\- Receive tuning suggestions and manage them (approve/reject) using the open-appsec-tuning-tool\
\
More details on the open-appsec-tuning-tool here: [Track Learning and Local Tuning in Standalone Deployments](/how-to/configuration-and-learning/track-learning-and-local-tuning-in-standalone-deployments)
{% endhint %}

`juiceshop` : This will deploy an additional, vulnerable juiceshop-backend container that can be used for demo and testing purposes.

{% hint style="warning" %}
Do not activate the juiceshop profile in production environments as the juiceshop container is intentionally highly vulnerable and meant for testing in lab environments only!
{% endhint %}

**USER\_EMAIL:** (Optional) Associate your email address with your specific deployment by replacing `user@email.com` with your own email address.

This allows the open-appsec team to provide you easy assistance in case of any issues you might have with your specific deployment in the future and also to provide you information proactively regarding open-appsec in general or regarding your specific deployment. This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future.

**APPSEC\_HTTPS\_PROXY**: (Optional) Configure an HTTP(S) proxy server to be used by the agent.&#x20;

**APPSEC\_AUTO\_POLICY\_LOAD**: (Optional) When set to `true`, allows you to set the open-appsec agent to automatically apply any new changes in the local\_policy.yaml file without having to restart the agent container or applying the changes with `open-appsec-ctl -ap` (note that this can take up to 30 seconds). This is useful especially in DevOps scenarios with continuous deployment scenarios.

**APPSEC\_VERSION**: Allows you to specify a specific version for deployment instead of using the default `latest` version for the containers provided by open-appsec (not relevant for postgres container).

**Additional configuration available specifically for this integration type:**

**KONG\_CONFIG**: Set the directory on the docker host used for the volume mount to the Kong  `/opt/kong` directory. Make sure to have a valid Kong declarative configuration file kong.yaml in the mounted directory.

For testing purposes in a lab environment you can activate the deployment of the vulnerable juiceshop-backend container via `COMPOSE_PROFILES` key (see above) and then deploy the available configuration example for exposing it via the proxy, which is provided by the open-appsec team (download link is provided in the .env file).

{% hint style="info" %}
You find some additional advanced configuration options described within the `docker-compose.yaml` file as comments.
{% endhint %}
{% endtab %}

{% tab title="Kong (Lua plugin, beta)" %}

* Download the default `.env` file here:

{% code overflow="wrap" %}

```bash
wget https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/kong-lua-plugin/.env
```

{% endcode %}

{% embed url="<https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/kong-lua-plugin/.env>" %}

* **If you created a deployment profile in the WebUI and copied the Token from it:**

  \
  Edit the `.env` file and add your token to the key `APPSEC_AGENT_TOKEN`.
* **If you did not create a deployment profile in the WebUI and do not want to connect your deployment to central WebUI (SaaS) at all:**

  \
  Set the value `standalone` for the key `COMPOSE_PROFILES` which will activate the deployment of additional containers which are required only when not connected to the WebUI at all (resulting in standalone, locally, declaratively managed deployment).
* Replace `user@email.com` in the .env file with your own email. (More details below.)

#### Available settings in the `.env` file allowing further customization of the deployment:

**APPSEC\_AGENT\_TOKEN:** For connecting your open-appsec deployment to central WebUI  set APPSEC\_AGENT\_TOKEN to your own deployment profile token as copied from profile settings in the open-appsec central WebUI (see section [#prerequisites](#prerequisites "mention") above).

**COMPOSE\_PROFILES:** Possible values you can set for this key:\
&#x20;(you can set multiple values, separated by comma)

`standalone` : This will activate the deployment of additional containers which are required **only** when you are not connected to the WebUI at all, resulting in standalone, locally- and  declaratively-managed deployment.

{% hint style="warning" %}
**Only** activate the `standalone` profile in case you did not set a WebUI deployment profile token as value for the APPSEC\_AGENT\_TOKEN key (see above)!
{% endhint %}

{% hint style="info" %}
The additional containers introduce some additional functionality, which is relevant for standalone deployments only (already available when connected to central management WebUI):\
\- Local syncing of learning between open-appsec processes and agents\
\- View learning progress on CLI with open-appsec-tuning-tool\
\- Receive configuration recommendations based on the learning progress using the open-appsec-tuning-tool\
\- Receive tuning suggestions and manage them (approve/reject) using the open-appsec-tuning-tool\
\
More details on the open-appsec-tuning-tool here: [Track Learning and Local Tuning in Standalone Deployments](/how-to/configuration-and-learning/track-learning-and-local-tuning-in-standalone-deployments)
{% endhint %}

`juiceshop` : This will deploy an additional, vulnerable juiceshop-backend container that can be used for demo and testing purposes.

{% hint style="warning" %}
Do not activate the juiceshop profile in production environments as the juiceshop container is intentionally highly vulnerable and meant for testing in lab environments only!
{% endhint %}

**USER\_EMAIL:** (Optional) Associate your email address with your specific deployment by replacing `user@email.com` with your own email address.

This allows the open-appsec team to provide you easy assistance in case of any issues you might have with your specific deployment in the future and also to provide you information proactively regarding open-appsec in general or regarding your specific deployment. This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future.

**APPSEC\_HTTPS\_PROXY**: (Optional) Configure an HTTP(S) proxy server to be used by the agent.&#x20;

**APPSEC\_AUTO\_POLICY\_LOAD**: (Optional) When set to `true`, allows you to set the open-appsec agent to automatically apply any new changes in the local\_policy.yaml file without having to restart the agent container or applying the changes with `open-appsec-ctl -ap` (note that this can take up to 30 seconds). This is useful especially in DevOps scenarios with continuous deployment scenarios.

**APPSEC\_VERSION**: Allows you to specify a specific version for deployment instead of using the default `latest` version for the containers provided by open-appsec (not relevant for postgres container).

**Additional configuration available specifically for this integration type:**

**KONG\_CONFIG**: Set the directory on the docker host used for the volume mount to the Kong  `/opt/kong` directory. Make sure to have a valid Kong declarative configuration file kong.yaml in the mounted directory.

For testing purposes in a lab environment you can activate the deployment of the vulnerable juiceshop-backend container via `COMPOSE_PROFILES` key (see above) and then deploy the available configuration example for exposing it via the proxy, which is provided by the open-appsec team (download link is provided in the .env file).

{% hint style="info" %}
You find some additional advanced configuration options described within the `docker-compose.yaml` file as comments.
{% endhint %}
{% endtab %}

{% tab title="APISIX" %}

* Download the default `.env` file here:

{% code overflow="wrap" %}

```bash
wget https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/apisix/.env
```

{% endcode %}

{% embed url="<https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/apisix/.env>" %}

* **If you created a deployment profile in the WebUI and copied the Token from it:**

  \
  Edit the `.env` file and add your token to the key `APPSEC_AGENT_TOKEN`.
* **If you did not create a deployment profile in the WebUI and do not want to connect your deployment to central WebUI (SaaS) at all:**

  \
  Set the value `standalone` for the key `COMPOSE_PROFILES` which will activate the deployment of additional containers which are required only when not connected to the WebUI at all (resulting in standalone, locally, declaratively managed deployment).
* Replace `user@email.com` in the .env file with your own email. (More details below.)

#### Available settings in the `.env` file allowing further customization of the deployment:

**APPSEC\_AGENT\_TOKEN:** For connecting your open-appsec deployment to central WebUI  set APPSEC\_AGENT\_TOKEN to your own deployment profile token as copied from profile settings in the open-appsec central WebUI (see section [#prerequisites](#prerequisites "mention") above).

**COMPOSE\_PROFILES:** Possible values you can set for this key:\
&#x20;(you can set multiple values, separated by comma)

`standalone` : This will activate the deployment of additional containers which are required **only** when you are not connected to the WebUI at all, resulting in standalone, locally- and  declaratively-managed deployment.

{% hint style="warning" %}
**Only** activate the `standalone` profile in case you did not set a WebUI deployment profile token as value for the APPSEC\_AGENT\_TOKEN key (see above)!
{% endhint %}

{% hint style="info" %}
The additional containers introduce some additional functionality, which is relevant for standalone deployments only (already available when connected to central management WebUI):\
\- Local syncing of learning between open-appsec processes and agents\
\- View learning progress on CLI with open-appsec-tuning-tool\
\- Receive configuration recommendations based on the learning progress using the open-appsec-tuning-tool\
\- Receive tuning suggestions and manage them (approve/reject) using the open-appsec-tuning-tool\
\
More details on the open-appsec-tuning-tool here: [Track Learning and Local Tuning in Standalone Deployments](/how-to/configuration-and-learning/track-learning-and-local-tuning-in-standalone-deployments)
{% endhint %}

`juiceshop` : This will deploy an additional, vulnerable juiceshop-backend container that can be used for demo and testing purposes.

{% hint style="warning" %}
Do not activate the juiceshop profile in production environments as the juiceshop container is intentionally highly vulnerable and meant for testing in lab environments only!
{% endhint %}

**USER\_EMAIL:** (Optional) Associate your email address with your specific deployment by replacing `user@email.com` with your own email address.

This allows the open-appsec team to provide you easy assistance in case of any issues you might have with your specific deployment in the future and also to provide you information proactively regarding open-appsec in general or regarding your specific deployment. This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future.

**APPSEC\_HTTPS\_PROXY**: (Optional) Configure an HTTP(S) proxy server to be used by the agent.&#x20;

**APPSEC\_AUTO\_POLICY\_LOAD**: (Optional) When set to `true`, allows you to set the open-appsec agent to automatically apply any new changes in the local\_policy.yaml file without having to restart the agent container or applying the changes with `open-appsec-ctl -ap` (note that this can take up to 30 seconds). This is useful especially in DevOps scenarios with continuous deployment scenarios.

**APPSEC\_VERSION**: Allows you to specify a specific version for deployment instead of using the default `latest` version for the containers provided by open-appsec (not relevant for postgres container).

**Additional configuration available specifically for this integration type:**

**APISIX\_CONFIG**: Set the directory on the docker host used for the APISIX configuration file mount to the APISIX file path `/usr/local/apisix/conf/apisix.yaml`.  Make sure to have a valid apisix configuration for APISIX in standalone mode in the mounted file.

For testing purposes in a lab environment you can activate the deployment of the vulnerable juiceshop-backend container via `COMPOSE_PROFILES` key (see above) and then deploy the available configuration example for exposing it via the proxy, which is provided by the open-appsec team (download link is provided in the .env file).

{% hint style="info" %}
You find some additional advanced configuration options described within the `docker-compose.yaml` file as comments.
{% endhint %}
{% endtab %}

{% tab title="Envoy (Beta)" %}

* Download the default `.env` file here:

{% code overflow="wrap" %}

```bash
wget https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/envoy/.env
```

{% endcode %}

{% embed url="<https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/envoy/.env>" %}

* **If you created a deployment profile in the WebUI and copied the Token from it:**

  \
  Edit the `.env` file and add your token to the key `APPSEC_AGENT_TOKEN`.
* **If you did not create a deployment profile in the WebUI and do not want to connect your deployment to central WebUI (SaaS) at all:**

  \
  Set the value `standalone` for the key `COMPOSE_PROFILES` which will activate the deployment of additional containers which are required only when not connected to the WebUI at all (resulting in standalone, locally, declaratively managed deployment).
* Replace `user@email.com` in the .env file with your own email. (More details below.)

{% hint style="warning" %}
When providing your own envoy.yaml configuration file, make sure to add the required configuration to load the open-appsec attachment filter! Follow these instructions:\
[Load the Attachment in Proxy Configuration](/deployment-and-upgrade/load-the-attachment-in-proxy-configuration)
{% endhint %}

#### Available settings in the `.env` file allowing further customization of the deployment:

**APPSEC\_AGENT\_TOKEN:** For connecting your open-appsec deployment to central WebUI  set APPSEC\_AGENT\_TOKEN to your own deployment profile token as copied from profile settings in the open-appsec central WebUI (see section [#prerequisites](#prerequisites "mention") above).

**COMPOSE\_PROFILES:** Possible values you can set for this key:\
&#x20;(you can set multiple values, separated by comma)

`standalone` : This will activate the deployment of additional containers which are required **only** when you are not connected to the WebUI at all, resulting in standalone, locally- and  declaratively-managed deployment.

{% hint style="warning" %}
**Only** activate the `standalone` profile in case you did not set a WebUI deployment profile token as value for the APPSEC\_AGENT\_TOKEN key (see above)!
{% endhint %}

{% hint style="info" %}
The additional containers introduce some additional functionality, which is relevant for standalone deployments only (already available when connected to central management WebUI):\
\- Local syncing of learning between open-appsec processes and agents\
\- View learning progress on CLI with open-appsec-tuning-tool\
\- Receive configuration recommendations based on the learning progress using the open-appsec-tuning-tool\
\- Receive tuning suggestions and manage them (approve/reject) using the open-appsec-tuning-tool\
\
More details on the open-appsec-tuning-tool here: [Track Learning and Local Tuning in Standalone Deployments](/how-to/configuration-and-learning/track-learning-and-local-tuning-in-standalone-deployments)
{% endhint %}

`juiceshop` : This will deploy an additional, vulnerable juiceshop-backend container that can be used for demo and testing purposes.

{% hint style="warning" %}
Do not activate the juiceshop profile in production environments as the juiceshop container is intentionally highly vulnerable and meant for testing in lab environments only!
{% endhint %}

**USER\_EMAIL:** (Optional) Associate your email address with your specific deployment by replacing `user@email.com` with your own email address.

This allows the open-appsec team to provide you easy assistance in case of any issues you might have with your specific deployment in the future and also to provide you information proactively regarding open-appsec in general or regarding your specific deployment. This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future.

**APPSEC\_HTTPS\_PROXY**: (Optional) Configure an HTTP(S) proxy server to be used by the agent.&#x20;

**APPSEC\_AUTO\_POLICY\_LOAD**: (Optional) When set to `true`, allows you to set the open-appsec agent to automatically apply any new changes in the local\_policy.yaml file without having to restart the agent container or applying the changes with `open-appsec-ctl -ap` (note that this can take up to 30 seconds). This is useful especially in DevOps scenarios with continuous deployment scenarios.

**APPSEC\_VERSION**: Allows you to specify a specific version for deployment instead of using the default `latest` version for the containers provided by open-appsec (not relevant for postgres container).

**Additional configuration available specifically for this integration type:**

**ENVOY\_CONFIG**: Set the directory on the docker host used for the Envoy configuration file mount to the Envoy file path `/envoy.yaml`.  Make sure to have a valid envoy.yaml configuration file for Envoy in the mounted file path.

For testing purposes in a lab environment you can activate the deployment of the vulnerable juiceshop-backend container via `COMPOSE_PROFILES` key (see above) and then deploy the available configuration example for exposing it via the proxy, which is provided by the open-appsec team (download link is provided in the `.env` file).

{% hint style="warning" %}
When providing your own envoy.yaml configuration file, make sure to add the required configuration to load the open-appsec attachment filter! Follow these instructions:\
[Load the Attachment in Proxy Configuration](/deployment-and-upgrade/load-the-attachment-in-proxy-configuration)
{% endhint %}

**ENVOY\_CONCURRENCY**: Allows setting the desired amount of Envoy worker processes. I order to use this parameter, specify this in the `.env` file and also adjust the "command" line for the appsec-envoy container in the `docker-compose.yaml` file (see additional comments in that file).\
Make sure to also adjust the following two parameters `ENVOY_CONCURRENCY_CALC` and `ENVOY_CONCURRENCY_NUMBER` accordingly if you adjusted `ENVOY_CONCURRENCY`.

**ENVOY\_CONCURRENCY\_CALC**: Only relevant if you made a custom configuration for the amount of Envoy worker threads using the optional ENVOY\_CONCURRENCY parameter (see also explanation in docker-compose.yaml). In this case you must set `ENVOY_CONCURRENCY_CALC=custom` and then also provide the specified amount of Envoy worker threads in the `ENVOY_CONCURRENCY_NUMBER` parameter.\
This will make sure that the open-appsec attachment will create the right amount of transaction handlers.\
Possible values for `ENVOY_CONCURRENCY_CALC`: "numOfCores" (default), "custom"

**ENVOY\_CONCURRENCY\_NUMBER**: Only relevant if you made a custom configuration for the amount of Envoy worker threads using the optional ENVOY\_CONCURRENCY parameter (see also explanation in docker-compose.yaml).&#x20;

See explanation for `ENVOY_CONCURRENCY_CALC` for more details.

{% hint style="info" %}
You find some additional advanced configuration options described within the `docker-compose.yaml` file as comments.
{% endhint %}
{% endtab %}
{% endtabs %}

4. If you decided to locally, declaratively manage open-appsec with `local_policy.yaml` file: \
   \
   Download the initial declarative configuration file for open-appsec into new subfolder `./appsec-localconfig`:<br>

   ```bash
   mkdir ./appsec-localconfig
   wget https://raw.githubusercontent.com/openappsec/openappsec/main/config/linux/v1beta1/prevent/local_policy.yaml -O ./appsec-localconfig/local_policy.yaml
   ```

{% hint style="info" %}
This example configuration file is already set to `mode: prevent-learn` so that open-appsec will prevent attacks right from the start.\
Here's the path for an alternative *local\_policy.yaml* file set to detect-learn mode.\
<https://raw.githubusercontent.com/openappsec/openappsec/main/config/linux/v1beta1/detect/local_policy.yaml>\
(or simply adjust the setting in the `mode` setting in the earlier *local\_policy.yaml* file to `detect-learn`)\
\
In production environments it's always recommended to start in `detect-learn` mode to allow open-appsec to achieve a certain learning level based on traffic observed before moving to `prevent-learn`for better detection accuracy and strongly reduced false positives.\
\
Read more about this here: \
[Track Learning and Move From Learn/Detect to Prevent](/how-to/configuration-and-learning/track-learning-and-move-from-learn-detect-to-prevent)
{% endhint %}

5. (only relevant when upgrading existing postgres database) Postgres database upgrade instructions

{% hint style="warning" %}
This is ONLY relevant if ALL of the following applies to your current deployment:

* you are redeploying/ugprading an existing open-appsec deployment\
  (this is not relevant for new deployments)

* your current deployment is a standalone deployment\
  (without a web UI profile token provided in the `.env` file, when connecting to web UI with a profile token typically there should not be any local postgres database being deployed/used)

* your current deployment has the docker.compose `standalone`  profile set in the `.env` file\
  (otherwise postgres container wouldn't be deployed)

* you now want to use a newer postgres image version, which is a new major release\
  (which means database conversion is required)
  {% endhint %}

* If all of the above applies, make sure to perform a postgres database upgrade following the steps provided here: [Upgrade Postgres version (Docker-Compose)](/deployment-and-upgrade/upgrade-postgres-version-docker-compose)

6. Perform the deployment

{% hint style="warning" %}
This docker-compose file requires a postgres container version ≥ 18 due to changes in the postgres database path. If you already have a postgres container with tag "latest" of an earlier version in your local registry, make sure to pull the latest container image first, also it is highly recommended to specify a specific postgres major release version tag in the `.env` file, e.g. `APPSEC_POSTGRES_VERSION=18`
{% endhint %}

```bash
docker-compose up -d
```

You will see output similar to the below.\
Note that the amount of container will vary based between deployments with and without connection to central WebUI.\
\
![](/files/n78DmRFlWPu29yOokxla)

7. Verify that all containers are up and running by verifying their status in docker ps output. Note that the amount of container will vary based between deployments with and without connection to central WebUI.

```bash
docker ps
```

You will see output similar to the below:

<figure><img src="/files/68gPCyP7G02HskqKHLsz" alt=""><figcaption><p>docker ps example output with all containers up</p></figcaption></figure>

**Congratulations, you successfully deployed open-appsec WAF integrated with the reverse proxy solution of your choice!**

{% hint style="info" %}
For Production usage we recommend to switch from using the Basic to the more accurate Advanced Machine Learning model, as described here:&#x20;

[Using the Advanced Machine Learning Model](/getting-started/using-the-advanced-machine-learning-model)
{% endhint %}

## Recommended next steps:

* **If you connected to central WebUI AND configured your deployment profile in the WebUI to "This management" mode for centrally managing open-appsec configuration**:\
  \
  **Create one or more assets in the WebUI** which represent web applications and/or Web APIs which you want to be protected by open-appsec WAF and allows you to adjust the open-appsec configuration specifically for each of them. <br>

  Make sure to link your assets to the specific WebUI Profile which you created earlier (General -> Profiles) and adjust the Threat Prevention mode to Detect-Learn or Prevent (Threat Prevention -> Mode), the steps are described here: \
  \
  [Protect Additional Assets](/getting-started/using-the-web-ui-saas/protect-additional-assets)

{% hint style="warning" %}
Don't forget to Enforce policy in the WebUI after you did any changes for those changes to become effective!
{% endhint %}

* **If you decided to locally, declaratively manage open-appsec (with or without connection to central WebUI in "Declarative configuration" mode):**\
  \
  Follow the steps described here to configure your open-appsec deployment using the `local_policy.yaml` file: \
  \
  [Configuration Using Local Policy File (Docker)](/getting-started/start-with-docker/configuration-using-local-policy-file-docker)\
  \
  In case you connected your locally managed deployment also to the central WebUI in "Declarative Configuration" mode, you can check security logs and view agent status and configuration also in the central WebUI at <https://my.openappsec.io> .

{% hint style="warning" %}
Don't forget to apply the policy using `open-appsec-ctl -ap` in the open-appsec-agent container or by setting `APPSEC_AUTO_POLICY_LOAD` in the `.env` file to `true` for automatic  application of any configuration changes done in the `local_policy.yaml` file for the changes to become effective!
{% endhint %}


# Configuration Using Local Policy File (Docker)

For deployments of open-appsec on Docker the configuration can be done in a declarative way using a single YAML file which holds all the relevant configuration objects. \
This way it is fully compatible for integration in GitOps CD-based processes.

Alternatively management can also be done centrally via the central open-appsec WebUI (SaaS).

### Location of the declarative configuration file

On Docker the declarative configuration file for the open-appsec Agent is typically provided to the agent container via a volume mount.

In your `docker-compose.yaml` or the `docker run` command which you used for your current deployment you can find the specific folder on the docker host which gets mounted to `/ext/appsec` in the open-appsec agent container.\
This is the folder which should contain your `local_policy.yaml` file.\
\
(Note that this folder then gets mounted internally to `/etc/cp/policy/local_policy.yaml` which is where the agent looks for the actual local policy to apply, but on Docker you should always manage the file in `/ext/appsec` file location)

You can show and edit the full default declarative configuration file with the following command:

#### From within the appsec-agent container:

`vi /ext/appsec/local_policy.yaml`

or by using the interactive CLI tool `open-appsec-ctl` : [Using the open-appsec-ctl Tool](/getting-started/start-with-linux/using-the-open-appsec-ctl-tool)

#### From the docker host:

(replace "appsec-agent" with your own agent container name, if you adjusted it):

`docker exec -it appsec-agent vi /ext/appsec/local_policy.yaml`

### Basic configuration

The default policy within the default configuration file, which is deployed during the installation, contains the following setting which sets the mode to `detect-learn` for all web resources provided by the NGINX or Kong Gateway:

`policies.default.mode: detect-learn`

If you want attacks instead to be prevented by default for all web resources you can change this as follows:

`policies.default.mode: prevent-learn`

The specific rules section `policies.specific-rules` (v1beta1) / `policies.specificRules` (v1beta2) allows you to create specific rule entries for specific hostnames, hostname-path combinations or paths which override the default policy.

{% hint style="danger" %}
The mode settings defined in the policy for default or specific-rules will only have an effect on the actual enforcement for specific security features when the `override-mode` setting in the referenced practice is set to `as-top-level` as this will cause it to inherited the mode setting from the policy.
{% endhint %}

**It is recommended to configure a specific rule for each of your protected web applications and web APIs assets** (starting with `detect-learn` mode, later move to `prevent-learn`).\
\
This allows you to apply a separate enforcement mode setting for each of these protected assets as well as to customize many other settings like selecting the logging configuration, the threat prevention and access control (introduced in v1beta2) practices configuration or selecting a custom-response like a specific response code or a custom block page.

Also the real-time contextual machine learning will be done individually per each configured specific rule representing a protected asset.\
\
Note that these settings are all configured by referencing other elements which are defined separately in the configuration file as well, so that you can reuse them multiple times in a kind of object-oriented way, see examples below:

{% tabs %}
{% tab title="v1beta1" %}

```yaml
policies:
  default:
  ...
  ...
  specific-rules:
  - host: "www.my-specific-host.com/my-specific-path"
    triggers:
    - appsec-default-log-trigger
    mode: detect-learn
    practices:
    - webapp-default-practice
    custom-response: appsec-default-web-user-response
```

It is recommended that once sufficient confidence was gained in `detect-learn` mode for an asset which has a specific rule (review the logs) to change the mode for this specific rule to `prevent-learn` mode:

```yaml
policies:
  default:
  ...
  ...
  specific-rules:
  - host: "www.my-specific-host.com/my-specific-path"
    triggers:
    - appsec-default-log-trigger
    mode: prevent-learn
    practices:
    - webapp-default-practice
    custom-response: appsec-default-web-user-response
```

{% endtab %}

{% tab title="v1beta2" %}

```yaml
policies:
  default:
  ...
  ...
  specificRules:
  - host: "www.my-specific-host.com/my-specific-path"
    triggers:
    - appsec-default-log-trigger
    mode: detect-learn
    threatPreventionPractices:
    - webapp-default-practice
    accessControlPractices:
    - webapp-default-practice
    customResponse: appsec-default-web-user-response
```

It is recommended that once sufficient confidence was gained in `detect-learn` mode for an asset which has a specific rule (review the logs) to change the mode for this specific rule to `prevent-learn` mode:

```yaml
policies:
  default:
  ...
  ...
  specificRules:
  - host: "www.my-specific-host.com/my-specific-path"
    triggers:
    - appsec-default-log-trigger
    mode: prevent-learn
    threatPreventionPractices:
    - webapp-default-practice
    accessControlPractices:
    - webapp-default-practice
    customResponse: appsec-default-web-user-response
```

{% endtab %}
{% endtabs %}

### Applying a changed local declarative configuration file&#x20;

Once you did any changes to the local declarative configuration file `local_policy.yaml` there's two ways how you can get those changes applied:

1. By using the open-appsec-ctl tool to apply the changes in the policy:

* From inside the Agent container:

```
open-appsec-ctl --apply-policy
```

* From the docker host:

```
docker exec -it appsec-agent open-appsec-ctl --apply-policy
```

Replace `appsec-agent` with your agent container name, if it has a different name.

2. By configuring the agent to automatically apply all changes in the `local_policy.yaml` file in `/ext/appsec`  once you save any changes within the file:\
   \
   Activate automatic policy load for the open-appsec agent by setting the following environment variable to true in your `docker-compose.yaml` or `docker run` command: \
   \
   `autoPolicyLoad=true`\
   \
   This is especially useful in CI/CD-style deployments that have a continuous deployment process in place.


# Local Policy File (Advanced)

The structure of the local configuration file which can be used for for managing the open-appsec Agent declaratively (as alternative to managing centrally via the open-appsec WebUI) on Docker is identical to the one used in Linux deployments.

The relevant documentation for the Local Policy File is provided here:

{% content-ref url="/pages/KokD6qvwxDg2XFok6k8D" %}
[Local Policy File (Advanced)](/getting-started/start-with-linux/local-policy-file-advanced)
{% endcontent-ref %}

{% content-ref url="/pages/0FbDJUC6OJ1a0lJ4lfQd" %}
[Local Policy File v1beta2 (beta)](/getting-started/start-with-linux/local-policy-file-v1beta2-beta)
{% endcontent-ref %}


# Deprecated Deployment Options

In this section you can find some deprecated deployment options for Docker, which are no longer recommended as they have been replaced by newer, improved deployment options since quite a while.

These are still shown here in case you are using these deployments in your environment.

<table><thead><tr><th width="249">Deprecated Deployment Type</th><th width="121">Deprecation Date</th><th>Deprecation Reason</th><th>Recommended Deployment</th></tr></thead><tbody><tr><td><a data-mention href="/pages/Figl5Clf9HtB0l99h5Yt">/pages/Figl5Clf9HtB0l99h5Yt</a></td><td>2025-08-25</td><td>Docker Compose is now the recommended deployment method</td><td><a data-mention href="/pages/rYOJ0WaqG1RkeSrxmN2H">/pages/rYOJ0WaqG1RkeSrxmN2H</a></td></tr><tr><td><a data-mention href="/pages/3baaCelK0AXgm6XTdnvt">/pages/3baaCelK0AXgm6XTdnvt</a></td><td>2025-08-25</td><td>Docker Compose is now the recommended deployment method</td><td><a data-mention href="/pages/rYOJ0WaqG1RkeSrxmN2H">/pages/rYOJ0WaqG1RkeSrxmN2H</a></td></tr></tbody></table>


# Install With Docker (Centrally Managed)

{% hint style="warning" %}
Deployment of open-appsec via `docker run` is now considered deprecated. Please deploy with Docker Compose instead following these instructions: [Deploy With Docker-Compose](/getting-started/start-with-docker/deploy-with-docker-compose)
{% endhint %}

## Prerequisites

* **Access to a SaaS tenant on my.openappsec.io (WebUI for SaaS management)**\
  Follow the instructions available here:

{% content-ref url="/pages/0ty9rMQEgnxS9LBuN7qw" %}
[Sign-Up and Login to Portal](/getting-started/using-the-web-ui-saas/sign-up-and-login-to-portal)
{% endcontent-ref %}

* **Agent profile created for open-appsec Docker deployment in SaaS tenant** \
  Follow the instructions available here, and make sure to choose the "**This management**" management mode. \
  Once done, don't forget to copy the profile token after policy installation as this is needed in the installation steps further below:

{% content-ref url="/pages/WMgZp7bTMiI5PD1ocIKp" %}
[Create a Profile](/getting-started/using-the-web-ui-saas/create-a-profile)
{% endcontent-ref %}

* Linux machine with:
  * Docker software installed (or similar compatible Container runtime)
  * Root Permissions&#x20;

## Installation

{% tabs %}
{% tab title="NGINX" %}
{% hint style="warning" %}
Make sure to meet the prerequisites on top of this page and to have the profile token available. Make sure you enforce the policy after profile creation.
{% endhint %}

**Follow these steps to deploy open-appsec and NGINX reverse proxy (including open-appsec attachment) with separate containers (e.g. on Docker) or implement this using your deployment CI pipeline:**\
(This is the standard deployment, an alternative option to deploy with a single, unified container is available as well, see "NGINX - Unified" tab.)

**Step 1:** Pull the open-appsec agent image or add/use it as part of the deployment CI’s container management system:

```bash
docker pull ghcr.io/openappsec/agent:latest
```

**Step 2:** Create the following empty directories to be used later for volume mounts in the docker run command for the agent.

```
<path-to-persistent-location-for-agent-config>
<path-to-persistent-location-for-agent-data-files>
<path-to-persistent-location-for-agent-debugs-and-logs>
```

{% hint style="info" %}
Creation of the folders above and the volume mounts shown in the next step with `-v` is optional but strongly recommended for having persistence of the important agent information (data, config, logs).
{% endhint %}

**Step 3:** Run the open-appsec agent container with this command:

<pre class="language-bash"><code class="lang-bash"><strong>docker run --name=open-appsec-agent \
</strong>--ipc=host \
-v &#x3C;path-to-persistent-location-for-agent-config>:/etc/cp/conf \
-v &#x3C;path-to-persistent-location-for-agent-data-files>:/etc/cp/data \
-v &#x3C;path-to-persistent-location-for-agent-debugs-and-logs>:/var/log/nano_agent \
-it \
-e registered_server='NGINX' \
-e user_email=&#x3C;your-email-address> \
-e AGENT_TOKEN=&#x3C;token> \
-e https_proxy=&#x3C;user:password@proxy address:port> \
-d ghcr.io/openappsec/agent:latest /cp-nano-agent
</code></pre>

Replace the `<token>` parameter with the token you copied from the profile in the WebUI before (see Prerequisites section above).&#x20;

The `https_proxy` environment variable allows you to configure an HTTP(S) proxy server to be used by the agent. It is optional and can be removed if not needed.

The optional `no-upgrade` flag to the `cp-nano-agent` command will start the agent without an initial upgrade.&#x20;

{% hint style="info" %}
The optional `user_email` environment variable allows you to associate your email address with your specific deployment by replacing `<your-email-address>` with your own email address.

This allows the open-appsec team to provide you easy assistance in case of any issues you might have with your specific deployment in the future and also to provide you information proactively regarding open-appsec in general or regarding your specific deployment. This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future.
{% endhint %}

**Step 3:** Create (or replace) the NGINX container by first pulling the open-appsec NGINX container, which already contains the open-appsec attachment. Alternatively, add/use it as part of the deployment CI’s container management system:

```bash
docker pull ghcr.io/openappsec/nginx-attachment:latest
```

**Step 4:** Run the open-appsec NGINX container, make sure to add the `--ipc=host` parameter, here’s an example command:

```bash
docker run --name open-appsec-nginx \
--ipc=host \
-p 80:80 \
-d ghcr.io/openappsec/nginx-attachment:latest
```

{% hint style="info" %}
For general NGINX configuration please check the relevant [NGINX documentation](https://nginx.org/en/docs/)
{% endhint %}

**Step 5:** Make sure both containers are running, use `docker ps` to verify.

**Step 6:** Navigate to the Agents tab and ensure the new Agent is successfully connected.

**Step 7:** Create one or more assets defining the specific resources that open-appsec should protect and don't forget to install the policy afterward. \
All required steps are explained here:

{% content-ref url="/pages/yvQt78cZU4kLymWzObq3" %}
[Protect Additional Assets](/getting-started/using-the-web-ui-saas/protect-additional-assets)
{% endcontent-ref %}
{% endtab %}

{% tab title="NGINX - Unified (beta)" %}
{% hint style="info" %}
This feature is currently in beta and may be subject to changes.
{% endhint %}

{% hint style="warning" %}
Make sure to meet the prerequisites on top of this page and to have the profile token available. Make sure you enforce the policy after profile creation.
{% endhint %}

**Follow these steps to deploy open-appsec combined with NGINX reverse proxy (including open-appsec attachment) with a single, unified container (e.g. on Docker) or implement this using your deployment CI pipeline:**

**Step 1:** Pull the open-appsec agent unified with NGINX image or add/use it as part of the deployment CI’s container management system:

```bash
docker pull ghcr.io/openappsec/agent-unified:latest
```

**Step 2:** Create the following empty directories to be used later for volume mounts in the docker run command for the agent.

```
<path-to-persistent-location-for-agent-config>
<path-to-persistent-location-for-agent-data-files>
<path-to-persistent-location-for-agent-debugs-and-logs>
```

{% hint style="info" %}
Creation of the folders above and the volume mounts shown in the next step with `-v` is optional but strongly recommended for having persistence of the important agent information (data, config, logs).
{% endhint %}

**Step 3:** Run the open-appsec agent container with this command:

```bash
docker run -d \
  --name open-appsec-agent-unified \
  --restart unless-stopped \
  -p 80:80 \
  -p 443:443 \
  -v <path-to-persistent-location-for-agent-config>:/etc/cp/conf \
  -v <path-to-persistent-location-for-agent-data-files>:/etc/cp/data \
  -v <path-to-persistent-location-for-agent-debugs-and-logs>:/var/log/nano_agent \
  -v <host-nginx-conf-path>:/etc/nginx/conf.d \
  -e user_email=<your-email-address> \
  -e AGENT_TOKEN=<token> \
  -e https_proxy=<user:password@proxy address:port> \
  ghcr.io/openappsec/agent-unified:latest /cp-nano-agent
```

Replace the `<token>` parameter with the token you previously copied from the profile in the WebUI (see Prerequisites section above).

The `https_proxy` environment variable allows you to configure an HTTP(S) proxy server to be used by the agent. It is optional and can be removed if not needed.

The optional `no-upgrade` flag to the `cp-nano-agent` command will start the agent without an initial upgrade.&#x20;

{% hint style="info" %}
The optional `user_email` environment variable allows you to associate your email address with your specific deployment by replacing `<your-email-address>` with your own email address.

This allows the open-appsec team to provide you easy assistance in case of any issues you might have with your specific deployment in the future and also to provide you information proactively regarding open-appsec in general or regarding your specific deployment. This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future.
{% endhint %}

{% hint style="info" %}
For general NGINX configuration please check the relevant [NGINX documentation](https://nginx.org/en/docs/)
{% endhint %}

**Step 3:** Make sure both containers are running, use `docker ps` to verify.

**Step 4:** Navigate to the Agents tab and ensure the new Agent is successfully connected.

**Step 5:** Create one or more assets defining the specific resources that open-appsec should protect and don't forget to install the policy afterward. \
All required steps are explained here:

{% content-ref url="/pages/yvQt78cZU4kLymWzObq3" %}
[Protect Additional Assets](/getting-started/using-the-web-ui-saas/protect-additional-assets)
{% endcontent-ref %}
{% endtab %}

{% tab title="Kong" %}
{% hint style="warning" %}
For Kong, as alternative to the traditional open-appsec attachment plugin, also a newer, more flexible Lua-based plugin is available, deployment instructions are available here:\
[Deploy With Docker-Compose](/getting-started/start-with-docker/deploy-with-docker-compose)
{% endhint %}

{% hint style="warning" %}
Make sure to meet the prerequisites on top of this page and to have the profile token available. Make sure you enforced the policy after profile creation.
{% endhint %}

**Follow these steps to install Kong with open-appsec using containers (e.g. on Docker) or using your deployment CI:**

**Step 1:** Pull the open-appsec agent image or add/use it as part of the deployment CI’s container management system:

```bash
docker pull ghcr.io/openappsec/agent:latest
```

**Step 2:** The volume mounts set in the next step with`-v` are optional but recommended for the persistence of the agent information (data, config, logs).\
If you want to use those parameters create the following empty directories to be used later for volume mounts in the docker run command for the agent.

```
<path-to-persistent-location-for-agent-config>
<path-to-persistent-location-for-agent-data-files>
<path-to-persistent-location-for-agent-debugs-and-logs>
```

**Step 3:** Run the open-appsec agent container with this command:

```bash
docker run --name=open-appsec-agent \
--ipc=host \
-v <path-to-persistent-location-for-agent-config>:/etc/cp/conf \
-v <path-to-persistent-location-for-agent-data-files>:/etc/cp/data \
-v <path-to-persistent-location-for-agent-debugs-and-logs>:/var/log/nano_agent \
-it \
-e registered_server='Kong' \
-e user_email=<your-email-address> \
-e AGENT_TOKEN=<token> \
-e https_proxy=<user:password@proxy address:port> \
-d ghcr.io/openappsec/agent:latest /cp-nano-agent
```

Replace the `<token>` parameter with the token you copied from the profile in the WebUI before (see Prerequisites section above).

The `https_proxy` environment variable allows you to configure an HTTP(S) proxy server to be used by the agent. It is optional and can be removed if not needed.

The optional `no-upgrade` flag to the `cp-nano-agent` command will start the agent without an initial upgrade.&#x20;

{% hint style="info" %}
The volume mounts set with`-v` are optional but recommended for the persistence of the agent information (data, config, logs).\
If you use those parameters create the following empty directories to be used later for volume mounts in the docker run command for the agent.

```
<path-to-persistent-location-for-agent-config>
<path-to-persistent-location-for-agent-data-files>
<path-to-persistent-location-for-agent-debugs-and-logs>
```

The optional `user_email` environment variable allows you to associate your email address with your specific deployment by replacing `<your-email-address>` with your own email address.

This allows us to provide you easy assistance in case of any issues you might have with your specific deployment in the future and also to provide you information proactively regarding open-appsec in general or regarding your specific deployment. This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future.
{% endhint %}

**Step 3:** Create (or replace) the Kong container by pulling the enhanced open-appsec Kong container, which already contains the open-appsec attachment. Alternatively, add/use it as part of the deployment CI’s container management system:

For Kong (open-source version):

```bash
docker pull ghcr.io/openappsec/kong-attachment:latest
```

For Kong Gateway (enterprise version):

```bash
docker pull ghcr.io/openappsec/kong-gateway-attachment:latest
```

**Step 4:** Run the open-appsec Kong container, make sure to add the `--ipc=host` parameter, here’s an example command:

For Kong (open-source version):

```bash
docker run \
--name kong \
--ipc=host \
-e KONG_DATABASE=off \
-p 8000:8000 -p 8443:8443 -p 127.0.0.1:8001:8001 -p 127.0.0.1:8444:8444 \
-d ghcr.io/openappsec/kong-attachment:latest
```

For Kong Gateway (enterprise version):

```bash
docker run \
--name kong-gateway \
--ipc=host \
-e KONG_DATABASE=off \
-p 8000:8000 -p 8443:8443 -p 127.0.0.1:8001:8001 -p 127.0.0.1:8444:8444 \
-d ghcr.io/openappsec/kong-gateway-attachment:latest
```

{% hint style="info" %}
For general Kong configuration details please check the [Kong documentation](< https://docs.konghq.com >)&#x20;
{% endhint %}

**Step 5:** Make sure both containers are running, use `docker ps` to verify.

**Step 6:** Navigate to the Agents tab and ensure the new Agent is successfully connected.

**Step 7:** Create one or more assets defining the specific resources that open-appsec should protect and don't forget to enforce the policy afterward. \
All required steps are explained here:

{% content-ref url="/pages/yvQt78cZU4kLymWzObq3" %}
[Protect Additional Assets](/getting-started/using-the-web-ui-saas/protect-additional-assets)
{% endcontent-ref %}
{% endtab %}

{% tab title="APISIX" %}
{% hint style="warning" %}
A new, enhanced version of the docker compose for APISIX\
is available here: [Deploy With Docker-Compose](/getting-started/start-with-docker/deploy-with-docker-compose) (Currently in Early Availability)
{% endhint %}

{% hint style="warning" %}
Make sure to meet the prerequisites on top of this page and to have the profile token available. Make sure you enforced the policy after profile creation.
{% endhint %}

**Follow these steps to install APISIX with open-appsec using containers (e.g. on Docker) or using your deployment CI:**

**Step 1:** Download the docker-compose.yaml file, see content bellow:&#x20;

```
wget https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/apisix/docker-compose.yaml
```

```
version: "3"

services:
  apisix:
    container_name: apisix
    image: "ghcr.io/openappsec/apisix-attachment:latest"
    ipc: host
    restart: always
    volumes:
      - .<apisix-conf-path>:/usr/local/apisix/conf/apisix.yaml:ro
    environment:
      - APISIX_STAND_ALONE=true
    ports:
      - "9180:9180/tcp"
      - "9080:9080/tcp"
      - "9091:9091/tcp"
      - "9443:9443/tcp"

  appsec-agent:
    container_name: appsec-agent
    image: 'ghcr.io/openappsec/agent:latest'
    ipc: host
    restart: unless-stopped
    environment:
      # adjust with your own email below
      - user_email=user@email.com
      - registered_server="APISIX"
      - AGENT_TOKEN=<TOKEN>
    volumes:
      - ./appsec-config:/etc/cp/conf
      - ./appsec-data:/etc/cp/data
      - ./appsec-logs:/var/log/nano_agent
      - ./appsec-localconfig:/ext/appsec
    command: /cp-nano-agent 
```

**Step 2:** Replace the following:

* &#x20;Replace the `<TOKEN>` parameter with the token you copied from the profile in the WebUI before (see Prerequisites section above),&#x20;
* Replace `<apisix-conf-path>` with the path for declarative configuration file for APISIX, an example file can be found [here](https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/apisix/apisix-example-config/apisix-standalone.yaml), for general APISIX configuration details please check the [APISIX Documentation](https://apisix.apache.org/docs/docker/manual/).

{% hint style="info" %}

* The volume mounts are optional but recommended for the persistence of the agent information (data, config, logs).
* The optional `user_email` environment variable allows you to associate your email address with your specific deployment by replacing `<your-email-address>` with your own email address. This allows us to provide you easy assistance in case of any issues you might have with your specific deployment in the future and also to provide you information proactively regarding open-appsec in general or regarding your specific deployment. This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future.
  {% endhint %}

**Step 3:** Run the Docker Compose

```
docker-compose up -d
```

**Step 4:** Make sure both containers are running, use `docker ps` to verify.

**Step 5:** Navigate to the Agents tab and ensure the new Agent is successfully connected.

**Step 6:** Create one or more assets defining the specific resources that open-appsec should protect and don't forget to enforce the policy afterward. \
All required steps are explained here:

{% content-ref url="/pages/yvQt78cZU4kLymWzObq3" %}
[Protect Additional Assets](/getting-started/using-the-web-ui-saas/protect-additional-assets)
{% endcontent-ref %}
{% endtab %}

{% tab title="Envoy" %}
For Envoy deployment on Docker please follow the docs for `docker-compose`-based installation provided here:

{% content-ref url="/pages/rYOJ0WaqG1RkeSrxmN2H" %}
[Deploy With Docker-Compose](/getting-started/start-with-docker/deploy-with-docker-compose)
{% endcontent-ref %}
{% endtab %}
{% endtabs %}

{% hint style="success" %}
Now your open-appsec installation on Docker is completed and your configured web app or API assets are protected!
{% endhint %}


# Install With Docker (Locally Managed)

{% hint style="warning" %}
Deployment of open-appsec via `docker run` is now considered deprecated. Please deploy with Docker Compose instead following these instructions: [Deploy With Docker-Compose](/getting-started/start-with-docker/deploy-with-docker-compose)
{% endhint %}

## Prerequisites

* Linux machine with:
  * &#x20;Docker installed (or similar, compatible container runtime)
  * &#x20;Root permissions&#x20;

**The following prerequisites are optional and only relevant if you want to connect your open-appsec agent directly to a WebUI (SaaS) management tenant:**

* Access to a SaaS tenant on my.openappsec.io (WebUI for SaaS management)\
  Follow the instructions available here:

{% content-ref url="/pages/0ty9rMQEgnxS9LBuN7qw" %}
[Sign-Up and Login to Portal](/getting-started/using-the-web-ui-saas/sign-up-and-login-to-portal)
{% endcontent-ref %}

* Agent profile created for open-appsec Docker deployment in SaaS tenant \
  Follow the instructions available here, make sure to choose the "**Declarative configuration"** management mode.\
  Once done, don't forget to copy the profile token after policy installation as this is needed in the installation steps further below:

{% content-ref url="/pages/WMgZp7bTMiI5PD1ocIKp" %}
[Create a Profile](/getting-started/using-the-web-ui-saas/create-a-profile)
{% endcontent-ref %}

## Installation

{% tabs %}
{% tab title="NGINX" %}
**Follow these steps to deploy open-appsec and NGINX reverse proxy (including open-appsec attachment) with separate containers (e.g. on Docker) or implement this using your deployment CI pipeline:**\
(This is the standard deployment, an alternative option to deploy with a single, unified container is available as well, see "NGINX - Unified" tab.)

**Step 1:** Pull the open-appsec agent image or add/use it as part of the deployment CI’s container management system:

```bash
docker pull ghcr.io/openappsec/agent:latest
```

**Step 2:** Create a valid `local_policy.yaml` file which contains the desired declarative configuration for the agent container and put it in a local directory of your choice to be used in the docker run command for the agent as `<path-to-persistent-location-for-local-configuration-file>` (see also Step 4 for the docker run command).

You can also download and use the example default `local_policy.yaml` from the [open-appsec GitHub repository](https://raw.githubusercontent.com/openappsec/openappsec/main/examples/local_policy.yaml).

Full details regarding the declarative local policy file structure are available here:&#x20;

{% content-ref url="/pages/XgfzlOEGSM2hy1w6e94z" %}
[Configuration Using Local Policy File (Docker)](/getting-started/start-with-docker/configuration-using-local-policy-file-docker)
{% endcontent-ref %}

**Step 3:** Create the following empty directories to be used later for volume mounts in the docker run command for the agent.

```
<path-to-persistent-location-for-agent-config>
<path-to-persistent-location-for-agent-data-files>
<path-to-persistent-location-for-agent-debugs-and-logs>
```

{% hint style="info" %}
Creation of the folders above and the volume mounts shown in the next step with `-v` is optional but strongly recommended for having persistence of the important agent information (data, config, logs).\
Mounting a folder `<path-to-local-configuration-file>`, which must contain a valid local configuration file for the open-appsec agent, to `/ext/appsec` directory inside the agent container on the other hand is mandatory for standalone deployments.
{% endhint %}

**Step 4:** Run the open-appsec agent container with this command:

```bash
docker run --name=open-appsec-agent \
--ipc=host \
-v <path-to-persistent-location-for-agent-config>:/etc/cp/conf \
-v <path-to-persistent-location-for-agent-data-files>:/etc/cp/data \
-v <path-to-persistent-location-for-agent-debugs-and-logs>:/var/log/nano_agent \
-v <path-to-persistent-location-for-local-configuration-file>:/ext/appsec \
-e registered_server='NGINX' \
-e user_email=<add-your-email-here> \
-e https_proxy=<user:password@proxy-address:port> \
-e autoPolicyLoad=false \
-it -d ghcr.io/openappsec/agent:latest /cp-nano-agent
```

{% hint style="info" %}

* `AGENT_TOKEN <TOKEN>`(environment variable, optional),  add with the token you copied from the profile in the WebUI before (see Prerequisites section above).&#x20;
* `https_proxy` (environment variable) : allows you to configure an HTTP(S) proxy server to be used by the agent. It is optional and can be removed if not needed.
* `autoPolicyLoad` (environment variable):  when set to `true`, allows you to set the open-appsec agent to automatically apply any new changes in the local\_policy.yaml file without having to restart the agent container or applying the changes with `open-appsec-ctl -ap` (note that this can take up to 30 seconds). This is useful, especially in DevOps/continuous deployment scenarios.
* `user_email` (environment variable): allows you to provide your email address.
* `no-upgrade` (optional) flag to the `cp-nano-agent` command will start the agent without an initial upgrade.&#x20;
  {% endhint %}

{% hint style="info" %}
The optional `user_email` environment variable allows you to associate your email address with your specific deployment by replacing `<your-email-address>` with your own email address.

This allows the open-appsec team to provide you easy assistance in case of any issues you might have with your specific deployment in the future and also to provide you information proactively regarding open-appsec in general or regarding your specific deployment. This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future.
{% endhint %}

**Step 5:** Create (or replace) the NGINX container by first pulling the open-appsec NGINX container, which already contains the open-appsec attachment. Alternatively, add/use it as part of the deployment CI’s container management system:

```bash
docker pull ghcr.io/openappsec/nginx-attachment:latest
```

**Step 6:** Run the open-appsec NGINX container, make sure to add the `--ipc=host` parameter, here’s an example command:

```bash
docker run \
--name open-appsec-nginx \
--ipc=host \
-p 80:80 \
-d ghcr.io/openappsec/nginx-attachment:latest
```

{% hint style="info" %}
For general NGINX configuration please check the relevant [NGINX documentation](https://nginx.org/en/docs/).
{% endhint %}

**Step 7:** Make sure both containers are running, use `docker ps` to verify.

**If you've connected to SaaS Management Tenant in Step 4:**

**Step 8:** Navigate to the Agents tab in the WebUI and ensure the new Agent is successfully connected.
{% endtab %}

{% tab title="NGINX - Unified (beta)" %}
{% hint style="info" %}
This feature is currently in beta and may be subject to changes.
{% endhint %}

{% hint style="warning" %}
Make sure to meet the prerequisites on top of this page and to have the profile token available. Make sure you enforce the policy after profile creation.
{% endhint %}

**Follow these steps to deploy open-appsec combined with NGINX reverse proxy (including open-appsec attachment) with a single, unified container (e.g. on Docker) or implement this using your deployment CI pipeline:**

**Step 1:** Pull the open-appsec agent unified with the NGINX image or add/use it as part of the deployment CI’s container management system:

```bash
docker pull ghcr.io/openappsec/agent-unified:latest
```

**Step 2:** Create a valid `local_policy.yaml` file which contains the desired declarative configuration for the agent container and put it in a local directory of your choice to be used in the docker run command for the agent as `<path-to-persistent-location-for-local-configuration-file>` (see also Step 4 for the docker run command).

You can also download and use the example default `local_policy.yaml` from the [open-appsec GitHub repository](https://raw.githubusercontent.com/openappsec/openappsec/main/examples/local_policy.yaml).

Full details regarding the declarative local policy file structure are available here:&#x20;

{% content-ref url="/pages/XgfzlOEGSM2hy1w6e94z" %}
[Configuration Using Local Policy File (Docker)](/getting-started/start-with-docker/configuration-using-local-policy-file-docker)
{% endcontent-ref %}

**Step 3:** Create the following empty directories to be used later for volume mounts in the docker run command for the agent.

```
<path-to-persistent-location-for-agent-config>
<path-to-persistent-location-for-agent-data-files>
<path-to-persistent-location-for-agent-debugs-and-logs>
```

{% hint style="info" %}
Creation of the folders above and the volume mounts shown in the next step with `-v` is optional but strongly recommended for having persistence of the important agent information (data, config, logs).\
Mounting a folder `<path-to-local-configuration-file>`, which must contain a valid local configuration file for the open-appsec agent, to `/ext/appsec`directory inside the agent container is mandatory for standalone deployments.
{% endhint %}

**Step 4:** Run the open-appsec agent container with this command:

<pre class="language-bash"><code class="lang-bash">docker run -d \
  --name open-appsec-agent-unified \
  --restart unless-stopped \
  -p 80:80 \
  -p 443:443 \
  -v &#x3C;path-to-persistent-location-for-agent-config>:/etc/cp/conf \
<strong>  -v &#x3C;path-to-persistent-location-for-agent-data-files>:/etc/cp/data \
</strong>  -v &#x3C;path-to-persistent-location-for-agent-debugs-and-logs>:/var/log/nano_agent \
  -v &#x3C;path-to-persistent-location-for-local-configuration-file>:/ext/appsec \
  -e user_email=&#x3C;your-email-address> \
  -e https_proxy=&#x3C;user:password@proxy address:port> \
  ghcr.io/openappsec/agent-unified:latest /cp-nano-agent
</code></pre>

{% hint style="info" %}

* `AGENT_TOKEN <TOKEN>`(environment variable, optional),  add with the token you copied from the profile in the WebUI before (see Prerequisites section above).
* The `https_proxy` environment variable allows you to configure an HTTP(S) proxy server to be used by the agent. It is optional and can be removed if not needed.
* The `user_email` environment variable allows you to provide your email address.
  {% endhint %}

{% hint style="info" %}
The optional `user_email` environment variable allows you to associate your email address with your specific deployment by replacing `<your-email-address>` with your own email address.

This allows the open-appsec team to provide you easy assistance in case of any issues you might have with your specific deployment in the future and also to provide you information proactively regarding open-appsec in general or regarding your specific deployment. This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future.
{% endhint %}

{% hint style="info" %}
For general NGINX configuration please check the relevant [NGINX documentation](https://nginx.org/en/docs/).
{% endhint %}

**Step 5:** Make sure both containers are running, use `docker ps` to verify.

**If you've connected to SaaS Management Tenant in Step 4:**

**Step 6:** Navigate to the Agents tab in the WebUI and ensure the new Agent is successfully connected.
{% endtab %}

{% tab title="Kong" %}
{% hint style="warning" %}
For Kong as alternative to the traditional open-appsec attachment plugin, also a newer, more flexible Lua-based plugin is available, deployment instructions are available here:\
[Deploy With Docker-Compose](/getting-started/start-with-docker/deploy-with-docker-compose)
{% endhint %}

**Follow these steps to install Kong with open-appsec using containers (e.g. on Docker) or using your deployment CI:**

**Step 1:** Pull the open-appsec agent image or add/use it as part of the deployment CI’s container management system:

```bash
docker pull ghcr.io/openappsec/agent:latest
```

**Step 2:** Create a valid `local-policy.yaml` file which contains the desired declarative configuration for the agent container (see also Step 3) and put it in a local directory to be used in the docker run command for the agent as `<path-to-persistent-location-for-local-configuration-file>` .

You can also download and use the example `local_policy.yaml` file from the [open-appsec GitHub repository](https://raw.githubusercontent.com/openappsec/openappsec/main/examples/local_policy.yaml).

Full details regarding the declarative local policy file structure are available here:&#x20;

{% content-ref url="/pages/XgfzlOEGSM2hy1w6e94z" %}
[Configuration Using Local Policy File (Docker)](/getting-started/start-with-docker/configuration-using-local-policy-file-docker)
{% endcontent-ref %}

**Step 3:** The volume mounts set in the next step with`-v` are optional but recommended for the persistence of the agent information (data, config, logs).\
If you want to use those parameters create the following empty directories to be used later for volume mounts in the docker run command for the agent.

```
<path-to-persistent-location-for-agent-config>
<path-to-persistent-location-for-agent-data-files>
<path-to-persistent-location-for-agent-debugs-and-logs>
```

**Step 4:** Run the open-appsec agent container with this command&#x20;

```bash
docker run --name=open-appsec-agent \
--ipc=host \
-v <path-to-persistent-location-for-agent-config>:/etc/cp/conf \
-v <path-to-persistent-location-for-agent-data-files>:/etc/cp/data \
-v <path-to-persistent-location-for-agent-debugs-and-logs>:/var/log/nano_agent \
-v <path-to-persistent-location-for-local-configuration-file>:/ext/appsec \
-e registered_server='Kong' \
-e user_email=<add-your-email-here> \
-e autoPolicyLoad=false \
-e https_proxy=<user:password@proxy-address:port> \
-it -d ghcr.io/openappsec/agent:latest /cp-nano-agent
```

{% hint style="info" %}

* `AGENT_TOKEN <TOKEN>`(environment variable, optional),  add with the token you copied from the profile in the WebUI before (see Prerequisites section above).&#x20;
* `https_proxy` (environment variable) : allows you to configure an HTTP(S) proxy server to be used by the agent. It is optional and can be removed if not needed.
* `autoPolicyLoad` (environment variable):  when set to `true`, allows you to set the open-appsec agent to automatically apply any new changes in the local\_policy.yaml file without having to restart the agent container or applying the changes with `open-appsec-ctl -ap` (note that this can take up to 30 seconds). This is useful, especially in DevOps/continuous deployment scenarios.
* `user_email` (environment variable): allows you to provide your email address.
* `no-upgrade` (optional) flag to the `cp-nano-agent` command will start the agent without an initial upgrade.&#x20;
  {% endhint %}

{% hint style="info" %}
The optional `user_email` environment variable allows you to associate your email address with your specific deployment by replacing `<your-email-address>` with your own email address.

This allows us to provide you easy assistance in case of any issues you might have with your specific deployment in the future and also to provide you information proactively regarding open-appsec in general or regarding your specific deployment. This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future.
{% endhint %}

**Step 5:** Create (or replace) the Kong container by pulling the enhanced open-appsec Kong container, which already contains the open-appsec attachment. Alternatively, add/use it as part of the deployment CI’s container management system:

For Kong (open-source version):

```bash
docker pull ghcr.io/openappsec/kong-attachment:latest
```

For Kong Gateway (enterprise version):

```bash
docker pull ghcr.io/openappsec/kong-gateway-attachment:latest
```

**Step 6:** Run the open-appsec Kong container, make sure to add the `--ipc=host` parameter, here’s an example command:

For Kong (open-source version):

```bash
docker run \
--name kong \
--ipc=host \
-e KONG_DATABASE=off \
-p 8000:8000 -p 8443:8443 -p 127.0.0.1:8001:8001 -p 127.0.0.1:8444:8444 \
-d ghcr.io/openappsec/kong-attachment:latest
```

For Kong Gateway (enterprise version):

```bash
docker run \
--name kong-gateway \
--ipc=host \
-e KONG_DATABASE=off  \
-p 8000:8000 -p 8443:8443 -p 127.0.0.1:8001:8001 -p 127.0.0.1:8444:8444 \
-d ghcr.io/openappsec/kong-gateway-attachment:latest

```

**Step 7:** Make sure both containers are running, use `docker ps` to verify.

**If you've connected to SaaS Management Tenant in Step 4:**

**Step 8:** Navigate to the Agents tab in the WebUI and ensure the new Agent is successfully connected. don't forget to enforce the policy afterward. More details here:

{% content-ref url="/pages/yvQt78cZU4kLymWzObq3" %}
[Protect Additional Assets](/getting-started/using-the-web-ui-saas/protect-additional-assets)
{% endcontent-ref %}

{% hint style="info" %}
For general Kong configuration details please check the [Kong documentation](https://docs.konghq.com)
{% endhint %}
{% endtab %}

{% tab title="APISIX Gateway" %}
{% hint style="warning" %}
A new, enhanced version of the docker compose for APISIX\
is available here: [Deploy With Docker-Compose](/getting-started/start-with-docker/deploy-with-docker-compose) (Currently in Early Availability)
{% endhint %}

**Follow these steps to install APISIX with open-appsec using containers (e.g. on Docker) or using your deployment CI:**&#x20;

**Step 1:** Create a folder to hold the appsec declarative configuration file, and download the example configuration file:&#x20;

```
mkdir ./appsec-localconfig
```

**Step 2:**  Create a valid `local_policy.yaml` file which contains the desired declarative configuration for the agent container and add to the folder:

```
wget https://raw.githubusercontent.com/openappsec/openappsec/main/examples/local_policy.yaml -O appsec-localconfig/local_policy.yaml
```

Full details regarding the declarative local policy file structure are available here:&#x20;

{% content-ref url="/pages/XgfzlOEGSM2hy1w6e94z" %}
[Configuration Using Local Policy File (Docker)](/getting-started/start-with-docker/configuration-using-local-policy-file-docker)
{% endcontent-ref %}

**Step 3:** Download the docker-compose file, see content bellow:&#x20;

```
wget https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/apisix/docker-compose.yaml
```

```
version: "3"

services:
  apisix:
    container_name: apisix
    image: "ghcr.io/openappsec/apisix-attachment:latest"
    ipc: host
    restart: always
    volumes:
      - .<apisix-conf-path>:/usr/local/apisix/conf/apisix.yaml:ro
    environment:
      - APISIX_STAND_ALONE=true
    ports:
      - "9180:9180/tcp"
      - "9080:9080/tcp"
      - "9091:9091/tcp"
      - "9443:9443/tcp"

  appsec-agent:
    container_name: appsec-agent
    image: 'ghcr.io/openappsec/agent:latest'
    ipc: host
    restart: unless-stopped
    environment:
      # adjust with your own email below
      - user_email=user@email.com
      - registered_server="APISIX"
    volumes:
      - ./appsec-config:/etc/cp/conf
      - ./appsec-data:/etc/cp/data
      - ./appsec-logs:/var/log/nano_agent
      - ./appsec-localconfig:/ext/appsec
    command: /cp-nano-agent 
```

**Step 4:** Replace `<apisix-conf-path>` with the path for declarative configuration file for APISIX, an example file can be found [here](https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/apisix/apisix-example-config/apisix-standalone.yaml), for general APISIX configuration details please check the [APISIX Documentation](https://apisix.apache.org/docs/docker/manual/).

{% hint style="info" %}

* The volume mounts are optional but recommended for the persistence of the agent information (data, config, logs).
* The optional `user_email` environment variable allows you to associate your email address with your specific deployment by replacing `<your-email-address>` with your own email address. This allows us to provide you easy assistance in case of any issues you might have with your specific deployment in the future and also to provide you information proactively regarding open-appsec in general or regarding your specific deployment. This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future.
* `AGENT_TOKEN <TOKEN>`(environment variable, optional),  add with the token you copied from the profile in the WebUI before (see Prerequisites section above).
  {% endhint %}

**Step 5:** Run the Docker Compose

```
docker-compose up -d
```

**Step 6:** Make sure both containers are running, use `docker ps` to verify.

**If you've added a Token Step 4:**

**Step 7:** Navigate to the Agents tab and ensure the new Agent is successfully connected.
{% endtab %}

{% tab title="Envoy" %}
For Envoy deployment on Docker please follow the docs for `docker-compose`-based installation provided here:

{% content-ref url="/pages/rYOJ0WaqG1RkeSrxmN2H" %}
[Deploy With Docker-Compose](/getting-started/start-with-docker/deploy-with-docker-compose)
{% endcontent-ref %}
{% endtab %}
{% endtabs %}

{% hint style="success" %}
Now your open-appsec installation on Docker is completed and your configured web app or API assets are protected!
{% endhint %}


# Start With Kubernetes

## Overview

open-appsec for Kubernetes protects web applications and APIs running in Kubernetes environments.\
It integrates with the popular [Ingress NGINX (Ingress Controller](https://kubernetes.github.io/ingress-nginx)), securing the ingress HTTP/S traffic to [Services](https://kubernetes.io/docs/concepts/services-networking/service/) inside Kubernetes [clusters](https://kubernetes.io/docs/concepts/architecture/).\
It also integrates with [Kong Gateway](https://konghq.com) (native Lua-based Kong plugin available) as well as [APISIX](https://apisix.apache.org/) API Gateways, securing distributed, exposed APIs at the API Gateway level.\
If you are using [Istio Service Mesh](https://istio.io/) with your Kubernetes clusters, you can integrate open-appsec directly with your existing [Istio Ingress Gateway](https://istio.io/latest/docs/tasks/traffic-management/ingress/ingress-control/).\
\
More integrations are planned to be added in the future (e.g. Envoy Gateway, Emissary Ingress).

{% tabs %}
{% tab title="Ingress NGINX" %}
The NGINX Ingress Controller and open-appsec for Kubernetes agent are deployed together with a single Helm chart. This diagram shows an example of a Kubernetes service exposed outside the Kubernetes cluster with an Ingress controller protected with open-appsec. The NGINX Ingress Controller container contains the open-appsec Attachment which communicates with the open-appsec Agent.

![](/files/vJbu3eZSaIa7M9nWMjZv)
{% endtab %}

{% tab title="Kong Gateway" %}
open-appsec can be flexibly integrated with Kong. This diagram shows K8s Web APIs/Apps exposed by an Kong API Gateway that is protected by open-appsec. Inside the Kong Gateway Pod there are following containers: Kong Gateway container, open-appsec Agent container and optional Kong Controller (Ingress Controller). Here open-appsec is integrated with the Kong Gateway container which contains the open-appsec Attachment for communication with the open-appsec Agent, this is implemented using a native Lua-based Kong plugin for attaching the open-appsec agent to the Kong Gateway.

<figure><img src="/files/XJXVJxjXRAKazZQzHcDF" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="APISIX gateway" %}
For Kubernetes based-deployments of APISIX integrated with open-appsec there’s a helm chart available, which is based on the official APISIX helm chart and further enhanced to also include the open-appsec attachment in the APISIX gateway container and the deployment of the open-appsec agent as a sidecar container in the same pod.

Here’s a simple architecture schematic for deployment on Kubernetes.

<figure><img src="/files/OaGsK2JwAdy89jMKJRPp" alt="" width="563"><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Istio Ingress Gateway" %}
open-appsec integrates with Istio Ingress Gateway in Kubernetes environments with Istio service mesh. This diagram shows K8s Web APIs/Apps exposed by an Istio Ingress Gateway that is protected by open-appsec. As part of the open-appsec deployment, using a K8s webhook, the open-appsec Agent container is injected automatically to the Istio Ingress Gateway pod and an Attachment filter is added to and loaded by the Envoy-based, `istio-proxy` container. This open-appsec Attachment filter is required for communication with the open-appsec Agent.

<figure><img src="/files/sll12EzpZaqYjl9Le3g1" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}

## Deployment Options

The recommended deployment option depends on the proxy solution you want to integrate with:

### Deployment with helm chart (recommended)

For integration with the following solutions, we provide a flexible helm chart, which is an extended version based on the original helm chart of the proxy solution to integrate with and offers separate, optional CRD deployment for locally, declaratively-managed deployments:&#x20;

* **Ingress NGINX**
* **APISIX API Gateway**
* Kong API Gateway (first generation of Kong integration using an NGINX attachment, an improved, native Kong integration using Lua-plugin is available further below!)

{% content-ref url="/pages/5K4Vs8LYwj2PuhVkLaka" %}
[Install Using Helm - new flow (beta)](/getting-started/start-with-kubernetes/install-using-helm-new-flow-beta)
{% endcontent-ref %}

### Deployment with injector helm chart (recommended)

For integration with the following proxy solutions, we provide a helm chart, which is used additionally to the original helm chart of the solution to integrate with, this helm chart automatically injects all required open-appsec components using a Kubernetes webhook into the existing solution's deployment:&#x20;

* **Kong API Gateway** (recommended Kong integration, using native Lua-based attachment plugin)
* **Istio Ingress Gateway**

{% content-ref url="/pages/UhUcVh3gY8dk44MjvbMd" %}
[Install With Helm using Webhook](/getting-started/start-with-kubernetes/install-with-helm-using-webhook)
{% endcontent-ref %}

### First generation helm chart (will be deprecated soon)

Our first generation Kubernetes helm chart is an extended version based on the original helm chart of the proxy solution to integrate with, following proxy solutions are supported:

{% hint style="warning" %}
This will be deprecated soon, as more flexible, improved helm-based installation options were made available already. This is shown primarily for existing users that still use this early deployment option.
{% endhint %}

* Ingress NGINX
* APISIX API Gateway
* Kong API Gateway (first generation of Kong integration using an NGINX attachment, an improved, native Kong integration using Lua-plugin is available further below!)

{% content-ref url="/pages/RL7uBssVsFZ06cSH7kmY" %}
[Install Using Helm](/getting-started/start-with-kubernetes/install-using-helm)
{% endcontent-ref %}

{% hint style="success" %}
You can always connect your deployment later to the open-appsec [central management web UI](https://my.openappsec.io/) (provided as SaaS service), which provides cloud logging & reporting, central management and monitoring of multiple K8s clusters and an easy-to-use WebUI for all administrative tasks.
{% endhint %}


# Install Using Interactive CLI Tool (Ingress NGINX)

The fastest and easiest way to deploy and configure open-appsec is using an interactive CLI tool which will guide you through the most commonly required customizations.

{% hint style="info" %}
You can try out the [Playground](https://www.openappsec.io/playground) - a fully operational K8S lab where you can learn to deploy open-appsec using the interactive CLI tool&#x20;

<img src="/files/b2FxzZWgtvIdlT9uBFGg" alt="" data-size="original">
{% endhint %}

## Prerequisites

* Kubernetes 1.16.0+ cluster with [RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) enabled with Cluster admin permissions
* [Helm 3 Package Manager](https://helm.sh/docs/intro/install/) installed on your local machine
* The `kubectl` and `wget` command-line tools installed on your bastion or platform that you use to access the Kubernetes cluster
* You have understanding of Kubernetes Ingress and either have a deployed Ingress or know how to configure one.

{% hint style="info" %}
For more details about Kubernetes Ingress see Kubernetes documentation [here](https://kubernetes.io/docs/concepts/services-networking/ingress/).&#x20;
{% endhint %}

## Installation

Download and run the installer (Linux-only, macOS soon) using these commands:

```bash
wget https://downloads.openappsec.io/open-appsec-k8s-install && chmod +x open-appsec-k8s-install
./open-appsec-k8s-install
```

The interactive installer has 3 steps:

**Step 1: Ingress**

The installer will present the available Kubernetes ingresses in the cluster and suggest two options:

1\) Duplicate an existing Ingress and add open-appsec to it. This option allows you to test that all services are properly accessible via the new ingress, while the existing ingress is up and running and without worrying about traffic disruption.

2\) Add open-appsec to an existing Ingress resource. This is a good approach for a lab, staging or non-critical production environment.

Choose the option that you prefer and press Enter. You will then be asked to select the ingress you wish to duplicate or add-to.

{% hint style="warning" %}
Note: In the current implementation the installer will only show existing ingress resources  where the ingress class name starts with "nginx".\
If your ingress resource's name does not match this requirement you can either rename it or install using helm (without the tool): [Install using Helm](/getting-started/start-with-kubernetes/install-using-helm).
{% endhint %}

{% tabs %}
{% tab title="NGINX Ingress Controller" %}
In both cases we will automatically add the required annotation linking the open-appsec policy to the ingress resource and we will also change the ingress class specification for the ingress (either to the copy or to the existing Ingress resource depending on your choice above) to point to the new NGINX Ingress Controller with open-appsec integration.&#x20;
{% endtab %}
{% endtabs %}

![](/files/U4Xjiqa79C5fgGHmtzxx)

**Step 2: Policy**

{% hint style="info" %}
The CLI tool will create a v1beta1 policy, if you are interested in using v1btea2 please use Helm to deploy open-appsec, find the full instructions [here](/getting-started/start-with-kubernetes/install-using-helm-new-flow-beta).
{% endhint %}

The installer will display the  default policy and allow you to change it if you wish. When saving you will be asked whether to save the settings as a manifest (YAML) or Helm chart

![](/files/xite4D0xqpWSamc0duxW)

{% hint style="info" %}
The default-best-practice-policy will:

* Inspect all traffic to all ingress rules (paths) / routes and learn it
* Detect suspicious requests in confidence high or critical.
* If set to prevent-learn, send an HTTP Error Code 403 Forbidden to the client that sent the bad request
* Log to stdout (so you can use fluentd/fluentbit) to send logs to ELK or other collector.
  {% endhint %}

**Step 3: Apply Configuration**

The installation tool will list commands to run in order to complete the installation and apply the configuration. The configuration resides in three files:

* open-appsec helm chart for NGINX Ingress Controller or Kong (CRDs and other necessary files)
* ingress.yaml - manifest created by the installer per your selections in Step 1
* open-appsec-policy.yaml - manifest created by the installer per your selections in Step 2

![](/files/orAibO4c4gn6cdeo8cso)

You can run the commands now or later. If you run them, congratulations - open-appsec is installed and working!

## Post-Install

{% tabs %}
{% tab title="NGINX Ingress Controller" %}

#### **Point your DNS to the Duplicated Ingress (skip if you chose existing Ingress in Step 1 above)**

After testing that your services are reachable, you can point your DNS to the new ingress.&#x20;

In case of a problem, at any time, you can either switch open-appsec off while running the same ingress code, or change your DNS back.

You can identify the IP address of the new ingress by running:

```
kubectl get ing -A
```

{% endtab %}
{% endtabs %}

### **Configuration Changes**

You can conduct policy changes, define exception and other advanced configuration in one of three ways:

* By running the interactive configuration tool: `open-appsec-cli`
* [By using open-appsec K8S custom resources](/getting-started/start-with-kubernetes/configuration-using-crds)
* [Using the WebUI](/getting-started/using-the-web-ui-saas)

{% hint style="info" %}
For Production usage you might want to switch from using the Basic to the more accurate Advanced Machine Learning model, as described here:&#x20;

[Using the Advanced Machine Learning Model](/getting-started/using-the-advanced-machine-learning-model)
{% endhint %}


# Configuration Using Interactive CLI Tool

{% hint style="info" %}
The CLI tool will create a v1beta1 policy, if you are interested in using v1btea2 please use Helm to deploy open-appsec, find the full instructions [here](/getting-started/start-with-kubernetes/install-using-helm-new-flow-beta).
{% endhint %}

{% hint style="info" %}
The open-appsec configuration tool supports:\
\- open-appsec for NGINX Ingress Controller\
\- open-appsec for Kong API Gateway\
\- open-appsec for Apache APISIX API Gateway
{% endhint %}

The open-appsec interactive configuration tool provides an easy way to set up open-appsec policies. It creates either a manifest (YAML) or Helmchart with all the configuration that you then can apply using kubectl apply or helm install commands.\
This tool is available once you performed the installation with the open-appsec-k8s-install tool.

Alternatively you can also download it from here:

```
wget https://downloads.openappsec.io/open-appsec-cli/linux/open-appsec-config
```

If you downloaded it make sure to run:

```
chmod +x open-appsec-config
```

To use the tool run:

```
./open-appsec-config
```

Select \[1] to setup and generate configuration files in YAML format.\
Then you can change, add or delete a specific rule or save your changes.

![](/files/g8LgbwU7UehX1LJahiMt)

When you decide to change a rule you must then select the specific rule you want to change before you will see the options to adjust every specific setting in that rule:

![](/files/Ke1o8tVKIkcJANyZf7UU)

Adjust the settings of the rule as required by selecting it and then Save (or Cancel if you don't want to keep the adjustments).


# Install Using Helm

For **Ingress NGINX Ingress Controller** with open-appsec the following method is recommended if you have an advanced understanding of Kubernetes topics and wish to have very granular controls using CRDs. For simplified installation you can alternatively use the available installation tool, see [here](/getting-started/start-with-kubernetes/install-using-interactive-cli-tool-ingress-nginx).

For **Kong** and **Apache APISIX** with open-appsec follow the instructions for installation using Helm below.&#x20;

{% hint style="warning" %}
A new installation flow using Helm is now available in beta, which will in the future replace the flow described on this page, you find the documentation and installation steps here: [Install Using Helm - new flow (beta)](/getting-started/start-with-kubernetes/install-using-helm-new-flow-beta)

This new flow will also provide option to use new, improved version of CRDs which provides more options in declaratively, locally managed deployments.

**For integration with Kong there's also a new Lua-based attachment plugin available now (in beta)**, you find the deployment instructions here: [Install With Helm using Webhook](/getting-started/start-with-kubernetes/install-with-helm-using-webhook)
{% endhint %}

## Prerequisites

* Kubernetes 1.16.0+ cluster with [RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) enabled with Cluster admin permissions
* [Helm 3 Package Manager](https://helm.sh/docs/intro/install/) installed on your local machine
* The `kubectl` and `wget` command-line tools installed on your bastion or platform that you use to access the Kubernetes cluster
* You have understanding of Kubernetes Ingress and either have a deployed Ingress or know how to configure one.

{% hint style="info" %}
For more details about Kubernetes Ingress see Kubernetes documentation [here](https://kubernetes.io/docs/concepts/services-networking/ingress/).&#x20;
{% endhint %}

## Installation

#### Step 1: Download the Helm chart

{% tabs %}
{% tab title="Ingress NGINX" %}
Run the following command to obtain the latest helm chart:

```bash
wget https://downloads.openappsec.io/packages/helm-charts/nginx-ingress/open-appsec-k8s-nginx-ingress-latest.tgz
```

{% endtab %}

{% tab title="Kong Gateway" %}
Run the following command to obtain the latest helm chart:

```bash
wget https://downloads.openappsec.io/packages/helm-charts/kong/open-appsec-k8s-kong-latest.tgz
```

{% endtab %}

{% tab title="APISIX Gateway" %}
Run the following command to obtain the latest helm chart:

```bash
wget https://downloads.openappsec.io/packages/helm-charts/apisix/open-appsec-k8s-apisix-latest.tgz
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Please note that the path above was recently changed.&#x20;
{% endhint %}

#### Step 2: Install open-appsec Helm Chart and CRDs (Custom Resource Definitions)

Run the following command to install open-appsec together with Ingress NGINX Ingress Controller, Kong API Gateway, or Apache APISIX API Gateway and create the open-appsec CRDs which add new K8s resource-types that will be used later for defining the protection policies, log settings, exceptions, user response and more.

{% hint style="info" %}
If you have persistent storage available in your cluster please set the "--set appsec.persistence.enabled=false" parameter in the following command to "true" to allow open-appsec to use persistent storage for the learning. This is only shown for maximum compatibility reasons below.
{% endhint %}

{% tabs %}
{% tab title="Ingress NGINX" %}

```bash
helm install open-appsec-k8s-nginx-ingress-latest.tgz \
--name-template=open-appsec \
--set appsec.mode=standalone \
--set controller.ingressClass=appsec-nginx \
--set controller.ingressClassResource.name=appsec-nginx \
--set controller.ingressClassResource.controllerValue="k8s.io/appsec-nginx" \
--set appsec.persistence.enabled=false \
--set controller.service.externalTrafficPolicy=Local \
--set appsec.userEmail="<your-email-address>" \
--set appsec.agentToken= \
-n appsec --create-namespace
```

This installs Ingress NGINX Ingress Controller with open-appsec into a new namespace "appsec" in local management mode (stand-alone). &#x20;
{% endtab %}

{% tab title="Kong Gateway" %}

```bash
helm install open-appsec-k8s-kong-latest.tgz \
--name-template=open-appsec \
--set appsec.mode=standalone \
--set ingressController.ingressClass=appsec-kong \
--set appsec.persistence.enabled=false \
--set appsec.userEmail="<your-email-address>" \
--set appsec.agentToken= \
-n appsec --create-namespace
```

This installs Kong with open-appsec into a new namespace "appsec" in local management mode (stand-alone). &#x20;
{% endtab %}

{% tab title="APISIX API Gateway" %}

```bash
helm install open-appsec-k8s-apisix-latest.tgz \
--name-template=appsec-apisix \
--set appsec.mode=standalone \
--set rbac.create=true \
--set service.type=LoadBalancer \
--set appsec.persistence.enabled=false \
--set ingress-controller.enabled=true \
--set ingress-controller.config.kubernetes.ingressClass=appsec-apisix \
--set appsec.userEmail="<your-email-address>" \
--set appsec.agentToken= \
--create-namespace \
-n appsec-apisix
```

This installs APISIX with open-appsec into a new namespace "appsec-apisix" in local management mode (stand-alone).&#x20;
{% endtab %}
{% endtabs %}

#### Optional open-appsec `helm install`  parameters

{% tabs %}
{% tab title="Ingress NGINX" %}

* `-n <namespace>`: select a namespace name that will include the open-appsec and NGINX ingress controller resources, please use the `appsec` namespace.
* `--create-namespace`: create namespace if it doesn't exist
* `--name-template`: name of your deployment, used for pod naming (optional)
* `--set appsec.userEmail`: allows you to associate your email address with your specific deployment by replacing `<your-email-address>` with your own email address.

  This allows us to provide you easy assistance in case of any issues you might have with your specific deployment in the future and also to provide you information proactively regarding open-appsec in general or regarding your specific deployment. This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future.
* `--set appsec.persistence.enabled`: persistent volume includes machine learning information, if this is set to false then machine learning information is lost when the appsec container is stopped/restarted.&#x20;

  * `true`: default is true
  * `false`

  If this value is set to true (default, when not overriding with `false`) you must also specify `appsec.persistence.learning.storageClass`
* `--set appsec.persistence.learning.storageClass`: Specify storage class to be used for the learning pod.\
  Note: storageClass name specified here must support ReadWriteMany (like AWS EFS or Azure Files).
* `--set appsec.mode`: Configure if the deployment is connected to the central management WebUI (SaaS)&#x20;
  * `standalone`: use this only for standalone deployment (locally managed via CRDs with no connection to central management WebUI (SaaS))
  * `managed`: use this for connection to central management WebUI (SaaS), **when this is set `appsec.agentToken` must be provided as well.**
* `--set appsec.agentToken`: set the deployment profile token from central management WebUI (SaaS) to connect your open-appsec deployment to the central WebUI (SaaS), also make sure to set `appsec.mode` to `managed` when you provide the token, see here how to get the token: [create a profile in web UI](/getting-started/using-the-web-ui-saas/create-a-profile).
* `--set controller.ingressClassResource.name`: specify unique ingress class name, default is 'appsec-nginx'
* `--set controller.ingressClassResource.controllerValue`: default is 'k8s.io/appsec-nginx'
* `--set controller.service.externalTrafficPolicy=Local` required for Azure.&#x20;

For additional available configuration values please check the values.yaml within the downloaded Helm chart and the Ingress NGINX documentation available [here](https://artifacthub.io/packages/helm/ingress-nginx/ingress-nginx).
{% endtab %}

{% tab title="Kong Gateway" %}

* `-n <namespace>`: select a namespace name that will include the open-appsec and Kong gateway resources, please use the `appsec` namespace.
* `--create-namespace`: create namespace if it doesn't exist
* `--name-template`: name of your deployment, used for pod naming (optional)
* `--set appsec.userEmail`: allows you to associate your email address with your specific deployment by replacing `<your-email-address>` with your own email address.

  This allows us to provide you easy assistance in case of any issues you might have with your specific deployment in the future and also to provide you information proactively regarding open-appsec in general or regarding your specific deployment. This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future.
* `--set appsec.persistence.enabled`: persistent volume includes machine learning information, if this is set to false then machine learning information is lost when the appsec container is stopped/restarted.&#x20;

  * `true`: default is true
  * `false`

  If this value is set to true (default, when not overriding with `false`) you must also specify `appsec.persistence.learning.storageClass`
* `--set appsec.persistence.learning.storageClass`: Specify storage class to be used for the learning pod.\
  Note: storageClass name specified here must support ReadWriteMany (like AWS EFS or Azure Files).
* `--set appsec.mode`: Configure if the deployment is connected to the central management WebUI (SaaS)&#x20;
  * `standalone`: use this only for standalone deployment (locally managed via CRDs with no connection to central management WebUI (SaaS))
  * `managed`: use this for connection to central management WebUI (SaaS), **when this is set `appsec.agentToken` must be provided as well.**
* `--set appsec.agentToken`: set the deployment profile token from central management WebUI (SaaS) to connect your open-appsec deployment to the central WebUI (SaaS), also make sure to set `appsec.mode` to `managed` when you provide the token, see here how to get the token: [create a profile in web UI](/getting-started/using-the-web-ui-saas/create-a-profile).
* `--set kind`: select deployment type
  * `AppSec`: Installs open-appsec and Kong as K8s Deployment (default, recommended for most scenarios)\
    Note: If required, in this mode you can also switch to Daemonset using by additionally setting `deployment.daemonset` to `true`)
  * `AppSecStateful`: Installs open-appsec and Kong as a K8s StatefulSet
  * `Vanilla`: (for debugging purposes only) installs just regular Kong based on the Helm chart without open-appsec.\
    Note: This can be useful when debugging if a potential  issue with the Kong deployment is caused by open-appsec or not.
  * NOTE: If `Vanilla` mode is used, then the Kong/Kong Gateway image specified under `image.repository`/`image.tag` is being used, instead of the open-appsec specific Kong/Kong Gateway image specified here: `appsec.kong.image.repository` / `appsec.kong.image.tag`
* `--set ingressController.ingressClass`: specify desired ingress class name

For additional available configuration values please check the values.yaml within the downloaded Helm chart and the Kong documentation available [here](https://docs.konghq.com/).
{% endtab %}

{% tab title="APISIX" %}

* `-n <namespace>`: select a namespace name that will include the open-appsec and Kong gateway resources, please use the `appsec` namespace.
* `--create-namespace`: create namespace if it doesn't exist
* `--name-template`: name of your deployment, used for pod naming (optional)
* `--set appsec.userEmail`: allows you to associate your email address with your specific deployment by replacing `<your-email-address>` with your own email address.

  This allows us to provide you easy assistance in case of any issues you might have with your specific deployment in the future and also to provide you information proactively regarding open-appsec in general or regarding your specific deployment. This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future.
* `--set appsec.persistence.enabled`: persistent volume includes machine learning information, if this is set to false then machine learning information is lost when the appsec container is stopped/restarted.&#x20;

  * `true`: default is true
  * `false`

  If this value is set to true (default, when not overriding with `false`) you must also specify `appsec.persistence.learning.storageClass`
* `--set appsec.persistence.learning.storageClass`: Specify storage class to be used for the learning pod.\
  Note: storageClass name specified here must support ReadWriteMany (like AWS EFS or Azure Files)
* `--set appsec.mode`: Configure if the deployment is connected to the central management WebUI (SaaS)&#x20;
  * `standalone`: use this only for standalone deployment (locally managed via CRDs with no connection to central management WebUI (SaaS))
  * `managed`: use this for connection to central management WebUI (SaaS), **when this is set `appsec.agentToken` must be provided as well.**
* `--set appsec.agentToken`: set the deployment profile token from central management WebUI (SaaS) to connect your open-appsec deployment to the central WebUI (SaaS), also make sure to set `appsec.mode` to `managed` when you provide the token, see here how to get the token: [create a profile in web UI](/getting-started/using-the-web-ui-saas/create-a-profile).
* `--set ingressController.ingressClass`: specify desired ingress class name

For additional available configuration values please check the values.yaml within the downloaded Helm chart and the APISIX documentation available [here](https://apisix.apache.org/docs/helm-chart/apisix/).
{% endtab %}
{% endtabs %}

#### Step 3: Validate that open-appsec is installed and running

{% tabs %}
{% tab title="NGINX Ingress Controller" %}

```
kubectl get pods -n appsec
```

The READY column should show 2/2 for the ingress controller pod and 1/1 for the learning deployment and shared storage deployment pods.&#x20;
{% endtab %}

{% tab title="Kong Gateway" %}

```
kubectl get pods -n appsec
```

The READY column typically shows 3/3 (or 2/2 if e.g. Kong is deployed without the Kong ingress controller) for the kong pod and 1/1 for the learning deployment and shared storage deployment pods.&#x20;
{% endtab %}

{% tab title="APISIX Gateway" %}

```
kubectl get pods -n appsec-apisix
```

The READY column should show 2/2 for the ingress controller pod and 1/1 for the learning deployment and shared storage deployment pods.&#x20;
{% endtab %}
{% endtabs %}

#### Step 4: Setup options

Here's the available options:

{% tabs %}
{% tab title="NGINX Ingress Controller (1)" %}

#### NGINX Ingress Controller Option 1: Add protection to existing running Ingress

open-appsec implements K8s ingress resources serving as an NGINX ingress controller with multi-layered Web App & API protection functionalities.

If you use today an NGINX Ingress, you can easily update your existing K8S ingress resource to use open-appsec ingress. Once you apply the change, the ingress will reload and traffic will be protected.&#x20;

{% hint style="warning" %}
This is a good approach for a lab, staging or non critical production environments.
{% endhint %}

**a. Create an open-appsec policy resource**

First you must create a K8s open-appsec policy resource.\
\
There's multiple **alternative** ways to create a policy:

* Use the available configuration tool as explained [here](/getting-started/start-with-kubernetes/configuration-using-interactive-cli-tool) to easily create a policy resource.
* Run the following commands to create the "open-appsec-best-practice-policy" resource in K8s:

```
kubectl apply -f https://downloads.openappsec.io/resources/open-appsec-policy.yaml -n appsec-nginx
```

* Create your own custom policy, [here](/getting-started/start-with-kubernetes/configuration-using-crds) you find all details.

**b. Find out the name of your relevant ingress resource:**

```bash
kubectl get ing -A
```

**c. Edit the ingress resource:**

```bash
kubectl edit ing/<ingress name> -n <ingress namespace>
```

**d. Change the ingressClassname to use open-appsec:**

```yaml
spec: ingressClassName: appsec-nginx
```

**e. Add this annotations to activate open-appsec:**

```yaml
openappsec.io/policy: open-appsec-best-practice-policy
```

Make sure to use the correct name for the open-appsec policy resource which you created above.

{% hint style="info" %}
The default mode of the open-appsec-best-practice-policy is detect-learn. It will not block any traffic, unless you change the policy mode to prevent-learn, either for a specific ingress rule or for the whole policy.
{% endhint %}
{% endtab %}

{% tab title="NGINX Ingress Controller (2)" %}

#### NGINX Ingress Controller Option 2: Run a new protected Ingress in parallel

open-appsec implements K8s ingress resources serving as an NGINX ingress controller with multi-layered Web App & API protection functionalities.

Duplicate your existing ingress rules and run a new ingress, side by side with your existing one.  Once you are happy with the result, you can change your DNS setting to point to the new, protected, ingress and take down the existing ("old") ingress.

{% hint style="success" %}
This option allows you to test that all services are properly accessible via the new ingress, without worrying about traffic disruption.
{% endhint %}

**a. Create an open-appsec policy resource**

First you must create a K8s open-appsec policy resource.\
\
There's multiple **alternative** ways to create a policy:

* Use the available configuration tool as explained [here](/getting-started/start-with-kubernetes/configuration-using-interactive-cli-tool) to easily create a policy resource.
* Run the following commands to create the "open-appsec-best-practice-policy" in K8s:

```
kubectl apply -f https://downloads.openappsec.io/resources/open-appsec-policy.yaml -n appsec-nginx
```

* Create your own custom policy, [here](/getting-started/start-with-kubernetes/configuration-using-crds) you find all details.<br>

**b. Find out the name of your ingress resource by running:**

```bash
kubectl get ing -A
```

**c. Duplicate your current ingress configuration:**

```bash
kubectl get ingress <ingress name> -n <namespace> -o json | jq 'del(.metadata.resourceVersion,.metadata.uid,.metadata.selfLink,.metadata.creationTimestamp,.status,.metadata.generation,.metadata.ownerReferences)' | yq eval - -P  > protected-ingress.yaml
```

**d. Edit the ingress YAML:**

```bash
vi protected-ingress.yaml
```

**e. Set a resource name for your new protected ingress, for example:**

```yaml
name: appsec-<existing ingress name>
```

**f. Change the ingressClassname to use open-appsec:**&#x20;

```yaml
ingressClassName: appsec-nginx
```

**g. Add this annotations to activate open-appsec in detect or prevent mode:**

```yaml
openappsec.io/policy: open-appsec-best-practice-policy
```

**h. Apply the new ingress:**

```bash
kubectl apply -f protected-ingress.yaml
```

{% endtab %}

{% tab title="Kong Gateway" %}

#### Kong Gateway: Add protection to existing Ingress resource

open-appsec will secure traffic integrating directly with the Kong Gateway container, as this allows open-appsec to also inspect HTTPS traffic terminated at the Kong Gateway.

In order for traffic to reach your API Gateway you can use the Kong Controller as an Ingress Controller alongside Kong API Gateway (Kong Controller will be deployed by default within the same pod as Kong Gateway as an additional container, but is an optional component).\
Alternatively you can use another ingress controller of your choice.&#x20;

If you use today an Ingress for proxying traffic to your Kong Gateway, you can easily update your existing K8S ingress resource to secure it's traffic with open-appsec. Once you apply the change, the ingress will reload and traffic will be protected.&#x20;

{% hint style="warning" %}
Note: Having an Ingress Resource defined for traffic to Kong Gateway is mandatory for being able to protect the traffic with open-appsec, as the open-appsec policy resource has to be linked to an ingress resource via an annotation, see below steps. Additional options will be provided in the future.
{% endhint %}

**a. Create an open-appsec policy resource**

First you must create a K8s open-appsec policy resource.\
\
There's multiple **alternative** ways to create a policy:

* Use the available configuration tool as explained [here](/getting-started/start-with-kubernetes/configuration-using-interactive-cli-tool) to easily create a policy resource.
* Run the following commands to create the "open-appsec-best-practice-policy" in K8s:

```
kubectl apply -f https://downloads.openappsec.io/resources/open-appsec-policy.yaml -n appsec-nginx
```

* Create your own custom policy, [here](/getting-started/start-with-kubernetes/configuration-using-crds) you find all details.

**b. Find out the name of your relevant ingress resource:**

```bash
kubectl get ing -A
```

**c. Edit the ingress resource:**

```bash
kubectl edit ing/<ingress name> -n <ingress namespace>
```

**d. Change the ingressClassname to use open-appsec:**

```yaml
spec: ingressClassName: appsec-kong
```

**e. Add this annotation to activate open-appsec:**

```yaml
openappsec.io/policy: open-appsec-best-practice-policy
```

{% hint style="info" %}
The default mode of this policy is detect-learn. It will not block any traffic, unless you change the policy mode to prevent-learn, either for a specific ingress rule or for the whole policy.
{% endhint %}

{% hint style="info" %}
open-appsec will read and enforce the open-appsec policy specified in the ingress resource by this annotation even though the actual enforcement is done in the Kong Gateway and not in the Ingress Controller (this is similar to how Kong implements its declarative policy).
{% endhint %}
{% endtab %}

{% tab title="APISIX Gateway" %}

#### APISIX Gateway: Add protection to existing Ingress resource

open-appsec will secure traffic integrating directly with the APISIX Gateway container, as this allows open-appsec to also inspect HTTPS traffic terminated at the APISIX Gateway.

In order for traffic to reach your API Gateway you can use the APISIX Ingress Controller as an Ingress Controller alongside APISIX API Gateway.&#x20;

If you use today an Ingress for proxying traffic to your APISIX Gateway, you can easily update your existing K8S ingress resource to secure it's traffic with open-appsec. Once you apply the change, the ingress will reload and traffic will be protected.&#x20;

**a. Create an open-appsec policy resource**

First you must create a K8s open-appsec policy resource.\
\
There's multiple **alternative** ways to create a policy:

* Use the available configuration tool as explained [here](/getting-started/start-with-kubernetes/configuration-using-interactive-cli-tool) to easily create a policy resource.
* Run the following commands to create the "open-appsec-best-practice-policy" resource in K8s:

```
kubectl apply -f https://downloads.openappsec.io/resources/open-appsec-policy.yaml -n appsec-apisix
```

**b. Find out the name of your relevant ingress resource:**

```bash
kubectl get ing -A
```

**c. Edit the ingress resource:**

```bash
kubectl edit ing/<ingress name> -n <ingress namespace>
```

**d. Change the ingressClassname to use open-appsec:**

```yaml
spec: ingressClassName: appsec-apisix
```

**e. Add this annotations to activate open-appsec:**

```yaml
openappsec.io/policy: open-appsec-best-practice-policy
```

Make sure to use the correct name for the open-appsec policy resource which you created above.

{% hint style="info" %}
The default mode of the open-appsec-best-practice-policy is detect-learn. It will not block any traffic, unless you change the policy mode to prevent-learn, either for a specific ingress rule or for the whole policy.
{% endhint %}
{% endtab %}
{% endtabs %}

#### Step 5: Validate that open-appsec works

Your existing or new Ingress is now running and you can try it out!

1. Generate some traffic to one of the services defined in your ingress.
2. Run this command to see logs:

{% tabs %}
{% tab title="Ingress NGINX" %}
Note the name of the ingress nginx pod by running:

```
kubectl get pods -n appsec
```

Show the logs of the open-appsec agent container by running:

```
kubectl logs [ingress nginx pod name] -c open-appsec -n appsec
```

{% endtab %}

{% tab title="Kong Gateway" %}
Note the name of the Kong pod by running:

```
kubectl get pods -n appsec
```

Show the logs of the open-appsec agent container by running:

```
kubectl logs [kong pod name] -c open-appsec -n appsec
```

{% endtab %}

{% tab title="APISIX Gateway" %}
Note the name of the apisix gateway pod by running:

```
kubectl get pods -n appsec-apisix
```

Show the logs of the open-appsec agent container by running:

```
kubectl logs [apisix gateway pod name] -c open-appsec -n appsec-apisix
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
With the default policy logging being done to stdout, so you can easily direct it with fluentd/fluentbit or similar to logs collector (ELK or other). It is possible to configure open-appsec to log also to syslog. &#x20;

open-appsec automatically logs the first 10 HTTP requests and then by default will only log malicious requests. You can change this setting.
{% endhint %}

**Step 6: Point your DNS to the New Ingress**&#x20;

After testing that your services are reachable, you can point your public DNS record to the new ingress.&#x20;

In case of a problem, at any time, you can either switch open-appsec off while running the same ingress code, or change your DNS back.

{% hint style="info" %}
For Production usage you might want to switch from using the Basic to the more accurate Advanced Machine Learning model, as described here:&#x20;

[Using the Advanced Machine Learning Model](/getting-started/using-the-advanced-machine-learning-model)
{% endhint %}

**Learn how to define your policies, set exception and other advanced configuration:**

{% content-ref url="/pages/F2qjXRaybFnVkZSAp0t3" %}
[Configuration Using CRDs](/getting-started/start-with-kubernetes/configuration-using-crds)
{% endcontent-ref %}


# Install Using Helm - new flow (beta)

{% hint style="warning" %}
The steps described here to deploy open-appsec on Kubernetes are currently in beta.

The installation flow as described here has changed from the previous one in the way that deployment of the open-appsec helm chart, CRDs and default configuration are now separate steps. This allows more flexibility and custom selection of the preferred CRD version by the user.\
\
Let us know if you have any feedback regarding this beta or require technical assistance: [mailto://info@openappsec.io](mailto:info@openappsec.io)
{% endhint %}

{% hint style="info" %}
The Kong deployment explained on this page is for the traditional open-appsec integration with Kong.&#x20;

A newer, native version of the Kong plugin based on Lua is now available as well, see separate tab. This is more flexible, as you can apply the attachment to specific traffic (e.g. selected routes only) and this is aligned with the official Kong plugin guidelines. You find the deployment instructions here: [Install With Helm using Webhook](/getting-started/start-with-kubernetes/install-with-helm-using-webhook)
{% endhint %}

## Prerequisites

* Kubernetes 1.16.0+ cluster with [RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) enabled with Cluster admin permissions
* [Helm 3 Package Manager](https://helm.sh/docs/intro/install/) installed on your local machine
* `kubectl` and `wget` command-line tools installed on the system that you use to access the Kubernetes cluster
* You have understanding of Kubernetes Ingress and either have an already deployed Ingress or know how to configure one.

{% hint style="info" %}
For more details about Kubernetes Ingress see Kubernetes documentation [here](https://kubernetes.io/docs/concepts/services-networking/ingress/).&#x20;
{% endhint %}

* **(Optional, Recommended) Sign-Up and Login to WebUI Portal**\
  If you want to centrally manage your open-appsec WAF deployment via WebUI (SaaS)\
  OR if you want to locally manage your open-appsec WAF deployment but still connect to central WebUI for viewing the local configuration (in read-only), central monitoring, logging and reporting:\
  \
  Follow the instructions below to sign-up and login to the WebUI available at <https://my.openappsec.io>:

{% content-ref url="/pages/0ty9rMQEgnxS9LBuN7qw" %}
[Sign-Up and Login to Portal](/getting-started/using-the-web-ui-saas/sign-up-and-login-to-portal)
{% endcontent-ref %}

* **(Optional, Recommended) Create deployment profile for the open-appsec deployment in WebUI Portal**\
  If you signed-up and logged in to the WebUI Portal (see prerequisite above), now follow the instructions below to create a new deployment profile for your open-appsec deployment.\
  **Once done, don't forget to copy the profile token after policy installation as this is needed in the installation steps further below.**

{% content-ref url="/pages/WMgZp7bTMiI5PD1ocIKp" %}
[Create a Profile](/getting-started/using-the-web-ui-saas/create-a-profile)
{% endcontent-ref %}

## Installation

#### Step 1: Add the Helm Repo

{% hint style="info" %}
Please note that this new installation flow with helm uses a different helm chart.
{% endhint %}

```
helm repo add openappsec https://charts.openappsec.io
helm repo update
```

#### Step 2: Install open-appsec Helm Chart

Run the following command to install open-appsec together with Ingress NGINX Ingress Controller, Kong API Gateway, or Apache APISIX API Gateway.

{% tabs %}
{% tab title="Ingress NGINX" %}

```bash
helm install open-appsec-nginx openappsec/open-appsec-nginx-ingress \
--set controller.ingressClass=appsec-nginx \
--set controller.ingressClassResource.name=appsec-nginx \
--set controller.ingressClassResource.controllerValue="k8s.io/appsec-nginx" \
--set appsec.persistence.enabled=false \
--set controller.service.externalTrafficPolicy=Local \
--set appsec.userEmail="<your-email-address>" \
--set appsec.agentToken= \
--namespace appsec --create-namespace
```

{% endtab %}

{% tab title="Kong Gateway" %}

```bash
helm install open-appsec-kong openappsec/open-appsec-kong \
--set ingressController.ingressClass=appsec-kong \
--set appsec.persistence.enabled=false \
--set appsec.userEmail="<your-email-address>" \
--set appsec.agentToken= \
--namespace appsec --create-namespace
```

{% endtab %}

{% tab title="APISIX API Gateway" %}

```bash
helm install open-appsec-apisix openappsec/open-appsec-apisix \
--set rbac.create=true \
--set service.type=LoadBalancer \
--set appsec.persistence.enabled=false \
--set ingress-controller.enabled=true \
--set ingress-controller.config.ingressClass=appsec-apisix \
--set appsec.userEmail="<your-email-address>" \
--set appsec.agentToken= \
--namespace appsec-apisix --create-namespace

```

{% endtab %}
{% endtabs %}

**Your deployment of open-appsec and the selected proxy solution for integration will be done into a new namespace `appsec`.**

**If you have created a deployment profile in the WebUI (see prerequisites section above) to connect your deployment to the central WebUI please specify this token as value for the `appsec.agentToken` parameter** (for standalone deployments leave parameter empty).

Replace the value `<your-email-address>` for the `appsec.userEmail` parameter with your own email address, for more details on this see below.

{% hint style="info" %}
If you have persistent storage available in your cluster please set the "--set appsec.persistence.enabled=false" parameter in the following command to "true" to allow open-appsec to use persistent storage for the learning. This is only shown for maximum compatibility reasons below.
{% endhint %}

#### Optional open-appsec `helm install`  parameters

{% tabs %}
{% tab title="Ingress NGINX" %}

* `-n <namespace>`: select a namespace name that will include the open-appsec and NGINX ingress controller resources, please use the `appsec` namespace.
* `--create-namespace`: create namespace if it doesn't exist
* `--name-template`: name of your deployment, used for pod naming (optional)
* `--set appsec.userEmail`: allows you to associate your email address with your specific deployment by replacing `<your-email-address>` with your own email address.

  This allows us to provide you easy assistance in case of any issues you might have with your specific deployment in the future and also to provide you information proactively regarding open-appsec in general or regarding your specific deployment. This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future.
* `--set appsec.persistence.enabled`: persistent volume includes machine learning information, if this is set to false then machine learning information is lost when the appsec container is stopped/restarted.&#x20;

  * `true`: default is true
  * `false`

  If this value is set to true (default, when not overriding with `false`) you must also specify `appsec.persistence.learning.storageClass`
* `--set appsec.persistence.learning.storageClass`: Specify storage class to be used for the learning pod.\
  Note: storageClass name specified here must support ReadWriteMany (like AWS EFS or Azure Files).
* `--set appsec.mode`: Configure if the deployment is connected to the central management WebUI (SaaS)&#x20;
  * `standalone`: use this only for standalone deployment (locally managed via CRDs with no connection to central management WebUI (SaaS))
  * `managed`: use this for connection to central management WebUI (SaaS), **when this is set `appsec.agentToken` must be provided as well.**
* `--set appsec.agentToken`: set the deployment profile token from central management WebUI (SaaS) to connect your open-appsec deployment to the central WebUI (SaaS), also make sure to set `appsec.mode` to `managed` when you provide the token, see here how to get the token: [create a profile in web UI](/getting-started/using-the-web-ui-saas/create-a-profile).
* `--set controller.ingressClassResource.name`: specify unique ingress class name, default is 'appsec-nginx'
* `--set controller.ingressClassResource.controllerValue`: default is 'k8s.io/appsec-nginx'
* `--set controller.service.externalTrafficPolicy=Local` required for preserving original IP address in conjunction with LoadBalancer in e.g. Azure AKS (Standard Load Balancer) or AWS EKS (Network Load Balancer).

For additional available configuration values please check the values.yaml within the downloaded Helm chart and the Ingress NGINX documentation available [here](https://artifacthub.io/packages/helm/ingress-nginx/ingress-nginx).
{% endtab %}

{% tab title="Kong Gateway" %}

* `-n <namespace>`: select a namespace name that will include the open-appsec and Kong gateway resources, please use the `appsec` namespace.
* `--create-namespace`: create namespace if it doesn't exist
* `--name-template`: name of your deployment, used for pod naming (optional)
* `--set appsec.userEmail`: allows you to associate your email address with your specific deployment by replacing `<your-email-address>` with your own email address.

  This allows us to provide you easy assistance in case of any issues you might have with your specific deployment in the future and also to provide you information proactively regarding open-appsec in general or regarding your specific deployment. This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future.
* `--set appsec.persistence.enabled`: persistent volume includes machine learning information, if this is set to false then machine learning information is lost when the appsec container is stopped/restarted.&#x20;

  * `true`: default is true
  * `false`

  If this value is set to true (default, when not overriding with `false`) you must also specify `appsec.persistence.learning.storageClass`
* `--set appsec.persistence.learning.storageClass`: Specify storage class to be used for the learning pod.\
  Note: storageClass name specified here must support ReadWriteMany (like AWS EFS or Azure Files).
* `--set appsec.mode`: Configure if the deployment is connected to the central management WebUI (SaaS)&#x20;
  * `standalone`: use this only for standalone deployment (locally managed via CRDs with no connection to central management WebUI (SaaS))
  * `managed`: use this for connection to central management WebUI (SaaS), **when this is set `appsec.agentToken` must be provided as well.**
* `--set appsec.agentToken`: set the deployment profile token from central management WebUI (SaaS) to connect your open-appsec deployment to the central WebUI (SaaS), also make sure to set `appsec.mode` to `managed` when you provide the token, see here how to get the token: [create a profile in web UI](/getting-started/using-the-web-ui-saas/create-a-profile).
* `--set kind`: select deployment type
  * `AppSec`: Installs open-appsec and Kong as K8s Deployment (default, recommended for most scenarios)\
    Note: If required, in this mode you can also switch to Daemonset using by additionally setting `deployment.daemonset` to `true`)
  * `AppSecStateful`: Installs open-appsec and Kong as a K8s StatefulSet
  * `Vanilla`: (for debugging purposes only) installs just regular Kong based on the Helm chart without open-appsec.\
    Note: This can be useful when debugging if a potential  issue with the Kong deployment is caused by open-appsec or not.
  * NOTE: If `Vanilla` mode is used, then the Kong/Kong Gateway image specified under `image.repository`/`image.tag` is being used, instead of the open-appsec specific Kong/Kong Gateway image specified here: `appsec.kong.image.repository` / `appsec.kong.image.tag`
* `--set ingressController.ingressClass`: specify desired ingress class name

For additional available configuration values please check the values.yaml within the downloaded Helm chart and the Kong documentation available [here](https://docs.konghq.com/).
{% endtab %}

{% tab title="APISIX" %}

* `-n <namespace>`: select a namespace name that will include the open-appsec and Kong gateway resources, please use the `appsec` namespace.
* `--create-namespace`: create namespace if it doesn't exist
* `--name-template`: name of your deployment, used for pod naming (optional)
* `--set appsec.userEmail`: allows you to associate your email address with your specific deployment by replacing `<your-email-address>` with your own email address.

  This allows us to provide you easy assistance in case of any issues you might have with your specific deployment in the future and also to provide you information proactively regarding open-appsec in general or regarding your specific deployment. This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future.
* `--set appsec.persistence.enabled`: persistent volume includes machine learning information, if this is set to false then machine learning information is lost when the appsec container is stopped/restarted.&#x20;

  * `true`: default is true
  * `false`

  If this value is set to true (default, when not overriding with `false`) you must also specify `appsec.persistence.learning.storageClass`
* `--set appsec.persistence.learning.storageClass`: Specify storage class to be used for the learning pod.\
  Note: storageClass name specified here must support ReadWriteMany (like AWS EFS or Azure Files)
* `--set appsec.mode`: Configure if the deployment is connected to the central management WebUI (SaaS)&#x20;
  * `standalone`: use this only for standalone deployment (locally managed via CRDs with no connection to central management WebUI (SaaS))
  * `managed`: use this for connection to central management WebUI (SaaS), **when this is set `appsec.agentToken` must be provided as well.**
* `--set appsec.agentToken`: set the deployment profile token from central management WebUI (SaaS) to connect your open-appsec deployment to the central WebUI (SaaS), also make sure to set `appsec.mode` to `managed` when you provide the token, see here how to get the token: [create a profile in web UI](/getting-started/using-the-web-ui-saas/create-a-profile).
* `--set ingressController.ingressClass`: specify desired ingress class name

For additional available configuration values please check the values.yaml within the downloaded Helm chart and the APISIX documentation available [here](https://apisix.apache.org/docs/helm-chart/apisix/).
{% endtab %}
{% endtabs %}

#### Step 3: Validate that open-appsec is installed and running

{% tabs %}
{% tab title="NGINX Ingress Controller" %}

```
kubectl get pods -n appsec
```

The READY column should show 2/2 for the ingress controller pod and 1/1 for the learning deployment and shared storage deployment pods.&#x20;
{% endtab %}

{% tab title="Kong Gateway" %}

```
kubectl get pods -n appsec
```

The READY column typically shows 3/3 (or 2/2 if e.g. Kong is deployed without the Kong ingress controller) for the kong pod and 1/1 for the learning deployment and shared storage deployment pods.&#x20;
{% endtab %}

{% tab title="APISIX Gateway" %}

```
kubectl get pods -n appsec-apisix
```

The READY column should show 2/2 for the ingress controller pod and 1/1 for the learning deployment and shared storage deployment pods.&#x20;
{% endtab %}
{% endtabs %}

**Step 4: If you connected to central WebUI AND configured your deployment profile in the WebUI to "This management" mode for centrally managing open-appsec configuration**:

* **Create one or more assets in the WebUI** which represent web applications and/or Web APIs which you want to be protected by open-appsec WAF and allows you to adjust the open-appsec configuration specifically for each of them. \
  \
  Make sure to link your assets to the specific WebUI Profile which you created earlier (General -> Profiles) and adjust the Threat Prevention mode to Detect-Learn or Prevent (Threat Prevention -> Mode), the steps are described here: \
  \
  [Protect Additional Assets](/getting-started/using-the-web-ui-saas/protect-additional-assets)

{% hint style="success" %}
Don't forget to Enforce policy in the WebUI after you did any changes for those changes to become effective!
{% endhint %}

{% hint style="danger" %}
The following steps 5-10 are **only** relevant if you want to **locally manage** this open-appsec deployment in Kubernetes using a declarative configuration using custom resources.

They apply to the following two cases:

* You do not want to connect to central WebUI at all (you didn't provide a deployment profile token earlier)
* You provided deployment profile token earlier for a WebUI profile set to mode "Declarative Management"
  {% endhint %}

#### Step 5: (only for locally-managed deployments) Download the yaml file for open-appsec CRD installation

Run the following command to obtain the yaml file containing the open-appsec CRD definitions, chose the CRD version you want to use.\
\
v1beta1 CRDs:

```bash
wget https://raw.githubusercontent.com/openappsec/openappsec/main/config/crds/open-appsec-crd-v1beta1.yaml
```

v1beta2 CRDs (beta):

```bash
wget https://raw.githubusercontent.com/openappsec/openappsec/main/config/crds/open-appsec-crd-v1beta2.yaml
```

#### Step 6:  (only for locally-managed deployments) Create the open-appsec CRDs which add new K8s resource-types that will be used later for defining the protection policies, log settings, exceptions, user response and more.

{% hint style="info" %}
You can skip this step if you skipped the previous step, becausae you plan to centrally manage open-appsec from central WebUI and not manage it locally using CRDs.
{% endhint %}

Deploy the CRDs using the following command:\
\
If you downloaded v1beta1 CRDs:

```bash
kubectl apply -f ./open-appsec-crd-v1beta1.yaml 
```

If you downloaded v1beta2 CRDs:

```bash
kubectl apply -f ./open-appsec-crd-v1beta2.yaml
```

#### Step 7: (only for locally-managed deployments) Download a default configuration for the open-appsec custom resources

Run the following command to obtain the yaml file containing the open-appsec default configuration custom resources, chose the CRD version which you have deployed in the steps above on your cluster.\
\
Default configuration for v1beta1 in detect-learn mode:

```bash
wget https://raw.githubusercontent.com/openappsec/openappsec/main/config/k8s/v1beta1/open-appsec-k8s-default-config-v1beta1.yaml
```

Default configuration for v1beta2 (beta) in detect-learn mode:

```bash
wget https://raw.githubusercontent.com/openappsec/openappsec/main/config/k8s/v1beta2/open-appsec-k8s-default-config-v1beta2.yaml
```

{% hint style="info" %}
The default configuration files provided above are set to detect-learn mode, which is recommended for new deployments to allow the machine learning engine sufficient learning before moving to prevent-learn mode. You can then later easily reconfigure the `open-appsec-best-practice-policy` custom policy resource to prevent-learn mode.\
\
If you would like to start in prevent-mode in non-critical environment for testing purposes right away, you can alternatively use these files, which are preconfigured to prevent-learn mode:\
\
Default configuration for v1beta1 in prevent-mode

`wget https://raw.githubusercontent.com/openappsec/openappsec/main/config/k8s/v1beta1/open-appsec-k8s-prevent-config-v1beta1.yaml`

Default configuration for v1beta2 (beta) in prevent-mode

`wget https://raw.githubusercontent.com/openappsec/openappsec/main/config/k8s/v1beta2/open-appsec-k8s-prevent-config-v1beta2.yaml`<br>
{% endhint %}

#### Step 8: (only for locally-managed deployments) Deploy default configuration for the open-appsec custom resources

To deploy the default configuration for the open-appsec custom resources perform the step below:\
\
Apply default configuration for v1beta1:

```bash
kubectl apply -f ./open-appsec-k8s-default-config-v1beta1.yaml
```

Default configuration for v1beta2 (beta):

```bash
kubectl apply -f ./open-appsec-k8s-default-config-v1beta2.yaml
```

#### Step 9: Setup options (only for locally-managed deployments)&#x20;

Here's the available options:

{% tabs %}
{% tab title="NGINX Ingress Controller (1)" %}

#### NGINX Ingress Controller Option 1: Add protection to existing running Ingress

open-appsec implements K8s ingress resources serving as an NGINX ingress controller with multi-layered Web App & API protection functionalities.

If you use today an NGINX Ingress, you can easily update your existing K8S ingress resource to use open-appsec ingress. Once you apply the change, the ingress will reload and traffic will be protected.&#x20;

{% hint style="warning" %}
This is a good approach for a lab, staging or non critical production environments.\
For production deployments we suggest to first run a new Ingress protected with open-appsec WAF in parallel, see instructions "NGINX Ingress Controller (2)" (next tab).
{% endhint %}

**a. Make sure to have an open-appsec policy resource**

If you followed the steps above you should now have an open-appsec-best-practice-policy custom resource deployed on your K8s cluster.\
\
You can check this with the following command which will list all open-appsec policy custom resources:

```bash
kubectl get policies.openappsec.io
```

If you want to check if it's set to `detect-learn` (default) or `prevent-learn` mode you can use this command:\
\
When using v1beta1 CRDs:

```bash
kubectl get policies.openappsec.io open-appsec-best-practice-policy -o yaml
```

When using v1beta2 CRDs:

```bash
kubectl get policies.openappsec.io default-policy -o yaml
```

If you want to create your own custom policy, you find all details here:

For v1beta1 CRDs: [Configuration Using CRDs](/getting-started/start-with-kubernetes/configuration-using-crds)

For v1beta2 CRDs: [Configuration Using CRDs - v1beta2](/getting-started/start-with-kubernetes/configuration-using-crds-v1beta2)

**b. Find out the name of your relevant ingress resource:**

```bash
kubectl get ing -A
```

**c. Edit the ingress resource:**

```bash
kubectl edit ing/<ingress name> -n <ingress namespace>
```

**d. Change the ingressClassname to the ingress class name used by open-appsec:**

```yaml
spec:
  ingressClassName: appsec-nginx
```

The default ingress class name used by open-appsec is `appsec-nginx`. In case you configured another ingress class name, please adjust the setting accordingly.

**e. Add this annotation to activate the desired open-appsec policy custom resource:**

```yaml
openappsec.io/policy: default-policy
```

Make sure to use the correct name for the open-appsec policy resource which you created above.

{% hint style="info" %}
The default mode of the "default-policy" custom resource is detect-learn. It will not block any traffic, unless you change the policy mode to prevent-learn, either for a specific ingress rule or for the whole policy.
{% endhint %}
{% endtab %}

{% tab title="NGINX Ingress Controller (2)" %}

#### NGINX Ingress Controller Option 2: Run a new protected Ingress in parallel

open-appsec implements K8s ingress resources serving as an NGINX ingress controller with multi-layered Web App & API protection functionalities.

Duplicate your existing ingress rules and run a new ingress, side by side with your existing one.  Once you are happy with the result, you can change your DNS setting to point to the new, protected, ingress and take down the existing ("old") ingress.

{% hint style="success" %}
This option allows you to test that all services are properly accessible via the new ingress, without worrying about traffic disruption.\
If you instead prefer to directly add open-appsec to your existing ingress this is possible as well. See alternative instructions "NGINX Ingress Controller (1)" (first tab).
{% endhint %}

**a. Make sure to have an open-appsec policy resource**

If you followed the steps above you should now have an open-appsec-best-practice-policy custom resource deployed on your K8s cluster.\
\
You can check this with the following command which will list all open-appsec policy custom resources:

```bash
kubectl get policies.openappsec.io
```

If you want to check if it's set to `detect-learn` (default) or `prevent-learn` mode you can use this command:

```bash
kubectl get policies.openappsec.io open-appsec-best-practice-policy -o yaml
```

If you want to create your own custom policy, you find all details here:

For v1beta1 CRDs: [Configuration Using CRDs](/getting-started/start-with-kubernetes/configuration-using-crds)

For v1beta2 CRDs: [Configuration Using CRDs - v1beta2](/getting-started/start-with-kubernetes/configuration-using-crds-v1beta2)

**b. Find out the name of your ingress resource by running:**

```bash
kubectl get ing -A
```

**c. Duplicate your current ingress configuration:**

```bash
kubectl get ingress <ingress name> -n <namespace> -o json | jq 'del(.metadata.resourceVersion,.metadata.uid,.metadata.selfLink,.metadata.creationTimestamp,.status,.metadata.generation,.metadata.ownerReferences)' | yq eval - -P  > protected-ingress.yaml
```

**d. Edit the ingress YAML:**

```bash
vi protected-ingress.yaml
```

**e. Set a resource name for your new protected ingress, for example:**

```yaml
name: appsec-<existing ingress name>
```

**f. Change the ingressClassname to use open-appsec:**&#x20;

```yaml
ingressClassName: appsec-nginx
```

**g. Add this annotation to activate open-appsec in detect or prevent mode:**

```yaml
openappsec.io/policy: open-appsec-best-practice-policy
```

Make sure to use the correct name for the open-appsec policy resource which you created above.

**h. Apply the new ingress:**

```bash
kubectl apply -f protected-ingress.yaml
```

{% hint style="info" %}
The default mode of the open-appsec-best-practice-policy is detect-learn. It will not block any traffic, unless you change the policy mode to prevent-learn, either for a specific ingress rule or for the whole policy.
{% endhint %}
{% endtab %}

{% tab title="Kong Gateway" %}

#### Kong Gateway: Add protection to existing Ingress resource

open-appsec will secure traffic integrating directly with the Kong Gateway container, as this allows open-appsec to also inspect HTTPS traffic terminated at the Kong Gateway.

In order for traffic to reach your API Gateway you can use the Kong Controller as an Ingress Controller alongside Kong API Gateway (Kong Controller will be deployed by default within the same pod as Kong Gateway as an additional container, but is an optional component).\
Alternatively you can use another ingress controller of your choice.&#x20;

If you use today an Ingress for proxying traffic to your Kong Gateway, you can easily update your existing K8S ingress resource to secure it's traffic with open-appsec. Once you apply the change, the ingress will reload and traffic will be protected.&#x20;

{% hint style="warning" %}
Note: Having an Ingress Resource defined for traffic to Kong Gateway is mandatory for being able to protect the traffic with open-appsec, as the open-appsec policy resource has to be linked to an ingress resource via an annotation, see below steps. Additional options will be provided in the future.
{% endhint %}

**a. Make sure to have an open-appsec policy resource**

If you followed the steps above you should now have an open-appsec-best-practice-policy custom resource deployed on your K8s cluster.\
\
You can check this with the following command which will list all open-appsec policy custom resources:

```bash
kubectl get policies.openappsec.io
```

If you want to check if it's set to `detect-learn` (default) or `prevent-learn` mode you can use this command:

```bash
kubectl get policies.openappsec.io open-appsec-best-practice-policy -o yaml
```

If you want to create your own custom policy, you find all details here:

For v1beta1 CRDs: [Configuration Using CRDs](/getting-started/start-with-kubernetes/configuration-using-crds)

For v1beta2 CRDs: [Configuration Using CRDs - v1beta2](/getting-started/start-with-kubernetes/configuration-using-crds-v1beta2)

**b. Find out the name of your relevant ingress resource:**

```bash
kubectl get ing -A
```

**c. Edit the ingress resource:**

```bash
kubectl edit ing/<ingress name> -n <ingress namespace>
```

**d. Change the ingressClassname to use open-appsec:**

```yaml
spec: ingressClassName: appsec-kong
```

Make sure to use the correct name for the open-appsec policy resource which you created above.

**e. Add this annotation to activate open-appsec:**

```yaml
openappsec.io/policy: open-appsec-best-practice-policy
```

{% hint style="info" %}
The default mode of this policy is detect-learn. It will not block any traffic, unless you change the policy mode to prevent-learn, either for a specific ingress rule or for the whole policy.
{% endhint %}
{% endtab %}

{% tab title="APISIX Gateway" %}

#### APISIX Gateway: Add protection to existing Ingress resource

open-appsec will secure traffic integrating directly with the APISIX Gateway container, as this allows open-appsec to also inspect HTTPS traffic terminated at the APISIX Gateway.

In order for traffic to reach your API Gateway you can use the APISIX Ingress Controller as an Ingress Controller alongside APISIX API Gateway.&#x20;

If you use today an Ingress for proxying traffic to your APISIX Gateway, you can easily update your existing K8S ingress resource to secure it's traffic with open-appsec. Once you apply the change, the ingress will reload and traffic will be protected.&#x20;

**a. Make sure to have an open-appsec policy resource**

If you followed the steps above you should now have an open-appsec-best-practice-policy custom resource deployed on your K8s cluster.\
\
You can check this with the following command which will list all open-appsec policy custom resources:

```bash
kubectl get policies.openappsec.io
```

If you want to check if it's set to `detect-learn` (default) or `prevent-learn` mode you can use this command:

```bash
kubectl get policies.openappsec.io open-appsec-best-practice-policy -o yaml
```

If you want to create your own custom policy, you find all details here:

For v1beta1 CRDs: [Configuration Using CRDs](/getting-started/start-with-kubernetes/configuration-using-crds)

For v1beta2 CRDs: [Configuration Using CRDs - v1beta2](/getting-started/start-with-kubernetes/configuration-using-crds-v1beta2)

**b. Find out the name of your relevant ingress resource:**

```bash
kubectl get ing -A
```

**c. Edit the ingress resource:**

```bash
kubectl edit ing/<ingress name> -n <ingress namespace>
```

**d. Change the ingressClassname to use open-appsec:**

```yaml
spec: ingressClassName: appsec-apisix
```

**e. Add this annotation to activate open-appsec:**

```yaml
openappsec.io/policy: open-appsec-best-practice-policy
```

Make sure to use the correct name for the open-appsec policy resource which you created above.

{% hint style="info" %}
The default mode of the open-appsec-best-practice-policy is detect-learn. It will not block any traffic, unless you change the policy mode to prevent-learn, either for a specific ingress rule or for the whole policy.
{% endhint %}
{% endtab %}
{% endtabs %}

#### Step 10: Validate that open-appsec works

Your existing or new Ingress is now running and you can try it out!

1. Generate some traffic to one of the services defined in your ingress.
2. Run this command to see logs:

{% tabs %}
{% tab title="Ingress NGINX" %}
Note the name of the ingress nginx pod by running:

```
kubectl get pods -n appsec
```

Show the logs of the open-appsec agent container by running:

```
kubectl logs [ingress nginx pod name] -c open-appsec -n appsec
```

{% endtab %}

{% tab title="Kong Gateway" %}
Note the name of the Kong pod by running:

```
kubectl get pods -n appsec
```

Show the logs of the open-appsec agent container by running:

```
kubectl logs [kong gateway pod name] -c open-appsec -n appsec
```

{% endtab %}

{% tab title="APISIX Gateway" %}
Note the name of the apisix gateway pod by running:

```
kubectl get pods -n appsec-apisix
```

Show the logs of the open-appsec agent container by running:

```
kubectl logs [apisix gateway pod name] -c open-appsec -n appsec-apisix
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
With the default policy logging being done to stdout, so you can easily direct it with fluentd/fluentbit or similar to logs collector (ELK or other). It is possible to configure open-appsec to log also to syslog. &#x20;

open-appsec automatically logs the first 10 HTTP requests and then by default will only log malicious requests. You can change this setting.
{% endhint %}

**Step 10: Point your DNS to the New Ingress**&#x20;

After testing that your services are reachable, you can point your public DNS record to the new ingress.&#x20;

In case of a problem, at any time, you can either switch open-appsec off while running the same ingress code, or change your DNS back.

{% hint style="info" %}
For Production usage you might want to switch from using the Basic to the more accurate Advanced Machine Learning model, as described here:&#x20;

[Using the Advanced Machine Learning Model](/getting-started/using-the-advanced-machine-learning-model)
{% endhint %}


# Install With Helm using Webhook

{% hint style="warning" %}
The installation steps on this page apply to following supported open-appsec integrations:

* Istio Ingress Controller (currently in beta)
* Kong, new integration using native, Lua-based open-appsec attachment plugin (currently in beta)

For all other open-appsec integrations on Kubernetes see: [Install Using Helm - new flow (beta)](/getting-started/start-with-kubernetes/install-using-helm-new-flow-beta)

Let us know if you have any feedback regarding these beta programs or require technical assistance: [mailto://info@openappsec.io](mailto:info@openappsec.io)
{% endhint %}

{% hint style="info" %}
The open-appsec integration with Kong as shown on this page is for the newer, more flexible version of the Kong open-appsec integration which is based on using a Lua plugin. This is a more native integration than the traditional plugin (also still available, but will be deprecated in the future) and is following the official Kong plugin guidelines.

As this is a regular Kong plugin, you must make sure to also configure the plugin to apply to your traffic (e.g. all traffic, specific routes, etc.), as otherwise the open-appsec agent will not receive the traffic for inspection. You find all required info below in the documentation
{% endhint %}

The steps described on this page explain how to deploy and integrate open-appsec on Kubernetes:

* with an existing Istio Ingress Gateway already deployed on Kubernetes
* with an existing Kong API Gateway already deployed on Kubernetes

## Prerequisites

* Kubernetes 1.16.0+ cluster with [RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) enabled with Cluster admin permissions
* [Helm 3 Package Manager](https://helm.sh/docs/intro/install/) installed on your local machine
* `kubectl` and `wget` command-line tools installed on the system that you use to access the Kubernetes cluster
* For Istio:
  * An existing deployment of Istio Ingress Gateway. Supported versions: 1.23 - 1.26
  * You should have an understanding of Istio Kubernetes CRD types "Virtual Service" and "Gateway"
* For Kong:
  * An existing deployment of Kong API Gateway.&#x20;
  * You should have an understanding of Kubernetes "Ingress"

### **Optional (Recommended)**

To use the open-appsec central management web UI for managing your open-appsec WAF deployment — either **centrally** via WebUI (SaaS) or **locally** with optional **read-only WebUI monitoring** — follow these steps (not required if you plan to manage your deployment only locally, declaratively):

* **Sign Up / Log In**\
  Go to <https://my.openappsec.io> and sign up or log in to access the WebUI.

{% content-ref url="/pages/0ty9rMQEgnxS9LBuN7qw" %}
[Sign-Up and Login to Portal](/getting-started/using-the-web-ui-saas/sign-up-and-login-to-portal)
{% endcontent-ref %}

* **Create a Deployment Profile**\
  Once logged in, create a new deployment profile for your open-appsec setup.\
  **Important:** After completing policy installation, **copy the profile token**—you’ll need it in the installation steps that follow.

{% content-ref url="/pages/WMgZp7bTMiI5PD1ocIKp" %}
[Create a Profile](/getting-started/using-the-web-ui-saas/create-a-profile)
{% endcontent-ref %}

## Installation

#### Step 1: Add the Helm Repo

{% hint style="info" %}
Please note that this new installation flow with helm uses a different helm chart.
{% endhint %}

```bash
helm repo add openappsec https://charts.openappsec.io
helm repo update
```

#### Step 2: Deployment

{% tabs %}
{% tab title="Istio" %}
Run the following command to deploy the open-appsec helm chart into your Istio Ingress Controller namespace:

```bash
helm install open-appsec-webhook openappsec/open-appsec-injector \
--set webhook.objectSelector.labelValue=istio-ingress \
--set webhook.objectSelector.labelName=app \
--set kind=istio \
--set appsec.persistence.enabled=false \
--set gateways.istio-ingressgateway.service.externalTrafficPolicy=Local \
--set appsec.userEmail=<your-email-address> \
--set appsec.agentToken= \
-n [istio ingress gateway namespace]
```

Before running the installation command, make sure to update the placeholders according to your environment:

* **`istio ingress gateway namespace`** - Replace this with the **namespace** of your existing Istio ingress gateway deployment.
* `appsec.agentToken`  - If you are connecting to the central WebUI, add the profile token you received after creating a deployment profile in the WebUI.
  * For standalone deployments leave parameter empty
* `appsec.userEmail` **-** Replace `<your-email-address>` with your own **email address**.

**open-appsec will now be deployed into the existing namespace of your istio ingress gateway.**

{% hint style="info" %}
If you have persistent storage available in your cluster please set the `--set appsec.persistence.enabled=false` parameter in the following command to `true` to allow open-appsec to use persistent storage for the learning. This is only shown for maximum compatibility reasons.
{% endhint %}

<details>

<summary>Optional open-appsec helm install  parameters</summary>

* `-n <istio ingress gateway namespace>`: select the existing namespace name of the istio ingress gateway deployment to which open-appsec should be added and integrated with.

{% hint style="warning" %}
The open-appsec-waf-injector is using a label in the istio ingress gateway deployment to identify those pods, to which the open-appsec agent container should be automatically added (via mutating webhook).\
In addition it adds and loads our attachment module as a filter in the istio ingress gateway container, allowing the open-appsec agent to inspect traffic arriving at the istio ingress gateway.\
\
In case of the default value an open-appsec agent container will e.g. be added to each istio ingress gateway pod which has the following label set: `app: istio-ingress` \
Two parameters are available that allow you to customize the name and value of that label.<br>
{% endhint %}

* `--set kind`: specify the integration you want to deploy, for Istio make sure to select `istio` as value.
* `--set webhook.objectSelector.labelName` : specify the name of the label (default name is `app`) which is used to identify the deployment istio ingress gateway deployment to which the open-appsec attachment should be automatically injected.
* `--set webhook.objectSelector.labelValue` : specify the value of the label (default is `istio-ingress)` which is used to identify the istio ingress gateway deployment to which the open-appsec attachment should be automatically injected.&#x20;
* `--set appsec.userEmail`: allows you to associate your email address with your specific deployment by replacing `<your-email-address>` with your own email address.

  This allows us to provide you easy assistance in case of any issues you might have with your specific deployment in the future and also to provide you information proactively regarding open-appsec in general or regarding your specific deployment. This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future.
* `--set appsec.persistence.enabled`: persistent volume includes machine learning information, if this is set to false then machine learning information is lost when the appsec container is stopped/restarted.&#x20;

  * `true`: default is true
  * `false`

  If this value is set to true (default, when not overriding with `false`) you must also specify `appsec.persistence.learning.storageClass`
* `--set appsec.persistence.learning.storageClass`: Specify storage class to be used for the learning pod.\
  Note: storageClass name specified here must support ReadWriteMany (like AWS EFS or Azure Files).
* `--set appsec.agentToken`: set the deployment profile token from central management WebUI (SaaS) to connect your open-appsec deployment to the central WebUI (SaaS), see here how to get the token: [create a profile in web UI](/getting-started/using-the-web-ui-saas/create-a-profile). If you don't set this then your deployment will be in standalone mode.
* `--set gateways.istio-ingressgateway.service.externalTrafficPolicy=Local` recommended for preserving original IP address by making sure that traffic for the loadbalancer service is only routed to pods on the same node.

For additional available configuration values please check the values.yaml within the downloaded Helm chart and the Ingress Ingress Gateways documentation available [here](https://istio.io/latest/docs/tasks/traffic-management/ingress/ingress-control/).

</details>
{% endtab %}

{% tab title="Kong" %}

### Kong helm chart adjustment and redeployment

You will continue to use your regular Kong helm chart, but with an adjustment to make the open-appsec Lua-based attachment plugin available:<br>

1. Redeploy your existing helm-based Kong gateway deployment by replacing the kong proxy container with an enhanced kong proxy container provided by open-appsec which already includes the *open-appsec-waf-kong-plugin* (or alternatively build a container yourself which includes the *open-appsec-waf-kong-plugin*). This plugin is required for the open-appsec agent to receive traffic from the Kong gateway for inspection and returning decisions about allowing/preventing http requests.

You can use one of the following parameters with your kong/kong helm chart deployment:\
\
For replacing the Kong Enterprise Gateway container with the enhanced one for open-appsec:

```bash
--set image.repository=ghcr.io/openappsec/kong-gateway-k8s-attachment-plugin
--set image.tag=latest
```

For replacing the Kong OSS container with the enhanced one for open-appsec:

```bash
--set image.repository=ghcr.io/openappsec/kong-k8s-attachment-plugin
--set image.tag=latest
```

2. Now that we have a Kong container deployed that includes the *open-appsec-waf-kong-plugin*, you must make sure to load it by creating and applying a KongPlugin resource as follows:

{% hint style="info" %}
If you use Kong Konnect, then this is not required, as you can enable the plugin centrally using open-appsec's plugin schema for Kong Konnect, find instructions and all details here:

[Using Kong Konnect (Kong only)](/getting-started/using-the-web-ui-saas/using-kong-konnect-kong-only)
{% endhint %}

Create a file `open-appsec-KongPlugin.yaml` with following content:

```yaml
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
  name: open-appsec-waf-kong-plugin
config: {}
plugin: open-appsec-waf-kong-plugin
```

Apply this file using following command:\
(Replace `[add your kong deployment namespace here]` with your kong deployment namespace.)

```bash
kubectl apply -f open-appsec-KongPlugin.yaml -n [add your kong deployment namespace here]
```

### open-appsec deployment

Run the following command to deploy the open-appsec helm chart into your existing Kong namespace.

Before running the installation command below, make sure to update the placeholders according to your environment:

* **`kong gateway namespace`** - Replace this with the **namespace** of your existing Kong gateway deployment.
* `appsec.agentToken`  - If you are connecting to the central WebUI, add the profile token you received after creating a deployment profile in the WebUI.
  * For standalone deployments leave parameter empty
* `appsec.userEmail` **-** Replace `<your-email-address>` with your own **email address**.

```bash
helm install open-appsec-webhook openappsec/open-appsec-injector \
--set webhook.objectSelector.labelName="app.kubernetes.io/name" \
--set webhook.objectSelector.labelValue=kong \
--set kind=kong \
--set appsec.persistence.enabled=false \
--set appsec.userEmail=<your-email-address> \
--set appsec.agentToken= \
-n [kong gateway namespace]
```

**open-appsec will now be deployed into the existing namespace of your Kong gateway.**

{% hint style="info" %}
If you have persistent storage available in your cluster please set the `--set appsec.persistence.enabled=false` parameter in the following command to `true` to allow open-appsec to use persistent storage for the learning. This is only shown for maximum compatibility reasons.
{% endhint %}

<details>

<summary>Optional open-appsec helm install  parameters</summary>

* `-n <kong gateway namespace>`: select the existing namespace name of the Kong gateway deployment to which open-appsec should be added and integrated with.

{% hint style="warning" %}
The open-appsec-waf-injector is using a label in the Kong gateway deployment to identify those pods, to which the open-appsec agent container should be automatically added (via mutating webhook).\
This allows the open-appsec agent to inspect traffic arriving at the Kong gateway (the attachment plugin which is part of the enhanced Kong container will hand over traffic for inspection to the open-appsec agent in the same pod).\
\
In case of the default value an open-appsec agent container will e.g. be added to each pod which has the following label set: `app: istio-ingress` (this helm chart also support istio integration). Make sure to adjust this for Kong, see helm install command above!\
Two parameters are available that allow you to customize the name and value of that label.
{% endhint %}

* `--set kind`: specify the integration you want to deploy, for Kong make sure to select `kong` as value.
* `--set webhook.objectSelector.labelName` : specify the name of the label (default name is `app`) which is used to identify the existing kong gateway to which the open-appsec attachment should be automatically injected.\
  Make sure to adjust this aligned with your kong gateway deployment, e.g. as shown in the helm install command for Kong above!
* `--set webhook.objectSelector.labelValue` : specify the value of the label (default is `istio-ingress`, as this helm chart also supports istio) which is used to identify the existing kong gateway deployment to which the open-appsec attachment should be automatically injected. \
  Make sure to adjust this aligned with your kong gateway deployment, e.g. as shown in the helm install command for Kong above!
* `--set appsec.userEmail`: allows you to associate your email address with your specific deployment by replacing `<your-email-address>` with your own email address.

  This allows us to provide you easy assistance in case of any issues you might have with your specific deployment in the future and also to provide you information proactively regarding open-appsec in general or regarding your specific deployment. This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future.
* `--set appsec.persistence.enabled`: persistent volume includes machine learning information, if this is set to false then machine learning information is lost when the appsec container is stopped/restarted.&#x20;

  * `true`: default is true
  * `false`

  If this value is set to true (default, when not overriding with `false`) you must also specify `appsec.persistence.learning.storageClass`
* `--set appsec.persistence.learning.storageClass`: Specify storage class to be used for the learning pod.\
  Note: storageClass name specified here must support ReadWriteMany (like AWS EFS or Azure Files).
* `--set appsec.agentToken`: set the deployment profile token from central management WebUI (SaaS) to connect your open-appsec deployment to the central WebUI (SaaS), see here how to get the token: [create a profile in web UI](/getting-started/using-the-web-ui-saas/create-a-profile). If you don't set this then your deployment will be in standalone mode.

For additional available configuration values please check the values.yaml within the downloaded Helm chart and the Kong gateway's documentation available [here](https://developer.konghq.com/gateway/install/).

</details>
{% endtab %}
{% endtabs %}

#### Step 3: Enable open-appsec Injection to the existing deployment

To allow open-appsec to inspect the traffic through your existing Istio Ingress or Kong gateway, it must be attached to the existing deployment. This happens automatically **if the proper labels are set** and the deployment is restarted.

1. **Label the Namespace**\
   Add the `inject-waf-attachment=true` label to the **namespace** of your existing reverse proxy deployment (e.g. Istio Ingress Gateway or Kong):

   ```bash
   kubectl label namespace [existing reverse proxy deployment namespace] inject-waf-attachment="true" --overwrite
   ```
2. **Label the Deployment**\
   Ensure your current reverse proxy **deployment** has the required labels set as configured in your `webhook.objectSelector`:

   * `webhook.objectSelector.labelName`
   * `webhook.objectSelector.labelValue`

   *(These labels must match what’s configured in the open-appsec Helm chart. Refer to your Helm values or the section above for details.)*
3. **Restart the existing reverse proxy deployment**

Restart your existing deployment by using the following command:

```
kubectl rollout restart deployment [istio ingress gateway deployment name] -n [istio ingress gateway namespace]
```

{% hint style="success" %}
Here's what happens when you restart the deployment:

* The `inject-waf-attachment`  label **enables** open-appsec to patch the existing deployment.
* An open-appsec **agent container** is injected additionally into each pod using a **Kubernetes mutating webhook**.
* *In case of Istio:* During restart, the open-appsec **attachment** is injected into the existing ingress gateway container.
  {% endhint %}

{% hint style="info" %}
If you want to remove the agent (Istio or Kong) and injected attachment (Istio only) later again, you can set `inject-waf-attachment` to `false` and perform another rollout restart of the deployment so it gets removed again.
{% endhint %}

#### Step 4: Validate that open-appsec is installed and running

```
kubectl get pods -n [reverse proxy deployment namespace]
```

The READY column should now show an additional container running in your proxy pod and should show 1/1 for each of the following pods: waf injector, learning deployment (only in standalone deployment), shared storage deployment (only in standalone deployment).&#x20;

**Step 5: If you connected to central WebUI AND configured your deployment profile in the WebUI to "This management" mode for centrally managing open-appsec configuration**:

* **Create one or more assets in the WebUI** which represent web applications and/or Web APIs which you want to be protected by open-appsec WAF and allows you to adjust the open-appsec configuration specifically for each of them. \
  \
  Make sure to link your assets to the specific WebUI Profile which you created earlier (General -> Profiles) and adjust the Threat Prevention mode to Detect-Learn or Prevent (Threat Prevention -> Mode), the steps are described here:&#x20;

{% content-ref url="/pages/yvQt78cZU4kLymWzObq3" %}
[Protect Additional Assets](/getting-started/using-the-web-ui-saas/protect-additional-assets)
{% endcontent-ref %}

{% hint style="success" %}
Don't forget to Enforce policy in the WebUI after you did any changes for those changes to become effective!
{% endhint %}

{% hint style="danger" %}
The following steps 6-10 are **only** relevant if you want to **locally manage** this open-appsec deployment in Kubernetes using a declarative configuration using custom resources.

They apply to the following two cases:

* You do not want to connect to central WebUI at all (you didn't provide a deployment profile token earlier)
* You provided deployment profile token earlier for a WebUI profile set to mode "Declarative Management"

If you are not managing your deployment locally, scroll down to [#validate-that-open-appsec-works](#validate-that-open-appsec-works "mention")
{% endhint %}

#### Step 6: (only for locally-managed deployments) Download the yaml file for open-appsec CRD installation

Run the following command to obtain the yaml file containing the open-appsec CRD definitions, choose the CRD version you want to use.\
\
v1beta2 CRDs:

```bash
wget https://raw.githubusercontent.com/openappsec/openappsec/main/config/crds/open-appsec-crd-v1beta2.yaml
```

#### Step 7:  (only for locally-managed deployments) Create the open-appsec CRDs which add new K8s resource-types that will be used later for defining the protection policies, log settings, exceptions, user response and more.

{% hint style="info" %}
You can skip this step if you skipped the previous step, because you plan to centrally manage open-appsec from central WebUI and not manage it locally using CRDs.
{% endhint %}

Deploy the CRDs using the following command:

For the v1beta2 CRDs:

```bash
kubectl apply -f ./open-appsec-crd-v1beta2.yaml
```

#### Step 8: (only for locally-managed deployments) Download a default configuration for the open-appsec custom resources

Run the following command to obtain the yaml file containing the open-appsec default configuration custom resources, chose the CRD version which you have deployed in the steps above on your cluster.\
\
Default configuration for v1beta2 in detect-learn mode:

```bash
wget https://raw.githubusercontent.com/openappsec/openappsec/main/config/k8s/v1beta2/open-appsec-k8s-default-config-v1beta2.yaml
```

{% hint style="info" %}
The default configuration files provided above are set to detect-learn mode, which is recommended for new deployments to allow the machine learning engine sufficient learning before moving to prevent-learn mode. You can then later easily reconfigure the `open-appsec-best-practice-policy` custom policy resource to prevent-learn mode.\
\
If you would like to start in prevent-mode in non-critical environment for testing purposes right away, you can alternatively use these files, which are preconfigured to prevent-learn mode:

Default configuration for v1beta2 (beta) in prevent-mode

`wget https://raw.githubusercontent.com/openappsec/openappsec/main/config/k8s/v1beta2/open-appsec-k8s-prevent-config-v1beta2.yaml`<br>
{% endhint %}

#### Step 9: (only for locally-managed deployments) Deploy default configuration for the open-appsec custom resources

To deploy the default configuration for the open-appsec custom resources perform the step below:\
\
Default configuration for v1beta2 (beta):

```bash
kubectl apply -f ./open-appsec-k8s-default-config-v1beta2.yaml
```

#### Step 10: Configure open-appsec protection using custom resources (only relevant for locally-managed deployments)&#x20;

**a. Make sure to have an open-appsec `Policy` resource**

If you followed the steps above you should now have an open-appsec-best-practice-policy custom resource deployed on your K8s cluster.\
\
You can check this with the following command which will list all open-appsec policy custom resources:

```bash
kubectl get policies.openappsec.io
```

If you want to check if it's set to `detect-learn` (default) or `prevent-learn` mode you can use this command (the name of the policy created by the default configuration in v1beta2 is `default-policy`):

```bash
kubectl get policies.openappsec.io default-policy -o yaml
```

If you want to create your own custom policy, you find all details here:

For v1beta2 CRDs: [Configuration Using CRDs - v1beta2](/getting-started/start-with-kubernetes/configuration-using-crds-v1beta2)

**b. Create a `PolicyActivation` resource**\
\
Using a `PolicyActivation` custom resource you can now specify that your existing open-appsec policy (e.g. `default-policy`, see above)  should be applied to all traffic matching the hostname `example.com`. (You can have multiple `Policy` custom resources and also multiple `PolicyActivation` custom resources)

Create a new file `policy-activation.yaml` to specify a new `PolicyActivation` custom resource similar to the below specification (change `example.com` to your own hostname, adjust `default-policy` if you want to reference another `Policy` custom resource instead of the default one):

```yaml
apiVersion: openappsec.io/v1beta2
kind: PolicyActivation
metadata:
  name: policy-activation-example
spec:
  enabledPolicies:
    - name: default-policy
      hosts:
        - "example.com"
```

Then apply it to your Kubernetes cluster using:

```bash
kubectl apply -f policyactivation.yaml
```

If you want to create your own PolicyActivation custom resource, you find all details here:

For v1beta2 CRDs: [Configuration Using CRDs - v1beta2](/getting-started/start-with-kubernetes/configuration-using-crds-v1beta2)

## Validate the Deployment:

Your reverse proxy is now protected with open-appsec (in detect or prevent mode)!

1. *In case of Istio:* Generate some traffic to one of the services defined by your Istio `Gateway` and `VirtualService` resources\
   \
   *In case of Kong:* Generate some traffic to e.g. the web resource specified in your K8s ingress resource.
2. Run this command to see logs:

Note the name of an Istio ingress gateway pod by running:

```
kubectl get pods -n [reverse proxy deployment namespace]
```

Then show the logs of the open-appsec agent container by running:

```
kubectl logs [reverse proxy deployment pod name] -c open-appsec -n [reverse proxy deployment namespace]
```


# Integrate with Envoy Gateway

{% hint style="warning" %}
**Integration of open-appsec with Envoy Gateway is currently available as "alpha".**\
\
Please share your feedback with us and let us know if you encounter any issues: <info@openappsec.io>
{% endhint %}

## Prerequisites

* Kubernetes 1.16.0+ cluster with [RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) enabled with Cluster admin permissions
* **Existing Envoy Gateway** deployment on Kubernetes
* Current Deployment must be based on using **Envoy Gateway Operator** using `EnvoyProxy` CRD.\
  As a result of this there should be an `EnvoyProxy` resource deployed in your K8s cluster.

{% hint style="info" %}
At this time in the current alpha release, we only support open-appsec deployment in scenarios where the Envoy Gateway is deployed using the Envoy Gateway Operator (often preferred in large environments).

We also plan to support integration in scenarios where Envoy Gateway is deployed using helm charts soon as well, in case this is critical for you, please let us know at <mailto:info@openappsec.io> .
{% endhint %}

* **The Envoy Proxy container must be using the** **contrib image**: `envoyproxy/envoy:contrib-<version>` \
  Make sure that  `<version>`  specified is one of the following supported Envoy Proxy versions: 1.32 - 1.34\
  (Mandatory to allow loading the open-appsec "attachment" filter for envoy, which is golang-based)
* **Make sure that `enableEnvoyPatchPolicy` is enabled** in your Envoy Gateway via config map setting or Helm value, as an `EnvoyPatchPolicy` resource will be used to insert the go "attachment" filter for open-appsec to the Envoy configuration.
* **Sign-Up and Login to open-appsec central web UI portal**\
  Follow the instructions below to sign-up and login to the WebUI available at <https://my.openappsec.io>, so you can create a deployment profile for the new deployment\
  This allows you to either centrally manage your open-appsec WAF deployment via WebUI (SaaS)\
  OR to locally manage your open-appsec WAF deployment but still connect to central WebUI for viewing the local configuration (in read-only), central monitoring, logging and reporting:

{% content-ref url="/pages/0ty9rMQEgnxS9LBuN7qw" %}
[Sign-Up and Login to Portal](/getting-started/using-the-web-ui-saas/sign-up-and-login-to-portal)
{% endcontent-ref %}

{% hint style="info" %}
Local-only standalone deployments are not supported yet, we plan to add support for these as well soon, in case this is critical for you, please let us know at <mailto:info@openappsec.io> .
{% endhint %}

* **Create deployment profile for the open-appsec deployment in WebUI Portal**\
  After you signed-up and logged in to the WebUI Portal (see prerequisite above), now follow the instructions below to create a new deployment profile of type "Kubernetes" for your open-appsec deployment.\
  When you configure the profile, make sure to select the correct subtype "Envoy Gateway Application Security".\
  **Once done, don't forget to copy the profile token after policy installation as this is needed in the installation steps further below.**

{% content-ref url="/pages/WMgZp7bTMiI5PD1ocIKp" %}
[Create a Profile](/getting-started/using-the-web-ui-saas/create-a-profile)
{% endcontent-ref %}

## Known Limitations

As this is an alpha version there are are some limitations which will be resolved in future versions.

* Support for Helm-based installation:\
  Currently only installations with Envoy Gateway Operator are supported
* No support for standalone deployments:\
  You must provide token to connect to central web UI.\
  You currently have two management options available to be used with central web UI:
  * Declarative mode (set management mode to "Declarative configuration" in web UI profile),\
    here you manage your open-appsec deployment locally using custom resources/CRDs and see your current configuration represented in read-only also in the central web UI, as well as status monitoring and optional central security logging/reporting.
  * Centrally managed mode (set management mode to "This management" in web UI profile),\
    here you manage your configuration centrally, have central status monitoring and optional central security logging/reporting.

## Deployment

The integration has two key components:

* open-appsec "attachment" filter, this lightweight Envoy filter must be present on the Envoy Proxy, as it's providing the traffic to the open-appsec agent for security inspection, then receives the decisions (e.g. allow or block) from the agent and finally enforces these decisions accordingly.
* open-appsec "agent", the agent, running in K8s as a side-car container to the Envoy Proxy container, receives traffic from the "attachment", performs the actual security inspection using the contextual machine learning engine and takes decisions whether HTTP requests are malicious or benign. It then notifies the "attachment" about those decisions.

{% hint style="info" %}
The deployment of the attachment is performed using an init container which deliver the files for the attachment filter to a shared volume which the envoy proxy container can then access.

When using the deployment instructions below the official envoy contrib image remains unchanged!
{% endhint %}

### Step 1: Create a patch file in your Kubernetes environment

Create an `envoyproxy-deployment-patch.yaml` patch file in your Kubernetes environment with the following contents:

<details>

<summary>envoyproxy-deployment-patch.yaml</summary>

```yaml
spec:
  provider:
    kubernetes:
      envoyDeployment:
        patch:
          type: StrategicMerge
          value:
            spec:
              template:
                spec:
                  initContainers:
                    - name: envoy-attachments
                      image: ghcr.io/openappsec/openappsec-envoy-filters:latest
                      imagePullPolicy: Always
                      command: ["/prepare_attachment.sh"]
                      env:
                        - name: ENVOY_VERSION
                          value: "1.34"
                      volumeMounts:
                        - name: attachment-shared
                          mountPath: /envoy/attachment/shared
                  containers:
                    - name: envoy
                      env:
                        - name: LD_LIBRARY_PATH
                          value: /usr/lib/attachment
                      volumeMounts:
                        - name: attachment-shared
                          mountPath: /usr/lib/attachment
                    - name: openappsec-agent
                      image: ghcr.io/openappsec/agent:1.1.29
                      imagePullPolicy: IfNotPresent
                      command:
                        - /cp-nano-agent
                      env:
                        - name: AGENT_TOKEN
                          value: <token>
                        - name: registered_server
                          value: "Envoy Gateway"
                        - name: user_email
                          value: "<your-email-address>"
                      volumeMounts:
                        - name: agent-config
                          mountPath: /etc/cp/conf
                        - name: agent-data
                          mountPath: /etc/cp/data
                        - name: agent-logs
                          mountPath: /var/log/nano_agent
                      resources:
                        limits:
                          cpu: 200m
                          memory: 256Mi
                        requests:
                          cpu: 100m
                          memory: 128Mi
                      securityContext:
                        runAsUser: 0
                  volumes:
                    - name: attachment-shared
                      emptyDir: {}
                    - name: agent-config
                      emptyDir: {}
                    - name: agent-data
                      emptyDir: {}
                    - name: agent-logs
                      emptyDir: {}


```

</details>

### Step 2: Adjust the patch file configuration

#### Adjust the following parameters in the patch file:

`<your-email-address>`  allows you to associate your email address with your specific deployment by replace this with your own email address.

This allows us to provide you easy assistance in case of any issues you might have with your specific deployment in the future and also to provide you information proactively regarding open-appsec in general or regarding your specific deployment. This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future.

`<token>`  (mandatory in the current alpha version of this integration) set the deployment profile token from central management WebUI (SaaS) to connect your open-appsec deployment to the central WebUI (SaaS), which you created according to the instructions in the prerequisites section at the top of this page. \
(You can see here how to get the token: [create a profile in web UI](https://docs.openappsec.io/getting-started/using-the-web-ui-saas/create-a-profile))

`ENVOY_VERSION` allows adjustment of the Envoy Proxy version which is set with the key of the  `ENVOY_VERSION` environment variable.

### Step 3: Patch the envoyProxy resource to add open-appsec agent and attachment filter

Now apply the patch file to your deployment of envoy gateway after adjusting the parameters (see below):

```bash
kubectl patch envoyproxy <envoyProxy resource name> --namespace <envoy gateway namespace> --type=merge --patch-file envoyproxy-patch.yaml
```

Replace the following parameters with your own values:

`<envoyProxy resource name>` replace with the name of the envoyProxy resource of the envoy gateway to which you want to add open-appsec to

`<envoy gateway namespace>`  replace with the name of the namespace of your envoy gateway namespace

### Step 4: Patch the envoy configuration to load the open-appsec attachment filter

{% hint style="warning" %}
Ensure that `enableEnvoyPatchPolicy` is enabled in your Envoy Gateway config map or Helm values. This is required in order to apply the `EnvoyPatchPolicy` resource.
{% endhint %}

* Create a file `EnvoyPatchPolicy.yaml` with the content below:

<details>

<summary>EnvoyPatchPolicy.yaml</summary>

```yaml
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyPatchPolicy
metadata:
  name: insert-go-filter
  namespace: <gateway resource namespace>
spec:
  targetRef:
    group: gateway.networking.k8s.io
    kind: Gateway
    name: <gateway resource name>
  type: JSONPatch
  jsonPatches:
    - type: type.googleapis.com/envoy.config.listener.v3.Listener
      name: <gateway resource namespace>/<gateway resource name>/http
      operation:
        op: add
        path: "/default_filter_chain/filters/0/typed_config/http_filters/0"
        value:
          name: envoy.filters.http.golang
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config
            library_id: cp_nano_filter
            plugin_name: cp_nano_filter
            library_path: /usr/lib/attachment/libenvoy_attachment.so
            plugin_config:
              "@type": type.googleapis.com/xds.type.v3.TypedStruct
              value:
                prefix_localreply_body: "hello from go filter"
```

</details>

* Replace the following parameters in the `EnvoyPatchPolicy.yaml` file with your own values:

`<gateway resource namespace>`  replace with the name of the namespace of the gateway resource&#x20;

`<gateway resource name>`  replace with the name of the gateway resource

* Apply the adjusted  `EnvoyPatchPolicy.yaml` file:

```bash
kubectl apply -f EnvoyPatchPolicy.yaml -n <gateway resource namespace>
```

Replace the following parameter in the command with your own value:\
\
`<gateway resource namespace>`  replace with the name of the namespace of your envoy gateway resource

### **Step 5: If you connected to central WebUI AND configured your deployment profile in the WebUI to "This management" mode for centrally managing open-appsec configuration**:

* **Create one or more assets in the WebUI** which represent web applications and/or Web APIs which you want to be protected by open-appsec WAF and allows you to adjust the open-appsec configuration specifically for each of them. \
  \
  Make sure to link your assets to the specific WebUI Profile which you created earlier (General -> Profiles) and adjust the Threat Prevention mode to Detect-Learn or Prevent (Threat Prevention -> Mode), the steps are described here: \
  \
  [Protect Additional Assets](/getting-started/using-the-web-ui-saas/protect-additional-assets)

{% hint style="warning" %}
Make sure to configure the web application URLs for your open-appsec assets for the correct ports on which the `envoy` container is receiving the traffic. Usually these would be:\
For HTTP: 10080\
For HTTPS: 10443
{% endhint %}

{% hint style="success" %}
Don't forget to Enforce policy in the WebUI after you did any changes for those changes to become effective!
{% endhint %}

{% hint style="danger" %}
The following steps 6-10 are **only** relevant if you want to **locally manage** this open-appsec deployment in Kubernetes using a declarative configuration using custom resources.

This applies if  you provided a deployment profile token earlier for a WebUI profile set to mode "Declarative Management".
{% endhint %}

#### Step 6: (only for locally-managed deployments) Download the yaml file for open-appsec CRD installation

Run the following command to obtain the yaml file containing the open-appsec CRD definitions:\
\
v1beta2 CRDs:

```bash
wget https://raw.githubusercontent.com/openappsec/openappsec/main/config/crds/open-appsec-crd-v1beta2.yaml
```

#### Step 7:  (only for locally-managed deployments) Create the open-appsec CRDs which add new K8s resource-types that will be used later for defining the protection policies, log settings, exceptions, user response and more.

{% hint style="info" %}
You can skip this step if you skipped the previous step, because in that case you plan to centrally manage open-appsec from central WebUI and not manage it locally using CRDs.
{% endhint %}

Deploy the CRDs using the following command:

```bash
kubectl apply -f ./open-appsec-crd-v1beta2.yaml
```

#### Step 8: (only for locally-managed deployments) Download a default configuration for the open-appsec custom resources

Run the following command to obtain the yaml file containing the open-appsec default configuration custom resources, chose the CRD version which you have deployed in the steps above on your cluster.\
\
Default configuration for v1beta2 in detect-learn mode:

```bash
wget https://raw.githubusercontent.com/openappsec/openappsec/main/config/k8s/v1beta2/open-appsec-k8s-default-config-v1beta2.yaml
```

{% hint style="info" %}
The default configuration files provided above are set to detect-learn mode, which is recommended for new deployments to allow the machine learning engine sufficient learning before moving to prevent-learn mode. You can then later easily reconfigure the `open-appsec-best-practice-policy` custom policy resource to prevent-learn mode.\
\
If you would like to start in prevent-mode in non-critical environment for testing purposes right away, you can alternatively use these files, which are preconfigured to prevent-learn mode:\
\
Default configuration for v1beta2 in prevent-mode

`wget https://raw.githubusercontent.com/openappsec/openappsec/main/config/k8s/v1beta2/open-appsec-k8s-prevent-config-v1beta2.yaml`
{% endhint %}

#### Step 9: (only for locally-managed deployments) Deploy default configuration for the open-appsec custom resources

To deploy the default configuration for the open-appsec custom resources perform the step below:

Default configuration for v1beta2:

```bash
kubectl apply -f ./open-appsec-k8s-default-config-v1beta2.yaml
```

#### Step 10: (only relevant for locally-managed deployments) Configure open-appsec protection using custom resources&#x20;

**a. Make sure to have an open-appsec `Policy` resource**

If you followed the steps above you should now have an open-appsec-best-practice-policy custom resource deployed on your K8s cluster.\
\
You can check this with the following command which will list all open-appsec policy custom resources:

```bash
kubectl get policies.openappsec.io
```

If you want to check if it's set to `detect-learn` (default) or `prevent-learn` mode you can use this command (the name of the policy created by the default configuration in v1beta2 is `default-policy`):

```bash
kubectl get policies.openappsec.io default-policy -o yaml
```

If you want to create your own custom policy, you find all details here:

For v1beta2 CRDs: [Configuration Using CRDs - v1beta2](/getting-started/start-with-kubernetes/configuration-using-crds-v1beta2)

**b. Create a `PolicyActivation` resource**\
\
Using a `PolicyActivation` custom resource you can now specify that your existing open-appsec policy (e.g. `default-policy`, see above)  should be applied to all traffic matching the hostname `example.com`. (You can have multiple `Policy` custom resources and also multiple `PolicyActivation` custom resources)

Create a new file `policy-activation.yaml` to specify a new `PolicyActivation` custom resource similar to the below specification (change `example.com` to your own hostname, adjust `default-policy` if you want to reference another `Policy` custom resource instead of the default one):

```yaml
apiVersion: openappsec.io/v1beta2
kind: PolicyActivation
metadata:
  name: policy-activation-example
spec:
  enabledPolicies:
    - name: default-policy
      hosts:
        - "example.com"
```

Then apply it to your Kubernetes cluster using:

```bash
kubectl apply -f policyactivation.yaml
```

If you want to create your own PolicyActivation custom resource, you find all details here:

For v1beta2 CRDs: [Configuration Using CRDs - v1beta2](/getting-started/start-with-kubernetes/configuration-using-crds-v1beta2)

## Validate the Deployment:

Your reverse proxy is now protected with open-appsec (in detect or prevent mode)!

1. Generate some traffic to one of the services defined by your `gateway` resources.
2. Run this command to see logs:

Note the name of your envoy gateway pod by running:

```bash
kubectl get pods -n <envoy gateway deployment namespace>
```

Then show the logs of the open-appsec agent container by running:

```bash
kubectl logs <envoy gateway deployment pod name> -c openappsec-agent -n <envoy gateway deployment namespace>
```


# Configuration Using CRDs

{% hint style="warning" %}
The CRDs explained below are based on the openappsec.io CRD schema **v1beta1**.\
The latest available, significantly enhanced openappsec.io CRD schema is **v1beta2**,\
documentation for **v1beta2** is available here: [Configuration Using CRDs - v1beta2](/getting-started/start-with-kubernetes/configuration-using-crds-v1beta2)
{% endhint %}

You can create your own policies and apply them for either all or specific ingress rules, set exceptions and other advanced options using K8S native declarative configuration.

## Using open-appsec K8S Custom Resources

open-appsec configuration is done using [Kubernetes Custom Resource Definition](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) (CRD). Custom Resources are extensions of the Kubernetes API that allow powerful yet standard way of managing policies in a declarative way as well as using infrastructure-as-code paradigm. This support is an important goal of managing changes as part of your CI/CD processes.&#x20;

open-appsec provides seven CRDs. The main one is `policy` - which defines default behaviors that will apply to all Ingress rules and also behaviours that you wish to apply just to specific rules. The `policy` resource refers to all other CRDs.

The Kubernetes API serves and handles the storage of custom resources. They can be accessed and managed using standard tools: kubectl, a REST client that you write, Go and Python [client libraries](https://kubernetes.io/docs/reference/using-api/client-libraries/) and more.

For example, to see available policies:

```bash
$ kubectl get policy.openappsec.io
NAME                                       AGE
open-appsec-best-practice-policy           90m
```

To see e.g. the open-appsec-best-practice-policy-detect resource run:

```yaml
$ kubectl get policy.openappsec.io open-appsec-best-practice-policy -o yaml

apiVersion: openappsec.io/v1beta1
kind: Policy
metadata:
  name: open-appsec-best-practice-policy
spec:
  default:
    custom-response: 403-forbidden
    exceptions: []
    mode: detect-learn
    practices:
    - appsec-best-practice
    triggers:
    - appsec-log-trigger
```

In case you want to edit one of your own policies, e.g. your own default-policy you can do this with the following command (see further below for an example to create your own custom policy resource):&#x20;

```
kubectl edit policy.openappsec.io/open-appsec-best-practice-policy
```

## Activating open-appsec

In order to activate open-appsec, add the `policy` resource name (e.g. open-appsec-best-practice-policy) to your Ingress resource. \
\
For example:

```yaml
...
annotations:
  openappsec.io/policy: open-appsec-best-practice-policy
...
```

<details>

<summary>Ingress resource example</summary>

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    openappsec.io/policy: open-appsec-best-practice-policy-detect
    # openappsec.io/policy: open-appsec-best-practice-policy-prevent
  name: ingress-wildcard-host
spec:
  rules:
  - host: "foo.bar.com"
    http:
      paths:
      - pathType: Prefix
        path: "/bar"
        backend:
          service:
            name: service1
            port:
              number: 80
  - host: "*.foo.com"
    http:
      paths:
      - pathType: Prefix
        path: "/foo"
        backend:
          service:
            name: service2
            port:
                number: 80
```

</details>

{% hint style="info" %}
The open-appsec-best-practice-policy will by default:

* Inspect traffic to all ingress rules (paths) and learn it
* Detect  suspicious requests in confidence high or critical
* In case of the prevent policy send an HTTP Error Code 403 Forbidden to the client that sent the bad request
* Log to stdout (so you can use fluentd/fluentbit) to send logs to ELK or other collector.
  {% endhint %}

You can define your own policy and change relevant parameters as explained in the next section.

## Custom Resources Specifications

### Policy&#x20;

Policy resource defines default behaviors that will apply to all Ingress rules and optional policies that you wish to apply just to specific rules.&#x20;

<details>

<summary> Example</summary>

```yaml
apiVersion: openappsec.io/v1beta1
kind: Policy
metadata:
  name: open-appsec-best-practice-policy
spec:
  default:
    triggers:
    - appsec-special-log-trigger
    mode: detect-learn
    practices:
    - webapp-best-practice
    source-identifiers: appsec-source-identifiers-sourceip-example
    trusted-sources: appsec-trusted-source-example
    custom-response: appsec-web-user-response-example
    exceptions:
    - appsec-exception-example
  specific-rules:
  - host: web.server.com/example
    triggers:
    - appsec-special-log-trigger
    mode: prevent-learn
    practices:
    - webapp-best-practice
    source-identifiers: appsec-source-identifiers-sourceip-example
    trusted-sources: appsec-trusted-source-example
    custom-response: appsec-web-user-response-example
    exceptions:
    - appsec-exception-example
  - host: web.server.com/another-example
    triggers:
    - appsec-special-log-trigger
    mode: prevent-learn
    practices:
    - webapp-best-practice
    source-identifiers: appsec-source-identifiers-sourceip-example
    trusted-sources: appsec-trusted-source-example
    custom-response: appsec-web-user-response-example
    exceptions:
    - appsec-exception-example

```

</details>

<details>

<summary>Specification</summary>

**default**

* **mode** *string enum* - security engines operation mode. Blocking will only happen in prevent-learn mode
  * prevent-learn / detect-learn / prevent / detect / inactive\
    (note that prevent and detect are just aliases for prevent-learn and detect-learn)
* **practices** *array of strings* - defines which security engines to activate and their specific settings (Note there cannot be multiple practices of the same kind specified here!)
  * reference to Practice resource(s)
* **triggers** *array of strings* - defines logging verbosity and destination (stdout, syslog, cloud, etc) (Note for now only a single trigger is supported!)
  * reference to LogTrigger resource(s)
* **custom-response** *string* - defines prevent mode behaviors upon decision to block: HTTP response code, block page, http redirect
  * reference to CustomResponse resource
* **source-identifiers** *string* - defines how ML engine will  distinguish between sources based on IP address, X-Foward-For, Key in Header/Cookie/JWT
  * reference to SourcesIdentifier resource
* **trusted-sources** *string -* defines which traffic sources are very unlikely to be malicious. Used for Machine Learning engine.
* **exceptions** *arrays of strings* - defines exceptions to be applied based on e.g. countryCode, countryName, sourceIP, URL, hostName, sourceIdentifier
  * reference to Exception resource(s)

**specific-rules** list\
list of one or more per-host (ingress rule) policies that will override the defaults above

* **host** *string -* policy will apply to this host
  * network path (exactly as appear in ingress rules)
* *All other keys can be used same as decribed above for default.*

</details>

{% hint style="warning" %}
When configuring specific rules in the open-appsec policy for APISIX and Kong on Kubernetes, make sure to also specific the correct default ports on which the APISIX and Kong containers receive traffic, as they deviate from the usual ports 80 and 443:\
\
APISIX:   HTTP: 9080, HTTPS: 9443

Kong:   HTTP: 8000, HTTPS: 8443
{% endhint %}

### Practice

Practice resources define which security engine will be active and their settings.&#x20;

<details>

<summary>Example </summary>

```yaml
apiVersion: openappsec.io/v1beta1
kind: Practice
metadata:
  name: webapp-best-practice
spec:
  openapi-schema-validation:
    configmap: []
    override-mode: 'prevent'
  snort-signatures:
    configmap: []
    override-mode: 'prevent'
  web-attacks:
    max-body-size-kb: 1222
    max-header-size-bytes: 44343
    max-object-depth: 2111
    max-url-size-bytes: 34434
    minimum-confidence: high
    override-mode: 'prevent'
    protections:
      csrf-enabled: prevent
      error-disclosure-enabled: prevent
      non-valid-http-methods: true
      open-redirect-enabled: prevent
  anti-bot:
    injected-URIs: []
    validated-URIs: []
    override-mode: 'prevent'
```

</details>

<details>

<summary>Specification</summary>

* **web-attacks - open-appsec ML engine settings**
  * **override-mode** *string enum* - allows overriding the mode defined at the Policy level for this specific engine
    * prevent-learn / detect-learn / prevent / detect / inactive
  * **minimum-confidence** *string* *enum, default: high* - defines which security engines to activate and their specific settings
    * medium / high / critical
  * **max-url-size-bytes** *integer,* default: 32768
  * **max-object-depth** *integer,* default: 40
  * **max-body-size-kb** *integer,* default: 102400
  * **max-header-size-bytes** *integer,* default: 32768
  * **protections** *- settings for various advanced protections:*
    * **csrf-enabled** *string, default: inactive -* Cross Site Request Forgery protection
      * prevent-learn / detect-learn / prevent / detect / inactive
    * **error-disclosure-enabled** *string, default: inactive -* Prevent disclosure of technical information to the attacker in server error messages
      * prevent-learn / detect-learn / prevent / detect / inactive
    * **open-redirect-enabled** *string, default: inactive* - Protect against URL redirection to untrusted sites
      * prevent-learn / detect-learn / prevent / detect / inactive
    * **non-valid-http-methods** *boolean, default: false* - Prevent attacker from sending requests with unsafe HTTP methods
      * true / false
* **open-api-schema-validation (currently not supported yet, will be added soon)**
  * **configmap** *array of strings* - specify configmap(s) containing the OpenAPI schema definitions
  * **override-mode** *enum* - allows overriding the mode defined at the Policy level for this specific engine
    * prevent-learn / detect-learn / prevent / detect / inactive
* **anti-bot**
  * **override-mode** *enum* - allows overriding the mode defined at the Policy level for this specific engine
    * prevent-learn / detect-learn / prevent / detect / inactive
  * **injected-URIs** *array of strings* - Provide URL(s) where Anti-Bot check is injected with GET request
  * **validated-URIs** *array of strings -* Provide URL(s) where result of Anti-Bot check is received from with POST request
* **snort-signatures (currently not supported yet, will be added soon)**
  * **override-mode** *enum* - allows overriding the mode defined at the Policy level for this specific engine
    * prevent-learn / detect-learn / prevent / detect / inactive
  * **configmap** *array of strings* - specify configmap(s) containing snort signatures

</details>

### Custom Response

Practice resources define which security engine will be active and their settings.&#x20;

<details>

<summary>Examples </summary>

```yaml
apiVersion: openappsec.io/v1beta1
kind: CustomResponse
metadata:
  name: appsec-web-user-response-example
spec:
  mode: block-page
  http-response-code: 403
  message-title: Block page title
  message-body: "<h1>Access blocked by open-appsec.</h1><p>Your access will be logged.</p>"

apiVersion: openappsec.io/v1beta1
kind: CustomResponse
metadata:
  name: appsec-default-web-user-response
spec:
  mode: response-code-only
  http-response-code: 403
```

</details>

<details>

<summary>Specification</summary>

* **mode** *enum -* engine will take one of these actions upon decision to block request
  * block-page - send HTML with text to client + HTTP response code
  * response-code-only - send only response code
* **message-title** *string* - title of block page that will be displayed only in case mode is block page and engine decided to block
* **message-body** *string* - content of block page that will be displayed only in case mode is block page and engine decided to block
* **http-response-code** *integer between 100-599* - http code that will be returned to client upon engine decision to block; default is 403 - HTTP Forbidden

</details>

### Log Trigger

<details>

<summary>Example </summary>

```yaml
apiVersion: openappsec.io/v1beta1
kind: LogTrigger
metadata:
  name: appsec-special-log-trigger
spec:
  access-control-logging:
    allow-events: false
    drop-events: true
  additional-suspicious-events-logging:
    enabled: true
    minimum-severity: high
    response-body: false
  appsec-logging:
    all-web-requests: false
    detect-events: false
    prevent-events: true
  extended-logging:
    http-headers: false
    request-body: false
    url-path: false
    url-query: false
  log-destination:
    cloud: false
    file: "/a/b/c"
    stdout:
      format: json
    syslog-service:
    - address: 1.2.3.4
      port: 514
    cef-service:
    - address: 5.6.7.8
      port: 514
      proto: tcp
```

</details>

<details>

<summary>Specification</summary>

* **access-control-logging** - configure logging for Access Control events
  * **allow-events** *boolean, default: false* - log access control allow eve*nts*
    * true / false
  * **drop-events** *boolean, default: true* - log access control drop event*s*
    * true / false
* **additional-suspicious-events-logging** configure additional logging for suspicious events based on a selectable minimum severity-level
  * **enabled** *boolean default: true* - enable/disable additional suspicious events logging
    * true / false
  * **minimum-severity** *string enum, default: high* - select minimum severity level
    * high / critical
* **appsec-logging** configure logging for open-appsec events (threat prevention, machine learning)
  * **detect-events** *boolean, default: true* - log detected events
    * true / false
  * **prevent-events** *boolean, default: true* - log prevented events
    * true / false
  * **all-web-requests** *boolean, default: false* - log all web requests (has performance impact!)
    * true / false
  * **extended-logging**
    * **url-path** *boolean, default: true* - log URL path
      * true / false
    * **url-query** *boolean, default: true* - log URL query
      * true / false
    * **http-headers** *boolean, default: false* - log the HTTP headers (has performance impact!)
      * true / false
    * **request-body** *boolean, default: false* - log the request body (has performance impact)
      * true / false
* **log-destination**
  * **cloud** *boolean, default: false* - enable or disable logging to the appsec-open Cloud Service (relevant when being connected to SaaS Mgmt WebUI)
    * true / false
  * **file** *string* - define file path to save logs to (local path from root directory of the open-appsec container, could also refer to a mountPath for a mounted Persistent Volume in the container)
  * **stdout** - configure logging to standard-out
    * **format** *string enum* - define the desired log format
      * json / json-formatted - select between formatted or standard json
  * **syslog-service** *objects array* - define one or more syslog servers and corresponding ports to send logs to
    * **address** *string* - Syslog server IP address
    * **port** *integer* - Syslog server port
  * **cef-service** - allows sending files to a log destination in CEF format
    * **address** *string -* CEF server IP address
    * **port** *integer -* CEF server port
    * **proto** *string enum* Select the correct protocol
      * tcp / udp - Chose TCP or UDP protocol

</details>

### Exceptions

<details>

<summary>Example </summary>

```yaml
apiVersion: openappsec.io/v1beta1
kind: Exception
metadata:
  name: appsec-exception-example
spec:
- action: skip
  comment: This is an example exception comment
  countryCode:
  - CA
  - IL
  countryName:
  - Israel
  - Canada
  hostName:
  - fff
  paramName:
  - key
  paramValue:
  - rrr
  protectionName:
  - cveee
  sourceIdentifier:
  - david
  sourceIp:
  - 1.2.3.4
  - '3.3.3.3'
  url:
  - "/rrr"
- action: accept
  hostName:
  - fff
  url:
  - "/rrr"
- action: drop
  comment: This is an example exception comment
  countryName:
  - Israel
  - Canada
  protectionName:
  - cveee
  sourceIdentifier:
  - david
  sourceIp:
  - 1.2.3.4
  - 2.3.4.5
  url:
  - "/rrr"
- action: suppressLog
  comment: This is an example exception comment
  countryCode:
  - CA
  - IL
  countryName:
  - Israel
  - Canada
  hostName:
  - fff
  url:
  - "/rrr"

```

</details>

<details>

<summary>Specification</summary>

Define a list of actions-objects with the corresponding parameters to match to configure flexible custom exceptions/rules, each having the following configurable keys:

* **action** *string enum* - Action to be performed when exception matches
  * skip / accept / drop / suppressLog
* **sourceIp** *string array* - Source IP(s)&#x20;
* **url** *string array* - URL(s)
* **sourceIdentifier** *string array* - Identified source(s)
* **protectionName** *string arr*ay - Protection(s)
* **paramValue** *string array* - Parameter value(s)
* **paramName** s*tring array* - Parameter name(s)
* **hostName** *string array* - Host name(s)
* **countryCode** *string array* - Country code(s)
* **countryName** *string array* - Country name(s)
* **comment** st*ring* - Comment for the exception

</details>

### Trusted Sources

<details>

<summary>Example </summary>

```yaml
apiVersion: openappsec.io/v1beta1
kind: TrustedSource
metadata:
  name: appsec-trusted-source-example
spec:
  minNumOfSources: 3
  sourcesIdentifiers: [sources-identifiers-1, sources-identifiers-1]
```

</details>

<details>

<summary>Specification</summary>

Define trusted sources by referencing the source identifiers custom resources as well as setting the minimum amount of sources that need to be observed by the behavioural ML engine sending certain identical traffic patterns in order to learn this behaviour as being benign.

* **minNumOfSources** *integer* - Minimum amount of sources having to be observed sending same traffic patterns to learn behaviour as benign.
* **sourcesIdentifiers** *string array* -  Specify one or more source identifiers

</details>

### Source Identifiers

<details>

<summary>Examples </summary>

```yaml
apiVersion: openappsec.io/v1beta1
kind: SourcesIdentifier
metadata:
  name: appsec-source-identifiers-sourceip-example
spec:
  - sourceIdentifier: sourceip

apiVersion: openappsec.io/v1beta1
kind: SourcesIdentifier
metadata:
  name: appsec-source-identifiers-JWTKey-example
spec:
  - sourceIdentifier: JWTKey
    value: userfield

apiVersion: openappsec.io/v1beta1
kind: SourcesIdentifier
metadata:
  name: appsec-source-identifiers-x-forwarded-for-example
spec:
  - sourceIdentifier: x-forwarded-for
    value: [1.2.3.4,5.6.7.8]
```

</details>

<details>

<summary>Specification</summary>

Define list of one or more specific source identifiers that can be used in trusted sources custom resources.

* **sourceIdentifier** *string enum* - Specify the source identifier type of which the content shall be matched
  * headerkey, JWTKey, cookie, sourceip, x-forwarded-for
* **value** *string array* - Content to match the specified sourceIdentifier type
  * For types headerkey, cookie and JWTKey provide the fieldname that designates user&#x20;
  * For type Source IP no value is required
  * For type x-forwarded-for provide previous proxy hops if there are any

</details>


# Configuration Using CRDs - v1beta2

{% hint style="warning" %}
**Beta Feature Notice**\
This new CRD version v1beta2 is currently in beta and may undergo changes based on user feedback and testing. Please note that some functionality may be subject to updates or improvements in future releases.

We encourage you to explore this feature and share your feedback to help us enhance it. If you encounter any issues or have suggestions, please contact us at <info@openappsec.io> .
{% endhint %}

In order to configure open-appsec declaratively using the improved v1beta2 CRD version as explained on this page, you must deploy open-appsec using the new HELM-based installation flow described here:&#x20;

{% content-ref url="/pages/5K4Vs8LYwj2PuhVkLaka" %}
[Install Using Helm - new flow (beta)](/getting-started/start-with-kubernetes/install-using-helm-new-flow-beta)
{% endcontent-ref %}

## Using open-appsec K8S Custom Resources

open-appsec configuration is done using [Kubernetes Custom Resource Definitions](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) (CRDs). Custom Resources are extensions of the Kubernetes API that allow powerful yet standard way of managing configuration in a declarative way as well as using infrastructure-as-code paradigm. This support allows you to manage configuration changes as part of your GitOps CD processes.&#x20;

open-appsec CRD version v1beta2 provides nine CRD types. The main one is `policy` - which defines default behaviors for the inspected traffic but also allows you to define different behaviours for specific resources by configuring "specific rules". The `policy` resource refers to all other CRDs.

In order to activate the policy there's two options:

* If your deployed proxy solution provides Ingress Controller functionality and you are using ingress resources in your environment:\
  \
  Add an annotation with the desired open-appsec policy you want to activate for the ingress resource which you want to protect (make sure to also have the correct `ingressClassName` set in your ingress resource specification).

```yaml
openappsec.io/policy: open-appsec-best-practice-policy
```

* If your deployed proxy solution does not provide any ingress controller functionality, then you can alternatively use the `policyActivation` CRD  to activate your desired security policy for specific hosts directly (does not require any ingress resource or annotation). You find the specification further below.

## Custom Resources Specifications

You can download all the custom resource examples shown below in a single file here:

```
wget https://raw.githubusercontent.com/openappsec/openappsec/main/config/k8s/v1beta2/open-appsec-k8s-full-example-config-v1beta2.yaml
```

You can download custom resources shown below in a single file here:

```
wget https://raw.githubusercontent.com/openappsec/openappsec/main/config/crds/open-appsec-crd-v1beta2.yaml
```

{% hint style="warning" %}

### **Availability of namespace-scoped CRDs**

**For every CRD listed and explained below, there's also a separate namespace-scoped version available.** \
**These are mainly relevant for larger scale deployments.**\
\
**F**ind more details about usage of namespace-scoped custom resources here:\
[Using namespace-scoped custom resources](/getting-started/start-with-kubernetes/configuration-using-crds-special-options-for-large-scale-deployments/using-namespace-scoped-custom-resources)\
\
**Examples:**

To define **cluster-scoped** custom resources for defining an open-appsec **policy**, use kind:\
**`Policy`**\
To define **namespace-scoped** custom resources for defining an open-appsec **policy**, use kind:\
**`PolicyNS`**

To define **cluster-scoped** custom resources for defining a **threat prevention practice**, use kind:\
**`ThreatPreventionPractice`**\
To define **namespace-scoped** custom resources for defining a **threat prevention practice**, use kind:**`ThreatPreventionPracticeNS`**

**The same naming pattern applies to all other custom resource definition types which open-appsec supports for declarative configuration.**
{% endhint %}

### Policy

Policy resources define default behaviors that will apply to all inspected traffic and optional policies that you wish to apply just to specific rules. \
They must be activated in order to become effective, see "Using open-appsec K8s Custom Resources" above. You can activate them either by adding an annotation in the ingress resources you want to protect which links the policy to that ingress, or by specifying the hosts for which your policy should be activcated in the `policyActivation` CRD.

<details>

<summary>Example </summary>

```yaml
apiVersion: openappsec.io/v1beta2
kind: Policy
metadata:
    name: policy-example
spec:
    default:
        mode: detect-learn
        accessControlPractices: [access-control-practice-example]
        threatPreventionPractices: [threat-prevention-practice-example]
        triggers: [log-trigger-example]
        customResponse: custom-response-code-example
        sourceIdentifiers: ""
        trustedSources: ""
        exceptions:
        - exception-example
    specificRules:
        - host: "example.com"
          mode: prevent-learn
          threatPreventionPractices: [threat-prevention-practice-example]
          accessControlPractices: [access-control-practice-example]
          triggers: [log-trigger-example]
          customResponse: custom-response-code-example
          sourceIdentifiers: ""
          trustedSources: ""
          exceptions:
          - exception-example
```

</details>

<details>

<summary>Specifications</summary>

* **name** (`string` ,required) Unique name for the policy
* **appsecClassName** (`string`, optional): The name of the appsec class associated with the policy.
* **default** (`object,` required): The default configuration for the policy. This field is required.
  * **mode** (`string`, required): Specifies the mode of the entire policy.
    * Possible values: `prevent-learn`, `detect-learn`, `prevent`, `detect`, `inactive`.
    * Default: `detect-learn`.
  * **threatPreventionPractices** (`array <string>`, required): A list of threat prevention practices.
    * Minimum items: 0.
  * **accessControlPractices** (`array <string>`, required): A list of access control practices.
    * Minimum items: 0.
  * **customResponse** (`string`, optional): Specifies a custom response code.
    * Default: `403`.
  * **triggers** (`array <string>`, optional): Specifies additional triggers for the policy.
  * **sourceIdentifiers** (`string`, optional): Specifies source identifiers for the policy.
  * **trustedSources** (`string`, optional): Specifies trusted sources for the policy.
  * **exceptions** (`array <string>`, optional): Specifies exception rules for the policy.
* **specificRules** (`array <object>`, optional): Specifies rules tailored to specific hosts.
  * **host** (`string`, optional): Specifies the host for the rule.
  * **mode** (`string`, optional): Mode for the specific rule.
    * Possible values: `prevent-learn`, `detect-learn`, `prevent`, `detect`, `inactive`.
    * Default: `detect-learn`.
  * **threatPreventionPractices** (`array <string>`, optional): Threat prevention practices for the specific rule.
  * **accessControlPractices** (`array <string>`, optional): Access control practices for the specific rule.
  * **triggers** (`array <string>`, optional): Triggers for the specific rule.
  * **customResponse** (`string`, optional): Custom response code for the specific rule.
  * **sourceIdentifiers** (`string`, optional): Source identifiers for the specific rule.
  * **trustedSources** (`string`, optional): Trusted sources for the specific rule.
  * **exceptions** (`array <string>`, optional): Exception rules for the specific rule.

</details>

<details>

<summary>CRD</summary>

```yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata :
  name : policies.openappsec.io
  creationTimestamp: null
spec:
  group: openappsec.io
  versions:
    - name: v1beta2
      # Each version can be enabled/disabled by Served flag.
      served: true
      # One and only one version must be marked as the storage version.
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                appsecClassName:
                  type: string
                default:
                  type: object
                  required:
                    - mode
                    - threatPreventionPractices
                    - accessControlPractices
                  properties:
                    mode: # Mode of the policy, required
                      type: string
                      enum:
                        - prevent-learn
                        - detect-learn
                        - prevent
                        - detect
                        - inactive
                      default: detect-learn
                    threatPreventionPractices: # Threat prevention practices, required (min 0 items)
                      type: array
                      items:
                        type: string
                    accessControlPractices: # Access control practices, required (min 0 items)
                      type: array
                      items:
                        type: string
                    customResponse: # Custom response configuration, optional, default 403 (forbidden)
                      type: string
                      default: "403"
                    triggers: # Optional triggers
                      type: array
                      items:
                        type: string
                    sourceIdentifiers:
                      type: string
                    trustedSources:
                      type: string
                    exceptions:
                      type: array
                      items:
                        type: string
                specificRules: # Specific rules, optional
                  type: array
                  items:
                    type: object
                    properties:
                      host:
                        type: string
                      mode:
                        type: string
                        enum:
                          - prevent-learn
                          - detect-learn
                          - prevent
                          - detect
                          - inactive
                        default: detect-learn
                      threatPreventionPractices:
                        type: array
                        items:
                          type: string
                      accessControlPractices:
                        type: array
                        items:
                          type: string
                      triggers:
                        type: array
                        items:
                          type: string
                      customResponse:
                        type: string
                      sourceIdentifiers:
                        type: string
                      trustedSources:
                        type: string
                      exceptions:
                        type: array
                        items:
                          type: string

  scope: Cluster
  names:
    plural: policies
    singular: policy
    kind: Policy
    shortNames:
      - policy

```

</details>

### Policy Activation

The `PolicyActivation` Custom Resource Definition (CRD) defines a Kubernetes resource that manages the activation of security policies within the `openappsec.io` ecosystem. This CRD enables the association of security policies with specific hosts.\
This serves as an alterantive to adding the annotation to the ingress (see above) which references the desired policy.

<details>

<summary>Example</summary>

```yaml
apiVersion: openappsec.io/v1beta2
kind: PolicyActivation
metadata:
  name: policy-activation-example
spec:
  enabledPolicies:
    - name: policy-example
      hosts:
        - "example.com"
```

</details>

<details>

<summary>Specification</summary>

* **name** (`string` ,required) Unique name for the policy activation CRD
* **AppsecClassName** (`string`, optional): The name of the application security class associated with the policy.
* **EnabledPolicies** (`array`, required): A list of security policies to be enabled.
  * **Name** (`string`, ): The name of the security policy.
  * **Hosts** (`array`, required): List of hosts that the security policy applies to.

</details>

<details>

<summary>CRD</summary>

```yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata :
  name: policyactivations.openappsec.io
spec:
  group: openappsec.io
  versions:
    - name: v1beta2
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                appsecClassName:
                  type: string
                enabledPolicies:
                  type: array
                  items:
                    type: object
                    properties:
                      name:
                        type: string
                      hosts:
                        type: array
                        items:
                          type: string
                    required:
                      - hosts
              required:
                - enabledPolicies
  scope: Cluster
  names:
    plural: policyactivations
    singular: policyactivation
    kind: PolicyActivation
    shortNames:
      - policyactivation
```

</details>

### Threat Prevention Practice <a href="#custom-response" id="custom-response"></a>

<details>

<summary>Example</summary>

```yaml
apiVersion: openappsec.io/v1beta2
kind: ThreatPreventionPractice
metadata:
  name: threat-prevention-practice-example
spec:
  practiceMode: inherited
  webAttacks:
    overrideMode: inherited
    minimumConfidence: high
  intrusionPrevention:
  # intrusion prevention (IPS) requires "Premium Edition"
    overrideMode: inherited
    maxPerformanceImpact: medium
    minSeverityLevel: medium
    minCveYear: 2016
    highConfidenceEventAction: inherited
    mediumConfidenceEventAction: inherited
    lowConfidenceEventAction: detect
  fileSecurity:
  # file security requires "Premium Edition"
    overrideMode: inherited
    minSeverityLevel: medium
    highConfidenceEventAction: inherited
    mediumConfidenceEventAction: inherited
    lowConfidenceEventAction: detect
  snortSignatures:
    # you must specify snort signatures in configmap or file to activate snort inspection
    overrideMode: inherited
    configmap: []
    # relevant for deployments on kubernetes
    # 0 or 1 configmaps supported in array
    files: []
    # relevant for docker and linux embedded deployments
    # 0 or 1 files supported in array
  schemaValidation: # schema validation requires "Premium Edition"
    overrideMode: inherited
    configmap: []
    # relevant for deployments on kubernetes
    # 0 or 1 configmaps supported in array
    files: []
    # relevant for docker and linux embedded deployments
    # 0 or 1 files supported in array
  antiBot: # antibot requires "Premium Edition"
    overrideMode: inherited
    injectedUris: []
    validatedUris: []
```

</details>

<details>

<summary>Specifications</summary>

* **name** (`string` , required) Unique name for the threat prevention practice.
* **appsecClassName** (`string` , optional) Name of the AppSec class to which this practice belongs.
* **practiceMode** (`string` , optional) Defines the mode of operation for the practice. Possible values: `inherited, prevent-learn, detect-learn, prevent, detect, inactive`
  * Default: `inherited` from mode set in policy.
* **webAttacks** (`object` , required)
  * **overrideMode** (`string` , optional) The override mode for web attacks.  Possible values: `prevent-learn, detect-learn, prevent, detect, inactive, inherited`  #inherited from threatPreventionPractice mode set in policy
    * Default: `inherited`&#x20;
  * **minimumConfidence** (`string` , optional) The minimum confidence level for web attacks. Possible values: `medium, high, critical`
    * Default: `high`
  * **maxUrlSizeBytes** (`integer` , optional) Maximum URL size in bytes.
    * Default: `32768`
  * **maxObjectDepth** (`integer` , optional)Maximum object depth.
    * Default: `40`
  * **maxBodySizeKb** (`integer` , optional) Maximum body size in KB.
    * Default: `1000000`
  * **maxHeaderSizeBytes** (`integer` , optional) Maximum header size in bytes.
    * Default: `102400`
  * **protections** (`object,` optional)
    * **csrfProtection** (`string` , optional) CSRF protection mode. Possible values: `prevent-learn, detect-learn, prevent, detect, inactive, inherited` #inherited from overrideMode
      * Default: `inactive`
    * **errorDisclosure** (`string` , optional) Error disclosure mode. Possible values: `prevent-learn, detect-learn, prevent, detect, inactive, inherited` #inherited from overrideMode
      * Default: `inactive`
    * **openRedirect** (`string` , optional) Open redirect protection mode. Possible values: `prevent-learn, detect-learn, prevent, detect, inactive, inherited` #inherited from overrideMode
      * Default: `inactive`
    * **nonValidHttpMethods** (`boolean`, optional)
      * Default: `false`&#x20;
* **antiBot** (`object`, optional)
  * **overrideMode** (`string` , required) Override mode for bot prevention. Possible values: `prevent-learn, detect-learn, prevent, detect, inactive, inherited` #inherited from threatPreventionPractice mode set in policy
    * Default: `inactive`
  * **injectedUris** (`array <string>`, optional) List of injected URIs to be checked for bot prevention.
  * **validatedUris** (`array <string>`, optional) List of validated URIs to be checked for bot prevention.
* **snortSignatures**  (`object`, optional)
  * **overrideMode** (`string` , required) Override mode for Snort signatures.  Possible values: `prevent-learn, detect-learn, prevent, detect, inactive, inherited`
    * Default: `inherited` inherited from threatPreventionPractice mode set in policy
  * **configmap** (`array <string>` , optional) List of configuration maps related to Snort signatures.
  * **files** (`array<string>` ,optional)List of files related to Snort signatures.
* **schemaValidation** (`object`, optional)
  * **overrideMode** (`string` ,required) Override mode for schema validation. Possible values: `prevent-learn, detect-learn,prevent, detect, inactive, inherited`
    * Default: `inherited` inherited from threatPreventionPractice mode set in policy
  * **enforcementLevel** (`string` , optional) Level of enforcement for schema validation.
  * **configmap** (`array<string>` , optional) List of configuration maps related to schema validation.
  * **files** (`array<string>` , optional) List of files related to schema validation
* **intrusionPrevention**  (`object`, optional)
  * **overrideMode** `string`: (required) Override mode for intrusion prevention. Possible values: `prevent-learn, detect-learn, prevent, detect, inactive, inherited`  inherited from threatPreventionPractice mode set in policy
    * Default: `inactive`
  * **maxPerformanceImpact** (`string` , optional) Maximum acceptable performance impact. Possible values: `low, medium, high`
    * Default: `medium`
  * **minSeverityLevel** (`string` , optional) Minimum severity level for intrusion prevention events. Possible values: `low, medium, high, critical`
    * Default: `medium`
  * **minCveYear** (`integer`, optional) Minimum year of CVE for inclusion in intrusion prevention events.
    * Default: `2016`
  * **highConfidenceEventAction** (`string` , optional)  Action for high confidence events. Possible values: `prevent, detect, inactive, inherited`
    * Default: `inherited` as set in overrideMode for intrusionPrevention
  * **mediumConfidenceEventAction** (`string` , optional) Action for medium confidence events. Possible values:`prevent, detect, inactive, inherited`
    * Default: `inherited` as set in overrideMode for intrusionPrevention
  * **lowConfidenceEventAction** (`string` , optional) Action for medium confidence events. Possible values:`prevent, detect, inactive, inherited`
  * Default: `detect`&#x20;
* **fileSecurity** (`object`, optional)
  * **overrideMode** (`string`, required) Override mode for intrusion prevention. Possible values: `prevent-learn, detect-learn, prevent, detect, inactive, inherited` inherited from threatPreventionPractice mode set in policy
    * Default: `inactive`
  * **minSeverityLevel** (`string` , optional) Minimum severity level for file secuirty events. Possible values: `low, medium, high, critical`
    * Default: `medium`
  * **highConfidenceEventAction** (`string` , optional)  Action for high confidence events. Possible values: `prevent, detect, inactive, inherited`
    * Default: `inherited` as set in overrideMode for intrusionPrevention
  * **mediumConfidenceEventAction** (`string` , optional) Action for medium confidence events. Possible values:`prevent, detect, inactive, inherited`
    * Default: `inherited` as set in overrideMode for intrusionPrevention
  * **lowConfidenceEventAction** (`string` , optional) Action for medium confidence events. Possible values:`prevent, detect, inactive, inherited`
    * Default: `detect`&#x20;
  * **archiveInspection** (`object`, optional):
    * **extractArchiveFiles** (`boolean`, optional): Whether to extract files from archives for inspection.&#x20;
      * Default: `false`.
    * **scanMaxFileSize** (`integer`, optional): Maximum file size to scan within archives. Default: 10.
    * **scanMaxFileSizeUnit** (`string`, optional): Unit of the maximum file size for scanning. Possible values: `bytes, KB, MB, GB.`&#x20;
      * Default: `MB`.
    * **archivedFilesWithinArchivedFiles** (`string`, optional): Action for archived files nested within other archived files. Possible values: `prevent, detect, inactive, inherited`.&#x20;
      * Default: inherited, as set in overrideMode for fileSecurity.
    * **archivedFilesWhereContentExtractionFailed** (`string`, optional): Action when content extraction from archived files fails. Possible values: `prevent, detect, inactive, inherited`.&#x20;
      * Default: inherited, as set in overrideMode for fileSecurity.
  * **largeFileInspection** (`object`, optional):
    * **fileSizeLimit** (`integer`, optional): Maximum file size limit for inspection.
      * Default: `10`.
    * **fileSizeLimitUnit** (`string`, optional): Unit of the file size limit. Possible values: `bytes, KB, MB, GB`.&#x20;
      * Default: `MB`.
    * **filesExceedingSizeLimitAction** (`string`, optional): Action for files exceeding the size limit. Possible values: `prevent, detect, inactive, inherited.`
      * Default: `inherited`, as set in overrideMode for fileSecurity.
  * **unnamedFilesAction** (`string`, optional): Action for unnamed files. Possible values: `prevent, detect, inactive, inherited`.&#x20;
    * Default: `inherited`, as set in overrideMode for fileSecurity.
  * **threatEmulationEnabled** (`boolean`, optional): Whether threat emulation is enabled for file security.&#x20;
    * Default: `false`.

</details>

<details>

<summary>CRD</summary>

```yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata :
  name : threatpreventionpractices.openappsec.io
  creationTimestamp: null
spec:
  group: openappsec.io
  versions:
    - name: v1beta2
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              required:
                - webAttacks
                - intrusionPrevention
                - fileSecurity
                - snortSignatures
              properties:
                appsecClassName:
                  type: string
                name:
                  type: string
                practiceMode:
                  type: string
                  enum:
                    - inherited #inherited from mode set in policy
                    - prevent-learn
                    - detect-learn
                    - prevent
                    - detect
                    - inactive
                  default: inherited
                webAttacks:
                  type: object
                  required:
                    - overrideMode
                  properties:
                    overrideMode:
                      type: string
                      enum:
                        - prevent-learn
                        - detect-learn
                        - prevent
                        - detect
                        - inactive
                        - inherited #inherited from threatPreventionPractice mode set in policy
                      default: inactive
                    minimumConfidence:
                      type: string
                      enum:
                        - medium
                        - high
                        - critical
                      default: high
                    maxUrlSizeBytes:
                      type: integer
                      default: 32768
                    maxObjectDepth:
                      type: integer
                      default: 40
                    maxBodySizeKb:
                      type: integer
                      default: 1000000
                    maxHeaderSizeBytes:
                      type: integer
                      default: 102400
                    protections:
                      type: object
                      properties:
                        csrfProtection:
                          type: string
                          enum:
                            - prevent-learn
                            - detect-learn
                            - prevent
                            - detect
                            - inactive
                            - inherited #inherited from overrideMode
                          default: inactive
                        errorDisclosure:
                          type: string
                          enum:
                            - prevent-learn
                            - detect-learn
                            - prevent
                            - detect
                            - inactive
                            - inherited #inherited from overrideMode
                          default: inactive
                        openRedirect:
                          type: string
                          enum:
                            - prevent-learn
                            - detect-learn
                            - prevent
                            - detect
                            - inactive
                            - inherited #inherited from overrideMode
                          default: inactive
                        nonValidHttpMethods:
                          type: boolean
                          default: false
                antiBot:
                  type: object
                  required:
                    - overrideMode
                  properties:
                    overrideMode:
                      type: string
                      enum:
                        - prevent-learn
                        - detect-learn
                        - prevent
                        - detect
                        - inactive
                        - inherited #inherited from threatPreventionPractice mode set in policy
                      default: inactive
                    injectedUris:
                      type: array
                      items:
                        type: object
                        properties:
                          uri:
                            type: string
                    validatedUris:
                      type: array
                      items:
                        type: object
                        properties:
                          uri:
                            type: string
                snortSignatures:
                  type: object
                  required:
                    - overrideMode
                  properties:
                    overrideMode:
                      type: string
                      enum:
                        - prevent-learn
                        - detect-learn
                        - prevent
                        - detect
                        - inactive
                        - inherited #inherited from threatPreventionPractice mode set in policy
                      default: inactive
                    configmap:
                      type: array
                      items:
                        type: string
                    files:
                      type: array
                      items:
                        type: string
                schemaValidation:
                  type: object
                  required:
                    - overrideMode
                  properties:
                    overrideMode:
                      type: string
                      enum:
                        - prevent-learn
                        - detect-learn
                        - prevent
                        - detect
                        - inactive
                        - inherited #inherited from threatPreventionPractice mode set in policy
                      default: inactive
                    enforcementLevel:
                      type: string
                    configmap:
                      type: array
                      items:
                        type: string
                    files:
                      type: array
                      items:
                        type: string
                intrusionPrevention:
                  type: object
                  required:
                    - overrideMode
                  properties:
                    overrideMode:
                      type: string
                      enum:
                        - prevent-learn
                        - detect-learn
                        - prevent
                        - detect
                        - inactive
                        - inherited #inherited from threatPreventionPractice mode set in policy
                      default: inactive
                    maxPerformanceImpact:
                      type: string
                      enum:
                        - low
                        - medium
                        - high
                      default: medium
                    minSeverityLevel:
                      type: string
                      enum:
                        - low
                        - medium
                        - high
                        - critical
                      default: medium
                    minCveYear:
                      type: integer
                      default: 2016
                    highConfidenceEventAction:
                      type: string
                      enum:
                        - prevent
                        - detect
                        - inactive
                        - inherited #as set in overrideMode for intrusionPrevention
                      default: inherited
                    mediumConfidenceEventAction:
                      type: string
                      enum:
                        - prevent
                        - detect
                        - inactive
                        - inherited #as set in overrideMode for intrusionPrevention
                      default: inherited
                    lowConfidenceEventAction:
                      type: string
                      enum:
                        - prevent
                        - detect
                        - inactive
                        - inherited #as set in overrideMode for intrusionPrevention
                      default: detect
                fileSecurity:
                  type: object
                  required:
                    - overrideMode
                  properties:
                    overrideMode:
                      type: string
                      enum:
                        - prevent-learn
                        - detect-learn
                        - prevent
                        - detect
                        - inactive
                        - inherited #inherited from threatPreventionPractice mode set in policy
                      default: inactive
                    minSeverityLevel:
                      type: string
                      enum:
                        - low
                        - medium
                        - high
                        - critical
                      default: medium
                    highConfidenceEventAction:
                      type: string
                      enum:
                        - prevent
                        - detect
                        - inactive
                        - inherited #as set in overrideMode for fileSecurity
                      default: inherited
                    mediumConfidenceEventAction:
                      type: string
                      enum:
                        - prevent
                        - detect
                        - inactive
                        - inherited #as set in overrideMode for fileSecurity
                      default: inherited
                    lowConfidenceEventAction:
                      type: string
                      enum:
                        - prevent
                        - detect
                        - inactive
                        - inherited #as set in overrideMode for fileSecurity
                      default: detect
                    archiveInspection:
                      type: object
                      properties:
                        extractArchiveFiles:
                          type: boolean
                          default: false
                        scanMaxFileSize:
                          type: integer
                          default: 10
                        scanMaxFileSizeUnit:
                          type: string
                          enum:
                            - bytes
                            - KB
                            - MB
                            - GB
                          default: MB
                        archivedFilesWithinArchivedFiles:
                          type: string
                          enum:
                            - prevent
                            - detect
                            - inactive
                            - inherited #as set in overrideMode for fileSecurity
                          default: inherited
                        archivedFilesWhereContentExtractionFailed:
                          type: string
                          enum:
                            - prevent
                            - detect
                            - inactive
                            - inherited #as set in overrideMode for fileSecurity
                          default: inherited
                    largeFileInspection:
                      type: object
                      properties:
                        fileSizeLimit:
                          type: integer
                          default: 10
                        fileSizeLimitUnit:
                          type: string
                          enum:
                            - bytes
                            - KB
                            - MB
                            - GB
                          default: MB
                        filesExceedingSizeLimitAction:
                          type: string
                          enum:
                            - prevent
                            - detect
                            - inactive
                            - inherited #as set in overrideMode for fileSecurity
                          default: inherited
                    unnamedFilesAction:
                      type: string
                      enum:
                        - prevent
                        - detect
                        - inactive
                        - inherited #as set in overrideMode for fileSecurity
                      default: inherited
                    threatEmulationEnabled:
                      type: boolean
                      default: false
  scope: Cluster
  names:
    plural: threatpreventionpractices
    singular: threatpreventionpractice
    kind: ThreatPreventionPractice
    shortNames:
      - tpp

```

</details>

### **Access Control Practice**&#x20;

<details>

<summary>Example</summary>

```yaml
apiVersion: openappsec.io/v1beta2
kind: AccessControlPractice
metadata:
  name: access-control-practice-example
spec:
  practiceMode: prevent
  rateLimit:
    overrideMode: inherited
    rules:
    - action: prevent
      comment: Limiting access to the resource
      limit: 100
      triggers:
      - log-trigger-example
      unit: minute
      uri: /api/resource
    - action: inherited
      comment: Rate limiting for authentication requests
      limit: 50
      triggers:
      - log-trigger-example
      unit: second
      uri: /api/auth
```

</details>

<details>

<summary>Specifications</summary>

* **appsecClassName** (`string`, optional): The name of the application security class associated with the access control policy.
* **name** (`string`, required): The name of the access control policy.
* **practiceMode** (`string`, optional): Defines the mode for the access control policy. Possible values: `prevent, detect, inactive, inherited (inherited values are determined by the mode set in the policy)`.&#x20;
  * Default: `inherited`.
* **rateLimit** (`object`, required):
  * **overrideMode** (`string`, optional): Allows overriding the mode defined at the policy level for this specific engine. Possible values: `prevent, detect, inactive, inherited (inherited values are determined by the mode set in the practice)`.&#x20;
    * Default: `inactive`.
  * **rules** (`array <objects>`, optional): List of rate-limiting rules.
    * **action** (`string`, optional): Action to take when a rate limit is exceeded. Possible values: `inherited, prevent, detect (inherited values are determined by the mode set in the rate limiting overide mode)`.&#x20;
      * Default: `inherited`.
    * **condition** (`array <objects>`, optional): List of conditions for rate limiting (currently not supported).
      * **key** (`string`, required): The key for the condition.
      * **value** (`string`, required): The value for the condition.
    * **uri** (`string`, optional): URI pattern for the rate limit rule.
    * **limit** (`integer`, optional): The rate limit threshold.
    * **unit** (`string`, optional): The time unit for the rate limit. Possible values: `minute, second`.&#x20;
      * Default: `minute`.
    * triggers (`array <objects>`, optional): List of triggers that activate the rule.
    * comment (`string`, optional): A comment explaining the rate limit.

</details>

<details>

<summary>CRD</summary>

```yaml
apiVersion: apiextensions.k8s.io/v1beta2
kind: CustomResourceDefinition
metadata :
  name : accesscontrolpractices.openappsec.io
  creationTimestamp: null
spec:
  group: openappsec.io
  versions:
    - name: v1beta2
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              required:
                - rateLimit
              properties:
                appsecClassName:
                  type: string
                name:
                  type: string
                practiceMode:
                  type: string
                  enum:
                    - inherited #inherited from mode set in policy
                    - prevent
                    - detect
                    - inactive
                  default: inherited
                rateLimit:
                  type: object
                  required:
                    - overrideMode
                  properties:
                    overrideMode:
                      type: string
                      enum:
                        - prevent
                        - detect
                        - inactive
                        - inherited
                      default: inactive
                    rules:
                      type: array
                      items:
                        type: object
                        properties:
                          action: # currently not supported
                            type: string
                            enum:
                              - inherited
                              - prevent
                              - detect
                            default: inherited
                          condition: # currently not supported
                            type: array
                            items:
                              type: object
                              required:
                                - key
                                - value
                              properties:
                                key:
                                  type: string
                                value:
                                  type: string
                          uri:
                            type: string
                          limit:
                            type: integer
                          unit:
                            type: string
                            enum:
                              - minute
                              - second
                            default: minute
                          triggers:
                            type: array
                            items:
                              type: string
                          comment:
                            type: string
  scope: Cluster
  names:
    plural: accesscontrolpractices
    singular: accesscontrolpractice
    kind: AccessControlPractice
    shortNames:
      - acp

```

</details>

### Custom Response <a href="#custom-response" id="custom-response"></a>

<details>

<summary>Example</summary>

```yaml
apiVersion: openappsec.io/v1beta2
kind: CustomResponse
metadata:
  name: custom-response-code-example
spec:
  mode: response-code-only ## configurable modes: {block-page|redirect|response-code-only}
  messageTitle: ""
  messageBody: ""
  httpResponseCode: 403

```

</details>

<details>

<summary>Specifications</summary>

* **appsecClassName** (`string`, optional): Specifies the name of the AppSec class associated with this custom response.
* **name** (`string`, required): A unique name for the custom response configuration.
* **mode** (`string`, required): Defines the response mode for blocked requests. Possible values: blo`ck-page, redirect, response-code-only`.&#x20;
  * Default: `response-code-only`.
* **messageTitle** (`string`, optional): Title displayed on the block page (relevant when mode is block-page).
* **messageBody** (`string`, optional): Body message displayed on the block page (relevant when mode is block-page).
* **httpResponseCode** (`integer`, required): HTTP response code returned when blocking. Minimum: 100. Maximum: 599.&#x20;
  * Default: `403`.
* **redirectUrl** (`string`, optional): URL to redirect the blocked requests to (relevant when mode is redirect).
* **redirectAddXEventId** (`boolean`, optional): Adds an X-Event-ID header to redirected requests.&#x20;
  * Default: `false`.

</details>

<details>

<summary>CRD</summary>

```yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata :
  name : customresponses.openappsec.io
  creationTimestamp: null
spec:
  group: openappsec.io
  versions:
    - name: v1beta2
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              required:
                - mode
              properties:
                appsecClassName:
                  type: string
                name:
                  type: string
                mode:
                  type: string
                  enum:
                    - block-page
                    - redirect
                    - response-code-only
                  default: response-code-only
                messageTitle:
                  type: string
                messageBody:
                  type: string
                httpResponseCode:
                  type: integer
                  minimum: 100
                  maximum: 599
                  default: 403
                redirectUrl:
                  type: string
                redirectAddXEventId:
                  type: boolean
                  default: false
              required:
                - mode
  scope: Cluster
  names:
    plural: customresponses
    singular: customresponse
    kind: CustomResponse
    shortNames:
      - customresponse

```

</details>

### Log Trigger

<details>

<summary>Example</summary>

```yaml
apiVersion: openappsec.io/v1beta2
kind: LogTrigger
metadata:
  name: log-trigger-example
spec:
  accessControlLogging:
    allowEvents: false
    dropEvents: true
  appsecLogging:
    detectEvents: true
    preventEvents: true
    allWebRequests: false
  additionalSuspiciousEventsLogging:
    enabled: true
    minSeverity: high # {high|critical}
    responseBody: false
    responseCode: true
  extendedLogging:
    urlPath: true
    urlQuery: true
    httpHeaders: false
    requestBody: false
  logDestination:
    cloud: true
    stdout:
      format: json-formatted
```

</details>

<details>

<summary>Specifications </summary>

* **appsecClassName** (`string`, optional): Specifies the name of the AppSec class related to the log trigger.
* **name** (`string`, required): The unique name identifying the log trigger.
* **accessControlLogging** (`object`, required): Configuration for access control logs.
  * **allowEvents** (`boolean`, optional): Log allowed events.&#x20;
    * Default: `false`.
  * **dropEvents** (`boolean`, optional): Log dropped events.&#x20;
    * Default: `true`.
* **appsecLogging** (**object**, required): Configuration for application security logs.
  * **detectEvents** (`boolean`, optional): Log detection events.
    * Default: `true`.
  * **preventEvents** (`boolean`, optional): Log prevention events.&#x20;
    * Default: `true`.
  * **allWebRequests** (`boolean`, optional): Log all web requests, regardless of action.
  * Default: `false`.
* **additionalSuspiciousEventsLogging** (`object`, required): Configuration for logging suspicious events.
  * **enabled** (`boolean`, optional): Enable or disable logging for suspicious events. Default: `true`.
  * **minSeverity** (`string`, optional): Minimum severity level to log. Options: `high, critical`.&#x20;
    * Default: `high`.
  * **responseBody** (`boolean`, optional): Include response body in logs.&#x20;
    * Default: `false`.
  * **responseCode** (`boolean`, optional): Include response code in logs.&#x20;
    * Default: `true`.
* **extendedLogging** (`object`, required): Configuration for extended logging details.
  * **urlPath** (`boolean`, optional): Log URL path.&#x20;
    * Default: `false`.
  * **urlQuery** (`boolean`, optional): Log URL query parameters.&#x20;
    * Default: `false`.
  * **httpHeaders** (`boolean`, optional): Log HTTP headers.&#x20;
    * Default: `false`.
  * **requestBody** (`boolean`, optional): Log HTTP request body.&#x20;
    * Default: `false`.
* **logDestination** (`object`, required): Configuration for log destinations.
  * **cloud** (`boolean`, optional): Send logs to the cloud.&#x20;
    * Default: `false`.
  * **syslogService** (`array`, optional): List of syslog services.
    * **address** (`array <string>`, required): Syslog server address.
    * **port** (`integer`, required): Syslog server port.
  * **logToAgent** (`boolean`, optional): Send logs to the agent.&#x20;
    * Default: **true**.
  * **stdout** (`object`, optional): Configuration for logs sent to standard output.
    * **format** (`string`, optional): Log format. Options: `json, json-formatted`.
      * Default: `json`.
* **k8s-service** (`boolean`, optional): Enable logging to Kubernetes service (default depends on environment type).
* **cefService** (`array`, optional): List of CEF (Common Event Format) services.
  * **address** (`string`, required): CEF server address.
  * **port** (`integer`, required): CEF server port.
  * **proto** (`string`, optional): Protocol for CEF. Options: tcp, udp.

</details>

<details>

<summary>CRD</summary>

```yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata :
  name : logtriggers.openappsec.io
  creationTimestamp: null
spec:
  group: openappsec.io
  versions:
    - name: v1beta2
      # Each version can be enabled/disabled by Served flag.
      served: true
      # One and only one version must be marked as the storage version.
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              required:
                - accessControlLogging
                - appsecLogging
                - additionalSuspiciousEventsLogging
                - extendedLogging
                - logDestination
              properties:
                appsecClassName:
                  type: string
                name:
                  type: string
                accessControlLogging:
                  type: object
                  properties:
                    allowEvents:
                      type: boolean
                      default: false
                    dropEvents:
                      type: boolean
                      default: true
                appsecLogging:
                  type: object
                  properties:
                    detectEvents:
                      type: boolean
                      default: true
                    preventEvents:
                      type: boolean
                      default: true
                    allWebRequests:
                      type: boolean
                      default: false
                additionalSuspiciousEventsLogging:
                  type: object
                  properties:
                    enabled:
                      type: boolean
                      default: true
                    minSeverity:
                      type: string
                      enum:
                        - high
                        - critical
                      default: high
                    responseBody:
                      type: boolean
                      default: false
                    responseCode:
                      type: boolean
                      default: true
                extendedLogging:
                  type: object
                  properties:
                    urlPath:
                      type: boolean
                      default: false
                    urlQuery:
                      type: boolean
                      default: false
                    httpHeaders:
                      type: boolean
                      default: false
                    requestBody:
                      type: boolean
                      default: false
                logDestination:
                  type: object
                  properties:
                    cloud:
                      type: boolean
                      default: false
                    syslogService:
                      type: array
                      items:
                        type: object
                        properties:
                          address:
                            type: string
                          port:
                            type: integer
                    logToAgent:
                      type: boolean
                      default: true
                    stdout:
                      type: object
                      properties:
                        format:
                          type: string
                          enum:
                            - json
                            - json-formatted
                          default: json
                    k8s-service:
                      type: boolean # Default value is dependant on the environment type
                    cefService:
                      type: array
                      items:
                        type: object
                        properties:
                          address:
                            type: string
                          port:
                            type: integer
                          proto:
                            type: string
                            enum:
                              - tcp
                              - udp
  scope: Cluster
  names:
    plural: logtriggers
    singular: logtrigger
    kind: LogTrigger
    shortNames:
      - logtrigger

```

</details>

### Exceptions

<details>

<summary>Example</summary>

```yaml
apiVersion: openappsec.io/v1beta2
kind: Exception
metadata:
  name: exception-example
spec:
  action: "accept"
  condition:
    - key: "countryCode"
      value: "US"
```

</details>

<details>

<summary>Specifications</summary>

* **appsecClassName**: (`string`, optional) Specifies the name of the AppSec class related to the exception.
* **name**: (`string` ,required) - The unique name identifying the exception.
* **action**: (`string` ,required) - Action to take when the exception is triggered. Possible options: `skip`, `accept`, `drop`, `suppressLog`.&#x20;
  * Default: `accep`t.
* **condition**: (`array<object>` ,required) - List of one or more conditions that must be met for the exception to apply.
  * **key**: (`string` ,required) - The key to evaluate, such as `sourceIp, countryCode,  countryName, hostName,paramName, paramValue, protectionName, sourceIdentifier, url, hostName`
  * **value**: (`string` ,required) - The value associated with the key to match.

</details>

<details>

<summary>CRD</summary>

```yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: exceptions.openappsec.io
spec:
  group: openappsec.io
  versions:
    - name: v1beta2
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              required:
                - action
                - condition
              properties:
                appsecClassName:
                  type: string
                name:
                  type: string
                action:
                  type: string
                  enum:
                    - skip
                    - accept
                    - drop
                    - suppressLog
                  default: accept
                condition: # required minItems:1
                  type: array
                  items:
                    type: object
                    required:
                      - key
                      - value
                    properties:
                      key:
                        type: string
                      value:
                        type: string
  scope: Cluster
  names:
    plural: exceptions
    singular: exception
    kind: Exception
    shortNames:
      - exception

```

</details>

### Source Identifiers <a href="#source-identifiers" id="source-identifiers"></a>

<details>

<summary>Example </summary>

```yaml
kind: SourcesIdentifier
mapiVersion: openappsec.io/v1beta2
kind: SourcesIdentifier
metadata:
  name: sources-identifier-example
spec:
  sourcesIdentifiers:
    - identifier: sourceip
      value:
        - "0.0.0.0"
```

</details>

<details>

<summary>Specification</summary>

* **appsecClassName**: (`string` ,optional) Specifies the name of the AppSec class associated with this source identifier configuration.
* **name**: (`string` ,required) A unique identifier for the sources configuration.
* **sourcesIdentifiers**: (`array<object>`,  required)  A list of source identifiers to distinguish between sources based on the selected type and values. Each item is an `object` with the following properties:
  * **identifier**: (`string enum`, required) - The type of identifier. Possible options: `headerkey, JWTKey, cookie, sourceip, x-forwarded-for`
    * Default: `sourceip`.
  * **value**: (`array<string>`,  required) - A list of values associated with the identifier. Each item is a `string`.

</details>

<details>

<summary>CRD</summary>

```yaml
apiVersion: apiextensions.k8s.io/v1beta2
kind: CustomResourceDefinition
metadata :
  name : sourcesidentifiers.openappsec.io
  creationTimestamp: null
spec:
  group: openappsec.io
  versions:
    - name: v1beta2
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
              type: object
              required:
                - sourcesIdentifiers
              properties:
                appsecClassName:
                  type: string
                name:
                  type: string
                sourcesIdentifiers: # required, minItems: 1
                  type: array
                  items:
                    type: object
                    required:
                      - identifier
                      - value
                    properties:
                      identifier:
                        type: string
                        enum:
                          - headerkey
                          - JWTKey
                          - cookie
                          - sourceip
                          - x-forwarded-for
                        default: sourceip
                      value:
                        type: array
                        items:
                          type: string
  scope: Cluster
  names:
    plural: sourcesidentifiers
    singular: sourcesidentifier
    kind: SourcesIdentifier
    shortNames:
      - sourcesidentifier
```

</details>

### Trusted Sources <a href="#source-identifiers" id="source-identifiers"></a>

<details>

<summary>Examples </summary>

```haml
kind: TrustedSource
metadata:
  name: "trusted-sources-example"
spec:
  minNumOfSources: 3
  sourcesIdentifiers:
    - 1.0.0.27
    - 1.0.0.28
    - 1.0.0.29
```

</details>

<details>

<summary>Specification</summary>

* **appsecClassName**: (`string`, optional) Specifies the name of the AppSec class associated with this trusted source configuration.
* **name**: (`string`, optional). A unique identifier for the trusted source configuration.
* **minNumOfSources**: (`integer` , required) - The minimum number of trusted sources needed to apply the configuration.
  * Default: `3`.
* **sourcesIdentifiers**: (`array <string>` , required) - A list of identifiers representing trusted sources.

</details>

<details>

<summary>CRD</summary>

```yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata :
  name : trustedsources.openappsec.io
  creationTimestamp: null
spec:
  group: openappsec.io
  versions:
    - name: v1beta2
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              required:
                - minNumOfSources
                - sourcesIdentifiers
              properties:
                appsecClassName:
                  type: string
                name:
                  type: string
                minNumOfSources:
                  type: integer
                  default: 3
                sourcesIdentifiers:
                  type: array
                  items:
                    type: string
  scope: Cluster
  names:
    plural: trustedsources
    singular: trustedsource
    kind: TrustedSource
    shortNames:
      - trustedsource

```

</details>


# Configuration using CRDs - special options for Large Scale Deployments

{% hint style="warning" %}
The advanced configuration options explained on this page require an existing helm-based deployment on K8s with CRD version v1beta2. See here for instructions: [Install Using Helm - new flow (beta)](/getting-started/start-with-kubernetes/install-using-helm-new-flow-beta)
{% endhint %}

Specifically for usage in larger scale deployments on Kubernetes, open-appsec offers some advanced functionalities for declarative configurations:

### appsecClassName property for custom resources

appsecClassName support allows having multiple, distinct sets of custom resources for the configuration of different, parallel open-appsec deployments on the same Kubernetes cluster.\
It is possible to link each custom resource using the optional *appsecClassName* property with one of your open-appsec deployments set to use that same appsec class, find the configuration details here:

{% content-ref url="/pages/KiT1rbtMgbkqqty3junG" %}
[Using appsec class for assigning separate custom resources to specific deployments](/getting-started/start-with-kubernetes/configuration-using-crds-special-options-for-large-scale-deployments/using-appsec-class-for-assigning-separate-custom-resources-to-specific-deployments)
{% endcontent-ref %}

### namespace-scoped CRDs

It is possible to create and manage the custom resources for open-appsec configuration in a specific namespace by using the new namespace-scoped CRDs instead of using cluster-scoped CRDs, find the configuration details here:

{% content-ref url="/pages/GWifgIM7vLXdG26hgm0F" %}
[Using namespace-scoped custom resources](/getting-started/start-with-kubernetes/configuration-using-crds-special-options-for-large-scale-deployments/using-namespace-scoped-custom-resources)
{% endcontent-ref %}


# Using appsec class for assigning separate custom resources to specific deployments

{% hint style="warning" %}
The advanced configuration options explained on this page require an existing helm-based deployment on K8s with CRD version v1beta2. See here for instructions: [Install Using Helm - new flow (beta)](/getting-started/start-with-kubernetes/install-using-helm-new-flow-beta)
{% endhint %}

In deployment scenarios with **multiple parallel open-appsec deployments** on the same Kubernetes cluster (each having same or also different Proxy/API Gateway integration type) often also **separate, distinct sets of custom resources** for the open-appsec configuration of the different deployments are required.

Starting with open-appsec CRD version [v1beta2](/getting-started/start-with-kubernetes/configuration-using-crds-v1beta2) you can now define multiple, distinct sets of custom resources for the configuration of different, parallel open-appsec deployments on the same Kubernetes cluster by specifying an appsec class.

## Using appsec class&#x20;

When you [deploy open-appsec using helm](/getting-started/start-with-kubernetes/install-using-helm-new-flow-beta),  you can optionally specify an `appsec.className` as shown e.g. in the example below to associate that specific appsec class (`myCustomClass1` in the example) with your deployment.

```bash
helm install ... --set appsec.className=myCustomClass1 ...
```

As a result, this specific open-appsec deployment (more specifically the open-appsec agent) will only look at those custom resources, which also have the key `appsecClassName` set to that exact same value.

{% hint style="warning" %}
When you do not specify appsec.className for a deployment of open-appsec, then that open-appsec agent will **ignore** the appsecClassName property in custom resources and apply both of the following custom resource definitions, those with no appsecClassName set as well as those with an appsecClassName specified with the helm install command.
{% endhint %}

Here's an example of a policy custom resource with the added property `appsecClassName` (see line 6) set to `myCustomClass1` so that a deployment, which was also configured with `appsec.className` `myCustomClass1` (see above) would consider/implement it:

```yaml
apiVersion: openappsec.io/v1beta2
kind: Policy
metadata:
    name: policy-example
spec:
    appsecClassName: myCustomClass1
    default:
        mode: detect-learn
        accessControlPractices: [access-control-practice-example]
        threatPreventionPractices: [threat-prevention-practice-example]
        triggers: [log-trigger-example]
        customResponse: custom-response-code-example
        sourceIdentifiers: ""
        trustedSources: ""
        exceptions:
        - exception-example
    specificRules:
        - host: "example.com"
          mode: prevent-learn
          threatPreventionPractices: [threat-prevention-practice-example]
          accessControlPractices: [access-control-practice-example]
          triggers: [log-trigger-example]
          customResponse: custom-response-code-example
          sourceIdentifiers: ""
          trustedSources: ""
          exceptions:
          - exception-example
```

{% hint style="danger" %}
Make sure to set the `appsecClassName` property in all custom resources relevant for the specific open-appsec deployment which is configured to using it, including all relevant dependencies (e.g. the custom resources for customResponse, triggers, accessControlPractices, threatPreventionPractices, exceptions as referenced in the example policy custom resource above).
{% endhint %}

This approach is similar to how you can e.g. set different ingressClassNames to associate which ingress API resources should be satisfied by which Ingress Controllers.

{% hint style="warning" %}
open-appsec deployments without an `appsec.className` explicitly set, will only apply the configuration from those custom resources, which do not have any `appsecClassName` explicitly defined.

open-appsec deployments with an `appsec.className` explicitly set, will only apply the configuration from those custom resources, which do also have the exact same `appsecClassName` explicitly defined.
{% endhint %}


# Using namespace-scoped custom resources

{% hint style="warning" %}
The advanced configuration options explained on this page require an existing helm-based deployment on K8s with CRD version v1beta2. See here for instructions: [Install Using Helm - new flow (beta)](/getting-started/start-with-kubernetes/install-using-helm-new-flow-beta)
{% endhint %}

open-appsec's default custom resources, which are used for the declarative configuration when locally managing open-appsec, are **cluster-scoped** custom resources, which means they are not associated with a specific namespace but instead defined on cluster level.

In certain deployment scenarios, you might only have access to a specific namespace and do not have the permission to deploy any cluster-scoped custom resources on a given Kubernetes cluster.\
Or you might be an MSSP who only provides one or more dedicated namespaces to your customers.

Beginning with the open-appsec CRD version v1beta2 for Kubernetes, open-appsec now supports also namespace-scoped custom resources for the configuration as an alternative to the default cluster-scoped custom resources.

## Using namespace-scoped custom resources

When you [deploy open-appsec using helm](/getting-started/start-with-kubernetes/install-using-helm-new-flow-beta),  you can optionally set `appsec.crdsScope` attribute to `namespaced` as shown below to configure open-appsec for applying the configuration declaratively defined in namespace-scoped open-appsec custom resources instead of the regular cluster-scoped custom resources.

```bash
helm install ... --set appsec.crdsScope=namespaced ...
```

**open-appsec, starting with v1beta2, provides every custom resource in two versions, a cluster-scoped version and an alternative namespace-scoped version.**

Once you have set `crdsScope` to `namespaced` for you open-appsec deployment as explained above, make sure to **provide the desired configuration for that specific deployment** **using the dedicated namespace-scoped CRDs**, as shown in the examples below.

{% hint style="warning" %}
Namespace-scoped custom resources **must** reside in the exact same namespace, in which also the open-appsec agent is deployed, in order to be applied by an agent which is set to CRD scope `namespaced`.
{% endhint %}

### Examples:

To define **cluster-scoped** custom resources for defining an open-appsec **policy**, use kind:\
**`Policy`**\
To define **namespace-scoped** custom resources for defining an open-appsec **policy**, use kind:\
**`PolicyNS`**

To define **cluster-scoped** custom resources for defining a **threat prevention practice**, use kind:\
**`ThreatPreventionPractice`**\
To define **namespace-scoped** custom resources for defining a **threat prevention practice**, use kind:**`ThreatPreventionPracticeNS`**

**The same naming pattern applies to all other custom resource definition types which open-appsec supports for declarative configuration.**


# Monitor Events

## Logs

After installation, you may want to trigger some traffic to one of your services and access it via the ingress protected by open-appsec. You can then run these command to view open-appsec logs:

{% tabs %}
{% tab title="Ingress NGINX" %}
Note the name of the ingress nginx pod by running:

```bash
kubectl get pods -n appsec
```

Show the logs of the open-appsec agent container by running:

```bash
kubectl logs [ingress nginx pod name] -c open-appsec -n appsec
```

{% endtab %}

{% tab title="Kong Gateway" %}
Note the name of the Kong pod by running:

```bash
kubectl get pods -n appsec
```

Show the logs of the open-appsec agent container by running:

```bash
kubectl logs [kong pod name] -c open-appsec -n appsec
```

{% endtab %}

{% tab title="APISIX Gateway" %}
Note the name of the APISIX pod by running:

```bash
kubectl get pods -n appsec-apisix
```

Show the logs of the open-appsec agent container by running:

```bash
kubectl logs [apisix pod name] -c open-appsec -n appsec-apisix
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
ith the default policy logging is done to stdout, so you can easily direct it with fluentd/fluentbit or similar to logs collector (ELK or other). It is possible to configure AppSec to log also to sysconfig. &#x20;
{% endhint %}


# Using the Web UI (SaaS)

open-appsec provides a cloud-hosted central management for assets and policies, cloud logging,  graphical dashboards, events analysis and ability to manage multiple deployments/clusters in a scalable way. The cloud is highly available.

You can decide to use it for all functions above or do asset and policy management via Kubernetes declarative configuration while using the SaaS Web UI just for visibility and event analysis.

Follow the pages in this section to:

{% content-ref url="/pages/0ty9rMQEgnxS9LBuN7qw" %}
[Sign-Up and Login to Portal](/getting-started/using-the-web-ui-saas/sign-up-and-login-to-portal)
{% endcontent-ref %}

{% content-ref url="/pages/ALB46qyty6VrEbhWzPUO" %}
[Agents Deployment](/getting-started/using-the-web-ui-saas/agents-deployment)
{% endcontent-ref %}

{% content-ref url="/pages/WMgZp7bTMiI5PD1ocIKp" %}
[Create a Profile](/getting-started/using-the-web-ui-saas/create-a-profile)
{% endcontent-ref %}

{% content-ref url="/pages/yvQt78cZU4kLymWzObq3" %}
[Protect Additional Assets](/getting-started/using-the-web-ui-saas/protect-additional-assets)
{% endcontent-ref %}

{% content-ref url="/pages/Gt4cWQ1XxGsmi1x6f3WV" %}
[Connect Deployed Agents to SaaS Management Using Tool (K8s & Linux)](/getting-started/using-the-web-ui-saas/connect-deployed-agents-to-saas-management-using-tool-k8s-and-linux)
{% endcontent-ref %}

{% content-ref url="/pages/KPhlNAYqTnX6sYV6eUFm" %}
[Connect Deployed Agents to SaaS Management (Docker)](/getting-started/using-the-web-ui-saas/connect-deployed-agents-to-saas-management-docker)
{% endcontent-ref %}

{% content-ref url="/pages/tgaq7ncAIKmZ7utxH4Wp" %}
[Connect Deployed Agents to SaaS Management Using Helm (K8s)](/getting-started/using-the-web-ui-saas/connect-deployed-agents-to-saas-management-using-helm-k8s)
{% endcontent-ref %}


# Sign-Up and Login to Portal

## Portal

To reach the portal browse to [https://my.openappsec.io](https://my.openappsec.io?utm_medium=doc\&utm_source=gitbook\&utm_content=sign-up)

![](/files/vHcpnPj8tVNvw4rkvvJK)

If you already have an account, log in. If you don't have an account yet, click ***Sign up.***&#x20;

{% hint style="info" %}
Please tell us how did you get to know open-appsec by selecting the appropriate option at the top of the signup form
{% endhint %}

![](/files/XQ89n5m0ExmX2EfWH2SB)

## Additional Portal Functions

### Update User Data

You can add additional data about yourself such as Name, Country, etc. by clicking the user icon on the top right side and choosing **User Profile**. &#x20;

### Invite Users

You can invite additional users to the account, by clicking the user icon on the top right side and choosing **Tenant Profile**.&#x20;

### Multiple Tenants

Your user can be associated with multiple tenants. At the right side of the top banner of the\
open-appsec Portal it is possible to click on your user initials and open the user options menu.

Your active tenant name will be visible. Make sure the selected tenant is the tenant you want to configure.

![](/files/Y9wmzLRkgzwXO7CUkN59)

By clicking on the arrows next to the Tenant, you will be able to select from other tenants associated with this user:

![](/files/ngAnLvlHUpWITXlLTRSQ)

{% hint style="warning" %}
Creating another tenant for the same primary user (using the same email address) will be available soon. An existing user can already be added to other existing tenants.
{% endhint %}


# Agents Deployment

Skip this page if you already have Agents deployed

open-appsec supports support three types of agent deployments:

1. Kubernetes: integrated with NGINX Ingress Controller or Kong Gateway
2. Linux: integrated as plugin for NGINX/NGINX Plus/Kong Gateway
3. Docker: integrated with NGINX or Kong Gateway containers

{% hint style="info" %}
Currently open-appsec supports NGINX / NGINX Ingress Controller and Kong Gateway on Kubernetes, Linux and Docker platforms. Additional integrations will follow soon after.
{% endhint %}

## Agent Deployment for Kubernetes, Linux and Docker

{% content-ref url="/pages/XzPA7UFoksUJscLSZUHf" %}
[Start With Kubernetes](/getting-started/start-with-kubernetes)
{% endcontent-ref %}

{% content-ref url="/pages/pYtU2ANNgakFm2heJDfd" %}
[Start With Linux](/getting-started/start-with-linux)
{% endcontent-ref %}

{% content-ref url="/pages/lDQro0xuNxZzJgHABh5l" %}
[Start with Docker](/getting-started/start-with-docker)
{% endcontent-ref %}


# Connect Deployed Agents to SaaS Management Using Tool (K8s & Linux)

### Instructions

When logged in to the open-appsec portal, click on **Getting Started.** You will see this page:

<figure><img src="/files/hr5DWQjQPPy5swNONpsc" alt=""><figcaption></figcaption></figure>

Follow these steps to connect your agents to the management:

#### **Step 1:  Confirm agent is deployed**

Check the "I deployed an agent" box, the Central Management box will become enabled.

#### **Step 2: Create a profile**

{% hint style="info" %}
The best-practice recommendation is to create an individual profile in the WebUI for each of your open-appsec deployments. Examples for "deployments" would be e.g.:

\
\- K8s deployment using HELM or installation tool (consisting of one or multiple open-appsec agents)\
\- redundant deployment using Docker on two or more virtual machines (each having it's own agent) protecting the same web assets \
\- redundant Linux embedded deployment on two or more Linux machines protecting the same web assets \
\
Security-wise this makes sure that only policies for those assets which are protected by specific agents are enforced on those agents (by linking the Assets to only the relevant profile(s)), in addition to having separate tokens per each deployment and all associated agents.\
In addition this approach provides the flexibility of being able to configure various settings available on profile-level individually per each deployment, if required.
{% endhint %}

1. In the Getting Started page, click **Manage** and choose either **Kubernetes Profile** or **Linux Embedded Agent Profile** depending on your installation type. You will get into the related Profile page:

<figure><img src="/files/kzBan8OVf2Jf53VeeDxO" alt=""><figcaption><p>Kubernetes Kong Profile example</p></figcaption></figure>

<figure><img src="/files/Yl8gfrWCtbzAkcGtJOST" alt=""><figcaption><p>Linux NGINX Profile Example</p></figcaption></figure>

#### **Step 3:  Select Subtype**

In the "sub type" field select either NGINX or Kong depending on what kind of open-appsec agent / deployment you want to connect.

#### **Step 4:  Determine Management Master**

Choose the relevant option to decide whether you want to edit assets and policies via the WebUI or locally in a declarative way (using CRDs or configuration file). If you choose a declarative option you can still view the configuration in the WebUI in read-only mode.

<figure><img src="/files/JPWhOXaHjAYTliB3vpsi" alt=""><figcaption><p>Kubernetes management mode</p></figcaption></figure>

<figure><img src="/files/97cXaWHRpD74SlDgzkbd" alt=""><figcaption><p>NGINX management mode</p></figcaption></figure>

#### **Step 5: Create secure communication channel between Agent(s) and Management**

{% hint style="warning" %}
In case you want to connect to the SaaS Management using only Helm values (e.g. in a GitOps scenario where you deploy the Helm chart from a Git repo) please continue [here](/getting-started/using-the-web-ui-saas/connect-deployed-agents-to-saas-management-using-helm-k8s) and don't perform this step below.
{% endhint %}

Follow the guidelines under Download & Deployment:

1. Enforce policy, by clicking the button at the top right of the page.
2. Copy the commands **as shown in the selected profile** and run it in your Kubernetes or Linux Environment to connect your deployed agents to this profile and the central management.\
   Here are some examples:

<figure><img src="/files/u860G6wbnSgF55h8ewD5" alt=""><figcaption><p>Kong Linux Connect to managment example</p></figcaption></figure>

{% hint style="success" %}
Once you performed the instructions, after about two minutes, you will see a green notification bar in the Web UI. Your open-appsec agents are now connected to the management!
{% endhint %}


# Connect Deployed Agents to SaaS Management Using Helm (K8s)

You can also connect to the SaaS Management using only Helm values. This is relevant e.g. in a GitOps scenario where you deploy also the Helm chart from your Git repo.

## Instructions

#### When logged in to the open-appsec portal, click on **Getting Started.** You will see this page:

<figure><img src="/files/hr5DWQjQPPy5swNONpsc" alt=""><figcaption></figcaption></figure>

Follow these steps to connect your agents to the management:

#### **Step 1:  Confirm agent is deployed**

Check the "I deployed an agent" box, the Central Management box will become enabled.

#### **Step 2: Create a profile**

{% hint style="info" %}
The best-practice recommendation is to create an individual profile in the WebUI for each of your open-appsec deployments. Examples for "deployments" would be e.g.:

\
\- K8s deployment using HELM or installation tool (consisting of one or multiple open-appsec agents)\
\- redundant deployment using Docker on two or more virtual machines (each having it's own agent) protecting the same web assets \
\- redundant Linux embedded deployment on two or more Linux machines protecting the same web assets \
\
Security-wise this makes sure that only policies for those assets which are protected by specific agents are enforced on those agents (by linking the Assets to only the relevant profile(s)), in addition to having separate tokens per each deployment and all associated agents.\
In addition this approach provides the flexibility of being able to configure various settings available on profile-level individually per each deployment, if required.
{% endhint %}

In the Getting Started page, click **Manage** and choose **Kubernetes Profile**, you will get to the profile page:

<figure><img src="/files/AhybYaCijHKXhW0Ff6uz" alt=""><figcaption></figcaption></figure>

#### **Step 3:  Select Subtype**

In the "sub type" field select either NGINX or Kong depending on what kind of open-appsec agent/deployment you want to connect.

#### **Step 4:  Determine Management Master**

Choose the relevant option to decide whether you want to edit assets and policies via the WebUI or locally in a declarative way (using CRDs or configuration files). If you choose a declarative option you can still view the configuration in the WebUI in read-only mode.

<figure><img src="/files/JPWhOXaHjAYTliB3vpsi" alt="" width="499"><figcaption><p>Kubernetes management mode</p></figcaption></figure>

#### 5.  Enforce policy to confirm your choice

In the top-right of the WebUI click on "Enforce" to enforce the policy.

#### 6. Copy the token from Profile

In the WebUI go to the Profile you created in the step above and copy the token.

#### 7. Perform helm upgrade with adjusted Helm values

In order to connect to the management you need to run `helm upgrade` command as follows:

```
helm upgrade {open-appsec-helm-release-name} open-appsec-k8s-nginx-ingress-latest.tgz \
-n {open-appsec-namespace} \
--reuse-values \
--set appsec.mode="managed" \
--set appsec.agentToken={token}
```

#### Notes:

`open-appsec-helm-release-name` - replace with the name of the currently installed open-appsec-helm release, you can get this by using the following command which will show all currently installed helm releases `helm list -A`

`open-appsec-namespace` - replace with the namespace of your open-appsec deployment

`token` - replace with the token you copied from the Profile in the WebUI.&#x20;

`--reuse-values` - This tells Helm to reuse all Helm values you configured when originally deploying the open-appsec helm chart.\
Note that when doing the Helm deployment declaratively from a central Git repo using some GitOps CD tool you need to replace this to specify explicitly all the specific Helm values you require.

{% hint style="success" %}
Once you performed the instructions, after about two minutes, you will see a green notification bar in the Web UI. Your open-appsec agents are now connected to the management!
{% endhint %}


# Connect Deployed Agents to SaaS Management (Docker)

## Prerequisites

* **Access to a SaaS tenant on my.openappsec.io (WebUI for SaaS management)**\
  Follow the instructions available here:

{% content-ref url="/pages/0ty9rMQEgnxS9LBuN7qw" %}
[Sign-Up and Login to Portal](/getting-started/using-the-web-ui-saas/sign-up-and-login-to-portal)
{% endcontent-ref %}

* **Agent profile created for open-appsec Docker deployment in SaaS tenant** \
  Follow the instructions available bellow, once done, don't forget to copy the profile token after policy installation as this is needed in the installation steps further below:

{% content-ref url="/pages/WMgZp7bTMiI5PD1ocIKp" %}
[Create a Profile](/getting-started/using-the-web-ui-saas/create-a-profile)
{% endcontent-ref %}

* Linux machine with:

  * Docker software installed (or similar compatible Container runtime)
  * Root Permissions&#x20;

* Existing open-appsec WAF deployment on Docker which is:
  * locally managed
  * not connected to the central WebUI yet

### Instructions:&#x20;

<details>

<summary>Optional: Perform One-Time Upload of Your Existing Local Configuration to Central WebUI If You Want to Maintain It (relevant for Central Management Mode Only)</summary>

If you want to maintain your existing local, declarative configuration after connecting to central WebUI, so that it will become the initial starting point for the central management configuration (requires WebUI deployment profile set to "This management"), follow these optional steps to perform a one time upload of your existing local, declarative configuration to the central management (SaaS).

{% hint style="warning" %}
*This option is not relevant when you want to connect to a deployment profile in central management WebUI set to "Declarative configuration", as in that case WebUI will continuously show the current, declarative configuration, which you will still manage locally.*
{% endhint %}

{% hint style="danger" %}
*If you do not perform this step and have the deployment profile set to "This management" you will start with a new clean (empty) central configuration for your existing deployment.*
{% endhint %}

#### Step 1: Download the `mgmt-connect-linux` tool

Run the following command to download and prepare the `mgmt-connect-linux` tool inside the existing, running agent container:

```bash
docker exec -it open-appsec-agent bash -c "wget https://downloads.openappsec.io/scripts/mgmt-connect-linux && chmod +x mgmt-connect-linux"
```

#### Step 2: Perform one-time upload of the existing local configuration

Use the token generated in your deployment profile during the prerequisites to upload the policy. Replace `<TOKEN>` with your actual deployment profile token:

```bash
docker exec -it open-appsec-agent bash -c "./mgmt-connect-linux --token <TOKEN> --config-upload-only"
```

**Notes:**

* The container name for the agent container in your environment could have been changed based on your original deployment, in that case adjust `open-appsec-agent` in the commands above with your own agent container name.

</details>

{% tabs %}
{% tab title="Docker Compose with .env" %}
**If you deployed open-appsec using docker-compose command with `.env` file):**

**Step 1:** Add the deployment profile's token to your `.env` file:

* Locate the `APPSEC_AGENT_TOKEN=` key in your `.env` file.
* Copy the **Token** from your WebUI Docker Profile (as described in the prerequisites) and paste it as the value for the `APPSEC_AGENT_TOKEN` key.

Example `.env` file snippet, make sure to do the above change in your own `.env` file and provide your own deployment profile token copied from the Web UI for `<your-agent-token>`:

```yaml
## To connect your deployment to central open-appsec WebUI provide the token for a profile
## which you created in open-appsec WebUI at https://my.openappsec.io
## Example: APPSEC_AGENT_TOKEN=111-22222-111
APPSEC_AGENT_TOKEN=<your-agent-token>
```

{% hint style="info" %}
If you chose "***“Declarative configuration”*** management make sure to keep the agent local configuration file volume mount which gets mounted to `/ext/appsec` inside the agent container.&#x20;

If you chose "**This Management**" then the above mentioned volume mount is no longer needed, and can be removed. &#x20;
{% endhint %}

**Step 2:** Apply the adjusted Docker Compose configuration provided in the `.env` file:\
Run the following commands to recreate the agent container based on the adjusted Docker Compose file which now includes the `AGENT_TOKEN` specification for connecting to Management WebUI (SaaS):

```bash
docker-compose up -d
```

**Step 3:** Verify the connection:

* Log in to the Web UI and check if your agent is connected.
  {% endtab %}

{% tab title="Docker Compose without .env" %}
**If you deployed open-appsec using docker-compose command (without using a `.env` file):**

**Step 1:** Add the deployment profile's token to your `docker-compose.yaml` file:

* Locate the `AGENT_TOKEN` key in your `docker-compose.yaml` file.
* Copy the **Token** from your WebUI Docker Profile (as described in the prerequisites) and paste it as the value for the `AGENT_TOKEN` key.

Example `docker-compose.yaml` snippet, make sure to do the above change in your own `docker-compose.yaml` file providing your own deployment profile token copied from the Web UI for `<your-agent-token>`:

```yaml
version: '3'
services:
  openappsec-agent:
    image: ghcr.io/openappsec/agent:latest
    container_name: open-appsec-agent
    environment:
      - registered_server=NGINX Server
      - user_email=<add-your-email-here>
      - https_proxy=<user:password@proxy-address:port>
      - autoPolicyLoad=false
      - AGENT_TOKEN=<your-agent-token>
    volumes:
      - <path-to-persistent-location-for-agent-config>:/etc/cp/conf
      - <path-to-persistent-location-for-agent-data-files>:/etc/cp/data
      - <path-to-persistent-location-for-agent-debugs-and-logs>:/var/log/nano_agent
      - <path-to-persistent-location-for-local-configuration-file>:/ext/appsec
    ipc: host
```

{% hint style="info" %}
If you chose "***“Declarative configuration”*** management make sure to keep the agent local configuration file volume mount which gets mounted to `/ext/appsec` inside the agent container.&#x20;

If you chose "**This Management**" then the above mentioned volume mount is no longer needed, and can be removed. &#x20;
{% endhint %}

**Step 2:** Apply the adjusted Docker Compose configuration:\
Run the following commands to recreate the agent container based on the adjusted Docker Compose file which now includes the `AGENT_TOKEN` specification for connecting to Management WebUI (SaaS):

```bash
docker-compose up -d
```

**Step 3:** Verify the connection:

* Log in to the Web UI and check if your agent is connected.
  {% endtab %}
  {% endtabs %}

If you chose **“This management”** management mode, and didn't upload the policy:&#x20;

**Step 4:** Create one or more assets in the Web UI, make sure to connect the asset to the profile you have created in the Prerequisites:

{% content-ref url="/pages/yvQt78cZU4kLymWzObq3" %}
[Protect Additional Assets](/getting-started/using-the-web-ui-saas/protect-additional-assets)
{% endcontent-ref %}


# Create a Profile

#### **Step 1: Create a profile**

{% hint style="info" %}
The best-practice recommendation is to create an individual profile in the WebUI for each of your open-appsec deployments. Examples of "deployments" would be e.g.:

\
\- K8s deployment using HELM or installation tool (consisting of one or multiple open-appsec agents)\
\- redundant deployment using Docker on two or more virtual machines (each having its own agent) protecting the same web assets \
\- redundant Linux embedded deployment on two or more Linux machines protecting the same web assets \
\
Security-wise this makes sure that only policies for those assets that are protected by specific agents are enforced on those agents (by linking the Assets to only the relevant profile(s)), in addition to having separate tokens per each deployment and all associated agents.\
In addition, this approach provides the flexibility of being able to configure various settings available on the profile-level individually per each deployment, if required.
{% endhint %}

In the open-appsec WebUI create a new Profile as follows,&#x20;

<figure><img src="/files/I6bjOmVAu3H8NWhiBeIT" alt=""><figcaption></figcaption></figure>

You will get into the related Profile page:

<figure><img src="/files/jzF5yjW1l5QCbaI9yCKx" alt=""><figcaption><p>Profile example for Docker with sub type NGINX </p></figcaption></figure>

#### **Step 2: Select profile "Sub Type"**

Select the correct subtype for your intended open-appsec deployment on Docker (NGINX or Kong).

#### **Step 3:  Select Management Mode**

A deployment profile in the open-appsec WebUI supports two different management modes for connected agents to chose from:&#x20;

***“Declarative configuration” (Local Management)***: In this mode after connecting the deployment to WebUI you will still configure everything in the local declarative configuration file, but the WebUI will show you all settings (in read-only) and you can monitor agent status, logs and security events comfortably.\
In addition learning will be shared between multiple agents connected to the same profile and you can take decisions on tuning suggestions in the WebUI.\
\
![](/files/gXPempUaGeZ1b9gbmYZt)\
\
***“This management” (Central Management)*****:** In this mode after connecting the deployment to WebUI you will be able to manage all open-appsec settings centrally (local configuration file will not be used by the agent anymore) and monitor agent status, logs and security events comfortably from the central WebUI.\
\
![](/files/2Z9D8V2dIzz2zDWdiWWd)\
\
\
**Step 4: Enforce Policy**

Enforce policy, by clicking the button at the top right of the page.

**Step 5: Copy Token**

Copy the token shown in the profile by clicking the copy token option shown below. You need to provide this token in the following open-appsec installation steps on Docker:

<figure><img src="/files/LndHfCSxdVz4XpUa5AjX" alt=""><figcaption></figcaption></figure>

**Step 6: Install open-appsec**

Follow the instructions provided here to install open-appsec, once those have been successfully performed the deployed open-appsec Agent will automatically connect to the  Profile created in the steps above, and after about two minutes, you will see a green notification bar in the Web UI.

{% content-ref url="/pages/pYtU2ANNgakFm2heJDfd" %}
[Start With Linux](/getting-started/start-with-linux)
{% endcontent-ref %}

{% content-ref url="/pages/lDQro0xuNxZzJgHABh5l" %}
[Start with Docker](/getting-started/start-with-docker)
{% endcontent-ref %}

{% content-ref url="/pages/XzPA7UFoksUJscLSZUHf" %}
[Start With Kubernetes](/getting-started/start-with-kubernetes)
{% endcontent-ref %}


# Protect Additional Assets

This page discusses how to add additional assets for protection.&#x20;

## Web Application Configuration

#### Step 1: Create a new asset

* When logged in to the open-appsec portal, click on the **Assets** option in the top navigation menu.&#x20;
* If you have not configured any assets yet, the portal will show the following and a **New Asset** option will be available. For creating a new Web Application asset, select **New Asset->Web Application.**&#x20;

<figure><img src="/files/TE9y9htb2aTKXjd58U1g" alt=""><figcaption></figcaption></figure>

If you configured assets before, you can either click New Web Application or Clone Web Application.

<figure><img src="/files/BzymPyyNPDyOMpLVGYmu" alt=""><figcaption></figcaption></figure>

#### Step 2: Basic Details

Complete the following details:

<figure><img src="/files/SfnPQqxcVwtHL8gS6U3x" alt=""><figcaption></figcaption></figure>

* Name - choose a clear distinguishable name for your asset
* Tags (Optional) - can be used for searches.&#x20;
* Profile - Select the profile you have created during the previous step - make sure to connect your deployed agents to the SaaS management, see here: [Connect Deployed Agents to SaaS Management Using Tool (K8s & Linux)](/getting-started/using-the-web-ui-saas/connect-deployed-agents-to-saas-management-using-tool-k8s-and-linux), [Connect Deployed Agents to SaaS Management (Docker)](/getting-started/using-the-web-ui-saas/connect-deployed-agents-to-saas-management-docker)

**Step 3: Web Application/API details:**

Add the URLs that users/clients will access to reach the application/API - configure at least one host address with optional non-standard port. open-appsec will protect these hosts.

{% hint style="danger" %}
Make sure to also configure the correct port for policy enforcement if you're not using the defaults (port 80 for HTTP and/or port 443 for HTTPS). See also hint further below.
{% endhint %}

Examples:&#x20;

* `https://www.acme.com`&#x20;
* `http://www.acme.com`
* `https://www.acme.com/sales`
* `https://sales.acme.com`
* `https://172.20.20.4:3000 (sets non-standard port 3000 for policy enforcement)`
* `https://sales.acme.com:* (specifying * as port will enforce policy for all destination ports)`

{% hint style="warning" %}
Kong Gateway's default ports for inbound traffic for HTTP and HTTPS are 8000 and 8443. \
APISIX Gateway's default ports for inbound traffic for HTTP and HTTPS are 9080 and 9443. \
Envoy Gateway's default ports for inbound traffic for HTTP and HTTPS are 10080 and 10443.

Make sure to specify those correctly in addition to protocol, hostname and path as described above so that the specified asset will successfully match the traffic to your  Gateway.
{% endhint %}

#### Step 4: Source Identity&#x20;

Define how the Machine Learning engine should distinguish between different API or human users.

Select the method by which different users will be distinguished from one another. The commonly used options are:

* **X-Forwarded-For Header** - When there is a Reverse Proxy or ALB between the Reverse Proxy the agent is running on, and the internet - the original source IP address cannot be seen on the networking level.\
  This option allows the Nano-Agent to identify the original source IP inside the X-Forwarded-For header. No additional parameters are required in the common case where a single Reverse Proxy/ALB is found before the agent's deployment.

{% hint style="info" %}
In the less common case, where there is more than 1 reverse proxy and/or ALB deployments before the open-appsec reverse proxy deployment, add the IP addresses of the previous hops, to allow the distinction between them and the original source address.

This is explained in more details [here](/how-to/configuration-and-learning/configure-contextual-machine-learning-for-best-accuracy).
{% endhint %}

* **Source IP** **Address** - The Nano-Agent uses the source IP address as the identifier. No additional parameters are required.

{% hint style="info" %}
More advanced methods are also available. These include:

* **Cookie Key** - when you select this option, you need to add the key name within the cookie whose value is used as the unique identifier of the original source.
* **HTTP Header** - when you select this option, you need to add the HTTP header name whose value is used as the unique identifier of the original source.
* **JWT Key** - Authenticated API calls send a JSON Web Token (JWT) received by authentication API. This JWT usually contains identifying field. When you select this option, the value of one of the JWT keys can be used as the unique identifier of the original source.
  {% endhint %}

#### Step 5: Trusted Sources (optional)

Define how the Machine Learning engine should distinguish the users that can be trusted.

You may define trusted sources that serve as a baseline for comparison for *benign behavior*, and how many Users/Addresses must exhibit similar activity for it to really be considered benign by the learning model.

![](/files/kInsqsuzDIuOE8DF7gLe)

#### Step 6: Practices (optional)

The Web Attacks open-appsec protection is already configured and set to "Learn/Detect" mode. This is visible in the Threat Prevention tab showing the security practices configuration.

You do not need to make any changes as it is also recommended to start in "Learn/Detect" mode and move to prevent after the Machine Learning engine has reached a high enough learning level as explained [here](/how-to/configuration-and-learning/track-learning-and-move-from-learn-detect-to-prevent).

<figure><img src="/files/DWtvg6L9Yge5L0ky6aWB" alt=""><figcaption></figcaption></figure>

#### Step 7: Click Enforce

At the top of the portal near the right corner, there is an "**Enforce**" option. Click on it to publish the configuration settings to the already deployed agent.

<figure><img src="/files/6i0zcYPoFIiaHdP1VxLs" alt=""><figcaption></figcaption></figure>

#### Asset Mode&#x20;

The color of the Asset in the assets screen represents the asset's state:

* Orange: The asset is not connected to an agent
* Blue: The asset is connected to an agent in learning mode
* Green: The asset is connected to an agent in protection mode&#x20;

<figure><img src="/files/QaPzN7uXKUDnb3UVQTCv" alt=""><figcaption><p>assets in diffrent Modes</p></figcaption></figure>


# Monitor Events

open-appsec provides three views for monitoring system events:

* Graphical Dashboard - graphical view of security events with Critical & High severity.
* Important Events - tabular view of security events with Critical & High severity.
* Notifications - tabular view of administrative system events.

## Graphical Dashboard <a href="#using_the_appsec_dashboard" id="using_the_appsec_dashboard"></a>

The AppSec Dashboard is a single-pane view of important security events.

To reach the dashboard select **Monitor**, then **AppSec Dashboard** in the main menu.

![](/files/KVdnjeWXA8ZJyZBWZ6X9)

{% hint style="info" %}
Controls in the dashboard are clickable and will allow you to drill down and \
see granular event details.&#x20;
{% endhint %}

Following is a description of the Dashboard sections:

| Section              | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Overall HTTP Traffic | Statistics show the number of overall request for the time period and unique number of users and, or identities that use the protected web servers.                                                                                                                                                                                                                                                                                                                                                                                                                       |
| Malicious Activity   | Overall statistics of the number of attackers (users and, or identities) and the number of attacks on web servers.                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| Security Actions     | Overall number of events that where prevented and detected.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| Top Attack Sources   | <ul><li>A chart of the top attackers by the number of events.</li><li><p>Number of events on a time line, gives visibility to the changes in the security posture.</p><p><a href="https://sc1.checkpoint.com/documents/Infinity_Portal/WebAdminGuides/EN/Infinity-Next-Admin-Guide/Resources/Images/Images-for-Infinity-Next/waap_attack_sources.png"><img src="https://sc1.checkpoint.com/documents/Infinity_Portal/WebAdminGuides/EN/Infinity-Next-Admin-Guide/Resources/Images/Images-for-Infinity-Next/waap_attack_sources_thumb_0_113.png" alt=""></a></p></li></ul> |
| Attacks Level        | Chart of the number of attacks by severity.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| Top Attack Assets    | Chart of the most attacked web servers.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| Asset Statistics     | Table of protected web server(s) and its statistics.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| Attacks Timeline     | <p>Shows a specific time period on the dashboard.</p><p><a href="https://sc1.checkpoint.com/documents/Infinity_Portal/WebAdminGuides/EN/Infinity-Next-Admin-Guide/Resources/Images/Images-for-Infinity-Next/waap_time_filter.png"><img src="https://sc1.checkpoint.com/documents/Infinity_Portal/WebAdminGuides/EN/Infinity-Next-Admin-Guide/Resources/Images/Images-for-Infinity-Next/waap_time_filter_thumb_0_113.png" alt=""></a></p>                                                                                                                                  |

You can right click on Dashboard items to drill down as well as "filter in" or "filter out":

<figure><img src="/files/hOTRvF9BjQOM10MPqilh" alt=""><figcaption></figcaption></figure>

## Event Views

The Events view provides a tabular view of events with ability to select granular filter options (left pane in the image below), [search queries](/references/event-query-language) and Time ranges.

![](/files/W5Bnvy84R9PB6Gcaoaqi)

### **Event Cards**

When you double click on an event, a card shows details about the specific event.

Examples:

| **Event Severity Classification**       | ![](/files/N5NVWN9b9rEVPSrDLgk8) |
| --------------------------------------- | -------------------------------- |
| **Protected Web Asset Name and Policy** | ![](/files/qBj159Y9vLyEXNIJOaSJ) |
| **HTTP Transaction Information**        | ![](/files/o18UsSYM5Xn5fuomBFEQ) |
| **Threat Prevention details**           | ![](/files/W37yqwIoFLW8gbAamplE) |

### **Time filters**

You can filter events based on time ranges by clicking the time filter selector at the top left corner.

![](/files/tagMdT2KiUBgRpmZp9Ms)

## **Event Advisor**

To analyze an event in the security logs you can also use the **AI-based Event Advisor**, which will provide detailed answers on the following questions:

* What Happened?
* Why Was It Blocked?
* What Should You Do?

Learn more about the Event Advisor and how to use it here: [Analyze Security Events with Event Advisor](/management-web-ui/analyze-security-events-with-event-advisor)

## Event Query Language

open-appsec features an extensive event query language. For more details see here:

{% content-ref url="/pages/1LSoyxZcT2a5AX5wySbg" %}
[Event Query Language](/references/event-query-language)
{% endcontent-ref %}

## Notifications

When browsing to **Monitor->Notifications** a specific log view is shown.

This view includes notifications to the user about an issue and a remediation action item, usually regarding detection of a configuration or environment issue open-appsec has detected around it.

The Log view includes a "Remediation" column where the instructions will be shown.

Urgent notifications, if there are any, will appear on the top bar of the application in any page, leading to this page for additional information.


# Using Kong Konnect (Kong only)

{% hint style="warning" %}
The new Kong integration using Lua-based attachment plugin for the open-appsec integration is currently in beta. This also applies to the new Kong Konnect schema allowing you to manage this plugin directly from Kong Konnect web UI.
{% endhint %}

### Learn how to activate and configure the open-appsec WAF attachment plugin for Kong from Kong Konnect, Kong's central management web UI

If you are using open-appsec WAF integrated with Kong using the modern, Lua-based plugin (not the classical open-appsec attachment plugin, which integrates on NGINX level), then you can also activate and manage the open-appsec attachment plugin for Kong from Kong Konnect.

{% hint style="warning" %}
While Kong Konnect can be used to activate and manage the Lua-based open-appsec attachment plugin, note that you will continue to manage open-appsec in the usual ways, with local, declarative configuration or by using the [open-appsec web UI](https://my.openappsec.io/).
{% endhint %}

1. **Download the Kong Konnect schema** for the open-appsec attachment plugin:

```bash
wget https://raw.githubusercontent.com/openappsec/attachment/main/attachments/kong/plugins/open-appsec-waf-kong-plugin/schema.lua
```

2. **Login to your Kong Konnect web UI**
3. **Upload the schema file** `schema.lua` for the open-appsec-waf-kong-plugin

<figure><img src="/files/tKSKpKp0ESF4tRD4tXfC" alt="" width="563"><figcaption></figcaption></figure>

<figure><img src="/files/Y7eoz8Q3OcXk5F5JGGM4" alt="" width="563"><figcaption></figcaption></figure>

Now you should see the open-appsec-waf-kong-plugin listed under "Custom Plugins" in Kong Konnect.

<figure><img src="/files/ON3MRbfoHVMGinuoxMyR" alt="" width="547"><figcaption></figcaption></figure>

4. **Activate the plugin** in the Kong Konnect web UI by selecting "Enable", then you get to this screen:

<figure><img src="/files/spmXoyx33m4kdzEUdr5c" alt="" width="563"><figcaption></figcaption></figure>

Once enabled, the plugin is configured to be applied in "Global" mode by default, which means it will send all traffic to the open-appsec agent for security inspection, alternatively you can select "Scoped" mode here and apply open-appsec security inspection in a custom way only to e.g. to a selected Gateway Service, Route, Consumer or Consumer Group:

<figure><img src="/files/7BdTjAXa9FkmfOHFIs3S" alt="" width="563"><figcaption></figcaption></figure>

For more info on how to use Kong Konnect, see also the official docs available here: <https://developer.konghq.com/konnect/>


# Using the Advanced Machine Learning Model

## About open-appsec's Machine Learning Models

**open-appsec uses two machine learning models:**

1. A **"Supervised Model"** that was trained offline based on millions of requests, both malicious and benign.
2. An **"Unsupervised Model"** that is being built in real time in the protected environment.\
   This model uses traffic patterns specific to the environment.

**For the supervised model (see above) there are two alternative options you can chose from:**

* A **"Basic Model"** is provided as part of the [GitHub repository](https://github.com/openappsec/) and the default installations.\
  This is recommended for use in Monitor-Only and Test environments.
* An **"Advanced Model"** can be downloaded from [open-appsec portal](https://my.openappsec.io/). \
  This is more accurate and recommended for Production use.

## How to Download the Advanced Machine Learning Model

To download and extract the open-appsec advanced machine learning model follow these steps:

* Login to the open-appsec portal at [my.openappsec.io](https://my.openappsec.io/) .
* Download the advanced machine learning model by going to:\
  User Menu -> Download Advanced ML Model.

{% hint style="info" %}
This model updates from time to time and you will get an email when these updates happen. When the model is updated please redeploy the Advanced Machine Learning Model by downloading the new file, and following the instructions bellow.&#x20;
{% endhint %}

## How to Deploy / Update the Advanced Machine Learning Model

To deploy and use open-appsec's **advanced machine learning model** follow the instructions below to install this Advanced Model in your specific environment:

#### Deployment and usage of the advanced model inside the docker

1. Create a folder called `open-appsec-advance-model`

```
mkdir open-appsec-advanced-model
```

2. Copy the tgz file into the folder.&#x20;
3. Map this .tgz file into the appsec container to "/advanced-model/open-appsec-advanced-model.tgz" file inside the container.

{% tabs %}
{% tab title="docker compose" %}
If you are using `docker compose` to deploy open-appsec add a volume mount under the agent container as follows:\
`- ./open-appsec-advanced-model/open-appsec-advanced-model.tgz:/advanced-model/open-appsec-advanced-model.tgz:rw`\
\
See also the following example docker-compose file (used for deployment with NGINX Proxy Manager) to which the additional volume mount for the appsec-agent container was added accordingly:

```
version: '3.3'
# docker compose for npm open-appsec integration

services:
  appsec-npm:
    container_name: npm-attachment
    image: 'ghcr.io/openappsec/nginx-proxy-manager-attachment:latest'
    ipc: host
    restart: unless-stopped
    ports:
      - '80:80' # Public HTTP Port
      - '443:443' # Public HTTPS Port
      - '81:81' # Admin Web Port
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
      - ./appsec-logs:/ext/appsec-logs
      - ./appsec-localconfig:/ext/appsec

  appsec-agent:
    container_name: appsec-agent
    image: 'ghcr.io/openappsec/agent:latest'
    network_mode: service:appsec-npm
    ipc: host
    restart: unless-stopped
    environment:
      # adjust with your own email below
      - user_email=user@email.com
      - nginxproxymanager=true
      - autoPolicyLoad=true
    volumes:
      - ./appsec-config:/etc/cp/conf
      - ./appsec-data:/etc/cp/data
      - ./appsec-logs:/var/log/nano_agent
      - ./appsec-localconfig:/ext/appsec
      - ./open-appsec-advanced-model/open-appsec-advanced-model.tgz:/advanced-model/open-appsec-advanced-model.tgz:rw
    command: /cp-nano-agent --standalone

```

{% endtab %}
{% endtabs %}

2. Run the agent container (if you already have a running agent container make sure to redeploy it)

#### Deployment and usage of the advanced model in Kubernetes

1. Create a config map from the tgz file in the relevant namespace: `kubectl create configmap advanced-model-config --from-file open-appsec-advanced-model.tgz -n <namespace>`
2. Restart all open-appsec agent pods in the namespace of your open-appsec deployment, you can restart the pods by following the steps below:
   1. get open-appsec deployment name

      `kubectl get deployment -n <open-appsec deployment namespace>`
   2. Restart pods

      `kubectl rollout restart deployment <open-appsec deployment name> -n <open-appsec deployment namespace>`

#### Deployment and usage of the advanced model with a Linux-embedded agent

1. Create a folder under the following path in the root directory: /advanced-model\
   `mkdir -p /advanced-model`
2. Copy the .tgz file into the folder you created\
   `cp ./open-appsec-advanced-model.tgz /advanced-model/open-appsec-advanced-model.tgz`.
3. Deploy the embedded agent
4. if you already have an open-appsec agent.&#x20;
   1. Complete steps 1-3
   2. Run `open-appsec-ctl --stop-agent`&#x20;
   3. Extract the model to the relevant folder by running `tar -xzf /advanced-model/open-appsec-advanced-model.tgz -C /etc/cp/conf/waap`&#x20;
   4. Run `open-appsec-ctl --start-agent`

#### Adding the advanced model when building new agent code

1. Clone the open-appsec agent GitHub repository (<https://github.com/openappsec/openappsec>).
2. Extract the `open-appsec-advanced-model.tgz` file.\
   On Linux you can do this by using the following command:\
   `tar -xvf open-appsec-advanced-model.tgz`
3. Copy the extracted files to the `components/security_apps/waap/resources` folder.
4. Build the agent package or Docker by following the instructions in the GitHub repository README (<https://github.com/openappsec/openappsec/blob/main/README.md>).

### Validate the use of the Advanced Model

{% hint style="info" %}
The machine learning (AI) model version info is shown in the open-appsec-ctl tool from version 1.1.0 and onwards.
{% endhint %}

The machine learning AI model type and version being used can be validated using the command:

```
open-appsec-ctl --status 
```

<figure><img src="/files/KCLu0OytGSkGSmBtI191" alt=""><figcaption><p>Output of open-appsec-ctl --status</p></figcaption></figure>

The model being used by each agent can also be validated using the Agents tab in the web UI:

<figure><img src="/files/hPcmquJoX4RJO5FhsvyI" alt=""><figcaption><p>Agents tab in Web UI</p></figcaption></figure>


# Agents

open-appsec can be deployed on Kubernetes integrated with NGINX Ingress Controller or Kong or APISIX Gateway. It can also be added NGINX , Kong Gateway, Envoy, APISIX, NGINX Proxy Manager, or SWAG on Docker, and NGINX, Kong, and APISIX on Linux. All deployment vehicles share the same basic agent technology. In this section we will explain how agents work and what is the difference between the different deployment vehicles.

## Agents

Agents are small software components that can be easily deployed on top of an existing web server or  reverse proxy, without changing existing architecture and while ensuring minimal latency and maximum control.

As security processing is done locally sensitive data does not leave the protected environment and there is no need to share certificates and private keys with third parties. Moreover, there is no dependency on 3rd party uptime for processing traffic.

Agents can be managed by a master called **Fog.**  The Fog is a SaaS component that provides registration, policy update, configuration update, software updates, logging and learning data synchronization. Check Point operates highly available and scalable Fogs in several regions in the world.

Agents get all updates automatically and there is no need to upgrade them manually. It is possible to control the upgrade schedule.

{% hint style="success" %}
Agents are designed to act stand-alone and will operate without disruption to traffic and security enforcement even when Fog is unreachable. You can also run as many agents to support your load as needed with no license constraints.&#x20;
{% endhint %}

{% hint style="warning" %}
When Fog is unreachable some central administrative functions are not available: software and policy updates, lPS updates, logging to cloud and synchronization of learning data between agents. Logs will be kept locally in a configurable, cyclic buffer and be relayed when communication resumes. It also possible to configure logging to a local syslog server.
{% endhint %}

### Agent Main Components

Agent's main components are detailed in the following diagram and explained below:

![](/files/kDagt0Y0dWmPICXCjzpZ)

#### Attachment&#x20;

The Attachment connects between processes that provide HTTP data and the open-appsec security logic.&#x20;

The most common attachment is for NGINX (or open-resty, which is based on NGINX, also used by e.g. Kong gateway). It is a small dynamically loadable module that runs in the process space of NGINX acting as Web Server, Reverse proxy, Kubernetes ingress or API gateway. The Attachment gets HTTP data (URL, Header, Body, Response) from the hosting process and delivers it to the **HTTP Transaction handler**. The attachment does not keep any state and has no security logic.&#x20;

To deal with potential issues where the HTTP Transaction handler is not responding, the Attachment implements a retry mechanism and a configurable fail-open/fail-close mechanism.

It is also possible to order the Attachment to ignore specific IP addresses or ranges, which allows for a controlled, gradual deployment. See more details below.

#### HTTP Transaction handler nano-service

A process (or multiple instances, depending on load) that gets data for processing from the **Attachment**, executes open-appsec security logic, returns a verdict and issues relevant logs.

#### Orchestrator

A process in charge of agent registration, obtaining policy updates, software updates and other administrative operations.

#### Watchdog

A process in charge of making sure that all components are up and running.

## Deployment vehicles

open-appsec provides multiple deployment vehicles. All of them include the same agent technology:

{% hint style="info" %}
Currently, open-appsec supports NGINX, APISIX and Kong Gateway on Kubernetes, Linux and Docker platforms. Additional integrations will follow soon after.
{% endhint %}

#### Kubernetes Ingress Controller

* Helm chart for NGINX Ingress Controller (enhanced with open-appsec)
* Kubernetes Ingress Controller pod (based on the Ingress-NGINX Controller)
* open-appsec Agent (as sidecar container in the Ingress Controller pod)

#### Kubernetes Kong Gateway

* Helm chart for Kong (enhanced with open-appsec)
* Kong pod (containing Kong Gateway container and optionally Kong Controller container)
* open-appsec Agent (as sidecar container in the Kong pod)

#### Kubernetes APISIXGateway

* Helm chart for APISIX (enhanced with open-appsec)
* APISIX pod (containing APISIX Gateway container and optionally APISIX Controller container)
* open-appsec Agent (as sidecar container in the APISIX pod)

#### Container setup (e.g. on Docker)

Includes two containers that communicate with each other

* NGINX, Kong, APISIX, Envoy, NGINX Proxy Manager, SWAG (include open-appsec Attachment)
* open-appsec Agent

#### Linux NGINX

An agent installation script for environments that are already running NGINX or Kong on Linux, which installs:

* open-appsec attachment for NGINX, APISIX or Kong
* open-appsec Agent

{% hint style="success" %}
We encourage and provide assistance to anyone that wishes to develop their own Attachments and deployment vehicles.
{% endhint %}

## Secure Communication

Agents/Gateways communicate with the Fog over encrypted and authenticated secure channel.

* Agent/Gateway is using encrypted communication over HTTP/TLS (Port 443).
* One time agent registration is done using a 256bit key.
* The Agent/Gateway receives a unique agent key from the Fog that is used for identification.
* Authentication is based on OAuth 2.0 (RFC 6479).
* The agent periodically asks for an updated JSON Web Token (JWT).

{% hint style="info" %}
List of URLs of Check Point operated public Fog, make sure to have outbound communication allowed from your agent:

* <https://inext-agents.cloud.ngen.checkpoint.com>
* <https://downloads.openappsec.io>
  {% endhint %}

## Profiles

Agents are associated with a Profile that simplifies management and allows applying the same settings to multiple agents. When you create the first Web Application or Web API asset using the Wizard, a Profile is automatically created. You can later re-use this profile or create a new one.

Profiles determine the following shared settings:

* Type of deployment:
  * Kubernetes
  * Linux
  * Docker
* Registration Token for new Agents
* Agent upgrade Mode: Automatic, Scheduled, Manual
* SSL and Private Keys storage mode: On Gateway, in Public Cloud secure storage
* Advanced settings such as max number of agents that can connect to a profile

It is possible to delete an agent so that it will no longer be able to connect to the Fog.

{% hint style="info" %}
The best-practice recommendation is to create an individual profile in the WebUI for each of your open-appsec deployments. Examples for "deployments" would be e.g.:

\
\- K8s deployment using HELM or installation tool (consisting of one or multiple open-appsec agents)\
\- redundant deployment using Docker on two or more virtual machines (each having it's own agent) protecting the same web assets \
\- redundant embedded deployment on one or multiple redundant Linux machines protecting the same web assets \
\
Security-wise this makes sure that only policies for those assets which are protected by specific agents are enforced on those agents (by linking the Assets to only the relevant profile(s)), in addition to having a separate tokens per each deployment and all associated agents.\
In addition this approach provides the flexibility of being able to configure various settings available on profile-level individually per each deployment, if required.
{% endhint %}


# Management & Automation

open-appsec provides Enterprise grade SaaS management including ability to group changes and apply them together, ability for multiple admins to work in parallel with a sophisticated locking mechanism, audit-logs, undo/redo and other. Administration can be done using Web User Interface, GraphQL API or Infrastructure-as-code via Terraform.

## Sessions&#x20;

open-appsec management allows admins to make multiple changes, review them and then either Enforce them altogether or make them available to other administrators.&#x20;

When an administrator logs-in and upon API authentication, a new session starts. The changes that the administrator makes during the session are only available to that administrator. Other administrators see a lock icon on object and rules that are being edited. The changes are saved automatically. There is no need to manually save.

### Publish and Enforce

To make your changes available to other administrators, and to save the database before enforcing a policy, you must publish the session. When you publish a session, a new database version is created. You can do this by clicking **Publish** within the Quick Actions menu (top left corner, click on open-appsec logo). Before you publish the session, you can add some informative attributes to it.

<figure><img src="/files/cnsdcLUlCtvZRRW6MeVJ" alt=""><figcaption></figcaption></figure>

When you click the **Enforce** button at the top right menu, you also are prompted to publish all unpublished changes in the current session. You cannot enforce a policy if the included changes in the session are not published. Unpublished changes from other sessions will not be included in the policy installation.

<figure><img src="/files/UhaFh722cHk1I0JyZDif" alt=""><figcaption></figcaption></figure>

![](/files/yDmLGaDGHH2htfG9cuwm)

There is no need to save changes when working on a session. Changes are saved automatically. You can also log-out without publishing your changes from the session. You will see the changes next time you log in.

### Discard

It is possible to discard all changes in a session, by clicking **Discard** in the Quick Actions menu. You can discard all changes (made in other sessions as well) by clicking **Discard All Sessions**.

<figure><img src="/files/24QVSivxP524nLtesfbt" alt=""><figcaption></figcaption></figure>

### Undo/Redo&#x20;

It is possible to Undo/Redo any change until you publish a session by clicking **Undo** or **Redo** in the top right of the portal.

<figure><img src="/files/MvPUcnFnr4DW2bbUuG6z" alt=""><figcaption></figcaption></figure>

## Audit Logs

The system creates automatically an audit log for any configuration change. The log contains the details of the change, administrator and time stamp.

You can view the Audit Logs in the **Monitoring** section.

![](/files/4qc5HlXxYLf6CqtjD9jF)

## Automation & APIs

open-appsec provides two automation methods: GraphQL API and Infrastructure-as-code using Terraform. Both allow to Create, Read, Update or Delete any object in the system.

### Main Objects&#x20;

To do any kind of automation it is important to understand the main objects in open-appsec and their relations. The root objects are always Assets. Assets can refer to other objects according to the following hierarchy:

![](/files/2maufB5KLN8EWa5mrlK4)

* Asset - Web Application asset that you wish to protect
* Asset Behaviors - Trusted Sources used by the Machine Learning Engine
* Profile - defines shared settings of agents
* Practices - Web Application Protection Practice
* Triggers - Logging settings
* Behaviors - Web User Response and Exceptions

### GraphQL API

open-appsec provides a collection of GraphQL APIs that allows to Authenticate, Create, Read, Update or Delete any object in the system as well as Publish or Enforce a set of changes. &#x20;

GraphQL is a strongly typed API query language. It allows clients to define the structure of the data required, and exactly the same structure of the data is returned from the server. This avoids both the problems of over and under-fetching data, while also allowing for a powerful and flexible API.

See here more about the API: (available soon)

{% hint style="info" %}
To learn more about GraphQL see [here](https://graphql.org/learn/)
{% endhint %}

### Infrastructure-as-code using Terraform (Available soon)

Provisioning and managing infrastructure is a critical task in DevOps. To accomplish this, modern practices rely on Infrastructure as Code (IaC). By storing your infrastructure configuration in version control systems, you can standardize configuration across your organization, and simplify infrastructure updates.&#x20;

The open-appsec Terraform provider allows configuration of all aspects of open-appsec using HCL Infrastructure as Code (IaC).

Terraform uses the concept of Providers to provide an open source feature-rich plugin system. Providers adopt specific conventions programmatically that allow them to express the CRUD lifecycle of individual resources and how to maintain and verify the state of existing deployed resources.


# Security Practices

open-appsec provides security Practices that can be easily activated in Detect/Learn mode or Prevent Mode.

The practices use multiple security engines to analyze HTTP web requests and to deliver accurate verdict whether the request is malicious or benign. The engines protect applications and APIs against unknown and advanced web attacks, validate the input of APIs, distinguish humans from bots and protects against industry's well known attacks and CVEs.

## open-appsec Security Practices

* Web Attacks Protection Practice
  * Contextual Machine Learning based-WAF
  * Snort Signatures&#x20;
  * Intrusion Prevention (requires Check Point WAF or open-appsec Premium Edition \[deprecated])
  * File Security (requires Check Point WAF or open-appsec Premium Edition \[deprecated])&#x20;
* API Protection Practice
  * Schema Validation module ensure that API requests adhere to API schema (requires Check Point WAF Premium Edition or open-appsec Premium Edition \[deprecated])
* Anti Bot
  * Anti-Bot Protection (requires Check Point WAF or open-appsec Premium Edition \[deprecated])&#x20;
* Rate Limit&#x20;

## Security Engines

### Contextual Machine Learning-based WA&#x46;**: Prevent OWASP Top 10 and Advanced Attacks**

This patented engine protect against advanced and zero-day web attacks. It executes a three-stage HTTP web request analysis and delivers an accurate verdict. It uses [Contextual Machine Learning](/concepts/contextual-machine-learning) to identify if a web request is malicious or benign and provides:

1. Significantly reduced false-positive rate than traditional WAF (in traditional WAF decisions are mainly based on matches to signatures).
2. Provides zero-day protection by blocking different attack scenarios that are not blocked with a signature-only approach. For example, Log4Shell and Spring4Shell were blocked by open-appsec ML technology preemptively, without any software update.
3. Reduction in administration time because it is not constantly necessary to tune the engine, create exceptions, disable signatures, and more.

Learn more about the  [Contextual Machine Learning](/concepts/contextual-machine-learning) engines in the next section of this documentation.

### API Security: Validate Schema and Prevent Attacks

Frequently, software developers do not include verification of API input in their code.

The open-appsec API security component provides two protection models: positive and negative. Administrators can enable one of them, or the two of them.

* The **positive model** delivers preemptive protection for possible API vulnerabilities through a schema validation procedure.

  API schemas in OpenAPI (such as used in "Swagger") are uploaded to open-appsec.

  Incoming API requests are validated against these schemas to block all invalid API requests (requires Check Point WAF or open-appsec Premium Edition \[deprecated]).

{% hint style="info" %}
open-appsec supports OpenAPI Schemas V3 and above.
{% endhint %}

* The **negative model** uses the WAF and automatically detects and blocks malicious payloads in the API (included in all editions).

### **Anti-Bot Protection: Distinguish Humans from Bots**

appsec-open Anti-Bot protection component (requires Check Point WAF or open-appsec Premium Edition \[deprecated]) performs a three-step procedure:

1. Inject scripts into web application pages, such as login pages.
2. Collect data about input patterns and canalize key stroke sequences, mouse moves, and finger touches.

   Bots do not use such patterns. If a bot artificially creates such patterns, open-appsec identifies them.
3. Make a decision if the input is entered by a human or by an automatic script (such as a bot), and block this activity.

### **Intrusion Prevention (IPS) for HTTP/S**

In addition to the Contextual Machine-Learning based engine, open-appsec provides traditional signature-based protections for over 2800 web-based CVEs (Common Vulnerabilities and Exposures). One of the benefit of these signatures is the ability to see logs that indicate specific CVE number.

### File Security

Files being uploaded to the web server may contain malicious content. CloudGuard AppSec's File security contains several engines that allow detection of those malicious files.

### Custom Signatures (Snort Engine)

Admins can add also signatures in Snort format and they will be enforced by open-appsec Security Engines.

### Rate Limit

open-appsec agents can limit the number of requests to a matched URI within a configured time scope, according to the source identifier.&#x20;


# Contextual Machine Learning

open-appsec uses a Patented Contextual Machine Learning Engine that utilizes a three-phase approach for detecting and preventing web application and API attacks. In this section you will understand how these three phases deliver accurate results with a very low amount of false positives and how they protect the environment against known and unknown zero-day attacks with real-time protection.

![](/files/BVm9zz2irqR9tjbt4Hap)

## **Phase 1 – Payload Decoding**

Effective machine learning requires a deep understanding of the underlying application protocols which is continuously evolving. The engine analyzes all fields of the HTTP request including the URLs, HTTP headers, which are critical in this case, JSON/XML extraction and payload normalization such as base64 and other decoding's. A set of parsers covering common protocols feeds the relevant data into phase 2.

For example, in the case of Log4Shell attacks, some exploit attempts were using base64 and escaping encoding so it was possible to pass a space character for applying parameters.&#x20;

## **Phase 2 – Attack Indicators**

Following parsing and normalization, the network payload input is fed into a high-performance engine which is looking for attack indicators. An attack indicator is a pattern of exploiting vulnerabilities from various families. We derive these attack patterns based on on-going off-line supervised learning of huge number of payloads that are each assigned a score according to the likelihood of being benign or malicious. This score represents the confidence level that this pattern is part of an attack. Since combinations of these patterns can provide a better indication for an attack a score is also calculated for the combination of patterns.

For example, in the case of Log4Shell and Spring4Shell attacks, open-appsec used several indicators from Command Injection / Remote Code Execution / Probing families that signaled payloads to be malicious in a very high score which was enough on its own, but to ensure accuracy and avoidance of false positives, the engine always moves to the third and last phase.<br>

## **Phase 3 – Contextual Evaluation Engine**

This contextual engine is using machine learning techniques to make a final determination whether the payload is malicious, in the context of a specific customer/environment, user, URL and field that in a weighted function sums up to a confidence score. If the score is larger than the threshold the request is dropped.

These are the factors that are considered by the engine:

#### *Reputation factor*

In each request, the request originator is assigned a score. The score represents the originator’s reputation based on previous requests. This score is normalized and used to increase or decrease the confidence score.

#### *Application awareness*

Often modern applications allow users to modify web pages, upload scripts, use elaborate query search syntax, etc. These provide a better user experience but without application awareness, these are detected as malicious attacks. We use ML to analyze and baseline the underlying application’s behavior.

#### *Learn user input format*

The system can identify special user input types that are known to cause false detection and apply ML to modify our detection process and allow legitimate behavior without compromising attack detection.

#### *False detection factor*

If there is an inconsistency in detection a factor is applied to the confidence score based on the reputation factor per detection location.

#### *Supervised learning module*

Optional module that shows administrators payload and ask them to classify them thus accelerating the learning process.

## Additional Information

For further information on open-appsec's machine learning see also:

{% content-ref url="/pages/mKsRQYz4wJpG9drvO9pG" %}
[Configure Contextual Machine Learning for Best Accuracy](/how-to/configuration-and-learning/configure-contextual-machine-learning-for-best-accuracy)
{% endcontent-ref %}

{% content-ref url="/pages/hL9P2lcN6vILXJVps4bZ" %}
[Track Learning and Move From Learn/Detect to Prevent](/how-to/configuration-and-learning/track-learning-and-move-from-learn-detect-to-prevent)
{% endcontent-ref %}


# Setup Web Application Settings

Configuring [Web Application security](/getting-started/using-the-web-ui-saas/protect-additional-assets)  is easily done by configuring the relevant asset using its basic details, and in the vast majority of the cases, is enough to protect the web assets without additional manual changes.

There are, however, advanced options that a security administrator can configure to modify the security to his specific requirements.

## Web Application Protection Advanced Settings

### Web Attacks Settings

Browse to **Assets**, edit the web application asset object you have created and click on the "**Web Attacks**" Tab and look at the "**Web Attacks**" sub-practice configuration.

<figure><img src="/files/4JgMSh5AteQWxxKzCViB" alt=""><figcaption></figcaption></figure>

### Configuration Options

#### Mode override

Setting the Mode to **As Top Level** means inheriting the primary mode of the practice.

Otherwise you can override it only for this specific sub-practice to **Detect**/**Prevent**/**Disable**.

#### Confidence-dependent Prevent Mode

The option **Activate when confidence is** becomes available if practice or sub-practice are set to **Prevent**. The value determines the threshold in which open-appsec will block attacks and prevent them, rather than just send a log according to Log Trigger configuration.

<div align="left"><img src="/files/5BBBhWXfxVnre1WKsbU2" alt=""></div>

#### Advanced settings window

When clicking on **Advanced** additional advanced settings appear:

<div align="left"><img src="/files/zdmERIz2fuZPG4PphwnU" alt=""></div>

For all Size Limits - open-appsec Web Attacks engine will accept traffic that exceeds the limits if set to **Detect/Learn** mode (and that traffic will bypass inspection), or block traffic that exceeds the limits if set to **Prevent** mode.

<table><thead><tr><th width="150">Advanced Setting</th><th>Meaning</th></tr></thead><tbody><tr><td>URL Size (Bytes)</td><td>Determines the URL size limit for inspection</td></tr><tr><td>Max Object Depth</td><td>Determines the depth limit of a JSON/XML object inspected in the HTTP request. This includes embedded XML in JSON and the opposite.</td></tr><tr><td>Body Size (Kilobytes)</td><td>Determines the HTTP body size limit for inspection</td></tr><tr><td>Header Size (Bytes)</td><td>Determines the HTTP header size limit for inspection</td></tr><tr><td>CSRF Protection</td><td>Determines the mode for the advanced CSRF protection, which blocks <a href="https://owasp.org/www-community/attacks/csrf">CSRF attacks</a>. <br><strong>Important</strong> - This protection has a performance impact.</td></tr><tr><td>Error Disclosure</td><td>Determines the mode for the advanced Error Disclosure protection, which replaces <a href="https://owasp.org/www-community/Improper_Error_Handling">internal error codes in the response</a> and injects a different response instead.<br><strong>Important</strong> - This protection has a performance impact.</td></tr><tr><td>Open Redirect</td><td>Determines the mode for the advanced Open Redirect protection, which prevents<a href="https://owasp.org/www-project-web-security-testing-guide/v41/4-Web_Application_Security_Testing/11-Client_Side_Testing/04-Testing_for_Client_Side_URL_Redirect"> client side redirection to other domains</a> (e.g. as used by Phishing attacks)<br><strong>Important</strong> - This protection has a performance impact.</td></tr><tr><td>Non-Valid HTTP methods</td><td><p>When set to <strong>No</strong> and practice is set to <strong>Prevent</strong>, non-valid HTTP methods are blocked.<br>Valid HTTP methods are:</p><ul><li>GET, POST, DELETE, PATCH, PUT, CONNECT, OPTIONS, HEAD, TRACE</li><li>MKCOL, COPY, MOVE, PROPFIND, PROPPATCH, LOCK, UNLOCK, VERSION-CONTROL, REPORT, INDEX, CHECKOUT, CHECKIN, UNCHECK, MKWORKSPACE, UPDATE, LABEL, MERGE, BASELINE-CONTROL, MKACTIVITY, ORDERPATCH, ACL, SEARCH, MKREDIRECTREF, BIND, UNBIND</li></ul></td></tr></tbody></table>

## Additional Security Engines

open-appsec includes additional security engines other in addition to the Machine Learning based-Web Attacks protection and API attacks protection:

{% content-ref url="/pages/SDQdQL2KlKAGZhmPkMBX" %}
[Anti-Bot](/additional-security-engines/anti-bot)
{% endcontent-ref %}

{% content-ref url="/pages/7dNevGhg9MFNjuwdoFQb" %}
[API Schema Enforcement](/additional-security-engines/api-schema-enforcement)
{% endcontent-ref %}

{% content-ref url="/pages/cuQaC6rolRXweR5lurW8" %}
[Intrusion Prevention System (IPS)](/additional-security-engines/intrusion-prevention-system-ips)
{% endcontent-ref %}

{% content-ref url="/pages/JVtYvEmf7s5B7UvWAbTL" %}
[Import Snort Rules](/snort-rules/import-snort-rules)
{% endcontent-ref %}

{% content-ref url="/pages/ElltJEfJsBM6lNFM3nOw" %}
[Rate Limit](/additional-security-engines/rate-limit)
{% endcontent-ref %}


# Setup Custom Rules and Exceptions

Configuring [Web Application security](/getting-started/using-the-web-ui-saas/protect-additional-assets) is easily done via the configuration wizard, and in the vast majority of the cases, is enough to fully protect the web assets without additional manual changes.

However, as event logs appear, a security administrator might want to make specific exceptions to the default behavior of the system, regardless of the [automatic learning mechanism](/how-to/configuration-and-learning/configure-contextual-machine-learning-for-best-accuracy).

## Configuring Exceptions Upon Log

The most common use case of exception configuration is when a log is issued and as a security administrator decided that traffic matching one of the log fields (for example, the URI field) should not be detected or blocked by the open-appsec engine.

#### Step 1: From the events view, perform a "Right Click" on the relevant parameter in the log according to which the exclusion should occur and select "Add Exception"

![](/files/fvRoISzqK7WmBiE1n94i)

#### Step 2: Review the exception details and click OK

<figure><img src="/files/1d6dpd8eS70Nwuo43N67" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
A common change might be to generalize the exception to all sources by deleting the condition for "**Source Identifier**", or to change the action from "Skip" (relevant only for the "Matched Parameter" field) to "Accept".
{% endhint %}

{% hint style="info" %}
An exception configured this way applies to the combination of the specific open-appsec security practice that caught the original event and the Asset relevant for the same traffic.
{% endhint %}

For further information on how to configure exceptions from asset view and the full options an exception can provide, please read further.

## Possible actions for exception rules

* **Accept** - Traffic matching the exception's conditions will be accepted.
* **Drop** - Traffic matching the exception's conditions will be blocked.
* **Skip** - Relevant only for specific keys like "Parameter Name", "Parameter Value" and "Indicator. Allows skipping the value of the matching parameter from being inspected by the AppSec engines. \
  The rest of the traffic will be inspected for malicious behavior.
* **Suppress Log** - Traffic matching the exception's condition will not activate their Log Trigger object/s upon event.

## Possible conditions for exception rules

### Keys

There are several keys allowed to be set in exceptions rules, each of them may be relevant to a different security practice or sub-practice.

{% hint style="warning" %}
**IPS Exceptions Scope**\
Exceptions for requests that are **blocked or detected by IPS** are evaluated **only** against the following attributes:

* `protectionName` – The name of the signature
* `hostName` – The HTTP host name (if available)
* `sourceIP` – The client IP address (if available)
* `url` – The HTTP decoded path (if available)
* `sourceIdentifier` – The source identifier (if available)

Any additional attributes defined in an exception (for example, **HTTP method**) are **not supported** for IPS and are ignored.\
As a result, a request may still be blocked by IPS even if an exception is defined using unsupported fields.
{% endhint %}

For open-appsec:

<table><thead><tr><th width="150">Exception Key</th><th width="249.33951599538526">Value String Search Location</th><th width="150">Relevant for Skip Action</th><th>Relevant Practices</th></tr></thead><tbody><tr><td>Host</td><td>Regular expression of the HTTP Host name</td><td>No</td><td>All open-appsec Security (not including IPS)</td></tr><tr><td>URI</td><td>HTTP full URI in request</td><td>No</td><td>All open-appsec Security</td></tr><tr><td>Source Identifier</td><td>Regular Expression the identifier, according to the definition of <a href="/pages/mKsRQYz4wJpG9drvO9pG">Source Identifier in the Asset's configuration</a></td><td>No</td><td>All open-appsec Security</td></tr><tr><td>Source IP</td><td>IP address of the request's source in IP address or CIDR format (e.g. "&#x3C;IP address>/&#x3C;number of bits for network>")</td><td>No</td><td>All open-appsec Security</td></tr><tr><td>Parameter Name</td><td>Regular Expression of a parameter name is a key in the HTTP request body's XML or JSON file</td><td>Yes</td><td>Web and API attacks, and Schema Validation</td></tr><tr><td>Parameter Value</td><td>Regular Expression of a parameter value is the value to a key in the HTTP request body's XML or JSON file</td><td>Yes</td><td>Web and API attacks, and Schema Validation</td></tr><tr><td>Parameter Location</td><td>A value that matches the "Matched Location" field values in a the open-appsec Log (e.g. "body", "cookie", "url", etc.)</td><td>Yes</td><td>Web and API attacks</td></tr><tr><td>Indicator</td><td>Regular expression of indicator/s to be be used with the "Skip" action. Allows exclusion of desired indicators while continuing to provide security for all other traffic.</td><td>Yes</td><td>Web and API attacks</td></tr><tr><td>Protection Name</td><td>The protection name used by the security sub-practice</td><td>No</td><td>IPS and Snort Rules only</td></tr><tr><td>Country Code</td><td>Country is resolved according to the source IP address. Code is the recommended use for country-based exceptions and can be searched <a href="https://www.iso.org/obp/ui/#home">here</a> according to the <strong>Alpha-2 code</strong> of ISO-3166.</td><td>No</td><td>All open-appsec Security (not including IPS)</td></tr><tr><td>Country Name</td><td>Country is resolved according to the source IP address. Name is less recommended for country-based exceptions, but is more readable. Exact names can be searched <a href="https://www.iso.org/obp/ui/#home">here</a> according to ISO-3166.</td><td>No</td><td>All open-appsec Security (not including IPS)</td></tr><tr><td>File Hash</td><td>SHA-256 string of the file the exception should apply to.</td><td>No</td><td>File Security only</td></tr><tr><td>File Name</td><td>The file name to match the configured exception.</td><td>No</td><td>File Security only</td></tr><tr><td>Response Body<br><br><strong>Note</strong> - Scanning response traffic adds a performance impact.</td><td>Regular expression of a pattern within the HTTP Response Body</td><td>No</td><td>All AppSec Security. In addition, this key allows <a href="/pages/m8KzoNY4dOeiqv1vMHNJ">adding manually Data Loss Prevention (DLP) rules</a>.</td></tr><tr><td>Header Value</td><td>Regular expression of the HTTP header value</td><td>Not on its own</td><td>All open-appsec Security (not including IPS)</td></tr><tr><td>Header Name</td><td>Regular expression of the HTTP header name</td><td>Not on its own</td><td>All All open-appsec Security (not including IPS)-appsec Security</td></tr></tbody></table>

### Regular Expression Values

{% hint style="warning" %}
The following is only relevant for keys where the table states their value is a regular expression.
{% endhint %}

When an exception key expects a regular expression value (regex), it should be configured according to [PCRE 2.0](https://www.pcre.org/current/doc/html/), which will undergo a partial search unless the '^' or '$' regular expression operators are used.

For a nicer tutorial about PCRE regular expression crafting, visit [here](https://learnxinyminutes.com/docs/pcre/).

### Operators

A complex logical expression with "**AND**" and "**OR**" between conditions can be created.

In addition - the following operators are available for each condition:

* **Equals**
* **Not Equals**
* **Key Exists**

## View And Configure Exceptions In Assets

### Configuring exceptions

#### Step 1: Browse to Assets, edit an existing asset and click on the "Custom Rules and Exceptions" tab

<figure><img src="/files/UGGvCZBdzdYydJ4DNu6P" alt=""><figcaption></figcaption></figure>

#### Step 2: Click to add a new exception

<figure><img src="/files/up15RhcLKSy0EEgrUicr" alt=""><figcaption></figcaption></figure>

#### Step 3: Create the exclusion according to the options described in this page

When clicking the 3 dotted lines you will see the logical operators available for multiple conditions:

<div align="left"><img src="/files/06j69212OE7FBxg72yYl" alt=""></div>

When clicking on the ':' between key and value you will see the additional value-based operators for a single condition:

<figure><img src="/files/2mzTh5XRBgAUdWi7LO7H" alt=""><figcaption></figcaption></figure>

Add a comment for view purposes and click OK.

### Viewing Exceptions

When exceptions are configured, the same location in the asset provides a view of the exceptions for the practice used by the asset. The view shows the comment and the last administrator that edited the exception:

<figure><img src="/files/VzMv0ScuRmZqU0Uh6UT3" alt=""><figcaption></figcaption></figure>

## Save Exception for Reuse In Additional Assets/Practices

It is possible to save a group of exception rules under a global name, and then use the same object by multiple assets and practices.

### Configure an Existing Exception as Global

#### Step 1: Click on the 3 dots in the top right corner of the exceptions view

<figure><img src="/files/kJnvR9limdoO5KrRYVsd" alt=""><figcaption></figcaption></figure>

#### Step 2: Click Save and give a name to the new global "Exceptions" object

<div align="left"><img src="/files/NDX6JMvH3ceXuLiZr7mW" alt=""></div>

#### Step 3: In additional assets you can now click "Load" in the same location and select an existing "Custom Rules and Exceptions" object

<figure><img src="/files/7MFOe1Hjqa9DWW5KAK5C" alt=""><figcaption></figcaption></figure>

### View and Manage Global Exceptions Objects

The global exceptions objects can be viewed and edited under **Behaviors**:

<figure><img src="/files/caFxxKiGXuyhsZntc2Ia" alt=""><figcaption></figcaption></figure>


# Setup Web User Response Pages

open-appsec protects web servers from attacks when set to **Prevent** mode. It is possible to determine the response returned to the client who initiated the blocked traffic. The response can be a simple HTTP error code, an HTTP redirect message, or a Block page that a user can view in their browser.

## Setup a Web User Response Object

#### Step 1: Go to Behaviors and create a new Web User Response

If no behavior objects were configured yet you will see the following screen:

![](/files/OFjohEIaeafk6BCMctDE)

Alternatively the following screen with a "New" button at the top is shown:

![](/files/5pDkkDydPGDuQ8RgqQ0d)

#### Step 2: Select the type of the Web User Response and fill the form

Create a unique name for your Web User Response object and select a Type.

There are 3 types of Web User Response objects:

{% tabs %}
{% tab title="Block Page" %}
This option is not a recommended option for CloudGuard AppSec protecting Web API assets as it is designed to be seen by human users.

![](/files/bwOBwFB16nVK2l3nnpNX)

* **Message title:** The title of the web page to be shown to the user sending the malicious traffic
* **Message body:** The Body of the message to be shown to the user.
* **HTTP Response Code:** It is recommended to use a 403 (Forbidden) as a response code.

{% hint style="info" %}
Different browsers behave differently upon receiving different error codes.
{% endhint %}

{% hint style="info" %}
Using the Response code 444 will in fact reset the connection and the Message title and body will not be seen by the user.
{% endhint %}
{% endtab %}

{% tab title="Redirect" %}
![](/files/gwA5M1IExoLpkyz1IrF9)

* **Redirect URL:** the client will be redirected to the provided URL where you can provide any customized web page.
* **Add X-Event-Id to header**: When selected the redirect message will include this header with a value that provides an internal reference ID that will match a security log generated by the incident, if log triggers are configured.
  {% endtab %}

{% tab title="Response Code Only" %}
This option is recommended for open-appsec protecting Web API assets.

![](/files/ybtdBkXkoqLPiJfugNoe)

* **HTTP Response Code:** It is recommended to use a 403 (Forbidden) as a response code.

  <div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p>Different clients may behave differently upon receiving different error codes.</p></div>

{% endtab %}
{% endtabs %}

## Configure your AppSec practice to use the new Web User Response

#### Step 1: Select the assets you wish to use this Web User Response upon event detection

Go to **Assets** and edit the asset you wish to modify.

Select the **Web Attacks** tab and scroll to the bottom.

<figure><img src="/files/HcU7Ndvp3tTubf0iihYp" alt=""><figcaption></figcaption></figure>

#### Step 2: Select the Web User Response object

Once selected, you will see the object shown as part of the AppSec Security Practice configuration:

<div align="left"><img src="/files/RDkw5FsTo5LazcnNSuLV" alt=""></div>

#### Step 3: Enforce Policy

Policy is enforced after clicking Enforce above the top banner of the portal.


# Setup Log Triggers

appsec-open protects web servers from attacks. It is possible to trigger a logging event that includes information about the event that was detected or prevented.&#x20;

Logs can be configured to reach a variety of destinations.

## The Default Log Trigger

The default setup of appsec-open is already configured with a log trigger, and so, to view logs triggered by open-appsec event detection, no additional action is required.<br>

![](/files/81aHKIwhlLb7WYeZ7EJ8)

The default Log Trigger object is configured to log the most interesting events:

* Malicious events.
* High severity (and above) suspicious events.
* Most important identifying data from the request.
* Events are sent to open-appsec AppSec cloud to be visible in the [events views and dashboards](/getting-started/using-the-web-ui-saas/monitor-events).

{% hint style="info" %}
The configuration of the default Log Trigger object can be altered, but the object cannot be deleted.

If the default configuration has been altered, it is possible to click "**RESET TO DEFAULT VALUES**" at the bottom of the edit window to return to the default factory settings of this object as defined by Check Point.
{% endhint %}

## Customizing Log Triggers

#### Step 1: Create a new Log Trigger object

In the **Quick Actions** menu select **New Trigger.**

![](/files/nsv6VsFeZa6B9eizlLm8)

![](/files/ltkURx5hlmGwQGuZ15vU)

Configure a new name to the new trigger object:

![](/files/ChFNmMJsnJDVkthmUPlY)

#### Step 2: Configure Trigger conditions ("When to Log")

<div align="left"><img src="/files/k8p4cFmwaPiHCcOeWsYA" alt=""></div>

Select the conditions in which logs are issued:

* Detect/Prevent Events - Logs events caught by appsec-open engines in "Detect" mode or blocked by appsec-open engines in "Prevent" mode in addition to blocking.

{% hint style="info" %}
If configuration in appsec-open is set to "Detect" mode, Log Trigger configuration is the only action appsec-open will take upon detecting an attack.
{% endhint %}

* Logging all web requests regardless of appsec-open configuration.

{% hint style="danger" %}
Logging all web requests has a substantial impact on resources and network bandwidth consumed by appsec-open.
{% endhint %}

#### Step 3: Configure Trigger additional content ("What to Log")

Select the additional data you want to appear in the log sent upon event.

<div align="left"><img src="/files/RGw9idOsr0KDP4t0aohX" alt=""></div>

**Additional logging for suspicious events from Severity "X"** - Allows conditionally adding the Response Body and Response Code to logs according to the severity of the event reported.

{% hint style="warning" %}
**Limitations on Response Code Logging**

* **Response code reflects the upstream server only.**\
  When a request is **blocked by the agent**, there is **no upstream response**, and therefore **no response code is logged**.
  * The response code is determind by the Web User Response
* **Extended logging (including response code and response body) is only active for events with severity&#x20;*****High*****&#x20;and above.**\
  Requests evaluated with a **lower severity** will **not** include response-related information in the logs.
* **If your policy is set to&#x20;*****Prevent High*****, response information will never be logged.**\
  This is because blocked events at High severity do not reach the upstream server, so no response code exists, and extended logging does not apply to lower-severity events.
  {% endhint %}

{% hint style="danger" %}
Adding Request Body and Response Body to logs has the potential of substantially impacting the resources and network bandwidth consumed by CloudGuard AppSec, depending on the traffic.\
For this reason:

* The response body is conditional to the severity of the suspicious event.
* Either body content will not appear in the log if AppSec blocked the request prior to reading their values (for example, upon blocking a request based on its URL).\
  In the case of response body, it will be logged only if the action is set to "Detect" and not "Prevent" as no response will ever arrive, if the request is blocked.
  {% endhint %}

#### Step 4: Configure Trigger destination ("Where to send the Log")

This configuration determines the destination of the logs sent from the AppSec agent, and multiple options can be selected.

The trigger destination can be:

<div align="left"><figure><img src="/files/CPsnf7APJ8bZqy0knyh4" alt=""><figcaption></figcaption></figure></div>

* Cloud - appsec-open Cloud, to be viewed by the appsec-open Application [event views under Monitoring](/getting-started/using-the-web-ui-saas/monitor-events).
* Gateway/agent - Logging will be saved locally when possible in the folder ***/var/log/nano\_agent***.
* Syslog service and/or CEF service - Log to an external Syslog/CEF service by adding:
  * A destination address
  * Port (Usually 514 in both cases)
  * Either selecting UDP (common for syslog) or TCP (common for CEF).&#x20;

<div align="left"><figure><img src="/files/4waO24lobLU1RNrXf4pS" alt=""><figcaption></figcaption></figure></div>

#### Step 5: Setup your security practice to use the new Log Trigger object/s

Browse to Cloud->Assets and edit the asset you wish to modify.

Go to each of the practices tabs and scroll to the bottom.

Click on the '**+**' icon next to **Triggers** and add your new Log Trigger object.

<figure><img src="/files/as334eZ3bSevEKd1F7Up" alt=""><figcaption></figcaption></figure>

## Logs structure to Syslog/CEF <a href="#logs-structure-to-syslog-cef" id="logs-structure-to-syslog-cef"></a>

### Syslog <a href="#syslog" id="syslog"></a>

Syslog protocol is defined by [RFC 5242](https://datatracker.ietf.org/doc/html/rfc5424). The structure starts with a priority value in '<>' followed by a timestamp of the log. The agent will also send a value in the syslog header for:

* Host name - indicating the host name where the agent is installed
* Application name - indicating the nano-service issuing the log.

Following the syslog header there are space delimited key value pairs in the structure of `keyname='value'`.The possible keys and description can be seen in the [Events/Logs Schema](/references/events-logs-schema) documentation page.

<details>

<summary>Syslog Example</summary>

`<133>1 2022-05-17T05:55:37.623Z cpnano-agent-915faaab-6a40-4b55-be93-872e911397c0 HTTPTransactionHandler - 5 - title='API Request' agentId='915faaab-6a40-4b55-be93-872e911397c0' issuingEngineVersion='1.2228.372599' serviceName='HTTP Transaction Handler' eventReferenceId='eff9c697-d689-46c8-b702-87c92c728164' eventConfidence='Very High' matchedParameter='[readingValue]' matchedSample='[-45]' matchReason='[Value is lower than the minimum allowed value: -45 < 1.000000]' sourceIP='192.168.154.1' httpSourceId='192.168.154.1' sourcePort='64758' httpHostName='192.168.154.129:8080' httpMethod='POST' httpUriPath='/myApp/setParam' httpUriQuery='' ruleId='d8c0fda7-2ad1-e7ab-32bc-d1a6af6a2ca0' securityAction='Prevent' waapOverride='None' practiceType='Threat Prevention' practiceSubType='Web API' assetId='d8c0fda7-2ad1-e7ab-32bc-d1a6af6a2ca0' assetName='Customer Portal' practiceId='08c0fdac-3295-e034-be39-5ab4c2d11a28' practiceName='MY WEB API PROTECTION PRACTICE' waapIncidentType='Schema Validation' waapIncidentDetails='OpenAPI schema validation failed'`

</details>

### CEF <a href="#cef" id="cef"></a>

CEF protocol is explained [here](https://techdocs.broadcom.com/us/en/symantec-security-software/web-and-network-security/web-isolation/1-15/Configuring-Security-Policy/Configuring-ArcSight-Servers/ArcSight-CEF-Mapping.html). The protocol fields are '|' character delimited and the agent will send the value for:

* Device Vendor - Check Point.
* Device Product - indicating the nano-service issuing the log.
* Event Name - This field will appear in the log structure but is not sent in the key-value pair system.
* Severity

Following the CEF protocol fields there are space delimited key value pairs in the structure of `keyname=value`.The possible keys and description can be seen in the [Events/Logs Schema](/references/events-logs-schema) documentation page.

<details>

<summary>CEF example</summary>

`CEF:0|Check Point|HTTPTransactionHandler||Event Driven|API Request|High|agentId=915faaab-6a40-4b55-be93-872e911397c0 issuingEngineVersion=1.2228.372599 serviceName=HTTP Transaction Handler eventReferenceId=ad7a5181-b5d3-4b54-bd5b-106e180f0c9d eventConfidence=Very High matchedParameter=[readingValue] matchedSample=[-90] matchReason=[Value is lower than the minimum allowed value: -90 < 1.000000] sourceIP=192.168.154.1 httpSourceId=192.168.154.1 sourcePort=56060 httpHostName=192.168.154.129:8000 httpMethod=POST httpUriPath=/myApp/setParam httpUriQuery= ruleId=d8c0fda7-2ad1-e7ab-32bc-d1a6af6a2ca0 securityAction=Prevent waapOverride=None practiceType=Threat Prevention practiceSubType=Web API assetId=d8c0fda7-2ad1-e7ab-32bc-d1a6af6a2ca0 assetName=Customer Portal practiceId=08c0fdac-3295-e034-be39-5ab4c2d11a28 practiceName=MY WEB API PROTECTION PRACTICE waapIncidentType=Schema Validation waapIncidentDetails=OpenAPI schema validation failed`

</details>


# Setup E-Mail Notification Triggers

You can set up Trigger objects to specify actions when an event occurs. One type of Trigger object, "Notification", allows sending email notifications to multiple addresses for events related to your agents.

### Setting up a Notification Trigger <a href="#setting-up-a-notification-trigger" id="setting-up-a-notification-trigger"></a>

**Step 1: Create a new "Notification" trigger**

Browse to **Triggers** and create a new Trigger object of type **Notification**.

![](/files/zBaqS7n1E47P4L2NuB9Q)

Configure a new name to the new notification trigger object:

**Step 2: Configure intervals and email addresses**

1. **Intervals in hours** - Specify the interval in hours for receiving notifications. You will receive an email at each set interval (e.g., every 2 hours) if any events occurred.
2. **Emails recipients** - You can choose one of the following options:
   1. **Send all admins in the tenant** - According to the Admins listed under **Account** -> **Users**.
   2. **Send all users in the tenant** - According to the list of users listed under **Account** -> **Users**.
   3. **Custom Emails -** Send to a customize list of email addresses

![](/files/xqvpzN1cnapWpX2bW3sA)\
\
\
&#x20;**Step 3: Choose the Events you wish to get notified about**

Select the checkboxes for events you want to be notified about. You can also choose all the events.\
You can get select to get email notifications in case an Agent connects, gets disconnected and/or sends some kind of urgent notification.

<figure><img src="/files/rUpPRJY2ZU5tuzs1ncUJ" alt=""><figcaption></figcaption></figure>

**Step 4: Setup your Threat Prevention policy to use the new Log Trigger object/s**

1. Browse to **Policy**->**Assets** and edit the asset you wish to modify.
2. Connect the "Notification Trigger" by selecting it in the "Notification triggers" field in the "General Tab".
3. Enforce Policy.

&#x20;![](/files/L6qzXBMn5ttzWAAWYKXY)&#x20;

<br>


# Setup Behavior Upon Failure

open-appsec implements a Fail-Open mechanism designed to allow no interruption to traffic in case of load or errors. The mechanism is **enabled by default** and can be configured separately for each agent profile through the profile page.

## Setup

This configuration is available on the Agents' Profile level and will apply to all agents using this profile's authentication token for initial registration.

To configure the behavior upon failure, navigate to **Profiles->\[select your profile].** See the **Behavior Upon Failure** section:

<div align="left"><img src="/files/BCdgM5jQam3WOjtjKOR4" alt=""></div>

## How does it work?

### Traffic based-Fail-Open <a href="#traffic-based-fail-open" id="traffic-based-fail-open"></a>

* For each client request and server response, the attachment waits for a total of 3000 milliseconds for a benign/malicious verdict (the wait time for each portion, such as headers, URL, etc.) is up to 150 milliseconds). If a a verdict doesn't arrive, the request/response is allowed to pass. This state is called fail-open.
* In case of consecutive fail-opens the system enters a state called transparency mode in order not to damage connectivity to the upstream server.
* There are three levels of transparency mode fail-open:
  * Level 1: If there is failure to inspect 5 http requests in 20 seconds interval, system enters global fail-open mode for 1 minute and moves the threshold to level 2.
  * Level 2: If there is failure to inspect 5 http requests in 20 seconds interval, system enters fail-open mode for 5 minutes and moves the threshold to level 3. In any other case system falls back to level 1.
  * Level 3: If there is failure to inspect 5 http requests in 20 seconds interval, system enters global fail-open mode for 10 minutes. In any other case system falls back to level 1.

### **Agent CPU based Fail-Open** <a href="#agent-cpu-based-fail-open" id="agent-cpu-based-fail-open"></a>

In addition to the above traffic-based mechanism, the system also monitors the Agent CPU level. The CPU utilization is sampled every 5 seconds, if 6 consecutive samples (30 seconds) were above 85% we enter fail-open mode until we identify 6 consecutive samples below 60%.

### **Critical Errors** <a href="#critical-errors" id="critical-errors"></a>

In case of any internal error in the attachment or agent during http inspection traffic will be allowed by default.

Notification logs about critical alerts will be shown in a [Notifications logs view](file:///o/NmlxbSkVNQHTmh0JtAB1/s/EWA4nfgNrSRL8dA6Kap7/~/changes/TgrwpxFKfFk1imI4ck0a/getting-started/monitor-events).


# Setup Agent Upgrade Schedule

**By default the system is set to automatically and seamlessly upgrade agents**. Learn here how to configure a custom schedule instead or switch to a manual upgrade process.

{% hint style="info" %}
Automatic upgrades are available exclusively with a Check Point WAF or open-appsec Premium Edition (deprecated) subscription.
{% endhint %}

{% hint style="danger" %}
The explanations provided here relate to open-appsec agent upgrades only, they are not relevant for IPS signature updates.
{% endhint %}

## Configuring upgrade mode

To setup specific schedule or switch to manual upgrades only, navigate to **Profiles->\[select your profile].** See the **Agent Upgrade** section.

Here you can see the latest available version which you can compare with your active agents' versions.\
![](/files/xCuixWlbJKx4QfH0WlNp)

{% hint style="info" %}
You can find the currently installed agent version displayed under the **Agents** option.
{% endhint %}

## Configuring unscheduled automatic upgrades

The default upgrade mode is configured to **Automatic**. In this mode upgrades are performed with each release of a new agent version.&#x20;

![](/files/M3B6RPVMokevz9ehOhdr)

## Configuring scheduled automatic upgrades

For scheduled agent upgrades switch the mode to **Scheduled.**\
\
![](/files/mMIBQTKGjqut7jJHJpEo)&#x20;

In the **Day of week** field select any combination of days on which you want to allow upgrades to happen.

Configure your desired upgrade window by setting the begin time in UTC in the **Upgrade window starts at (UTC)** field and selecting the maximum allowed upgrade window duration in the **Duration** field between 2 hours and 12 hours (configuration possible in two hour increments).

{% hint style="info" %}
In the example screenshot above scheduled upgrades take place automatically between 2am and 6am only on Sundays, Thursdays and Tuesdays whenever a new upgrade is available.
{% endhint %}

## Disabling automatic upgrades

In order to prevent automatic scheduled or unscheduled upgrades from happening change the upgrade mode to **Manual**.

![](/files/B6qg9SjfskP66LLZYfKE)

This allows you to manually control the upgrade process of your deployed agents.

In order to trigger a manual upgrade hit the **Upgrade Now** button whenever there's a new version available that you want to install.&#x20;

{% hint style="warning" %}
The **Manual** upgrade mode option is not recommended unless you need full manual control of all agent upgrades. Instead the recommendation is to always use **Automatic** or **Scheduled** upgrade modes to prevent the agent from not being upgraded for a significant time (= more than three months) as after this time it becomes unsupported!&#x20;
{% endhint %}


# Setup Multi-Factor Authentication

As an open-appsec Premium Edition (deprecated) subscriber multi-factor authentication (MFA) is available for strong user authentication of your open-appsec web UI tenant (it's also available in Check Point WAF, the open-appsec Enterprise edition).

## How to activate MFA / 2FA

In order to activate 2FA for your tenant, please send us an email to <info@openappsec.io> and request activation, providing also your tenant ID or alternatively open a support request directly from your tenant.

In the future you will also be able to activate this directly from the open-appsec web UI.

Once 2FA was activated for a tenant, when any tenant user logs in who didn't use 2FA so far, he will be shown the QR code for registering the open-appsec 2FA authentication in his authenticator app (you can use e.g. the Google Authenticator or Microsoft Authenticator app for this) and be asked to confirm the correct registration in his authenticator app by entering a correct one time code from his authenticator app.

From now on that user will be required to provide his one-time-code in addition to the regular sign-in, see screenshots below.

<figure><img src="/files/to2QiFt1b1veh0jne1qC" alt="" width="310"><figcaption></figcaption></figure>

<figure><img src="/files/RJTBoQ7WLYNTSNMPahM9" alt="" width="251"><figcaption></figcaption></figure>


# Anti-Bot

{% hint style="success" %}
This feature is available exclusively with a Check Point WAF or open-appsec Premium Edition (deprecated) subscription.
{% endhint %}

open-appsec's **Web Bots** engine aims at recognizing if the origin of incoming traffic to the protected web application was a human or an automatic script (such as a bot), and to allow blocking non-human activity when set to **Prevent** mode.

## How to set up open-appsec Anti-Bot

#### Step 1: Locate the exact URLs used by the login/registration forms of your web application

The Anti-Bot protection injects scripts to the response when a user performs a "GET" request, and uses the output of the injected script to analyze the behavior upon the "POST" request of the login page, as the user fills the login/registration forms.

A security administrator protecting a web application, needs to request the owner of the web application's API, for the following:

* All **URIs** used to access login/registration pages (via the GET method).
* All **URIs** used to POST the login/registration request/form.

{% hint style="warning" %}
The required data is URIs and not URLs, meaning the relative path of the GET/POST requests (without the domain name).
{% endhint %}

Once both the security administrator has both lists, the next steps are performed in the administration web application for CloudGuard AppSec.

#### Step 2: Browse to Assets and edit the Web Application asset&#x20;

Once the asset edit window opens, select the "**Anti Bot**" tab and create a new "**Anti Bot**" practice.

<figure><img src="/files/gWllZvC902SJNX1lsEEb" alt=""><figcaption></figcaption></figure>

#### Step 3: Add the list of login/registration URIs to inject scripts and URIs to validate

Click on the '**+**' sign in each of the 2 URI tables and add:

* In the **Injected URIs** table - the login/registration "GET" URIs from step 1.
* In the **Validated URIs** table - the login/registration "POST" URIs from step 1.

#### Step 3: Make sure the Mode of the Web Bots sub-practice is as desired

Setting the Mode to **As Top Level** means inheriting the primary mode of the practice.

Otherwise you can override it only for this specific sub-practice to **Detect**/**Prevent**/**Disable**.

#### Step 4: Enforce Policy

Click **Enforce** above the top banner of the open-appsec portal.


# API Schema Enforcement

{% hint style="success" %}
This feature is available exclusively with a Check Point WAF Premium or open-appsec Premium Edition (deprecated) subscription.
{% endhint %}

open-appsec's **Schema Validation** engine (requires Check Point WAF Premium or open-appsec Premium Edition \[deprecated]) validates that API input conforms to the schema provided by the admin.

{% hint style="info" %}
When integrated with Kong Gateway, open-appsec's schema enforcement works independently of the Kong's own schema enforcement and is enforced first if activated.
{% endhint %}

The admin provides the schema (using the OpenAPI specification, or OAS in short) and enhances the ability of open-appsec to detect and prevent illegal requests that do not comply.

## What is OpenAPI Specifiction (OAS)

The [OpenAPI Specification (OAS)](https://spec.openapis.org/oas/latest.html) defines a standard, language-agnostic interface to RESTful APIs which allows both humans and computers to discover and understand the capabilities of the service without access to source code, documentation, or through network traffic inspection. When properly defined, a consumer can understand and interact with the remote service with a minimal amount of implementation logic.

An OpenAPI definition can then be used by documentation generation tools to display the API, code generation tools to generate servers and clients in various programming languages, testing tools, and many other use cases.

## How to set up open-appsec Schema Validation

#### Step 1: Create an OpenAPI YAML file of your API

* Create one from your existing API.
* Make sure to have a process where updates in the API specification of the application also recreate the YAML file and upload it to open-appsec for each update.

#### Step 2: Browse to Assets and edit the asset&#x20;

Once the asset edit window opens, select the **API Protection** tab and scroll to the **Schema Validation** sub-practice.

<figure><img src="/files/1XoXpZm8n6HLklmluDx3" alt=""><figcaption></figcaption></figure>

#### Step 3: Upload the schema file

Click on the **Upload** button the file selection window will appear:

<figure><img src="/files/pTyLl1IxTawWNKMMN9u2" alt=""><figcaption></figcaption></figure>

* Click the "Add File" icon to add the OpenAPI YAML file that was created.
* Optionally - you can click the "Download" icon to verify an existing file's content.
* Select the file you wish to be used for schema validation.
* Click OK.

When making the first change to the default Web API Best Practice's configuration such as uploading your unique OpenAPI schema file for Schema Validation purposes, you will be prompted to change the name of the Practice to your own custom practice name.

![](/files/gSSd8rdDW55Gers8HQ5p)

#### Step 4: Make sure the Mode of the Schema Validation sub-practice is as desired

Setting the Mode to **As Top Level** means inheriting the primary mode of the practice.

Otherwise you can override it only for this specific sub-practice to **Detect**/**Prevent**/**Disable**.

{% hint style="info" %}
It is recommended to initially set the mode to "Detect" to verify the input schema file is correct by looking at the logs created by this capability.\
Afterwards, restore the mode to the desired state.
{% endhint %}

#### Step 5: Enforce Policy

Click **Enforce** above the top banner of the open-appsec portal.


# Data Loss Prevention (DLP) Rules

{% hint style="warning" %}
This configuration uses HTTP response scanning. Adding traffic scanning to HTTP responses adds a performance impact.
{% endhint %}

open-appsec allow configuring custom rules based on regular expressions, detected in key locations in HTTP/S traffic. The custom rules can allow creating signatures to be excluded from detection, but also adding specific signatures that will always be dropped.

The ability to configure such signatures to be detected on HTTP/S Response body, provides means of configuring Data Loss Prevention (DLP) signatures that will be dropped.

#### Step 1: Prepare DLP signatures

If there is a specific data type that should not appear on responses (for example credit card numbers, emails, etc.) - create in advance a regular expression list for each data type.

#### Step 2: Browse to relevant Web assets and configure custom rules for each signature

A full explanation on setting up custom rules and custom rules can be found [**here**](/setup-instructions/setup-custom-rules-and-exceptions).

The custom rule should:

* Use the "**Drop**" action
* Use the "**Response Body**" condition key.

The value for each custom rule's condition should be a regular expression from the list that was prepared in step 1. It is recommended that the comment will explain precisely that this is a DLP signature.

Example:

<figure><img src="/files/NiyhNOGPuySvhiXsK3Ls" alt=""><figcaption></figcaption></figure>

#### Step 3: Enforce Policy


# File Security

{% hint style="success" %}
This feature is available exclusively with a Check Point WAF or open-appsec Premium Edition (deprecated) subscription.
{% endhint %}

In addition to the Contextual Machine-Learning based engine, open-appsec provides file security, aimed at preventing malicious files from being uploaded to the organization's servers.

The file security engine scans the HTTP traffic coming into the organization, analyzes any files uploaded, and consults Check Point's Threat Cloud regarding the file's reputation.

## How to change File Security settings

When defining a new [Web Application](/getting-started/using-the-web-ui-saas/protect-additional-assets) asset to protect, file security is inactive by default.\
However - a security administrator may choose to activate the mode of the file security engine.

#### Step 1: Browse to Assets and edit the Web Application asset&#x20;

Once the asset edit window opens, select the **Web Attacks** tab and scroll to the **File Security** sub-practice.

<figure><img src="/files/v8DwUN7PENGtvjF0XcPK" alt=""><figcaption></figcaption></figure>

#### Step 2: Make sure the Mode of the File Seucrity sub-practice is as desired

Setting the Mode to **As Top Level** means inheriting the primary mode of the practice.

Otherwise you can override it only for this specific sub-practice to **Detect**/**Prevent**/**Disable**.

#### Step 3: Edit the settings of the File Security sub-practice

<figure><img src="/files/RmJR69I4TGCdUg9yfdMk" alt=""><figcaption></figcaption></figure>

The settings allow:

* Configuring the **severity** threshold from which the engine will take an action, if the file was discovered to contain a potential security risk.
* Changing the exact behavior upon detection of signature according to its **confidence level** (**Prevent**/**Detect**/**Inactive,** or, **According to Practice** when there is no unique behavior to the group of protections)
* Selecting if to extract Archive files for analysis of the extracted content and the configuring:
  * Maximum limit to scan within an archive file
  * Exact behavior (**Prevent**/**Detect**/**Inactive,** or, **According to Practice** when there is no unique behavior to the group of protections) for the instance of detecting an archived file within another archived file.
  * Exact behavior (**Prevent**/**Detect**/**Inactive,** or, **According to Practice** when there is no unique behavior to the group of protections) for the instance of a failure in content extraction.
* Limiting file size and selecting the exact behavior (**Prevent**/**Detect**/**Inactive,** or, **According to Practice** when there is no unique behavior to the group of protections) any files exceeding the configured size.
* Selecting the exact behavior (**Prevent**/**Detect**/**Inactive,** or, **According to Practice** when there is no unique behavior to the group of protections) for the instance of un-named files, where the title name was not provided as part of the Content-disposition header (see [RFC-1521](https://www.ietf.org/rfc/rfc1521.txt)).

{% hint style="info" %}
Files that require more than a few seconds to be analyzed by the Threat Emulation engine, may be delivered to users before a final verdict is reached to provide better connectivity.
{% endhint %}

When making the first change to the default Web Application Best Practice's configuration such as making changes to the default configuration of the File Security engine settings, you will be prompted to change the name of the Practice to your own custom practice name

![](/files/gSSd8rdDW55Gers8HQ5p)

#### Step 5: Enforce Policy

Click **Enforce** on the top banner of the Infinity Portal.


# Intrusion Prevention System (IPS)

{% hint style="success" %}
This feature is available exclusively with a Check Point WAF or open-appsec Premium Edition (deprecated) subscription.
{% endhint %}

In addition to the Contextual Machine-Learning based engine, open-appsec provides traditional signature-based protections for over 2800 web-based CVEs (Common Vulnerabilities and Exposures). One specific benefit of these signatures is the ability to see logs that indicate a specific CVE number.

## How to change Intrusion Prevention settings

#### Step 1: Browse to Assets and edit the Web Application asset&#x20;

Once the asset edit window opens, select the **Web Attacks** tab and scroll to the **Intrusion Prevention** sub-practice.

<figure><img src="/files/MPOdJhed19ewLon81W8g" alt=""><figcaption></figcaption></figure>

#### Step 2: Edit the settings of the Intrusion Prevention sub-practice

The settings allow:

* Changing which protections will be active according to their:
  * **Performance Impact**
  * **Severity**
  * **Year** of the [CVE ](https://cve.mitre.org/)they protect against
* Changing the exact behavior upon detection of signature according to its **confidence level** (**Prevent**/**Detect**/**Inactive,** or, **According to Practice** when there is no unique behavior to the group of protections)

When making the first change to the default Web Application/API Best Practice's configuration such as making changes to the default configuration of the IPS engine settings, you will be prompted to change the name of the Practice to your own custom practice name

![](/files/gSSd8rdDW55Gers8HQ5p)

#### Step 4: Make sure the Mode of the Intrusion Prevention sub-practice is as desired

Setting the Mode to **As Top Level** means inheriting the primary mode of the practice.

Otherwise you can override it only for this specific sub-practice to **Detect**/**Prevent**/**Disable**.

You can also set up a specific action per confidence level of the the protection that caught the attack. **According to Practice** mode means the sub-practice's mode determines the action. But you can set up **Detect/Prevent/Disable** specifically for that group of protections per confidence level. For example - the default configuration of the IPS sub-practice configures that Low confidence protections will be set to "Detect" mode, unrelated to the general IPS mode.

#### Step 5: Enforce Policy

Click **Enforce** above the top banner of the open-appsec portal.


# Rate Limit

Rate Limit / DDOS Control

open-appsec agents can limit the number of requests to a matched URI within a configured time scope, according to the source identifier.&#x20;

## How to set up rate-limiting&#x20;

#### Prerequisites

An agent from version **1.1.2** and up is required.

#### Step 1: Activate Rate Limit from the Practices tab when editing an asset

Browse to **Assets** and edit the relevant Web Application asset. Choose the **RATE LIMIT** tab. &#x20;

{% hint style="warning" %}
Pay attention to the configuration of **Source Identity**. When counting requests to see if a limit was exceeded, the source identity is the key according to which they are counted,&#x20;

i.e. "X requests from the same source identifier...".&#x20;

In the community edition, only IP and X-Forwarded-For are supported as Source Identities.&#x20;

If the source identity configuration doesn't match a value, the source IP address is used instead to count the request.

{% endhint %}

<figure><img src="/files/oMEm9fDBQmUuG6fYvUvD" alt=""><figcaption></figcaption></figure>

#### Step 2: Determine the mode of the Rate Limit configuration:

<figure><img src="/files/LyvmW7KRQ4A6CxY97iBa" alt=""><figcaption></figcaption></figure>

There are 3 optional modes:

* **Prevent** - Rate limit is enforced.
* **Detect/Learn** - Only logs will be issued if the rate limit is reached.
* **Inactive** - Temporarily disable the rate limit function, instead of deleting the practice altogether.

<figure><img src="/files/BzWNs14dmIV2NmtbuVZu" alt=""><figcaption></figcaption></figure>

#### Step 3: Configure Rate Limit Rules

When creating a new rule or editing an existing rule, a configuration window will open:

<figure><img src="/files/uGg31mGsJ58FT11LFKoh" alt=""><figcaption></figcaption></figure>

A rate limit rule consists of:

* **Action** configuration. there are 3 options:
  1. **According to practice** - The action will be determined by the practice mode previously configured.
  2. **Detect** - Only logs will be issued if the rate limit for this rule is reached. This will override the practice mode unless it is Inactive.
  3. **Prevent** - Rate limit for this rule is enforced. This will override the practice mode unless it is Inactive.

<figure><img src="/files/Kx96VgYRJTcN5XFVboEs" alt=""><figcaption></figcaption></figure>

Match conditions:

* **URI** - A string written in this field is concatenated as a suffix to all defined URLs of the Web Application or Web API asset. The concatenation result is considered the prefix for all requests that will match this rule. \
  While the URI field does not accept a regular expression, it does support usage of '\*' wildcard character.\
  \&#xNAN;*Example -* If the Asset's defined URLs are "**<http://www.myapp.com>**" and "**<https://www.mysecureapp.com>**" and the URI in the rule is "**/docs**", it will be matched on all requests starting with either **<http://www.myapp.com/docs>** or **<https://www.mysecureapp.com/docs>**.

  Use "**/**" to match all requests to the asset's domains.
* **Additional Conditions** - An optional logical expression in addition to the main URI regular expression. The logical expression can use AND/OR/NOT between matching key-value pairs to decide what traffic should be counted to determine if rate of requests has exceeded. There are several keys that can be used:
  * **URI** - A regular expression that is matched on the URI field. Since the main URI field already creates an initial prefix match of the URI path, the regular expression is usually used to match specific states if a wildcard was used, or strings in the full URI beyond the prefix.&#x20;
  * **Source Identifier** - A regular expression matching the source identifier values according to Source Identity configuration of the asset. If source identifier is not detected in traffic according to configuration, the value will be matched vs the source IP address.
  * **Source IP** - A network IP address in X.X.X.X format or CIDR (e.g. 11.22.33.44/24).&#x20;

<figure><img src="/files/r7GyIp2vKEJevWeGRjE7" alt=""><figcaption></figcaption></figure>

* Limit configuration:
  * **Limit** - the maximum number of requests in a specific time scope.
  * **Time Unit** - the time scope in which the limit is enforced.

{% hint style="info" %}
If **Limit** is set to 7000 and **Unit** is set to "Minute" then an Active Rate Limit practice will prevent requests to the matched URI if they exceed 7000 requests from the same source identifier, in a single minute.
{% endhint %}

* Trigger configuration:\
  Configure the trigger (usually the log trigger) that will activate when a Rate Limit rule is fully matched by URI as well as requests rate.<br>

  <div data-gb-custom-block data-tag="hint" data-style="warning" class="hint hint-warning"><p>In <strong>Detect/Learn</strong> mode, the Trigger is the only action that will occur if the rate of matched URIs from the same source identifier has exceeded configured limits.</p></div>

After clicking OK, you will see the full rule:

<figure><img src="/files/lFDpyco75oJtiqwNRn4C" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
**Match priority** - The rate is enforced according to a single-matched rule. When the URI of the request matches multiple URIs in multiple rules, the longest match takes precedence and determines the rate limit count.&#x20;

*For example* - if there are 2 rules - one limiting the URI "/docs" for 10000 requests from the same source identifier in one minute, and the second limiting "/docs/external" for 3000 requests from the same source identifier in one minute, then requests to /docs/external/latest will be blocked if they exceed 3000 requests from the same source identifier in one minute, as this rule creates a longer match.
{% endhint %}

{% hint style="info" %}
In the community edition, only one rule is supported.
{% endhint %}

#### Step 4: Enforce Policy

Click **Enforce** on the top banner of the open-appsec portal.


# Snort Rules


# Import Snort Rules

Snort is a commonly used format for writing IPS signatures that is very poplar in the industry.

open-appsec provides the option for an administrator to provide a set of Snort signatures and have them enforced in the same way that open-appsec enforces the regular IPS signatures update from Check Point. Enforcement of IPS and Snort signatures (if configured) happens in parallel on all HTTP/S traffic.

## Why import Snort rules to IPS?

* It allows a security administrator to write their own signatures:
  * To block specific unique traffic that they see in their network and wish to prevent it.
  * As part of the testing of the product without running actual malicious attacks inside their environments.
* A security administrator might want to deploy rules from 3rd party sources such as National/Governmental CERTs.

## How to import Snort Signatures and configure an open-appsec practice to use them

#### Step 1: Browse to Assets and edit the Web Application asset

* Once the asset edit window opens, select the **Web Attacks** tab
* Scroll down to the Snort Signatures Sub-practice:

<figure><img src="/files/1z1QdXPOTRGM4miFtAhc" alt=""><figcaption></figcaption></figure>

#### Step 2: Make sure the Mode of the Snort Signatures sub-practice is as desired

Setting the Mode to **As Top Level** means inheriting the primary mode of the practice.

Otherwise you can override it only for this specific sub-practice to **Detect**/**Prevent**/**Disable**.

<figure><img src="/files/p8D5ahCY1ny4QHNa2nSI" alt=""><figcaption></figcaption></figure>

When making the first change to the default Web Application/API Best Practice's configuration such as uploading your unique Snort signatures file, you will be prompted to change the name of the Practice to your own custom practice name.

![](/files/gSSd8rdDW55Gers8HQ5p)

#### Step 3: Upload a Snort signature file

Press the **Upload** button to add a new Snort signatures file and the file selection window will appear:

<figure><img src="/files/0Rcpz3b6Za7YjhCJWNsm" alt=""><figcaption></figcaption></figure>

* Click the "Add File" icon to add a new file.
* Optionally - you can click the "Download" icon to verify an existing file's content.
* Select the file containing the SNORT signatures you wish to enforce.
* Click OK.

#### Step 4: Enforce Policy

Click **Enforce** above the top banner of the open-appsec portal.

## How to PoC the Snort Signatures feature?

#### Step 1: Create an example Signature file

Create a test file with a simple Snort rule. For example:

```
alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS ( msg:"Testing AppSec Snort"; flow:to_server,established; http_header; content:"Testing: AppSec Snort"; service:http; sid: 99999; rev: 1; )
```

#### Step 2: Import the signature file into your policy

Save the file and use the above instructions to enforce policy using this file

#### Step 3: Trigger the signature

Trigger the signature that you have just written. For example by using a `curl` command:

```
curl -H "Testing: AppSec Snort" <your asset's URL>
```

Browse to **Monitoring** and make sure you see a log issued for this traffic

## FAQ

### Can you help me get started with a few signatures? <a href="#cloudguardappsecsnortpractice-ea-canyougetmestartedwithafewsignatures" id="cloudguardappsecsnortpractice-ea-canyougetmestartedwithafewsignatures"></a>

Of course, here are a couple of them:

```
alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS ( msg:"MALWARE-CNC Win.Trojan.Strictor variant outbound connection"; flow:to_server,established; http_uri; bufferlen:>19; content:"/mod/lookfashon.jpg",fast_pattern,nocase; http_header; content:!"Accept-Language:"; metadata:impact_flag red,policy balanced-ips drop,policy security-ips drop,ruleset community; service:http; reference:url,www.virustotal.com/en/file/0fe413704c85751b060546ebfd428d57726d8fd002ca95ec8deb76f5f37ed9c4/analysis/1389125202/; classtype:trojan-activity; sid:29220; rev:1; )

alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS ( msg:"EXPLOIT-KIT Styx exploit kit plugin detection connection jlnp"; flow:to_server,established; http_uri; content:"/jlnp.html",fast_pattern,nocase; pcre:"/\/jlnp\.html$/"; metadata:policy balanced-ips drop,policy max-detect-ips drop,policy security-ips drop,ruleset community; service:http; reference:cve,2007-5659; reference:cve,2008-0655; reference:cve,2011-3544; reference:cve,2012-0507; reference:cve,2012-1723; reference:cve,2012-4681; reference:cve,2012-4969; reference:cve,2013-0422; reference:cve,2013-2423; classtype:trojan-activity; sid:27041; rev:4; )

alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS ( msg:"EXPLOIT-KIT Styx exploit kit plugin detection connection jovf"; flow:to_server,established; http_uri; content:"/jovf.html",fast_pattern,nocase; pcre:"/\/jovf\.html$/"; metadata:policy balanced-ips drop,policy max-detect-ips drop,policy security-ips drop,ruleset community; service:http; reference:cve,2007-5659; reference:cve,2008-0655; reference:cve,2011-3544; reference:cve,2012-0507; reference:cve,2012-1723; reference:cve,2012-4681; reference:cve,2012-4969; reference:cve,2013-0422; reference:cve,2013-2423; classtype:trojan-activity; sid:27042; rev:5; )

alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS ( msg:"MALWARE-CNC Bancos variant outbound connection SQL query POST data"; flow:to_server,established; http_client_body; content:"a=select CAMPO from PAGINA where CODIGO = ",fast_pattern,nocase; metadata:policy balanced-ips drop,policy security-ips drop,ruleset community; service:http; reference:url,www.virustotal.com/en/file/88efcb549a52e3fb6359a3888e72726aac00c730edcd5280e0248d11306a645d/analysis/; classtype:trojan-activity; sid:26075; rev:2; )

alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS ( msg:"MALWARE-CNC Win.Trojan.Rovnix variant outbound connection"; flow:to_server,established; http_method; content:"POST"; http_uri; content:"/vbulletin/post.php?qu=",fast_pattern,nocase; http_header; content:!"User-Agent:"; content:!"Accept"; metadata:impact_flag red,policy balanced-ips drop,policy security-ips drop,ruleset community; service:http; reference:url,www.virustotal.com/en/file/a184775757cf30f9593977ee0344cd6c54deb4b14a012a7af8e3a2cdbb85a749/analysis/; classtype:trojan-activity; sid:34868; rev:1; )

alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS ( msg:"MALWARE-CNC Win.Trojan.Prok variant outbound connection"; flow:to_server,established; http_uri; content:"/prok/"; http_header; content:"Content-Type: multipart/form-data, boundary=7DF051D",fast_pattern,nocase; metadata:impact_flag red,policy balanced-ips drop,policy security-ips drop,ruleset community; service:http; reference:url,www.virustotal.com/en/file/ada4a63abae42266f9d472f1d4ebd0bd22702270f8b38ad7a824a16ce449ea2b/analysis/; classtype:trojan-activity; sid:34950; rev:1; )
```

### Can I use any available Snort Signatures? <a href="#cloudguardappsecsnortpractice-ea-caniuseanyavailablesnortsignatures" id="cloudguardappsecsnortpractice-ea-caniuseanyavailablesnortsignatures"></a>

You can use version 3 Snort signatures from any source, however please be mindful of the list known limitations below. If you load a file containing unsupported signatures, then the unsupported signatures will be ignored (with warnings) but they will not stop the loading of those signatures that are valid.

### How can I write my own signatures? <a href="#cloudguardappsecsnortpractice-ea-howcaniwritemyownsignatures" id="cloudguardappsecsnortpractice-ea-howcaniwritemyownsignatures"></a>

See our links and guide here:

{% content-ref url="/pages/IhFPSUQMI7nMMCNVwNcB" %}
[Write Snort Signatures](/snort-rules/write-snort-signatures)
{% endcontent-ref %}

### What will be the performance impact if I add many Snort signatures? <a href="#cloudguardappsecsnortpractice-ea-whatwillbetheperformanceimpactifiaddmanysnortsignatures" id="cloudguardappsecsnortpractice-ea-whatwillbetheperformanceimpactifiaddmanysnortsignatures"></a>

Enforcing Snort signatures uses the same mechanisms as other open-appsec security apps, so just adding the Snort security app doesn't have any performance impact.

There is also the performance impact that each additional signature generates. This differs from one signature to the next, but as a rule-of-thumb Snort signatures typically have a performance rating equivalent to IPS "Medium" performance.

### Is there a maximum number of Snort signatures that can be added? <a href="#cloudguardappsecsnortpractice-ea-isthereamaximumnumberofsnortsignaturesthatcanbeadded" id="cloudguardappsecsnortpractice-ea-isthereamaximumnumberofsnortsignaturesthatcanbeadded"></a>

### Is there an API available? <a href="#cloudguardappsecsnortpractice-ea-isthereanapiavailable" id="cloudguardappsecsnortpractice-ea-isthereanapiavailable"></a>

Will be published soon.

### Would any type of existing Snort signatures be compatible? <a href="#cloudguardappsecsnortpractice-ea-wouldanytypeofexistingsnortsignaturesbecompatible" id="cloudguardappsecsnortpractice-ea-wouldanytypeofexistingsnortsignaturesbecompatible"></a>

Unfortunately, no. Snort version 3 has made some significant changes from previous versions. This means that Snort signatures from older versions may not work as intended.

### What are the known limitations? <a href="#cloudguardappsecsnortpractice-ea-whataretheknownlimitations" id="cloudguardappsecsnortpractice-ea-whataretheknownlimitations"></a>

1. Explicit context must be provided
2. The following keywords are not fully supported:
   1. "**flow**" - only supports "to\_server" (see above).
   2. Low level keywords ("**flags**", "**ack**", etc.) - not supported (see above).
   3. "**file\_data**" - not supported.
   4. "**flowbits**" - not supported.
   5. "**byte\_test**" - not supported.
   6. "**dsize**" - not supported.
   7. "**isdataat**" - not supported.
   8. "**byte\_jump**" - not supported.
   9. "**base64\_data**" - not supported.
   10. "**base64\_encode**" - not supported.
   11. "**detection\_filter**" - not supported.


# Write Snort Signatures

## Snort usage in open-appsec

It is possible to use a signature language called Snort to create or download custom signatures to be enforced by open-appsec. For exact details how to configure:

{% content-ref url="/pages/JVtYvEmf7s5B7UvWAbTL" %}
[Import Snort Rules](/snort-rules/import-snort-rules)
{% endcontent-ref %}

There are many guides and video tutorials online on how to write Snort rules, and you can read the full documentation [Snort v2 documentation](http://manual-snort-org.s3-website-us-east-1.amazonaws.com/node27.html) and the [Compendium to v3](https://snort-org-site.s3.amazonaws.com/production/document_files/files/000/000/596/original/Rules_Writers_Guide_to_Snort_3_Rules.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256\&X-Amz-Credential=AKIAU7AK5ITMGOEV4EFM%2F20211228%2Fus-east-1%2Fs3%2Faws4_request\&X-Amz-Date=20211228T184320Z\&X-Amz-Expires=172800\&X-Amz-SignedHeaders=host\&X-Amz-Signature=287f900eb57dfa17ee338c7ea6e524aa84c96f6cdff7d1ed9824b6e9e027040c).

This page will provide a short guide on top of those links.

## Snort rules overview <a href="#cloudguardappsecsnortpractice-ea-snortrulesoverview" id="cloudguardappsecsnortpractice-ea-snortrulesoverview"></a>

Each Snort rule is written in a single line and is made up of two parts: the header and the keywords.&#x20;

The header section has a fixed format made up of seven distinct elements, and answers the questions: What action to take (detect or drop), and on which connections (remember that Snort was originally conceived as a layer 3 IDS) is should apply to.

The keywords section is made of parenthesis that holds a variable set of distinct instructions called keywords, and each keyword is terminated by a semi-colon.

## The Snort header <a href="#cloudguardappsecsnortpractice-ea-thesnortheader" id="cloudguardappsecsnortpractice-ea-thesnortheader"></a>

The Snort header is made of seven parts:

1. Action
2. Protocol
3. IP address or addresses
4. Port number or set of numbers
5. Direction operator
6. IP address or addresses
7. Port number or set of numbers

The header is intended to answer the questions: What action to take (detect or drop), and on which connections (remember that Snort was originally conceived as a layer 3 IDS) it should apply to. However, in our setting these definitions will be overridden by what the user definitions in the system.

Since that is the case, the simplest thing to do is just copy a standard header for any rule that you write, like this one:

```
alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS
```

## The Snort keywords section <a href="#cloudguardappsecsnortpractice-ea-thesnortkeywordssection" id="cloudguardappsecsnortpractice-ea-thesnortkeywordssection"></a>

The Snort keywords section contains a variable number of keywords - each one of them represent one "thing" that the rule should do.

We can divide the keywords into three categories:

1. Metadata keywords - these keywords provides general information on the rule, the log that will be produced, etc..
2. Context keywords - these keywords express on which part of the traffic (in our case, which part of the HTTP protocol) will the inspection keywords will apply.
3. Inspection keywords - these keywords test the traffic for certain conditions. They are the ones that determine if the rule is matched and an action should be taken.

### Metadata keywords <a href="#cloudguardappsecsnortpractice-ea-metadatakeywords" id="cloudguardappsecsnortpractice-ea-metadatakeywords"></a>

Metadata-type keywords can be divide into three categories:

* Must-have keywords need to be present in the rule, or the rule won't be enforced.
* Recommended keywords can be absent from the rule, but we suggest they will be added for ease of operational use of the feature: managing signatures, tracking them, etc..&#x20;
* Optional keywords won't effect any operational aspect of the system, but may contribute to the user-experience.

**Must-have metadata keywords**

* "**msg**" keyword: This keyword determine the text that will appear in the log as the protection name. The name itself should be inside a quotation marks, for example:&#x20;

  > msg: "Testing AppSec Snort";
* "**flow**" keyword: This keyword determine which side of the communication should the rule inspect. In AppSec we protect servers so the keyword should read:

  > flow: to\_server,established;
* "**service**" keyword: This keyword marks which parser should apply for the rule. In AppSec we protect HTTP traffic so the keyword should read:

  > service: http;

**Recommended metadata keywords**

* "**sid**" keyword: The "signature id" keywords provides a unique numerical value that identify the signature. These allows you to have the same log message for different rules and still distinguish between them. It should have a "random" numerical value, for example:

  > sid: 12345;
* "**rev**" keyword: The "revision" keywords is meant to distinguish between different iterations of the same signature, so you can tell for example if a false-positive is from an old version that is already fixed or not. It should start with the number 1 and increase with each version, for example:

  > rev: 1;

**Optional metadata keywords**

* "**reference**" keyword: This keywords allows you to add links that will appear in the log and will provide more information. There can be multiple instances of this keyword in a single rule. The easiest way to use it is to write the word "url", followed by comma, followed by the URL itself. For example:

  > reference: url,[www.acunetix.com](http://www.acunetix.com);

### Context keywords <a href="#cloudguardappsecsnortpractice-ea-contextkeywords" id="cloudguardappsecsnortpractice-ea-contextkeywords"></a>

Context-type keywords define which section of the HTTP protocol the following inspection keywords will refer to. So when wanting to check the URI, you need to first mention the appropriate keyword and then all the following inspection keyword will apply to the URI - until another context keyword will appear.

By default Snort scan the raw packet, not parsed HTTP. Since we are working in Layer 7 only, this is not possible for us to do. **So you must use a context keyword before using any inspection keywords.**

The main context keywords you want to know are:

* "**http\_raw\_uri**" - This holds the URI as it appears "on the wire" without decoding. So if we send '/%41ppSec' the context will be '/%41ppSec'.
* "**http\_uri**" - This holds the URI after decoding any encoding in the URI (only, we don't resolve directory traversal for example. So if we send '/%41ppSec' the context will be '/AppSec'.
* "**http\_header**" - This holds the headers section of the HTTP (request in our case).
* "**http\_client\_body**" - This holds the body of an HTTP request.

### Inspection keywords <a href="#cloudguardappsecsnortpractice-ea-inspectionkeywords" id="cloudguardappsecsnortpractice-ea-inspectionkeywords"></a>

Inspection-type keywords determine if the request's data (in the section specified by the previous context keyword) meets a certain condition. If it does, than the keywords are said to be matched. If all the inspection keywords match then the rule is said to be matched and the appropriate action (drop and\or send log) will take place.

There are several inspection keywords, and each of them usually have several options. Here we are going to present only the basic syntax of two inspection keywords - this is sufficient for most proposes.

* "**content**" keyword - This keyword checks whether a specific content (i.e. a simple string) appears in the context. The string itself appears within quotation marks. For example, if we want to search for the string "attack data" we can write:

  > content: "attack data";
* "**pcre**" keyword - This keywords checks whether a specific [**P**erl **C**ompatible **R**egular **E**xpression](https://learnxinyminutes.com/docs/pcre/) is found in the context (For a full description of the syntax see [here](https://www.pcre.org/current/doc/html/)). The expression is placed with forward-slashes within quotation marks. For example, if we want to search for "hello" followed any number of spaces followed by "world", we can write:

  > pcre: "/hello\s\*world/";


# Configuration and Learning

{% content-ref url="/pages/mKsRQYz4wJpG9drvO9pG" %}
[Configure Contextual Machine Learning for Best Accuracy](/how-to/configuration-and-learning/configure-contextual-machine-learning-for-best-accuracy)
{% endcontent-ref %}

{% content-ref url="/pages/hL9P2lcN6vILXJVps4bZ" %}
[Track Learning and Move From Learn/Detect to Prevent](/how-to/configuration-and-learning/track-learning-and-move-from-learn-detect-to-prevent)
{% endcontent-ref %}

{% content-ref url="/pages/gScpqUNo3rgBeVM7kAGU" %}
[Track Learning and Local Tuning in Standalone Deployments](/how-to/configuration-and-learning/track-learning-and-local-tuning-in-standalone-deployments)
{% endcontent-ref %}

{% content-ref url="/pages/RW9C4ZryRddlG2TOHyzH" %}
[Move From Detect to Prevent in K8s With Many Ingress Rules](/how-to/configuration-and-learning/move-from-detect-to-prevent-in-k8s-with-many-ingress-rules)
{% endcontent-ref %}


# Track Learning and Move From Learn/Detect to Prevent

When [a new asset is added](/getting-started/using-the-web-ui-saas/protect-additional-assets) it is recommended that open-appsec runs in Learn/Detect mode to allow it to create an initial baseline. When the [Contextual Machine Learning](/concepts/contextual-machine-learning)  is properly configured and the application receives a substantial amount of traffic, the learning period takes about 2-3 days.&#x20;

Depending on amount and variance of traffic the machine learning engine will reach a stage where it has observed a sufficient amount of web requests to understand how the application is used. The faster this stage is reached, the faster detection is accurate and it is recommended to move to Prevent mode.

To speed up the learning period the [Contextual Machine Learning](/concepts/contextual-machine-learning) engine proposes **tuning suggestions**. The administrator can review the tuning suggestions and help the engine reach even better accuracy, a Machine Learning process also known as supervised learning.

When a certain maturity level is reached, open-appsec will advice to move into **Prevent** mode. In this section you will understand how to track the learning level and how to optimize and tune the model for faster learning.

## Understand The Learning Level

When HTTP requests are inspected the open-appsec [Contextual Machine Learning](/concepts/contextual-machine-learning) model will reach different learning levels. Each level represents the maturity of the learning model and helps to understand what it needs to reach the next level. It will also indicate when it is time to move from **Learn/Detect to Prevent** mode. The model progresses through the following learning levels:

![](/files/eI4Jkv8yIg9NX6keEqKH)

When the learning level becomes **Graduate,** it is recommended to change the asset **Mode** to **Prevent** for either High confidence or above or Critical confidence events. Graduate level ensures very good level of accuracy (e.g. low amount of false positives).  To reach **Master** or **PhD** level is is necessary to [configure Trusted Sources](/how-to/configuration-and-learning/configure-contextual-machine-learning-for-best-accuracy). The **Phd** level is the highest level, which means that more learning is less likely going to improve the model further.

#### Step 1: Track the learning level

![](/files/tqHX6X0xLA1nIynCS9qB)

1. Go to **Assets** and select the Asset you want to track.
2. Select the **Learn** tab. This tab shows the learning **statistics of the last 7 days**, the **Elapsed Time**, the **Learning Level** and the **Recommendation** at this level.
3. Hover over the **Learning Level** tooltip:information\_source: to learn the current learning level and the next level. It will also indicate what is required to reach the next level in the '**Watch next?'** section. Positive contributing factors to the learning process are: number of [trusted sources](/how-to/configuration-and-learning/configure-contextual-machine-learning-for-best-accuracy) defined by the admin, time elapsed, amount of traffic inspected, amount of supervised learning suggestions and some other model parameters.&#x20;

{% hint style="info" %}
The example below shows that the machine learning is in **Kindergarten** level and needs 999 additional HTTP requests and 6 additional learning hours to reach **Primary School** level.
{% endhint %}

![](/files/WKIj3JvzLTJ7G0YO0qbX)

When an agent enforcing open-appsec first sees a connection to a web application/web API defined URL, a banner will also show at the top of the management web application to denote that "Learning has started":

![](/files/AwW4fDUzzDHqrDZrG3dw)

#### Step 2: Learn the recommended action

1. Hover over the **Recommendation** tooltip:information\_source: to learn what the current recommended action is for the asset. Recommendations include:

| Recommendation                         | Action Required                                                                                                                                                                                                                                   |
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Keep Learning                          | No action required. The machine learning model requires additional HTTP requests (and additional time).                                                                                                                                           |
| Review Tuning Suggestions              | The learning mechanism generated tuning suggestions. Go to the [**Optimize Learning And Tuning**](#optimize-learning-and-tuning) section in this documentation to learn how to review them and decide whether the events are malicious or benign. |
| Prevent Critical Severity Events       | The system is ready to prevent critical severity events. Navigate to the **Threat Prevention** tab and change the Web Attacks practice Mode to **Prevent** for Critical Severity events.                                                          |
| Prevent High Severity And Above Events | The system is ready to prevent high severity (and above) events. Navigate to the **Threat Prevention** tab and change the Web Attacks practice Mode to **Prevent** for High and above Severity events.                                            |

{% hint style="info" %}
In the example below the **Recommendation** is Keep Learning and additional HTTP requests are required to reach the next learning level.
{% endhint %}

![](/files/jjlWLZNhSanugzwIVPNV)

{% hint style="info" %}
Another example shows sufficient learning is achieved and the **Recommendation** is to Prevent High Severity And Above events. Since the Web Attack Practice is already in **Prevent** mode the tool tip shows a '**Well done!**' message.
{% endhint %}

![](/files/MlPLyow1Y0dhmKmxV9bP)

## Tuning Suggestions

The [Contextual Machine Learning](/concepts/contextual-machine-learning) model may ask to review certain events, also called **Tuning Suggestions**. Providing feedback to these suggestions is not mandatory as the engine is capable of learning by itself. However doing this, allows the machine learning engine to reach a higher maturity level and therefore a better accuracy faster based on human guidance.&#x20;

#### Step 1: Review Tuning Suggestions

1. Go to **Assets** and select the Asset you want to review.
2. Select the **Learn** tab. This tab shows **Tuning Suggestions** and **Tuning Decisions**.
3. Review the proposed **Tuning Suggestions**.

![](/files/gvfDfckfZPPKRTrXsXM3)

#### Step 2: Provide feedback to the proposed Tuning Suggestions

1. Click on the **Malicious** or **Benign** button next to the line of the Tuning Suggestion. Your Tuning Suggestion now moves to the **Tuning Decisions** list.

![](/files/s7EHEPYWvnx1tzLJAVAK)

#### Step 3: Review the new recommended action

1. Go to [Step 2: Learn the recommended action](#step-2-learn-the-recommended-action) of the previous section to learn what to do next to improve the learning process.

## Move To Prevent Mode <a href="#moving_to_prevent_mode" id="moving_to_prevent_mode"></a>

Follow these actions when it is time to change the Practice mode from **Learn/Detect** to **Prevent**.&#x20;

1. Go to **Assets** and select the Asset you wish to Protect.
2. Select the **Learn** tab and examine the recommendation.&#x20;
3. Select the **Events** tab and examine Critical and High Events for the asset from the last 1-2 days.&#x20;
4. If needed, right-click on event and add **Exceptions** for traffic that the machine learning engine may have misclassified (exceptions can be added based on the `uri,` source identifier, parameter, and more). See more about this [here](/setup-instructions/setup-custom-rules-and-exceptions).
5. Select the **Threat Prevention** tab and change the mode to **Prevent**
6. You can further tune the sensitivity to block either **High or above** or just **Critical** events.&#x20;
   * Set the level based on the recommendation in the **Learn** tab as well as your impression when looking at the events during the last day of the learning period.&#x20;
   * You can also start with **Critical** for few days, examine the events and then move to **High or above**.&#x20;
7. **Enforce** policy.


# Configure Contextual Machine Learning for Best Accuracy

The [Contextual Machine Learning](/concepts/contextual-machine-learning) reaches a verdict more accurately when it can differentiate between users or sources of HTTP requests. open-appsec allows to configure how to identify the source of a web request, per web application or API.

Once open-appsec knows how to identify the source, you can also configure **trusted sources**. Understanding the behavior of multiple trusted sources helps the contextual machine learning engine to learn faster what is considered a benign or malicious request for a specific web application or API.

{% hint style="success" %}
Configuration of the below items can accelerate the learning process and allow reaching more accurate decision by the Machine Learning Engine.
{% endhint %}

{% hint style="warning" %}
Configuring trusted sources is **not** a method of exclusion. It is a method to enhance the learning capabilities of the contextual machine learning.\
[Exclusions are configured separately](/setup-instructions/setup-custom-rules-and-exceptions).
{% endhint %}

## Source Identity and Trusted Sources

They can also be found when browsing to **Assets** and editing an asset under **Source Identity** and **Trusted Sources**.

<figure><img src="/files/uYv1xMDbaiTUV5EsKFa6" alt=""><figcaption></figcaption></figure>

#### Step 1: Identify the source of the web request

The source of an HTTP web request can be identified in a number of ways. Use the below table to select the appropriate identifier for the sources of your web application.

<table><thead><tr><th width="150">Definition</th><th width="289">Parameter</th><th>View</th><th data-hidden></th></tr></thead><tbody><tr><td>Source IP</td><td>This is the HTTP request source IP or CIDR. No additional parameters are necessary.</td><td><img src="/files/e8MSNk8mGX0vQmUH1dxI" alt=""></td><td></td></tr><tr><td>X-Forwarded-For Header in HTTP requests</td><td>IP address or CIDR of the trusted source is received in the X-Forwarded-For header. If you select this option, you must add the IP addresses of previous reverse proxy/ALB hops to distinguish the unique IP address of the source from them. For example:<img src="/files/5WyZLf9dGPqWlhHtfubT" alt="" data-size="original"><br><strong>Note</strong> - Adding the address of previous hops is required when there is more than 1 reverse proxy and/or ALB before Reverse Proxy with AppSec installation. If there is only one, it is not required. </td><td><img src="/files/XYnlL4AgaExuogAvr0lJ" alt=""></td><td></td></tr><tr><td>Header Key</td><td>If you select this option, it is necessary to add the header field name. This value is used for identification.</td><td><img src="/files/lHhOOmvLo5cCCigv1UJr" alt=""></td><td></td></tr><tr><td>JWT Key</td><td>If you select this option, it is necessary to add the key within the JWT. This value is used for identification. <strong>This option is recommended.</strong></td><td><img src="/files/lHhOOmvLo5cCCigv1UJr" alt=""></td><td></td></tr><tr><td>Cookie</td><td>When you select this option, it is necessary to add the key within the cookie. This value is used for identification. A recommended key is <code>oauth2_proxy</code></td><td><img src="/files/lHhOOmvLo5cCCigv1UJr" alt=""></td><td></td></tr></tbody></table>

1. Go to **Assets** and select the Asset you want to configure.
2. Select a method to distinguish the sources according to the above table.
3. (Optional) Add the name of field that uniquely identifies the user.

#### Step 2: Configure Trusted Sources

1. Add specific IP addresses (incase of Source IP or X-Forward-For) or specific user identifiers (in case of Header/JWT/Cookie) of trusted sources to the list
2. **Minimum Users To Trust** - You may change the default from 3 to a lower (not recommended) number or higher.\
   If we take the example of "3", the learning mechanism will not learn about "benign" behavior from the trusted sources until at least 3 of them created similar traffic patterns. This is to avoid one source becoming a "malicious source of truth".\
   The number of trusted sources in the table has to be at least that minimum number, to allow the machine learning engine to have a good indication of "benign behavior".
3. Click **Publish** to publish the changes to the management
4. Click **Enforce** to deploy the changes to the enforcement points

<div align="left"><img src="/files/jAXdgVbzN2FsizIAQdwo" alt=""></div>

## What's Next?

Depending on amount and variance of traffic, after some time, the machine learning engine will reach a stage where it has observed a sufficient amount of web requests to understand how the application is used. The faster this stage is reached, the faster detection is accurate and it is recommended to move to prevent mode.

Read more about how you can optimize and tune the Machine Learning process in the [Track Learning and Move from Detect to Prevent](/how-to/configuration-and-learning/track-learning-and-move-from-learn-detect-to-prevent) section of this documentation.


# Track Learning and Local Tuning in Standalone Deployments

{% hint style="info" %}
Checking learning progress and performing local tuning decisions in standalone deployments (see above) is currently **in beta.**
{% endhint %}

{% hint style="warning" %}
This feature is not yet supported for embedded deployments on Linux.
{% endhint %}

{% hint style="warning" %}
This is only relevant if your deployment is **not connected to central WebUI at all**, thus running in **standalone mode** with local, decalarative management.\
Once you are connected to the central WebUI with deployment profile in either "This management" mode or "Declarative configuration" mode, then you can see learning\
progress and decide on local tuning suggestions from within the central WebUI at\
<https://my.openappsec.io>.
{% endhint %}

**Here you find instructions how you can get access to the following features in open-appsec standalone deployments:**

* Check open-appsec machine learning progress locally
* Get configuration recommendations based on current learning progress level
* Receive and decide upon tuning suggestions (supervised learning) presented to you by the open-appsec contextual machine-learning engine.

**Make sure to read this first to learn more about learning, tuning suggestions and moving from detect to prevent in open-appsec:**

{% content-ref url="/pages/hL9P2lcN6vILXJVps4bZ" %}
[Track Learning and Move From Learn/Detect to Prevent](/how-to/configuration-and-learning/track-learning-and-move-from-learn-detect-to-prevent)
{% endcontent-ref %}

## Prerequisites:

{% hint style="warning" %}
**If your deployment is on Docker:**\
In order to have access to the below functionality your deployment must have been done using the "docker-compose" based deployment option, as only this deployment option will deploy the required additional containers for local learning and tuning when configured correctly for standalone deployment.\
Currently as this is still in beta phase for docker platform this is available for integration with NGINX, more integrations will be reported soon as well.\
See here for details: \[add link to docker-compose based deployment option]
{% endhint %}

* Existing open-appsec deployment (Docker-Compose or Kubernetes)\
  (Linux-embedded are not supported for local tuning in standalone mode.)
* No Agent Token configured in the deployment (no connection to central WebUI)
* Make sure that agent already received some traffic already, as otherwise the open-appsec-tuning-tool will not be able to provide any statistics, recommendations, etc.

## Installation of the "open-appsec-tuning-tool"

* Download the open-appsec-local-tuning tool

```bash
wget https://downloads.openappsec.io/tools/open-appsec-tuning-tool && chmod +x ./open-appsec-tuning-tool
```

## Using the open-appsec-tuning-tool

1. Run the open-appsec-tuning-tool to get an overview of the available options:

```bash
./open-appsec-tuning-tool
```

<figure><img src="/files/d4MuBbashZkv9EriB0wc" alt=""><figcaption><p>open-appsec tuning tool main menu</p></figcaption></figure>

2. Select among the available options presented:

* **View statistics**\
  Select **\[1]** to view current learning statistics, learning progress and receive recommendations for configuration based on those.&#x20;

{% hint style="info" %}
It may take up to 10 min until you see updated metrics here based on new traffic.
{% endhint %}

<figure><img src="/files/s4NsTYb4E3aU0fTAEwnV" alt="" width="375"><figcaption><p>statistics view in open-appsec-tuning-tool</p></figcaption></figure>

* **Manage tuning suggestions for learning**\
  Select **\[2]** to view tuning suggestions in case there are some available based on observed traffic and learning state.\
  To perform tuning:\
  \- First select a tuning suggestion based on it's ID.\
  \- Review the relevant logs presented which allow you to better decide what decision to take for that suggestion. (You also have the option to export those logs into a .csv file.)\
  \- Take a decision on that tuning suggestion by setting it to "malicious" or "benign".<br>

<figure><img src="/files/16F2L4UEiRcATJJa0IPw" alt="" width="356"><figcaption><p>see tuning suggestions in open-appsec-tuning-tool</p></figcaption></figure>

<figure><img src="/files/a4a1xaqSleW9x7LJ7nuK" alt="" width="375"><figcaption><p>manage tuning suggestions in open-appsec-tuning-tool</p></figcaption></figure>

* **View tuning decisions**\
  Select **\[3]** to view tuning decisions which you already took based on earlier tuning suggestions.

#### The `open-appsec-tuning-tool` supports the following optional parameters:

**-env {k8s|docker|embedded}**\
set the environment type, by default the tool will try to auto-detect the environment type of the open-appsec deployment

**-tuning-host \<host\[:port]|pod>**\
set the tuning container hostname and optionally also a non-standard port for Docker-based deployments or the pod name for deployments in Kubernetes (see also the  `-namespace` parameter below for setting open-appsec deployment's Kubernetes namespace)

**-namespace**\
set the open-appsec deployment namespace (Kubernetes only)

**-agent \<container|pod>**\
set open-appsec agent container (Docker) or pod (Kubernetes) for open-appsec tuning tool to connect to  default is auto-detect

**-port**\
set local port on host to use for port-forwarding to the tuning container default is auto-select an available port (Kubernetes)

**-help**\
show open-appsec-tuning-tool help

**-version**\
show version of the open-appsec-tuning-tool


# Move From Detect to Prevent in K8s With Many Ingress Rules

Larger K8s environments can have many ingress rules specified within the ingress resource(s) or routes defined for Kong gateway.&#x20;

Here's a suggested workflow explaining how to set open-appsec to prevent to protect them after initial onboarding was done in detect mode and sufficient time has passed to gain confidence about open-appsec and allow the solution to perform the learning.

Start with your own detect policy, see following example:\
(Or create a new one and apply to your ingress, see [Configuration Using CRDs](/getting-started/start-with-kubernetes/configuration-using-crds))

```
apiVersion: openappsec.io/v1beta1
kind: Policy
metadata:
  name: example-policy
  # BEFORE moving certain ingress rules to prevent-learn
spec:
  default:
    triggers:
    - appsec-special-log-trigger
    mode: detect-learn
    practices:
    - webapp-best-practice
    source-identifiers: my-source-identifiers
    trusted-sources: my-trusted-sources
    custom-response: appsec-web-user-response-example
    exceptions:
    - appsec-exception-example
```

Once sufficient confidence as well as training is reached for certain resources to move them to prevent:\
Create specific rules in "prevent-learn" mode in the policy object for those resources (see also the hint below the following example).\
The learning recommendations as shown in the WebUI will provide helpful suggestions about when to move to prevent for each protected asset, see [Track Learning and Move From Learn/Detect to Prevent](/how-to/configuration-and-learning/track-learning-and-move-from-learn-detect-to-prevent)\
\
In the following example the following hosts/path will be protected in "prevent-learn" mode, assuming ingress rules are defined as well to allow the traffic:\
\- web.server.com/example\
\- web.server.com/another-example\
\- another.webserver.com\
The default mode for all other resources based on existing ingress rules will remain "detect-learn", as specified in the default section of the policy example.

```
apiVersion: openappsec.io/v1beta1
kind: Policy
metadata:
  name: example-policy
  # AFTER moving certain ingress rules to prevent-learn
spec:
  default:
    triggers:
    - appsec-special-log-trigger
    mode: detect-learn
    practices:
    - webapp-best-practice
    source-identifiers: my-source-identifiers
    trusted-sources: my-trusted-sources
    custom-response: appsec-web-user-response-example
    exceptions:
    - appsec-exception-example
    
  specific-rules:
  - host: web.server.com/example
    triggers:
    - appsec-special-log-trigger
    mode: prevent-learn
    practices:
    - webapp-best-practice
    source-identifiers: my-source-identifiers
    trusted-sources: my-trusted-sources
    custom-response: appsec-web-user-response-example
    exceptions:
    - appsec-exception-example
  - host: web.server.com/another-example
    triggers:
    - appsec-special-log-trigger
    mode: prevent-learn
    practices:
    - webapp-best-practice
    source-identifiers: my-source-identifiers
    trusted-sources: my-trusted-sources
    custom-response: appsec-web-user-response-example
    exceptions:
    - appsec-exception-example
  - host: another.webserver.com
    triggers:
    - appsec-special-log-trigger
    mode: prevent-learn
    practices:
    - webapp-best-practice
    source-identifiers: my-source-identifiers
    trusted-sources: my-trusted-sources
    custom-response: appsec-web-user-response-example
    exceptions:
    - appsec-exception-example
```

{% hint style="info" %}
It is possible to create kind of "super rules" in the open-appsec policy that match multiple specific rules in your ingress and reduces effort and complexity, as well of the size of the policy object. \
\
Example: For protecting multiple ingress rules that might exist in an ingress resource which are all for the same host "another.webserver.com" (but having different paths defined) it is sufficient to have a single host entry for "another.webserver.com" in the specific-rules section of the open-appsec policy object configured for "prevent-learn" mode (as shown in the above example).\
Those "super rules" are defined as any other rule in the specific-rules section.\
\
With this concept the amount of specific policy rules for open-appsec required to protect a complex environment in K8s can be much lower than the amount of ingress rules defined for it.
{% endhint %}


# Deployment and Upgrade

#### **Deployment & Integration**

{% content-ref url="/pages/9qtOay1Dm2uZtpI1L6GQ" %}
[Load the Attachment in Proxy Configuration](/deployment-and-upgrade/load-the-attachment-in-proxy-configuration)
{% endcontent-ref %}

{% content-ref url="/pages/9iUEuZpCwJxGhdnlh9ly" %}
[Upgrade Your Reverse Proxy/API Gateway When an Agent is Installed](/deployment-and-upgrade/upgrade-your-reverse-proxy-api-gateway-when-an-agent-is-installed)
{% endcontent-ref %}

{% content-ref url="/pages/MmEADjsasrUVXuNzu3a6" %}
[Integration in GitOps CD (K8s)](/deployment-and-upgrade/integration-in-gitops-cd-k8s)
{% endcontent-ref %}

{% content-ref url="/pages/cvtdaRiCGnKvMjhyxpfw" %}
[Build open-appsec Based on Source Code](/deployment-and-upgrade/build-open-appsec-based-on-source-code)
{% endcontent-ref %}


# Load the Attachment in Proxy Configuration

open-appsec **Agents** receive the HTTP data from open-appsec **Attachments** integrating with the Proxy server. This allows the Agents to inspect traffic, once inspection is done, the resulting decision (e.g. to allow traffic or to block it) is returned back to the Attachment for the actual enforcement.\
\
When you are providing your own proxy configuration it is therefor critical to make sure that it contains the relevant settings for the proxy to load the attachment.

## How do I get the attachment for my proxy?

### Linux embedded deployments&#x20;

The attachment module is automatically downloaded specifically matching your proxy type and version and operating system when you run the open-appsec-install tool to install open-appsec.

Here you find lists of all supported/pre-compiled attachments per supported OS versions for each available integration: [NGINX](https://downloads.openappsec.io/packages/supported-nginx.txt), [Kong](https://downloads.openappsec.io/packages/supported-kong.txt), [APISIX](https://downloads.openappsec.io/packages/supported-apisix.txt)

### Docker and Kubernetes deployments

We provide "enhanced" versions of the containers for all supported proxies that open-appsec can integrate with. These containers already include the open-appsec attachment.

### Compiling the attachment yourself

You can also compile the attachment yourself, this allows you to deploy on currently unsupported versions of the supported proxies or on unsupported operating systems. You can also build your own customized proxy containers. Source code and instructions are available here:

{% embed url="<https://github.com/openappsec/attachment>" %}

## How to load the open-appsec attachment in the proxy configuration

Please follow the instructions provided below for your specific deployment type explaining what needs to be included in your local proxy configuration in order to load the open-appsec attachment module.

{% tabs %}
{% tab title="NGINX" %}
{% hint style="success" %}
When installing open-appsec on Linux embedded the `open-appsec-install` command will automatically patch the existing `nginx.conf` file to add the line for loading the module.

In the `nginx-attachment` container provided by open-appsec for containerized deployments this is already included in the file `/etc/nginx/nginx.conf`.
{% endhint %}

In the NGINX configuration file `nginx.conf` make sure to have the open-appsec attachment loaded as an NGINX module.

The open-appsec attachment module is usually located in this path:\
`/usr/lib/nginx/modules/`

Make sure the following line exists **as the first line** in the nginx.conf file in order to load the open-appsec attachment module:

`load_module /usr/lib/nginx/modules/ngx_cp_attachment_module.so;`
{% endtab %}

{% tab title="NGINX Unified" %}
{% hint style="success" %}
In the `open-appsec-agent-unified` container provided by open-appsec for Docker deployments the line to load the attachment module is already included in the file `/etc/nginx/nginx.conf`.
{% endhint %}

In the NGINX configuration file `nginx.conf` make sure to have the open-appsec attachment loaded as an NGINX module.

The open-appsec attachment module is usually located in this path:\
`/usr/lib/nginx/modules/`

Make sure the following line exists **as the first line** in the nginx.conf file in order to load the open-appsec attachment module:

`load_module /usr/lib/nginx/modules/ngx_cp_attachment_module.so;`
{% endtab %}

{% tab title="Kong" %}
{% hint style="success" %}
When installing open-appsec on Linux embedded the `open-appsec-install` command will automatically patch the existing `nginx.conf` file to add this line.

In the `kong-attachment` container provided by open-appsec for containerized deployments this is already included in the file `/usr/local/kong/nginx.conf`.
{% endhint %}

Kong is based on OpenResty, in OpenResty's NGINX configuration file `nginx.conf` make sure to have the open-appsec attachment loaded as an NGINX module.

The open-appsec attachment module is usually located in this path:\
`/usr/lib64/nginx/modules/`

Make sure the following line exists **as the first line** in the nginx.conf file in order to load the open-appsec attachment module:

`load_module /usr/lib64/nginx/modules/ngx_cp_attachment_module.so;`
{% endtab %}

{% tab title="APISIX" %}
{% hint style="success" %}
When installing open-appsec on Linux embedded the `open-appsec-install` command will automatically patch the existing `nginx.conf` file to add this line.

In the apisix-attachment container provided by open-appsec for containerized deployments this is already included in the file `/usr/local/apisix/conf/nginx.conf`.
{% endhint %}

APISIX is build on OpenResty. In OpenResty's NGINX configuration file `nginx.conf` make sure to have the open-appsec attachment loaded as an NGINX module.

The open-appsec attachment module is usually located in this path:\
`/usr/lib/nginx/modules/`

Make sure the following line exists **as the first line** in the nginx.conf file in order to load the open-appsec attachment module:\
(Note that in APISIX the nginx.conf file is automatically generated, so you cannot adjust its contents directly)

`load_module /usr/lib/nginx/modules/ngx_cp_attachment_module.so;`
{% endtab %}

{% tab title="Envoy (beta)" %}
{% hint style="warning" %}
When installing Envoy on Docker:\
As an `envoy.yaml` configuration file is not included in the Envoy container make sure to have the above configuration added yourself to that file!
{% endhint %}

In the Envoy configuration file, which is typically called `envoy.yaml` make sure to have the open-appsec attachment loaded as a filter for HTTP traffic.

The open-appsec attachment is usually located here:\
`/usr/lib/libenvoy_attachment.so`

In the configuration example below you can see the relevant **lines 16 to 25** which must be added for loading the open-appsec attachment filter for Envoy:

{% code lineNumbers="true" %}

```yaml
static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address:
        address: 0.0.0.0
        port_value: 80
    filter_chains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
          stat_prefix: ingress_http
          http_filters:
          ## The following 10 lines are required to load the envoy attachment filter for open-appsec
          - name: envoy.filters.http.golang
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config
              library_id: cp_nano_filter
              library_path: "/usr/lib/libenvoy_attachment.so"
              plugin_name: cp_nano_filter
              plugin_config:
                "@type": type.googleapis.com/xds.type.v3.TypedStruct
                value:
                  prefix_localreply_body: "Configured local reply from go"
          ## 
          - name: envoy.filters.http.router
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router          
```

{% endcode %}
{% endtab %}
{% endtabs %}


# Upgrade Your Reverse Proxy/API Gateway When an Agent is Installed

One of the possible deployments for open-appsec is a Linux agent installed on top of a [supported Reverse Proxy](/getting-started/start-with-linux).

If you wish to upgrade the Reverse Proxy while the agent is installed, follow the steps described in this documentation page.

{% tabs %}
{% tab title="NGINX" %}

#### Step 1: **Delete the agent module's load\_module line**

* Locate your nginx *modules* folder path by running:\
  nginx -V\
  and look for the value of the "--modules-path" parameter.\
  It is usually /usr/share/nginx/modules or /usr/lib/nginx/modules
* Via command line access to the machine with the NGINX server and the agent, edit the following file:\
  \&#xNAN;*/etc/nginx/nginx.conf*
* **Delete** the following line (look for the path located previously):\
  \&#xNAN;*load\_module /\<modules folder path>/ngx\_cp\_attachment\_module.so;*

#### Step 2: Comment out the agent module's configuration lines

* Edit all files in the paths */etc/nginx/conf.d/\** or */etc/nginx/sites\_enabled/\**
  * Comment out (add '#' in the beginning of the line) all the lines, if exist, that begin with:\
    \&#xNAN;*cp-nano-nginx-attachment*
* If you added manually additional lines in other server configuration files - comment them out as well.

#### Step 3: Run a test command

Run the command '*nginx -t*'. You should see it print out "*test is successful*".

#### Step 4: Upgrade the NGINX's software version

Run any commands you intended to run in order to upgrade the NGINX's software version

#### Step 5: Stop and start the agent, while triggering deployment of a new attachment

Run the following commands:\
\&#xNAN;*cpnano -q*\
*rm -rf /etc/cp/packages*\
*rm /etc/cp/conf/manifest.json*\
*cpnano -r*

#### Step 6: Verify the agent has restarted

After one minute that the agent has restarted successfully using the following command:\
\&#xNAN;*cpnano -s*

Last update status should state “Succeeded” and Last update should show a time in the scope of the last few minutes.

#### Step 7: Undo the changes done in step 2

Remove the "comment out" character ('#') from all the lines it was added to in step 2 (In the paths */etc/nginx/conf.d/\** or */etc/nginx/sites\_enabled/\** )

#### Step 8: NGINX reload

Run the following commands:\
\&#xNAN;*nginx -s reload*\
*systemctl restart nginx*
{% endtab %}

{% tab title="Kong Gateway" %}
**Step 1: Delete the agent module's load\_module line**

* Locate your nginx *modules* folder path by running:\
  /usr/local/openresty/nginx/sbin/nginx -V\
  and look for the value of the "--modules-path" parameter.\
  It is usually /usr/share/nginx/modules or /usr/lib/nginx/modules
* Via command line access to the machine with the NGINX server and the agent, edit the following file:\
  /usr/local/kong/nginx.conf
* **Delete** the following lines (look for the path located previously):\
  \&#xNAN;*load\_module /\<modules folder path>/open\_appsec\_ngx\_module.so;*\
  *cp\_worker\_processes auto;*

**Step 2: Run a test command**

Run the command '*/usr/local/openresty/nginx/sbin/nginx -p /usr/local/kong -c nginx.conf -t*'. You should see it print out "*test is successful*".

**Step 3: Upgrade the Kong Gateway's software version**

Run any commands you intended to run in order to upgrade the Kong Gateway's software version

**Step 4: Backup your declarative policy (optional)**

If you are using a declarative policy, copy your local configuration to a new folder by running:

open-appsec-ctl --list-policies\
cp \<output of list-policies-command> \<your backup folder>

**Step 5: Stop the agent and re-deploy attachment**

Run the following commands:\
\&#xNAN;*open-appsec-ctl -q*\
*rm /etc/cp/conf/manifest.json*

Run the open-appsec install command:\
\&#xNAN;*wget <https://downloads.openappsec.io/open-appsec-install> && chmod +x open-appsec-install*\
./open-appsec-install --auto

**Step 6: Restore you declarative policy (optional)**

Copy your backed up declarative policy to the original folder:\
cp \<your backed up declarative policy file> \<output of list-policies-command>

**Step 7: Verify the agent has restarted**

After one minute that the agent has restarted successfully use the following command:\
\&#xNAN;*open-appsec-ctl -s*\
Last update status should state “Succeeded” and Last update should show a time in the scope of the last few minutes.
{% endtab %}
{% endtabs %}


# Integration in GitOps CD (K8s)

open-appsec supports integration into existing GitOps CD processes where everything is configured "as-code" within a git repo. Learn how this is typically done for each of the following tasks.

## Deployment

In order to declaratively install open-appsec as code the helm command can be used with the required parameters in the repo used for GitOps .

#### Step 1 (optional): Download helm chart for storing in custom helm repo and adjust references

Run the following command to obtain the latest helm chart, in case you have a requirement to store helm charts in your own helm repo.

{% tabs %}
{% tab title="NGINX Ingress Controller" %}

```
wget https://downloads.openappsec.io/packages/helm-charts/nginx-ingress/open-appsec-k8s-nginx-ingress-latest.tgz
```

{% endtab %}

{% tab title="Kong Gateway" %}

```
wget https://downloads.openappsec.io/packages/helm-charts/kong/open-appsec-k8s-kong-latest.tgz
```

{% endtab %}

{% tab title="APISIX" %}

```
wget https://downloads.openappsec.io/packages/helm-charts/apisix/open-appsec-k8s-apisix-latest.tgz
```

{% endtab %}
{% endtabs %}

#### Step 2 (optional): Download the containers for storing in custom container registry and adjust references

{% tabs %}
{% tab title="NGINX Ingress Controller" %}
If required run the following commands to pull the required container images and import them to a custom container registry:

\
For the **nginx ingress ingress controller** container image run:

```
docker pull ghcr.io/openappsec/nginx-ingress-attachment:[tag]
```

Replace \[tag] with the tag specified in the helm chart's values.yaml file under:\
appsec.nginx.image.tag

Upload the downloaded container image to the custom container registry.

Adjust the container reference in helm chart's values.yaml or with helm command parameters here to point to the container in the custom registry:

appsec.nginx.image.repository (image and repo)\
appsec.nginx.image.tag

For the **open-appsec agent sidecar** container run:

```
docker pull ghcr.io/openappsec/agent:[tag]
```

Replace \[tag] with the tag specified in the helm chart's values.yaml file under:\
appsec.image.tag

Upload the downloaded container image to the custom container registry.

Adjust the container reference in helm chart's values.yaml or with helm command parameters here to point to the container in the custom registry:

appsec.image.repository\
appsec.image.image\
appsec.image.tag

For the **open-appsec learning** container run:

```
docker pull ghcr.io/openappsec/open-appsec-learning:[tag]
```

Replace \[tag] with the tag specified in the helm chart's values.yaml file under:\
appsec.image.tag

Upload the downloaded container image to the custom container registry.

Adjust the container reference in helm chart's values.yaml or with helm command parameters here to point to the container in the custom registry:

appsec.learning.image.registry \
appsec.learning.image.image\
appsec.learning.image.tag

For the **open-appsec shared storage** container run:

```
docker pull ghcr.io/openappsec/open-appsec-shared-storage:[tag]
```

Replace \[tag] with the tag specified in the helm chart's values.yaml file under:\
appsec.image.tag

Upload the downloaded container image to the custom container registry.

Adjust the container reference in helm chart's values.yaml or with helm command parameters here to point to the container in the custom registry:

appsec.storage.image.registry\
appsec.storage.image.image\
appsec.storage.image.tag\
\
\
For the **open-appsec tuning** container run:

```
docker pull ghcr.io/openappsec/open-appsec-tuning:[tag]
```

Replace \[tag] with the tag specified in the helm chart's values.yaml file under:\
appsec.tuning.image.tag

Upload the downloaded container image to the custom container registry.

Adjust the container reference in helm chart's values.yaml or with helm command parameters here to point to the container in the custom registry:

appsec.tuning.image.registry\
appsec.tuning.image.image\
appsec.tuning.image.tag
{% endtab %}

{% tab title="Kong Gateway" %}

For the **kong/kong-gateway container** image run one of the following:

* For `kong` container:

```
docker pull ghcr.io/openappsec/kong-attachment:[tag]
```

* For `kong-gateway` container:

```
docker pull ghcr.io/openappsec/kong-gateway-attachment:[tag]
```

Replace \[tag] with the tag specified in the helm chart's values.yaml file under:\
appsec.kong.image.tag

Upload the downloaded container image to the custom container registry.

Adjust the container reference in helm chart's values.yaml or with helm command parameters here to point to the container in the custom registry:

appsec.kong.image.repository (image and repo)\
appsec.kong.image.tag&#x20;

For the **open-appsec agent sidecar** container run:

```
docker pull ghcr.io/openappsec/agent:[tag]
```

Replace \[tag] with the tag specified in the helm chart's values.yaml file under:\
appsec.image.tag

Upload the downloaded container image to the custom container registry.

Adjust the container reference in helm chart's values.yaml or with helm command parameters here to point to the container in the custom registry:

appsec.image.repository\
appsec.image.image\
appsec.image.tag

For the **open-appsec learning** container run:

```
docker pull ghcr.io/openappsec/open-appsec-learning:[tag]
```

Replace \[tag] with the tag specified in the helm chart's values.yaml file under:\
appsec.image.tag

Upload the downloaded container image to the custom container registry.

Adjust the container reference in helm chart's values.yaml or with helm command parameters here to point to the container in the custom registry:

appsec.learning.image.registry \
appsec.learning.image.image\
appsec.learning.image.tag

For the **open-appsec shared storage** container run:

```
docker pull ghcr.io/openappsec/open-appsec-shared-storage:[tag]
```

Replace \[tag] with the tag specified in the helm chart's values.yaml file under:\
appsec.image.tag

Upload the downloaded container image to the custom container registry.

Adjust the container reference in helm chart's values.yaml or with helm command parameters here to point to the container in the custom registry:

appsec.storage.image.registry\
appsec.storage.image.image\
appsec.storage.image.tag\
\
\
For the **open-appsec tuning** container run:

```
docker pull ghcr.io/openappsec/open-appsec-tuning:[tag]
```

Replace \[tag] with the tag specified in the helm chart's values.yaml file under:\
appsec.tuning.image.tag

Upload the downloaded container image to the custom container registry.

Adjust the container reference in helm chart's values.yaml or with helm command parameters here to point to the container in the custom registry:

appsec.tuning.image.registry\
appsec.tuning.image.image\
appsec.tuning.image.tag

{% hint style="warning" %}
Proceed similarly for any additional Kong-related containers that are required as part of your Kong deployment (e.g. Kong ingress controller, database, ...).
{% endhint %}
{% endtab %}

{% tab title="APISIX" %}

For the **APISIX-gateway container** image run one of the following:

```
docker pull ghcr.io/openappsec/apisix-attachment:[tag]
```

Replace \[tag] with the tag specified in the helm chart's values.yaml file under:\
appsec.apisix.image.tag

Upload the downloaded container image to the custom container registry.

Adjust the container reference in helm chart's values.yaml or with helm command parameters here to point to the container in the custom registry:

appsec.kong.image.repository (image and repo)\
appsec.kong.image.tag&#x20;

For the **open-appsec agent sidecar** container run:

```
docker pull ghcr.io/openappsec/agent:[tag]
```

Replace \[tag] with the tag specified in the helm chart's values.yaml file under:\
appsec.image.tag

Upload the downloaded container image to the custom container registry.

Adjust the container reference in helm chart's values.yaml or with helm command parameters here to point to the container in the custom registry:

appsec.image.repository\
appsec.image.image\
appsec.image.tag

For the **open-appsec learning** container run:

```
docker pull ghcr.io/openappsec/open-appsec-learning:[tag]
```

Replace \[tag] with the tag specified in the helm chart's values.yaml file under:\
appsec.image.tag

Upload the downloaded container image to the custom container registry.

Adjust the container reference in helm chart's values.yaml or with helm command parameters here to point to the container in the custom registry:

appsec.learning.image.registry \
appsec.learning.image.image\
appsec.learning.image.tag

For the **open-appsec shared storage** container run:

```
docker pull ghcr.io/openappsec/open-appsec-shared-storage:[tag]
```

Replace \[tag] with the tag specified in the helm chart's values.yaml file under:\
appsec.image.tag

Upload the downloaded container image to the custom container registry.

Adjust the container reference in helm chart's values.yaml or with helm command parameters here to point to the container in the custom registry:

appsec.storage.image.registry\
appsec.storage.image.image\
appsec.storage.image.tag\
\
\
For the **open-appsec tuning** container run:

```
docker pull ghcr.io/openappsec/open-appsec-tuning:[tag]
```

Replace \[tag] with the tag specified in the helm chart's values.yaml file under:\
appsec.tuning.image.tag

Upload the downloaded container image to the custom container registry.

Adjust the container reference in helm chart's values.yaml or with helm command parameters here to point to the container in the custom registry:

appsec.tuning.image.registry\
appsec.tuning.image.image\
appsec.tuning.image.tag

{% hint style="info" %}
Proceed similarly for any additional APISIX-related containers that are required as part of your APISIX deployment (e.g. APISIX ingress controller, database, ...).
{% endhint %}

{% endtab %}
{% endtabs %}

#### Step 3: Use open-appsec helm chart for install and CRD deployment in GitOps CD

Use the following helm command in your git repo for declarative deployment of open-appsec to your cluster via GitOps CD. This will also add the CRDs for open-appsec's new custom K8s resource types that will be used later for defining the protection policies, logging settings, exceptions, user response and more.

{% hint style="warning" %}
Make sure to check the documentation of your GitOps CD tool how exactly it requires the helm command and the helm parameters to be specified in the git repo.
{% endhint %}

{% tabs %}
{% tab title="NGINX Ingress Controller" %}

```
helm install open-appsec-k8s-nginx-ingress-latest.tgz \
--name-template=open-appsec \
--set appsec.mode=standalone \
--set controller.ingressClass=appsec-nginx \
--set controller.ingressClassResource.name=appsec-nginx \
--set controller.ingressClassResource.controllerValue="k8s.io/appsec-nginx" \
--set appsec.persistence.enabled=false \
--set controller.service.externalTrafficPolicy=Local \
-n appsec --create-namespace
```

{% endtab %}

{% tab title="Kong Gateway" %}

```
helm install open-appsec-k8s-kong-latest.tgz \
--name-template=open-appsec \
--set appsec.mode=standalone \
--set ingressController.ingressClass=appsec-kong \
--set appsec.persistence.enabled=false \
--set appsec.userEmail="<your-email-address>" \
-n appsec --create-namespace
```

{% endtab %}

{% tab title="APISIX" %}

```
helm install open-appsec-k8s-apisix-latest.tgz \
--name-template=appsec-apisix \
--set appsec.mode=standalone \
--set rbac.create=true \
--set service.type=LoadBalancer \
--set appsec.persistence.enabled=false \
--set ingress-controller.enabled=true \
--set ingress-controller.config.kubernetes.ingressClass=appsec-apisix \
--set appsec.userEmail="<your-email-address>" \
--set appsec.agentToken= \
--create-namespace \
-n appsec-apisix
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
If you stored the helm chart in your own helm repo adjust the helm chart URL above accordingly. \
If you stored the container images in your own container registry don't forget to add the parameters mentioned in Step 1 and Step 2 above to the helm install command to specify the new locations.
{% endhint %}

{% hint style="warning" %}
Note: The above requires persistent storage to be available in your K8s cluster, otherwise set the value for the appsec.persistence.enabled to false.
{% endhint %}

{% hint style="info" %}
More details on the available helm parameters: [Install Using Helm](/getting-started/start-with-kubernetes/install-using-helm#optional-helm-install-parameters)\
For the full list of available parameters please see the values.yaml file in the helm chart.
{% endhint %}

## Configuration

#### Step 4:  Create custom CRDs for configuration&#x20;

Create all required custom CRDs as .yaml files and place them in your Git repo.\
Specify the code locations as required by your GitOps CD tool for deployment to your cluster.\
\
You find all details as well as examples for the available CRDs here: [Configuration Using CRDs](/getting-started/start-with-kubernetes/configuration-using-crds)

You would typically create at least one of each of the following custom resources to get started:

* policy.openappsec.io
* practice.openappsec.io
* logtrigger.openappsec.io

#### Step 5: Add annotation to ingress resource to activate open-appsec

Specify the policy CRD you created in the ingress resource you want to protect with open-appsec.

In the example below replace "open-appsec-custom-policy" with the name of the policy resource you created.

```yaml
openappsec.io/policy: open-appsec-custom-policy
```

**Step 6: Change the ingressClassName to use open-appsec**

{% tabs %}
{% tab title="Ingress NGINX" %}
In the ingress definition make sure to set the ingressClassName to use open-appsec.

```yaml
spec: ingressClassName: appsec-nginx
```

{% endtab %}

{% tab title="Kong" %}
In the ingress definition make sure to set the ingressClassName to use open-appsec.

```yaml
spec: ingressClassName: appsec-kong
```

{% endtab %}

{% tab title="APISIX" %}

```
spec: ingressClassName: appsec-apisix
```

{% endtab %}
{% endtabs %}

#### Done! Now open-appsec's deployment, configuration as well as the activation and policy assignment in the selected ingress resource or for Kong Gateway are configured declaratively as code.

{% hint style="info" %}
Instead of configuring open-appsec declaratively via your git repo using CRDs it's possible to use the open-appsec's cloud management WebUI while continuing to use GitOps CD for the actual deployment of open-appsec.

Create or access your open-appsec tenant here: [https://my.openappsec.io](http://my.openappsec.io)

Create or access a new profile of type "Kubernetes profile" in the WebUI.

Then use the helm chart in the same way as above in your code repo, but adjust/include the following two paramenter settings:\
\
Adjust the management mode helm parameter to switch to central management:&#x20;

\--set appsec.mode="managed"\
\
Add following helm parameter (replace \[token] with your open-appsec profile's token) to associate your open-appsec deployment with the selected profile in your cloud management:

\--set appsec.agentToken=\[token]

(Copy the token from profile's properties under Authentication -> Token in the WebUI.)
{% endhint %}


# Build open-appsec Based on Source Code

### open-appsec Source Code (GitHub)

As open-appsec is open source you can build/compile its different software components yourself based on the available sources.

The different source code repos are available in the open-appsec GitHub account: <https://github.com/openappsec>

### Available open-appsec Source Code Repositories&#x20;

Here's a list of open-appsec software components and the corresponding source code repos.\
In each of the repos you find instructions how to build software and if relevant also the containerized version yourself, deployment instructions where relevant as well as the license information.

#### open-appsec Agent

This is the main open-appsec software running as the open-appsec agent. It contains the contextual machine learning engine.

The source code for the open-appsec software is available in this repo:

{% embed url="<https://github.com/openappsec/openappsec>" %}

In the README.md you will find instructions how to

* build the installation package
* build a corresponding container image&#x20;
* install it

#### open-appsec Attachment

open-appsec Attachments connect between processes that provide HTTP data and the open-appsec Agent security logic.

The source code for the open-appsec attachment is available in this repo:

{% embed url="<https://github.com/openappsec/attachment>" %}

In the README.md you will find instructions how to&#x20;

* build the attachment suitable for your specific environment (OS, NGINX version, Platform)
* build a container image enhanced with the open-appsec attachment for an existing nginx container&#x20;
* deploy it to NGINX / Kong

#### smartsync Service (relevant for K8s only)

open-appsec smartsync service is in charge of correlating learning data from multiple agent instances and delivering a unified learning model for each asset.

The source code for the open-appsec smartsync service is available in this repo:

{% embed url="<https://github.com/openappsec/smartsync>" %}

In the README.md you will find instructions how to

* build the smartsync service
* build a container image for the smartsync service

#### smartsync-shared-files Service (relevant for K8s only)

open-appsec smartsync-shared-files service provides an interface to physical storage used by smartsync service for storing learning data.\
\
The source code for the open-appsec smartsync-shared-files service is available in this repo:

{% embed url="<https://github.com/openappsec/smartsync-shared-files>" %}

In the README.md you will find instructions how to

* build the smartsync-shared-files service
* build a container image for the smartsync-shared-files service


# Deploying open-appsec WAF on AWS ECS

This guide explains how to deploy the open-appsec Web Application Firewall (WAF) on Amazon Elastic Container Service (ECS).

{% hint style="warning" %}
The deployment process and configuration options may change based on updates to Amazon ECS and open-appsec. Please validate the latest requirements and options before deploying.
{% endhint %}

### Prerequisites

#### For Declarative Configuration

* Create a `local_policy.yaml` file with your desired configuration and save it in a local directory.
* Use this directory in the Docker run command as `<path-to-persistent-location-for-local-configuration-file>`.
* You can also download the default `local_policy.yaml` from the open-appsec GitHub repository. Full details about the file structure can be found [here](https://github.com/openappsec/openappsec/tree/main/config).

#### For Connecting to WebUI (SaaS)

* Create an agent profile in your SaaS tenant for the open-appsec Docker deployment.

{% content-ref url="/pages/WMgZp7bTMiI5PD1ocIKp" %}
[Create a Profile](/getting-started/using-the-web-ui-saas/create-a-profile)
{% endcontent-ref %}

### Method 1: Manual Setup via the ECS Console

#### Step 1: Create or Access Your ECS Cluster

1. **Open the ECS Console:** Go to the [ECS console](https://console.aws.amazon.com/ecs) and either create a new cluster or access an existing cluster.
2. **Create a Cluster (Optional):**
   * Choose a launch type.
   * Configure the cluster settings as needed (network, compute options, etc.).

#### Step 2: Create a New Task Definition

1. **Open Task Definitions:** Navigate to "Task Definitions" in the ECS console.
2. **Create New Task Definition:**
   * Choose EC2 or Fargate, depending on your cluster type.
3. **Configure Infrastructure Requirements:** Define the required CPU, memory, and IAM roles. Be sure to select roles that allow access to necessary AWS services and network resources.

#### Step 3: Define Container Settings

1. **Add a Container Definition:** In the task definition, add a container using the following details:
   * **Image URI:**\
     `ghcr.io/openappsec/agent-unified:<version>`\
     (You can use the latest version by using `:latest` in place of `<version>`).
2. **Port Mappings:** Specify the necessary port mappings. We recommend allowing SSH communication on your deployment to help with debugging, especially if issues arise with the agent.
3. **Volumes (Optional):**\
   Add the following volume mounts based on your setup requirements:

   * `<host-openappsec-logs>:/var/log/nano_agent`
   * `<host-openappsec-conf-path>:/etc/cp/conf`
   * `<host-openappsec-data-path>:/etc/cp/data`
   * `<host-certs-path>:<container-certs-path>`
   * `<host-nginx-conf-path>:/etc/nginx/conf.d`

   These volumes are optional but recommended for persisting logs, configurations, and data between deployments.
4. **Environment Variables:** \
   Add an environment variable for the WebUI token:
   * Key: `AGENT_TOKEN`
   * Value: `<YOUR_PROFILE_TOKEN>` copied from the profile created in the prerequisites&#x20;

#### Step 4: Docker Configuration

1. **Entry Point:**\
   Use the following entry point for the container:

   ```bash
   /cp-nano-agent
   ```
2. **Working Directory:**\
   Set the working directory to root:

   ```bash
   /
   ```

#### Step 5: Run the Task

1. **Create a Service:**\
   After defining the task, you can launch it by creating a service in ECS. This will ensure your open-appsec WAF runs continuously, scaling based on your needs.
2. **Verify:**\
   Once the service is up, check the ECS logs and ensure the agent is running properly. You can also monitor logs through your defined volume mounts.

### Method 2: Automated Setup via JSON Task Definition

For users who prefer automating their setup, you can use the following ECS task definition in JSON format. This option is especially useful if you are deploying multiple environments or want to automate the process.

#### ECS Task Definition JSON Example

```json
{
  "containerDefinitions": [
    {
      "name": "openappsec-agent",
      "image": "ghcr.io/openappsec/agent-unified:latest",
      "memory": 512,
      "cpu": 256,
      "environment": [
        {
          "name": "AGENT_TOKEN",
          "value": "<YOUR_PROFILE_TOKEN>"
        }
      ],
      "portMappings": [
        {
          "containerPort": 80,
          "hostPort": 80
        },
        {
          "containerPort": 443,
          "hostPort": 443
        }
      ],
      "mountPoints": [
        {
          "sourceVolume": "openappsec-logs",
          "containerPath": "/var/log/nano_agent"
        },
        {
          "sourceVolume": "openappsec-conf",
          "containerPath": "/etc/cp/conf"
        },
        {
          "sourceVolume": "openappsec-data",
          "containerPath": "/etc/cp/data"
        }
      ],
      "entryPoint": ["/cp-nano-agent"],
      "command": [""],
      "workingDirectory": "/"
    }
  ],
  "volumes": [
    {
      "name": "openappsec-logs",
      "host": {
        "sourcePath": "<host-openappsec-logs>"
      }
    },
    {
      "name": "openappsec-conf",
      "host": {
        "sourcePath": "<host-openappsec-conf-path>"
      }
    },
    {
      "name": "openappsec-data",
      "host": {
        "sourcePath": "<host-openappsec-data-path>"
      }
    }
  ]
}
```


# Upgrade Postgres version (Docker-Compose)

Here you will learn how to upgrade the postgres database version of your existing open-appsec deployment on docker (relevant for docker-compose-based deployment).

## When is a postgres database upgrade required?

**This is ONLY relevant if ALL of the following applies to your current deployment:**

* redeployment/ugprade of an **existing** open-appsec deployment\
  (this is not relevant for new deployments)
* current deployment is a **standalone** deployment\
  (without a web UI profile token provided in the `.env` file, when connecting to web UI with a profile token typically there should not be any local postgres database being deployed/used)
* current deployment has the `docker-compose` `standalone`  profile set in the `.env` file\
  (otherwise postgres container wouldn't be deployed/used at all)
* current postgres version shall be replaced with **newer postgres image version**, which is also a **new major release** (which means database conversion is required)

## Postgres database upgrade instructions

**Before upgrading from an existing to a newer major release postgres database version (using newer  postgres container version tag) in your existing open-appsec deployment on Docker, the existing database files must be converted properly for compatibility with the new version.**

{% hint style="info" %}
If you already switched and ran a newer postgres container image with new postgres major version, follow the instructions further below to run a script to fixing your postgres database structure so it will work with the new postgres version: [#how-to-recover-the-postgres-structure-if-postgres-version-was-upgraded-without-running-migrate\_postg](#how-to-recover-the-postgres-structure-if-postgres-version-was-upgraded-without-running-migrate_postg "mention")
{% endhint %}

* If you are not using the latest `docker-compose` files yet:\
  Download the latest `docker-compose.yaml` file and `.env` file and apply your desired configuration changes (see also [Deploy With Docker-Compose](/getting-started/start-with-docker/deploy-with-docker-compose))
* In the `.env` file set the value for `APPSEC_POSTGRES_VERSION` as required to a new major release postgres version.\
  This setting will be used for the database upgrade using the script below and also as the tag for the new `postgres` container to be deployed (postgres database downgrades are not supported!)
* Now run the `migrate-postgres.sh` script following these steps before deploying the updated environment with `docker-compose`:

{% hint style="warning" %}
Your current deployment including the postgres container should still be running when performing this step!
{% endhint %}

```bash
wget https://downloads.openappsec.io/scripts/migrate_postgres.sh
chmod +x ./migrate_postgres.sh
./migrate_postgres.sh
```

This script will automatically migrate the existing postgres database to the database format of the new postgres version specified in the `.env` file in with this configuration key: `APPSEC_POSTGRES_VERSION`.

* Now you can restart your existing `docker-compose`-based deployment including pulling the new container images<br>

  ```bash
  docker-compose down
  docker-compose pull
  docker-compose up -d
  ```

You now have an open-appsec deployment with an upgraded postgres database version up and running.

## Recover postgres structure if postgres version was upgraded without running migrate\_postgres.sh tool first

If you already switched and ran a newer postgres container image with new postgres major version, follow the instructions further below to fix your postgres database structure retroactively so it will work correctly with the new postgres version.&#x20;

Perform these steps to download and run a script which recovers your postgres structure to make it work correctly with your new postgres major version.

{% hint style="warning" %}
These commands should be executed from within your deployment folder which also holds the `docker-compose.yaml` and the `.env` file.
{% endhint %}

```bash
wget https://downloads.openappsec.io/scripts/recover_postgres_structure.sh
chmod +x ./recover_postgres_structure.sh
./recover_postgres_structure.sh 
```


# Management Web UI

{% content-ref url="/pages/8mbENukkfe58OTQM2Pxg" %}
[Analyze Security Events with Event Advisor](/management-web-ui/analyze-security-events-with-event-advisor)
{% endcontent-ref %}

{% content-ref url="/pages/eTPGGbzkcEh2jH107cA0" %}
[Track Agent Status](/management-web-ui/track-agent-status)
{% endcontent-ref %}

{% content-ref url="/pages/nMBMbys5j9lGOhI9BwUv" %}
[Delete or Reset Management Tenant (SaaS)](/management-web-ui/delete-or-reset-management-tenant-saas)
{% endcontent-ref %}

{% content-ref url="/pages/KKCuKIjbagKniwvsrsKi" %}
[Disconnect an open-appsec agent from Central Management](/management-web-ui/disconnect-an-open-appsec-agent-from-central-management)
{% endcontent-ref %}


# Analyze Security Events with Event Advisor

## Overview <a href="#overview" id="overview"></a>

The **AI-based Event Advisor** helps you get detailed insight into open-appsec Security Events and is divided into three easy-to-read sections:

* What Happened?
* Why Was It Blocked?
* What Should You Do?

## How to Use <a href="#how-to-enable" id="how-to-enable"></a>

* Navigate to your open-appsec Security Logs in the Monitoring section.
* Right-click on any individual log entry.
* Select “Event Advisor” from the context menu.
* A panel opens on the right-hand side of the screen, showing the detailed event analysis.

![](https://waf-doc.inext.checkpoint.com/~gitbook/image?url=https%3A%2F%2F2760087783-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FEWA4nfgNrSRL8dA6Kap7%252Fuploads%252F4AWPK7h9Uhldfba5olZ0%252Fimage.png%3Falt%3Dmedia%26token%3D5304bdd1-5064-4ac3-8cf2-f500773306a6\&width=768\&dpr=4\&quality=100\&sign=56ce8dd0\&sv=2)

## Event Advisor Output <a href="#the-adviser-output" id="the-adviser-output"></a>

![](https://waf-doc.inext.checkpoint.com/~gitbook/image?url=https%3A%2F%2F2760087783-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FEWA4nfgNrSRL8dA6Kap7%252Fuploads%252FsqC2VYKLunydJ72VGIWd%252Fimage.png%3Falt%3Dmedia%26token%3Dbf642b15-2d6a-4c74-ad21-4a4cf1e71199\&width=768\&dpr=4\&quality=100\&sign=e0f80b90\&sv=2)

### **What Happened?**

This section gives a short, clear summary of the event.

* It shows the request method (GET, POST, etc.), the source IP, the destination host/path, and whether the request was blocked or detected.
* Example: “*A POST request from 192.168.0.1 to the root path of "example.com" was blocked due to missing authentication token*.”

### **Why Was It Blocked?**

This section explains why open-appsec took action.

* It describes what was missing, suspicious, or malicious in the request.
* Example: “*The request contained patterns matching Java JNDI injection attempts in the URL path. The presence of 'jndi:' in the URI is a strong indicator of an attempt to exploit Log4j vulnerabilities (Log4Shell) or similar Java deserialization attacks. The request also matched XPath injection patterns. These attacks could allow remote code execution or unauthorized data access on the target system*.*”*

### **What Should You Do?**

This section provides recommended next steps.

The guidance here always starts with the verdict sentence, then adds 2–3 hardening steps relevant to the detected attack type(s):

* **If malicious (blocked/detected):**\
  No action is required.
* **If likely a false positive (blocked/detected but looks legitimate)**:\
  Create a narrow Custom Rule/Exception for the specific URL and parameter or click ‘Report misclassification’.

### **Reporting Misclassification**

If you believe the log classification is incorrect (for example, a false positive), you can click Report misclassification.


# Track Agent Status

## Banner Notifications about Agents

When an agent is first connected a green banner will be shown in open-appsec's web application regardless of your location within the application, informing about the agent connection and including links to the Agents or Events view.

![](/files/aej4qGwZrFZQdf9frOX5)

## Agents View

Go to **Agents**&#x20;

![](/files/hGppaSA3FJTNA8GlZhNe)

#### Agents Table View

The table columns show the important details of the agent like the agents profile to which the agent has connected.

* **Latest Version** - This column indicates if the agent's software version is the latest. It is recommended you always keep your agent updated as new versions are released frequently.
* **Policy Version** - This column indicates the policy version. \
  If the column is empty, it means the agent has registered but is currently being installed and has not received yet its first policy.\
  The latest policy version can also be seen when browsing to **Profiles**, selecting the relevant profile and looking at the advanced tab (version is "V3" in the below screenshot):

<figure><img src="/files/jX8DeJGXhI0LMa8igaRr" alt=""><figcaption></figcaption></figure>

#### Agent Details Card

When selecting an agent in the table, the bottom card shows more advanced details of the agent.

#### Disconnected agents

It is possible to toggle the view to see agents that were previously connected but have not created any communication for over 15 minutes. This can assist with troubleshooting.

<div align="left"><img src="/files/RsbOuFP3BcHmXbQbY2jG" alt=""></div>

{% hint style="warning" %}
A disconnected agent might also indicate the workload it has been installed on is offline, or that connectivity to Check Point cloud has been disrupted.\
When an agent, which should be connected, is disconnected, please verify the Web Server/Reverse Proxy that agent is installed on is live and with connectivity before additional actions.
{% endhint %}


# Delete or Reset Management Tenant (SaaS)

## Delete Tenant

The delete tenant feature allows you to completely delete the tenant and cancel any associated subscriptions at the next possible date.

{% hint style="warning" %}
This action is permanent and your tenant and all configuration data within it will be deleted and will not be recoverable.
{% endhint %}

The "Delete this tenant" functionality is available in the "Tenant Profile" settings which can be accessed from the user menu:

<figure><img src="/files/F5F5AHaiNVaf5FFcuEUG" alt=""><figcaption><p>"Edit Tenant Profile" option in User Menu</p></figcaption></figure>

In order to Delete tenant click the "Delete" button as shown below.

<figure><img src="/files/0Xm9M5WfStUf6WxKkPM4" alt=""><figcaption><p>"Delete this tenant" option in "Tenant Profile" settings</p></figcaption></figure>

## Reset Tenant

The reset tenant feature allows you to reset your tenant's configuration to its default state (like a new tenant) but will keep all existing users, their assigned permissions as well as existing log data.

A typical use case would be if you did some initial configuration for testing and decide you want to start from scratch using the very same tenant.

{% hint style="warning" %}
This action is permanent and all configuration within your tenant will be deleted and will not be recoverable, except for existing users, their assigned permissions and existing log data.
{% endhint %}

The "Delete this tenant" functionality is available in the "Tenant Profile" settings which can be accessed from the user menu:

<figure><img src="/files/F5F5AHaiNVaf5FFcuEUG" alt=""><figcaption><p>"Edit Tenant Profile" option in User Menu</p></figcaption></figure>

In order to Reset tenant click the "Delete" button as shown below.

<figure><img src="/files/RBBbs8kKTC0QzDhOZB9U" alt=""><figcaption><p>"Reset your tenant" option in "Tenant Profile" settings</p></figcaption></figure>


# Disconnect an open-appsec agent from Central Management

When working with open-appsec, there are two management systems: **Declarative Management** and **Central Management**. Depending on your setup, the steps to disconnect an agent may vary.

Agents can be deleted from central management using the Delete button, please note that while the agent won't be displayed in the Web UI it won't be uninstall.&#x20;

<figure><img src="/files/nUWP6Eqlr4jLKBtK5rbL" alt=""><figcaption></figcaption></figure>

#### **Disconnecting from Central Management**

The **recommended** and safest way to disconnect an agent from Central Management is to **uninstall** it and then redeploy. This ensures a clean disconnection and avoids potential issues.

However, if you need to **disconnect the agent quickly and temporarily**, follow these steps based on your environment.

**Linux:**&#x20;

Currently, manual disconnection is **not available**. To disconnect, you must **uninstall and reinstall** the agent:

```
./open-appsec-install --uninstall
./open-appsec-install --auto
```

**Docker:**

**Remove the AGENT\_TOKEN Environment Variable**

The agent authenticates with Central Management using the `AGENT_TOKEN`. To disconnect, **remove** it from your Docker configuration.

Modify your **Docker command** or **Docker Compose file** to exclude the `AGENT_TOKEN`:

* **Modify the Docker Command or Docker Compose File**:\
  Edit your Docker configuration by removing the `AGENT_TOKEN` environment variable,

  ```yaml
  environment:
    - AGENT_TOKEN=
  ```

* **Remove the presistance folders:** Delete the following persistent storage mounts to clear cached configuration and data:

```bash
${APPSEC_CONFIG}:/etc/cp/conf - 
${APPSEC_DATA}:/etc/cp/data - 
${APPSEC_LOGS}:/var/log/nano_agent
```

* &#x20;**Ensure the Correct Policy Setup**
  * If you are using **Declarative Management**, ensure that the local policy file is still **mounted to `/ext/appsec`**.
  * If you were using **Central Management**, you will need to **add a local policy** before restarting.
* **Restart the Agent**:\
  After making the change, restart the agent to apply the update:

  ```bash
  docker-compose up -d
  ```

#### Kubernetes:

1. **Uninstall** the deployment.

```
helm list -n <namespace>
helm uninstall <release-name> -n <namespace>
```

2. Verify that **no persistent volumes** remain.
3. Redeploy, usimng instrcions bellow:

{% content-ref url="/pages/XzPA7UFoksUJscLSZUHf" %}
[Start With Kubernetes](/getting-started/start-with-kubernetes)
{% endcontent-ref %}


# About Integrations With 3rd Party Solutions

As an open-source solution open-appsec embraces integrations with other open-source projects and provides options for integration with other 3rd party solutions.

{% hint style="info" %}
Please note that you find the primary deployment integrations for NGINX, NGINX Ingress and Kong in the [Getting Started](/getting-started/getting-started) section of this documentation.
{% endhint %}

Here's the current list of available integrations with 3rd party solutions. More will be added in the future. If you would like to suggest additional integrations let us know via the chat on the website <https://www.openappsec.io> .

{% hint style="info" %}
With regards to full details about capabilities, deployment and usage of the 3rd party solutions that open-appsec integrates with, please visit that specific projects website and docs.
{% endhint %}

### Available 3rd party integrations:

#### open-appsec bouncer support for CrowdSec

Allows open-appsec to consume CrowdSec Threat Intelligence (CTI) as provided by the CrowdSec API for additional threat prevention/detection capabilities based on IP and network based threat indicators.&#x20;

{% content-ref url="/pages/m6M2an1zE2ucev1Uo44x" %}
[CrowdSec Bouncer Support](/integrations/crowdsec/crowdsec-bouncer-support)
{% endcontent-ref %}

#### open-appsec parser/scenario support for CrowdSec

Allows open-appsec logs to be evaluated by a CrowdSec parser/scenario combination so that these can be consumed by a CrowdSec agent as additional Threat Intelligence indicators within the CrowdSec ecosystem.&#x20;

{% content-ref url="/pages/VnIOQZLbFvD7lgvy00dw" %}
[CrowdSec Intelligence Sharing Using open-appsec Parser/Scenario](/integrations/crowdsec/crowdsec-intelligence-sharing-using-open-appsec-parser-scenario)
{% endcontent-ref %}

#### open-appsec Integration with NGINX Proxy Manager

Integration of open-appsec WAF with NGINX Proxy manager, enabling NGINX Proxy Manager (NPM) users to protect their NGINX reverse proxy by easily activating and configuring open-appsec protection for each of the configured Proxy Host objects in NPM directly from the Web UI (or via central SaaS WebUI) and monitor security events.

{% content-ref url="/pages/XlfFqJpuzT3LtYuqIpmf" %}
[NGINX Proxy Manager](/integrations/nginx-proxy-manager)
{% endcontent-ref %}

#### open-appsec Integration with NPMplus

Integration of open-appsec WAF with NPMplus, which is a project forking NGINX Proxy Manager to provide various additional capabilities on top of it.&#x20;

{% content-ref url="/pages/UA2XRtFDlgkm1nQ1YqEB" %}
[NPMplus](/integrations/npmplus)
{% endcontent-ref %}

#### open-appsec Integration with Docker SWAG

This integration enhances and secures your Docker SWAG deployment with automatic and preemptive threat prevention using machine learning to protect the web services exposed by Docker SWAG protecting against zero-day and OWASP-TOP-10 attacks.

{% content-ref url="/pages/QeaecnKQ1TrTdxRgnqIW" %}
[Docker SWAG](/integrations/docker-swag)
{% endcontent-ref %}


# CrowdSec

This section covers two optional integrations between **CrowdSec** and **open-appsec**, designed to enhance your threat detection and mitigation capabilities:

{% content-ref url="/pages/m6M2an1zE2ucev1Uo44x" %}
[CrowdSec Bouncer Support](/integrations/crowdsec/crowdsec-bouncer-support)
{% endcontent-ref %}

{% content-ref url="/pages/VnIOQZLbFvD7lgvy00dw" %}
[CrowdSec Intelligence Sharing Using open-appsec Parser/Scenario](/integrations/crowdsec/crowdsec-intelligence-sharing-using-open-appsec-parser-scenario)
{% endcontent-ref %}

Choose one or both integrations depending on your use case and deployment needs.


# CrowdSec Bouncer Support

{% hint style="info" %}
Note: open-appsec integration with CrowdSec is currently in alpha.\
It currently supports:\
\- open-appsec for NGINX ingress controller on K8s \
\- open-appsec Docker with NGINX and Kong\
more platforms and integrations will be added soon.
{% endhint %}

### About CrowdSec

CrowdSec is an open-source project which provides crowd-sourced protection against malicious IP addresses. The CrowdSec Threat Intelligence (CTI) distributes reputation intelligence for e.g. known malicious IP addresses and networks, which originates from tens of thousands of CrowdSec users sharing their local threat intelligence data with the community using "parsers" and "scenarios" to generate threat indicators based on 3rd party security logs like open-appsec.\
The actual enforcement of these CTI indicators is performed by 3rd party (security) solutions like open-appsec that provide so called "CrowdSec bouncers" allowing them to block traffic from those indicators in addition to their own (security) capabilities.

More information about CrowdSec: [www.crowdsec.net](https://www.crowdsec.net)\
CrowdSec Docs: [docs.crowdsec.net](https://docs.crowdsec.nwet)\
CrowdSec Threat Intelligence (CTI): [www.crowdsec.net/product/threat-intelligence](https://www.crowdsec.net/product/threat-intelligence)

Here's an overview of the CrowdSec integration architecture:

<figure><img src="/files/dPeQOrqjRBwFmPp6MoJI" alt=""><figcaption></figcaption></figure>

### open-appsec bouncer for CrowdSec Threat Intelligence (CTI)

open-appsec's provides CrowdSec integration by offering a CrowdSec "bouncer".\
This allows open-appsec to detect or prevent traffic based on CrowdSec's CTI indicators (source IP addresses and source IP networks) in addition to its own various security capabilities like the contextual ML engine, IPS and more.

{% hint style="warning" %}
Please make sure to also install the base-http-scenarios in your CrowdSec deployment to get all relevant HTTP/HTTPS based IP indicators from CrowdSec Threat Intelligence.\
\
These are available here:\
<https://hub.crowdsec.net/author/crowdsecurity/collections/base-http-scenarios>
{% endhint %}

### Configuration

#### Prerequisites:

Make sure the following prerequisites are met:

* Existing installation of open-appsec for NGINX Ingress Controller (see: [Start with Kubernetes](/getting-started/start-with-kubernetes))
* Existing installation of CrowdSec on the K8s cluster with accessible LAPI (= local API, exposed by crowdsec-lapi pod) (see: [docs.crowdsec.net](https://docs.crowdsec.net/)) OR access to some CrowdSec LAPI
* URL known for the CrowdSec API to be used (LAPI)
* API key created and known allowing access to CrowdSec API (LAPI)

{% hint style="warning" %}
Note that support for direct connection to CrowdSec CAPI isn't available yet, but will be added soon.\
Therefor please connect to LAPI which will provide Intelligence from the CAPI as well like the CrowdSec Community Blocklist.
{% endhint %}

{% tabs %}
{% tab title="NGINX Ingress (Helm)" %}
In Kubernetes the configuration of open-appsec's CrowdSec bouncer functionality is maintained in a ConfigMap and confidential information like the API key in a Secret.

The easiest way is to configure the content of the configmap and secret directly using the values listed below with the deployment of open-appsec using Helm.\
Alternatively you can just specify the name of the ConfigMap and the Secret using the corresponding Helm values and populate their contents yourself (e.g. using a GitOps CD process).\
\
**List of available key-values:**

`appsec.configMapName: STRING`\
allows you to specify the name of the configMap for advanced open-appsec configurations (default is "appsec-settings-configmap")&#x20;

`appsec.configMapContent.crowdsec.enabled: {true|false}` \
enable or disable CrowdSec bouncer

`appsec.configMapContent.crowdsec.mode: {detect|prevent}`\
set enforcement mode for the CrowdSec bouncer to "detect" or "prevent"

`appsec.configMapContent.crowdsec.logging: {enabled|disabled}`\
enable or disable the logging of security events based on CrowdSec Threat Intelligence

`appsec.configMapContent.crowdsec.api.url: STRING`\
configure the URL that is used by open-appsec to communicate with the CrowdSec API (LAPI or CAPI), default is <http://crowdsec-service:8080/v1/decisions/stream> (which is example for the LAPI (local API) as exposed by the crowdsec-lapi pod in K8s)

`appsec.configMapContern.crowdsec.auth.method: [apikey]`\
select desired authentication method for the authentication against the CrowdSec API (note that currently only authentication using API key is supported) (default is "apikey")

`appsec.secretName: STRING`\
specify the name of the secret holding confidential information like api-keys (default is "appsec-settings-secret")

`appsec.secretContent.crowdsec.auth.data:` \
provide the CrowdSec API key which open-appsec will use to authenticate against the API

Note: You can e.g. get this for the LAPI (local API) using CrowdSec's "cscli" command as follows (or you can create it for the CAPI (central API) in CrowdSec's WebUI), you will then see an API key shown in the resulting output.

```
cscli bouncers add openappsec
```

{% hint style="warning" %}
Note: When changing the above parameters make sure that the open-appsec ingress controller pod is redeployed for the performed changes to become effective.
{% endhint %}
{% endtab %}

{% tab title="Docker" %}
In Docker environments (Kong and NGINX) the configuration of open-appsec's CrowdSec bouncer functionality is maintained using environment variables.\
\
You can enhance your existing `docker run` command for the open-appsec Agent with the following environment variables which are relevant specifically for CrowdSec.

**List of available environment variables:**\
\
`-e CROWDSEC_ENABLED={true|false}`\
enable or disable CrowdSec bouncer

`-e CROWDSEC_MODE={"detect"|"prevent"}`\
set enforcement mode for the CrowdSec bouncer to "detect" or "prevent"

`-e CROWDSEC_LOGGING={"enabled"|"disabled"}`\
enable or disable the logging of security events based on CrowdSec Threat Intelligence

`-e CROWDSEC_API_URL=["Add-CrowdSec-API-URL-here"]`\
configure the URL that is used by the open-appsec Agent to communicate with the CrowdSec API (LAPI), e.g. <http://crowdsec-service:8080/v1/decisions/stream> .

`-e CROWDSEC_AUTH_METHOD={apikey}`\
select desired authentication method for the authentication against the CrowdSec API (note that currently only authentication using API key is supported) (default is "apikey")

`-e CROWDSEC_AUTH_DATA=["Add-CrowdSec-API-Key-here"]`\
provide the CrowdSec API key which open-appsec will use to authenticate against the API
{% endtab %}

{% tab title="Linux" %}
Note that Linux support for open-appsec's CrowdSec bouncer functionality is not available yet but will be available soon. \
\
Please check this documentation again later.
{% endtab %}

{% tab title="WebUI (SaaS)" %}
{% hint style="warning" %}
Note that central configuration for open-appsec's CrowdSec bouncer functionality is not available yet but will be available soon. Until then please use the configuration via the CrowdSec helm chart. This will also continue to work when open-appsec is managed centrally via the WebUI (SaaS).\
\
Please check this documentation again later.
{% endhint %}
{% endtab %}
{% endtabs %}

**Congratulations, now you have successfully configured open-appsec to bounce traffic from malicious source IPs based on CrowdSec Threat Intelligence (CTI).**\
\
**Now is a good time to also configure your own CrowdSec deployment to share signals based on your local open-appsec Security Logs with CrowdSec's Threat Intelligence Community.**\
**You find the simple configuration steps below:**

{% content-ref url="/pages/VnIOQZLbFvD7lgvy00dw" %}
[CrowdSec Intelligence Sharing Using open-appsec Parser/Scenario](/integrations/crowdsec/crowdsec-intelligence-sharing-using-open-appsec-parser-scenario)
{% endcontent-ref %}

### Additional information

**Which Threat Intelligence is imported from the CrowdSec API?**\
\
open-appsec will load CrowdSec Threat Intelligence (CTI) via the configured CrowdSec API based on the following criteria, once connection to CrowdSec LAPI is configured:

* CTI with origin "capi", which contains tens of thousands "Shoot-in-sight" IPs with high confidence level of being indeed malicious (collaborative threat intelligence)
* CTI with origin "cscli" (local, manual threat intelligence) &#x20;
* CTI with origin "crowdsec" (local, automatic threat intelligence)
* Note that threat intelligence from scenarios where the CrowdSec scenario name contains "openappsec" or "open-appsec" and origin is "crowdsec" is NOT imported. The reason is explained below.

{% hint style="warning" %}
Note: This excluding filter allows you to use a custom local CrowdSec scenario on CrowdSec security engine side to parse the original open-appsec logs to create/share additional CrowdSec Threat Intelligence based on open-appsec's preemptive, ML-based detection capabilities which include zero day attack detection/prevention.\
Always make sure to include "open-appsec" in the name of such scenario for this filter to work to prevent a loop where IP-based indicators originating from open-appsec logs that are added to CrowdSec's local Threat Intelligence would then again be loaded by open-appsec.\
As open-appsec can itself prevent those attacks and provides much more in-depths details about each attack (like threat indicators included in the attack) it wouldn't make sense to have them blocked only based on the Source IP based on CrowdSec's indicators.
{% endhint %}

**Which CrowdSec Threat Intelligence can be detected/prevented by open-appsec?**

Based on the above filter criteria for importing CrowdSec Threat Intelligence (CTI) open-appsec is then able to detect or prevent (based on the configured mode for enforcement) all resulting CTI indicators with CrowdSec mode set to "ban" (IP addresses and networks).


# CrowdSec Intelligence Sharing Using open-appsec Parser/Scenario

When using CrowdSec alongside open-appsec to consume CrowdSec Threat Intelligence you might also want to have the CrowdSec security engine parse the security logs created by open-appsec's multiple security layers to add additional security indicators to your local CrowdSec "ecosystem" and share intelligence with CrowdSec Threat Intelligence to contribute to their Community Blocklist. \
To achieve this you can use our open-appsec collection available from the [CrowdSec Hub](https://hub.crowdsec.net/author/openappsec/collections/openappsec).

#### Required Parsers and Collections

In order to parse open-appsec logs within CrowdSec the following parsers require installation:

* [crowdsecurity/cri-logs](https://hub.crowdsec.net/author/crowdsecurity/configurations/cri-logs)
* [crowdsecurity/dateparse-enrich](https://hub.crowdsec.net/author/crowdsecurity/configurations/dateparse-enrich)

The following Collections must be installed:

* [crowdsecurity/nginx](https://hub.crowdsec.net/author/crowdsecurity/collections/nginx)
* [openappsec/openappsec](https://hub.crowdsec.net/author/openappsec/collections/openappsec)

### Required CrowdSec Configuration for Parsing open-appsec Logs

{% tabs %}
{% tab title="Kubernetes" %}

#### For CrowdSec and open-appsec both deployed on Kubernetes:

For information on how to deploy CrowdSec on Kubernetes with Helm see here:\
<https://artifacthub.io/packages/helm/crowdsec/crowdsec>\
\
Make sure to add the following configuration to your helm chart's **crowdsec-values.yaml** file:

1. Set the **container\_runtime** value to “**containerd**”.
2. Set the following docker image values in the "**image**" section:

   <pre><code><strong>repository = crowdsecurity/crowdsec
   </strong>pullPolicy = IfNotPresent
   tag = "v1.4.6"
   # mandatory to use CrowdSec container version v1.4.6 or later
   </code></pre>
3. Under the "**agent**" section, add an entry in the "**acquisition**" array and configure in with the following namespace, pod name and program values:

   <pre><code>namespace = "&#x3C;namespace-of-your-open-appsec-agent>"
   podName = "appsec-open-appsec-*"
   # make sure this query matches the names of the deployed open-appsec pods, especially if you adjusted the name-template parameter for the open-appsec deployment
   <strong>program = "openappsec"
   </strong></code></pre>
4. Under the "**agent**" section, add 2 entries in the "**env**" array:

   ```
   - name: PARSERS
     value: "crowdsecurity/cri-logs crowdsecurity/dateparse-enrich"
   - name: COLLECTIONS
     value: "crowdsecurity/nginx openappsec/openappsec"
   ```

{% endtab %}

{% tab title="Linux" %}

#### For CrowdSec and open-appsec both deployed on Linux:

1. Make sure to have a CrowdSec version >= 1.4.6 installed on your Linux machine, see <https://docs.crowdsec.net/docs/getting_started/install_crowdsec/>
2. Configure the acquisition for consuming the open-appsec log-files in CrowdSec's main yaml configuration file `/etc/crowdsec/config.yaml` as follows:

   ```
   source: file
   filenames:
     - /var/log/nano_agent/cp-nano-http-transaction-handler.log*
   labels:
     type: openappsec
   ```
3. Edit the following configuration file `/etc/crowdsec/collections/linux.yaml` \
   and add the relevant parsers and collections as shown below:

   ```
   parsers:
     - crowdsecurity/cri-logs
     - crowdsecurity/dateparse-enrich

   collections:
     - crowdsecurity/nginx
     - openappsec/openappsec
   ```
4. Restart crowdsec to apply the changes by running\
   `sudo systemctl restart crowdsec`\
   \
   Alternatively you can use CrowdSec's `cscli` command to apply the changes:\
   `sudo cscli capi update`
   {% endtab %}

{% tab title="Docker" %}

#### For CrowdSec and open-appsec both deployed on Docker:

1. Make sure to have a CrowdSec container version >= 1.4.6 installed on Docker, see <https://hub.docker.com/r/crowdsecurity/crowdsec>
2. Configure the acquisition for consuming the open-appsec log-files in CrowdSec's main yaml configuration file `/etc/crowdsec/config.yaml` mounted into your crowdsec docker container as follows:

   ```
   source: docker
   container_name:
    - open-appsec-agent
   labels:
     type: openappsec
   ```
3. Edit the following configuration file `/etc/crowdsec/collections/linux.yaml` \
   mounted into your crowdsec docker container and add the required parsers and collections as shown below:

   ```
   parsers:
     - crowdsecurity/cri-logs
     - crowdsecurity/dateparse-enrich

   collections:
     - crowdsecurity/nginx
     - openappsec/openappsec
   ```
4. Restart your CrowdSec docker container to apply the changed configuration.
   {% endtab %}
   {% endtabs %}

{% hint style="danger" %}
CrowdSec version needs to be above or equal to 1.4.6 for open-appsec log parsing integration to work. Note that if you use specify "latest" as tag you might still get an older version below v1.4.6.
{% endhint %}

{% hint style="info" %}
For further details on this please consult the CrowdSec documentation available here:\
[https://docs.crowdsec.net ](<https://docs.crowdsec.net >)
{% endhint %}

If you didn't configure open-appsec to bounce malicious source IP addresses based on CrowdSec's Threat Intelligence using the Community Blocklist you can follow the steps explained here to configure this in couple easy steps:

{% content-ref url="/pages/m6M2an1zE2ucev1Uo44x" %}
[CrowdSec Bouncer Support](/integrations/crowdsec/crowdsec-bouncer-support)
{% endcontent-ref %}


# NGINX Proxy Manager

Deploy and configure open-appsec ML-based WAF integrated with NGINX Proxy Manager to preemptively protect your web apps and APIs against zero-day attacks and OWASP Top 10 attacks.

<figure><img src="/files/YOGeX6Q8HfBe9prtE2vv" alt="" width="263"><figcaption></figcaption></figure>

This integration enables users of the NGINX Proxy Manager (NPM) to protect their web applications and web APIs by easily activating and configuring open-appsec protection for each of the configured Proxy Host objects in NPM directly from the NPM Web UI and monitor security events.\
Alternatively open-appsec, when integrated with NPM, can also be managed by central WebUI (SaaS).

### About NGINX Proxy Manager:

Nginx Proxy Manager is a popular open-source project that simplifies the management of NGINX reverse proxy configurations, offering a user-friendly web-based interface for easy setup and maintenance. It was created by “jc21” (<https://www.jc21.com/>).\
This project is particularly useful for individuals and organizations looking to streamline the deployment of web applications and services by efficiently managing multiple domains and subdomains through a centralized interface.\
With NGINX Proxy Manager, users can effortlessly create and manage SSL certificates, enabling secure HTTPS connections for their applications, while also providing advanced features such as Let's Encrypt integration for automated certificate renewal.\
NGINX Proxy Manager (NPM) is based on NGINX and provided as a container image that can be easily deployed in containerized environments like Docker (typically using Docker Compose) or others.\
NPM itself does not include any WAF solution for effective Threat Prevention against modern attacks or Zero day attacks.\
\
Website and Docs: [nginxproxymanager.com](https://nginxproxymanager.com/)      Github: [www.github.com/NginxProxyManager](https://www.github.com/NginxProxyManager)

### Integration of open-appsec WAF with NGINX Proxy Manager:

With this integration, we are focusing on maximum simplicity for the user to maintain the low entry barrier as a key design principle of the NGINX proxy manager (NPM) project, which we want in the same way to apply also to the addition of open-appsec.

The actual deployment of NPM with open-appsec is performed using a slightly enhanced docker-compose file (see below) which also adds the open-appsec agent container to it, which will perform the actual security inspection.\
The NGINX proxy manager container deployed as part of the docker-compose is using the “nginx-proxy-manager-attachment”  or the "nginx-proxy-manager-centrally-managed-attachment" images, provided by the open-appsec team, which are based on the regular NPM code but also add the open-appsec attachment to it as an NGINX module. This attachment enables the connection between the NGINX and the open-appsec agent and provides the HTTP data for inspection to the agent.\
The “nginx-proxy-manager-attachment” image also contains various NPM WebUI enhancements and the integration logic allowing the configuration, administration and monitoring of open-appsec directly from the NPM WebUI.\
\
You can read more about open-appsec’s technology here:\
<https://www.openappsec.io/tech>

The resulting architecture with the open-appsec Agent container and the NGINX Proxy Manager container then looks like this:

<figure><img src="/files/S8cLJDYiQu0AxKn8Ly3w" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Alternatively to managing open-appsec directly from the local Nginx Proxy Manager WebUI it is also possible to manage and monitor open-appsec centrally from the open-appsec central WebUI, which provides advanced configuration options and allows to manage and monitor multiple open-appsec installations. This uses a different docker-compose and container image for NGINX Proxy Manager (based on regular NPM image with open-appsec attachment added). Details here:

[Deploy NGINX Proxy Manager with open-appsec managed from central WebUI (SaaS)](/integrations/nginx-proxy-manager/deploy-nginx-proxy-manager-with-open-appsec-managed-from-central-webui-saas)
{% endhint %}

### How does this integration work?

open-appsec was developed from the start in a way that would allow two alternative main ways of managing the open-appsec configuration:

* a user-friendly WebUI for central management (available at [my.openappsec.io](https://my.openappsec.io) as a SaaS service)
* a local declarative configuration which is especially suitable for GitOps CD processes, Dev(Sec)Ops flows, etc.

**You can choose between two different deployment types of the open-appsec integration with NGINX Proxy Manager (NPM):**<br>

* **(Recommended for new users) Deploy NGINX Proxy Manager with open-appsec, while performing configuration management and security log analysis directly from an enhanced NGINX Proxy Manager Web UI.**\
  \
  When managing open-appsec from the NGINX Proxy Manager UI, any changes to the open-appsec configuration are saved in the `/ext/appsec` folder in the local\_policy.yaml file.\
  This configuration file is volume-mounted (see docker compose) to both, the open-appsec agent container “appsec-agent” as well as the NPM container “appsec-npm”. This allows the open-appsec agent to automatically apply any changes observed in that file within a short time.\
  \
  *Deployment and usage instructions:*

{% content-ref url="/pages/AxlgbZaDcGZZd0Y2C7ey" %}
[Deploy NGINX Proxy Manager with open-appsec managed from NPM WebUI](/integrations/nginx-proxy-manager/deploy-nginx-proxy-manager-with-open-appsec-managed-from-npm-webui)
{% endcontent-ref %}

* **(Recommended for advanced users) Deploy NGINX Proxy Manager with open-appsec, while performing configuration management, monitoring and security log analysis from the open-appsec web UI.**\
  \
  *Deployment and usage instructions:*

{% content-ref url="/pages/XlgYmQShGOt1BNHDYqzR" %}
[Deploy NGINX Proxy Manager with open-appsec managed from central WebUI (SaaS)](/integrations/nginx-proxy-manager/deploy-nginx-proxy-manager-with-open-appsec-managed-from-central-webui-saas)
{% endcontent-ref %}

{% hint style="info" %}
In order to allow the open-appsec agent to inspect traffic arriving at the NPM (NGINX) container an open-appsec “attachment” was added to the original NPM container, which technically is an NGINX module which is loaded based on a `load_module` directive added to the `nginx.conf`.\
This “attachment” is responsible for sending the content of incoming http as well as https requests to the open-appsec “agent” container, which will perform the inspection using machine learning and then notify the attachment about the decision, if traffic should be blocked or if it can pass.
{% endhint %}

***

### Contribution

We are looking forward to receiving your contributions via the [project’s GitHub repo](https://github.com/openappsec/open-appsec-npm).\
Please also let us know via <info@openappsec.io> if you intend to contribute in some way so we can provide you some initial feedback and perhaps align with some improvements we might be already working on on our side.

{% hint style="info" %}
If you have any questions, feedback or need assistance with some technical issue please contact us at <info@openappsec.io> or alternatively use the chat on our project website available at [www.openappsec.io](http://www.openappsec.io).
{% endhint %}


# Deploy NGINX Proxy Manager with open-appsec managed from NPM WebUI

### Deployment:

{% hint style="warning" %}
Before you start, make sure to have a Linux environment with Docker and Docker Compose available.
{% endhint %}

{% hint style="info" %}
If you want to migrate from an existing NGINX Proxy Manager deployment to use this integration with open-appsec, please check out our guide which is available here: [How to Migrate from an Existing  NGINX Proxy Manager Deployment and Keep Configuration](/integrations/nginx-proxy-manager/how-to-migrate-from-an-existing-nginx-proxy-manager-deployment-and-keep-configuration)
{% endhint %}

#### To deploy NGINX Proxy Manager with open-appsec integration follow the steps below

{% tabs %}
{% tab title="Docker Compose (recommended)" %}

## Prerequisites

* **Linux Docker Host with root permission**
* **Docker-Compose tool installed**
* **(Optional, Recommended) Sign-Up and Login to WebUI Portal**\
  If you want to locally manage your open-appsec WAF deployment using the NPM WebUI but still connect to central WebUI for viewing the local configuration (in read-only), central monitoring, logging and reporting:\
  \
  Follow the instructions below to sign-up and login to the WebUI available at <https://my.openappsec.io>:

{% content-ref url="/pages/0ty9rMQEgnxS9LBuN7qw" %}
[Sign-Up and Login to Portal](/getting-started/using-the-web-ui-saas/sign-up-and-login-to-portal)
{% endcontent-ref %}

* **(Optional, Recommended) Create deployment profile for the open-appsec deployment in WebUI Portal**\
  If you signed-up and logged in to the WebUI Portal (see prerequisite above), now follow the instructions below to create a new deployment profile for your open-appsec deployment.\
  **Once done, don't forget to copy the profile token after policy installation as this is needed in the installation steps further below.**

{% content-ref url="/pages/WMgZp7bTMiI5PD1ocIKp" %}
[Create a Profile](/getting-started/using-the-web-ui-saas/create-a-profile)
{% endcontent-ref %}

## Deployment

#### To deploy NGINX Proxy Manager integrated with open-appsec using `docker-compose` (and optionally connect also to the central open-appsec WebUI) follow the steps below:

1. Create a folder for your new open-appsec deployment and switch to that folder, e.g.

```bash
mkdir open-appsec-deployment
cd ./open-appsec-deployment
```

2. Download the docker compose file for your desired open-appsec integration

```bash
wget https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/nginx-proxy-manager/docker-compose.yaml
```

`docker-compose.yaml` file content:

{% embed url="<https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/nginx-proxy-manager/docker-compose.yaml>" %}

3. Download the `.env` file for your desired open-appsec integration and adjust the configuration to your requirements as described below:

```bash
wget https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/nginx-proxy-manager/.env
```

`.env` file content:

{% embed url="<https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/nginx-proxy-manager/.env>" fullWidth="false" %}

* **If you created a deployment profile in the WebUI and copied the Token from it:**

  \
  Edit the `.env` file and add your token to the key `APPSEC_AGENT_TOKEN`.
* **If you did not create a deployment profile in the WebUI and do not want to connect your deployment to central WebUI (SaaS) at all:**

  \
  Set the value `standalone` for the key `COMPOSE_PROFILES` which will activate the deployment of additional containers which are required only when not connected to the open-appsec central WebUI at all (resulting in standalone, locally, declaratively managed deployment).
* Replace `user@email.com` in the .env file with your own email. (More details below.)

#### Available settings in the `.env` file allowing further customization of the deployment:

**APPSEC\_AGENT\_TOKEN:** For connecting your open-appsec deployment to central WebUI  set APPSEC\_AGENT\_TOKEN to your own deployment profile token as copied from profile settings in the open-appsec central WebUI (see section [#prerequisites](#prerequisites "mention") above).

**COMPOSE\_PROFILES:** Possible values you can set for this key:\
&#x20;(you can set multiple values, separated by comma)

`standalone` : This will activate the deployment of additional containers which are required **only** when you are not connected to the open-appsec central WebUI at all, resulting in standalone, locally, declaratively managed deployment.

{% hint style="warning" %}
**Only** activate the `standalone` profile in case you did not set a WebUI deployment profile token as value for the APPSEC\_AGENT\_TOKEN key (see above)!
{% endhint %}

{% hint style="info" %}
The additional containers which get deployed in `standalone` mode introduce some additional functionality, which is relevant for standalone deployments only (that same functionality is already available when connected to open-appsec's central management WebUI):\
\- Local syncing of learning between open-appsec processes and agents\
\- View learning progress on CLI with open-appsec-tuning-tool\
\- Receive configuration recommendations based on the learning progress using the open-appsec-tuning-tool\
\- Receive tuning suggestions and manage them (approve/reject) using the open-appsec-tuning-tool\
\
More details on the open-appsec-tuning-tool here: [Track Learning and Local Tuning in Standalone Deployments](/how-to/configuration-and-learning/track-learning-and-local-tuning-in-standalone-deployments)
{% endhint %}

`juiceshop` : This will deploy an additional, vulnerable juiceshop-backend container that can be used for demo and testing purposes.\
In the .env file you also find a download link for the proxy-specific configuration allowing you to access the juiceshop backend via the proxy. More info on the OWASP juiceshop project: <https://owasp.org/www-project-juice-shop/>

{% hint style="warning" %}
Do not activate the juiceshop profile in production environments as the juiceshop container is intentionally highly vulnerable and meant for testing in lab environments only!
{% endhint %}

**USER\_EMAIL:** (Optional) Associate your email address with your specific deployment by replacing `user@email.com` with your own email address.

This allows the open-appsec team to provide you easy assistance in case of any issues you might have with your specific deployment in the future and also to provide you information proactively regarding open-appsec in general or regarding your specific deployment. This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future.

**APPSEC\_HTTPS\_PROXY**: (Optional) Configure an HTTP(S) proxy server to be used by the agent.&#x20;

**APPSEC\_AUTO\_POLICY\_LOAD**: (Optional) When set to `true`, allows you to set the open-appsec agent to automatically apply any new changes in the local\_policy.yaml file without having to restart the agent container or applying the changes with `open-appsec-ctl -ap` (note that this can take up to 30 seconds). This is useful especially in DevOps scenarios with continuous deployment scenarios.

**APPSEC\_VERSION**: Allows you to specify a specific version for deployment instead of using the default `latest` version for the containers provided by open-appsec (not relevant for postgres container).

**Additional configuration available specifically for this integration type:**

**NPM\_DATA:** Specify the local folder on the host for the volume mount of the NPM data directory, in the `appsec-nginx-proxy-manager` container this gets mounted into `/data`.

**NPM\_LETSENCRYPT:**  Specify the local folder on the host for the LetsEncrypt data, in the `appsec-nginx-proxy-manager` container this gets mounted into `/etc/letsencrypt`.

For testing purposes in a lab environment you can activate the deployment of the vulnerable juiceshop-backend container via `COMPOSE_PROFILES` key (see above) and then deploy the available configuration example for exposing it via the proxy, which is provided by the open-appsec team (download link is provided in the `.env` file).

{% hint style="info" %}
You find some additional advanced configuration options described within the `docker-compose.yaml` file as comments.
{% endhint %}

4. Download the initial declarative configuration file for open-appsec into new subfolder `./appsec-localconfig` (note this is a specifically adjusted version for the NPM integration):<br>

   ```bash
   mkdir ./appsec-localconfig
   wget https://raw.githubusercontent.com/openappsec/open-appsec-npm/main/deployment/managed-from-npm-ui/local_policy.yaml -O ./appsec-localconfig/local_policy.yaml
   ```

   \
   `local_policy.yaml` file contents:

{% embed url="<https://raw.githubusercontent.com/openappsec/open-appsec-npm/main/deployment/managed-from-npm-ui/local_policy.yaml>" %}

{% hint style="info" %}
This example configuration file is already set to `mode: prevent-learn` so that open-appsec will prevent attacks right from the start.\
Here's the path for an alternative local-config.yaml file set to detect-learn mode.\
<https://raw.githubusercontent.com/openappsec/openappsec/main/config/linux/v1beta1/detect/local_policy.yaml>\
(or simply adjust the setting in the `mode` setting in the earlier local\_policy.yaml file to `detect-learn`)\
\
In production environments it's always recommended to start in `detect-learn` mode to allow open-appsec to achieve a certain learning level based on traffic observed before moving to `prevent-learn`for better detection accuracy and strongly reduced false positives.\
\
Read more about this here: \
[Track Learning and Move From Learn/Detect to Prevent](/how-to/configuration-and-learning/track-learning-and-move-from-learn-detect-to-prevent)
{% endhint %}

5. Perform the deployment

```bash
docker-compose up -d
```

You will see output similar to the below.\
(The example screenshot below is for an NGINX deployment.)\
Note that the amount of container will vary based between deployments with and without connection to central WebUI.\
\
![](/files/n78DmRFlWPu29yOokxla)

6. Verify that all containers are up and running by verifying their status in docker ps output. Note that the amount of container will vary based between deployments with and without connection to central WebUI.

```bash
docker ps
```

You will see output similar to the below:\
(The example screenshot below is for an NGINX deployment.)

<figure><img src="/files/68gPCyP7G02HskqKHLsz" alt=""><figcaption><p>docker ps example output with all containers up</p></figcaption></figure>
{% endtab %}

{% tab title="Docker Compose (deprecated)" %}
{% hint style="warning" %}
This version of the docker-compose for NGINX Proxy Manager integration with open-appsec is now deprecated since 2025-08-25, please use the "recommended" version instead which contains many improvements.
{% endhint %}

1. Within the directory which you want to use for the deployment:\
   Create a folder appsec-localconfig which will hold the appsec declarative configuration file (this will be managed by the enhanced NPM WebUI).

```
mkdir ./appsec-localconfig
```

2. Download the initial declarative configuration file for open-appsec into that folder:

```bash
wget https://raw.githubusercontent.com/openappsec/open-appsec-npm/main/deployment/managed-from-npm-ui/local_policy.yaml -O ./appsec-localconfig/local_policy.yaml
```

`local_policy.yaml` file contents:

{% embed url="<https://raw.githubusercontent.com/openappsec/open-appsec-npm/main/deployment/managed-from-npm-ui/local_policy.yaml>" %}

3. Create a docker-compose.yaml file with the content below, it can be downloaded as follows:

```bash
wget https://raw.githubusercontent.com/openappsec/open-appsec-npm/main/deployment/managed-from-npm-ui/docker-compose.yaml
```

`docker-compose.yaml` content:

{% embed url="<https://raw.githubusercontent.com/openappsec/open-appsec-npm/main/deployment/managed-from-npm-ui/docker-compose.yaml>" %}

4. Edit the docker-compose.yaml file and replace "<user@email.com>" with your own email address, so we can provide assistance in case of any issues with the specific deployment in the future and provide information proactively regarding open-appsec.\
   \
   This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future
5. Start the deployment of all relevant containers using `docker-compose`:

```bash
docker-compose up -d
```

6. Check if the appsec-npm and the appsec-agent containers are up and running:

```bash
docker ps
```

{% endtab %}
{% endtabs %}

#### **Congratulations, you successfully deployed NGINX Proxy Manager with open-appsec integration!**

{% hint style="info" %}
For Production usage we recommend to switch from using the Basic to the more accurate Advanced Machine Learning model, as described here:&#x20;

[Using the Advanced Machine Learning Model](/getting-started/using-the-advanced-machine-learning-model)
{% endhint %}

Now you can login with your web browser to the WebUI of NGINX Proxy Manager with open-appsec integration as follows:

```bash
http://[hostname or IP of your host]:81
```

<figure><img src="/files/hrV0ohEGZhGgYYD8fW8W" alt=""><figcaption><p>NGINX Proxy Manager - Login Window</p></figcaption></figure>

At first login please use the following default administrator user credentials:\
\
E-mail address:       <admin@example.com>\
Password:                 changeme

You will then be prompted to provide your own user details and asked to change the password, before being presented with the NGINX Proxy Manager Dashboard view:

<figure><img src="/files/KQKuu0IfV6CvvgA9XSN3" alt=""><figcaption><p>Network Proxy Manager - Dashboard</p></figcaption></figure>

### Configuration

{% hint style="info" %}
To learn how to use NGINX Proxy Manager (NPM) see project documentation:\
<https://nginxproxymanager.com> (NPM usage and configuration will not be explained here).
{% endhint %}

Once you created a new Proxy Host within NGINX Proxy Manager WebUI you can now easily enable and configure open-appsec protection (see also screenshot below):

1. Enable open-appsec by flipping the “open-appsec” switch to enabled.
2. Select the Enforcement Mode, it can be either “Prevent-Learn” or “Detect-Learn”
3. Select the minimum confidence level for open-appsec to prevent an attack (only relevant when in prevent mode), it can be either “Critical”, “High” or “Medium” confidence.
4. Click “Save”

<figure><img src="/files/PjUTgYhICon5wY4xfKj1" alt=""><figcaption><p>NGINX Proxy Manager - Edit Proxy Host</p></figcaption></figure>

{% hint style="info" %}
This screenshot as an example shows a “Proxy Host” reverse proxy configuration in NPM that will listen to inbound traffic for hostnames “100.25.161.101”, “localhost” or “my.webserver.com”.

This Proxy Host has open-appsec enabled in “Prevent-Learn” mode and therefore will prevent incoming http or https requests when there’s a minimum confidence level of “High” or higher, as configured for the “Minimum confidence for prevent” setting.

Non-malicious traffic will then be proxied using “http” protocol to the configured backend webserver with the IP address “192.168.160.2” on port “80”.
{% endhint %}

{% hint style="info" %}
If you deployed the new docker-compose file (beta) which includes the optional vulnerable juiceshop container (just for testing purposes, do not use in production environments!)  and added the value `juiceshop` to the parameter `COMPOSE_PROFILES`  then you can configure `juiceshop-backend` in the `Forward Hostname / IP` field of the Edit Proxy Host window to proxy inbound traffic to it.
{% endhint %}

#### Using Custom Locations in Proxy Host objects

If you are using “Custom locations” in NPM for a more granular backend configuration you can configure open-appsec in similar same way as described above, but configuration will then be specific and applied only to this “Custom location”:

<figure><img src="/files/Qz0R8N9EFnvxiuFDXdxQ" alt=""><figcaption></figcaption></figure>

This gives you for example the flexibility to set open-appsec to “Detect-Learn” for a specific “Custom location” while the main Proxy Host configuration is set to “Prevent-Learn”.\
\
Alternatively, you could also use this option to have open-appsec configured to\
“Detect-Learn” for your Proxy Host configuration but already set it to “Prevent-Learn” for some specific paths which require immediate protection or which you want to test prevent mode before enabling it for the “whole” Proxy Host.

{% hint style="warning" %}
*Changes in the open-appsec configuration performed and saved in the NPM Web UI can take up to 30 seconds before they become effective.*
{% endhint %}

### How to view open-appsec Logs in NPM Web UI:

If you want to check out the open-appsec Logs click on the new menu option “Security Log” which allows you to view the open-appsec specific logs directly from the NPM Web UI.\
\
Within the Security Log view you can chose between three separate views:

* Important Events
* All Events
* Notifications

<figure><img src="/files/kMyovVj7PBIlOsNoxZgy" alt=""><figcaption><p>NGINX Proxy Manager - Security Log</p></figcaption></figure>

The "open" button at the beginning of each log allows you to view the full log in json format:

<figure><img src="/files/GBS8xsATOtrPb7CnkC8P" alt=""><figcaption><p>NGINX Proxy Manager - Full Log View</p></figcaption></figure>

### How to configure open-appsec advanced settings:

{% hint style="danger" %}
Performing direct changes of the local declarative configuration file for open-appsec in the "open-appsec Advanced" section will be "at your own risk", as you might break the configuration. Only do this if required and if you know what you do or test stuff in a risk-free lab environment.
{% endhint %}

{% hint style="warning" %}
Note that as the integration with NPM Web UI is built based on the v1beta1 local configuration schema of open-appsec, you must only use the v1beta1 version of open-appsec with this integration.

If you have requirement to manage open-appsec WAF declaratively with local configuration in v1beta2 schema version, you can instead use the container image `nginx-proxy-manager-centrally-managed` which does not contain the integration with NPM Web UI but just the open-appsec attachment, this is compatible with both, v1beta1 and v1beta2 schema versions.
{% endhint %}

What if you want to configure some advanced settings of open-appsec which are not covered or not covered “yet” as part of the open-appsec enhanced NPM WebUI?\
We thought about this as well and added an extra editor allowing you to adjust the declarative open-appsec configuration under “Settings” -> “open-appsec Advanced”.

{% hint style="info" %}
The local policy file specification for v1beta1 configuration schema is available here:\
[Local Policy File (Advanced)](https://docs.openappsec.io/getting-started/start-with-linux/local-policy-file-advanced)
{% endhint %}

Make sure to push the “save” button once you did any changes here and be especially careful with the configuration that has “npm-managed...” as part of the name, as these configuration elements are created and partly managed by the open-appsec configuration in the NPM WebUI.\
\
As a rule of thumb only adjust stuff for which there’s no UI element yet to configure it and be aware that e.g. disabling open-appsec in a “Proxy Host” or “Custom Location” might also remove the corresponding configuration from the open-appsec Configuration File.

{% hint style="info" %}
Check out the open-appsec documentation if you want to learn more about all the additional options and security layers which are available in open-appsec: [docs.openappsec.io](https://docs.openappsec.io/)
{% endhint %}

<figure><img src="/files/aKGpfN27rj87Tf506dCY" alt=""><figcaption></figcaption></figure>


# Deploy NGINX Proxy Manager with open-appsec managed from central WebUI (SaaS)

## Prerequisites

* **Access to a SaaS tenant on my.openappsec.io (WebUI for SaaS management)**\
  Follow the instructions available here:

{% content-ref url="/pages/0ty9rMQEgnxS9LBuN7qw" %}
[Sign-Up and Login to Portal](/getting-started/using-the-web-ui-saas/sign-up-and-login-to-portal)
{% endcontent-ref %}

* **Agent profile created for open-appsec Docker deployment in SaaS tenant** \
  Follow the instructions available here.\
  Once done, don't forget to copy the profile token after policy installation as this is needed in the installation steps further below:

{% content-ref url="/pages/WMgZp7bTMiI5PD1ocIKp" %}
[Create a Profile](/getting-started/using-the-web-ui-saas/create-a-profile)
{% endcontent-ref %}

* **Linux machine with:**
  * Docker and Docker Compose installed
  * Root Permissions&#x20;

{% hint style="info" %}
If you want to migrate from an existing NGINX Proxy Manager deployment to use this integration with open-appsec, please check out specific the FAQ further below on this page for specific instructions and further information.
{% endhint %}

#### To deploy NGINX Proxy Manager with open-appsec integration follow the steps below:

{% tabs %}
{% tab title="Docker Compose (recommended)" %}

## Prerequisites

* **Linux Docker Host with root permission**
* **Docker-Compose tool installed**
* **Sign-Up and Login to WebUI Portal**\
  For centrally managing your configuration of open-appsec integrated with NPM first follow the instructions below to sign-up and login to the WebUI available at <https://my.openappsec.io>:

{% content-ref url="/pages/0ty9rMQEgnxS9LBuN7qw" %}
[Sign-Up and Login to Portal](/getting-started/using-the-web-ui-saas/sign-up-and-login-to-portal)
{% endcontent-ref %}

* **Create deployment profile for the open-appsec deployment in WebUI Portal**\
  Now follow the instructions below to create a new deployment profile for your open-appsec deployment.\
  **Once done, don't forget to copy the profile token after policy installation as this is needed in the installation steps further below.**

{% content-ref url="/pages/WMgZp7bTMiI5PD1ocIKp" %}
[Create a Profile](/getting-started/using-the-web-ui-saas/create-a-profile)
{% endcontent-ref %}

## Deployment

#### To deploy open-appsec with docker-compose and connect to the central management WebUI available at <https://my.openappsec.io> follow the steps below:

1. Create a folder for your new open-appsec deployment and switch to that folder, e.g.

```bash
mkdir open-appsec-deployment
cd ./open-appsec-deployment
```

2. Download the docker compose file for your desired open-appsec integration

```bash
wget https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/nginx-proxy-manager-centrally-managed/docker-compose.yaml
```

`docker-compose.yaml` file content:

{% embed url="<https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/nginx-proxy-manager-centrally-managed/docker-compose.yaml>" %}

3. Download the `.env` file for your desired open-appsec integration and adjust the configuration to your requirements as described below:

```bash
wget https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/nginx-proxy-manager-centrally-managed/.env
```

`.env` file content:

{% embed url="<https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/nginx-proxy-manager-centrally-managed/.env>" %}

* **Edit the** `.env` **file and add your token to the key** `APPSEC_AGENT_TOKEN`**.**
* Replace `user@email.com` in the .env file with your own email. (More details below.)

#### Available settings in the `.env` file allowing further customization of the deployment:

**APPSEC\_AGENT\_TOKEN:** For connecting your open-appsec deployment to central WebUI  set APPSEC\_AGENT\_TOKEN to your own deployment profile token as copied from profile settings in the open-appsec central WebUI (see section [#prerequisites](#prerequisites "mention") above).

**COMPOSE\_PROFILES:** Possible values you can set for this key:\
&#x20;(you can set multiple values, separated by comma)

`standalone` : This will activate the deployment of additional containers which are required **only** when you are **not** connected to the WebUI at all, resulting in standalone, locally, declaratively managed deployment.

{% hint style="warning" %}
**Only** activate the `standalone` profile in case you **did not set** a WebUI deployment profile token as value for the APPSEC\_AGENT\_TOKEN key (see above) and want to manage open-appsec integrated with NGINX Proxy Manager using open-appsec's local declarative configuration file `local_policy.yaml`!
{% endhint %}

{% hint style="info" %}
The additional containers which get deployed in `standalone` mode introduce some additional functionality, which is relevant for standalone deployments only (that same functionality is already available when connected to open-appsec's central management WebUI):\
\- Local syncing of learning between open-appsec processes and agents\
\- View learning progress on CLI with open-appsec-tuning-tool\
\- Receive configuration recommendations based on the learning progress using the open-appsec-tuning-tool\
\- Receive tuning suggestions and manage them (approve/reject) using the open-appsec-tuning-tool\
\
More details on the open-appsec-tuning-tool here: [Track Learning and Local Tuning in Standalone Deployments](/how-to/configuration-and-learning/track-learning-and-local-tuning-in-standalone-deployments)
{% endhint %}

`juiceshop` : This will deploy an additional, vulnerable juiceshop-backend container that can be used for demo and testing purposes.\
In the .env file you also find a download link for the proxy-specific configuration allowing you to access the juiceshop backend via the proxy. More info on the OWASP juiceshop project: <https://owasp.org/www-project-juice-shop/>

{% hint style="warning" %}
Do not activate the juiceshop profile in production environments as the juiceshop container is intentionally highly vulnerable and meant for testing in lab environments only!
{% endhint %}

**USER\_EMAIL:** (Optional) Associate your email address with your specific deployment by replacing `user@email.com` with your own email address.

This allows the open-appsec team to provide you easy assistance in case of any issues you might have with your specific deployment in the future and also to provide you information proactively regarding open-appsec in general or regarding your specific deployment. This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future.

**APPSEC\_HTTPS\_PROXY**: (Optional) Configure an HTTP(S) proxy server to be used by the agent.&#x20;

**APPSEC\_AUTO\_POLICY\_LOAD**: (Optional) When set to `true`, allows you to set the open-appsec agent to automatically apply any new changes in the local\_policy.yaml file without having to restart the agent container or applying the changes with `open-appsec-ctl -ap` (note that this can take up to 30 seconds). This is useful especially in DevOps scenarios with continuous deployment scenarios.

**APPSEC\_VERSION**: Allows you to specify a specific version for deployment instead of using the default `latest` version for the containers provided by open-appsec (not relevant for postgres container).

**Additional configuration available specifically for this integration type:**

**NPM\_DATA:** Specify the local folder on the host for the volume mount of the NPM data directory, in the `appsec-nginx-proxy-manager` container this gets mounted into `/data`.

**NPM\_LETSENCRYPT:**  Specify the local folder on the host for the LetsEncrypt data, in the `appsec-nginx-proxy-manager` container this gets mounted into `/etc/letsencrypt`.

For testing purposes in a lab environment you can activate the deployment of the vulnerable juiceshop-backend container via `COMPOSE_PROFILES` key (see above) and then deploy the available configuration example for exposing it via the proxy, which is provided by the open-appsec team (download link is provided in the .env file).

{% hint style="info" %}
You find some additional advanced configuration options described within the `docker-compose.yaml` file as comments.
{% endhint %}

4. Perform the deployment

```bash
docker-compose up -d
```

You will see output similar to the below.\
(The example screenshot below is for an NGINX deployment.)\
Note that the amount of container will vary based between deployments with and without connection to central WebUI.\
\
![](/files/n78DmRFlWPu29yOokxla)

6. Verify that all containers are up and running by verifying their status in docker ps output. Note that the amount of container will vary based between deployments with and without connection to central WebUI.

```bash
docker ps
```

You will see output similar to the below:\
(The example screenshot below is for an NGINX deployment.)

<figure><img src="/files/68gPCyP7G02HskqKHLsz" alt=""><figcaption><p>docker ps example output with all containers up</p></figcaption></figure>
{% endtab %}

{% tab title="Docker Compose (deprecated)" %}
{% hint style="warning" %}
This version of the docker-compose for NGINX Proxy Manager integration with open-appsec is now deprecated since 2025-08-25, please use the "recommended" version instead which contains many improvements.
{% endhint %}

1. Create a docker-compose.yaml file with the content below, it can be downloaded as follows:

<pre><code><strong>wget https://raw.githubusercontent.com/openappsec/open-appsec-npm/main/deployment/managed-from-open-appsec-ui/docker-compose.yaml
</strong></code></pre>

`docker-compose.yaml` file content:

{% embed url="<https://raw.githubusercontent.com/openappsec/open-appsec-npm/main/deployment/managed-from-open-appsec-ui/docker-compose.yaml>" %}

2. Replace the `<TOKEN>` parameter in the docker-compose.yaml file with the token you copied from the profile in the WebUI before (see Prerequisites section above).
3. Start the deployment of all relevant containers using `docker-compose`:

```
docker-compose up -d
```

4. Check if the appsec-npm and the appsec-agent containers are up and running:

```
docker ps
```

{% endtab %}
{% endtabs %}

**Congratulations, you successfully deployed NGINX Proxy Manager with open-appsec integration!**

{% hint style="info" %}
For Production usage you might want to switch from using the Basic to the more accurate Advanced Machine Learning model, as described here:

[Using the Advanced Machine Learning Model](https://docs.openappsec.io/getting-started/using-the-advanced-machine-learning-model)
{% endhint %}

Now you can login with your web browser to the WebUI of NGINX Proxy Manager with open-appsec integration as follows:

```
http://[hostname or IP of your host]:81
```

<figure><img src="/files/htBZLkKu1hA2fKRqLvVy" alt=""><figcaption></figcaption></figure>

At first login please use the following default administrator user credentials:\
\
E-mail address:       <admin@example.com>\
Password:                 changeme

You will then be prompted to provide your own user details and asked to change the password, before being presented with the NGINX Proxy Manager Dashboard view:

<figure><img src="/files/8FDyWzSJIP0P9ii7Ywg4" alt=""><figcaption><p>NGINX Proxy Manager Dashboard</p></figcaption></figure>

### Configuration

{% hint style="info" %}
To learn how to use NGINX Proxy Manager (NPM) see project documentation:\
<https://nginxproxymanager.com> (NPM usage and configuration will not be explained here).
{% endhint %}

{% hint style="info" %}
If you deployed the new docker-compose file (beta) which includes the optional vulnerable juiceshop container (just for testing purposes, do not use in production environments!) and added the value `juiceshop` to the parameter `COMPOSE_PROFILES`  then you can configure `juiceshop-backend` in the `Forward Hostname / IP` field of the Edit Proxy Host window to proxy inbound traffic to it.
{% endhint %}

Once you created a new Proxy Host within NGINX Proxy Manager WebUI you can now configure open-appsec protection for it in the open-appsec WebUI (<https://my.openappsec.io>).&#x20;

5. In the open-appsec Web UI: Navigate to the Agents tab and ensure the new agent is successfully connected.
6. In the open-appsec Web UI: Create one or more assets defining the specific resources that open-appsec should protect and don't forget to install the policy afterwards.\
   \
   One typical approach would be to create one asset in the open-appsec WebUI per each "Proxy Host" you configured in the NGINX Proxy Manager WebUI. This would allow you to have individual  open-appsec security settings per each Proxy Host configured in NPM.\
   \
   All required steps are explained here:

{% content-ref url="/pages/yvQt78cZU4kLymWzObq3" %}
[Protect Additional Assets](/getting-started/using-the-web-ui-saas/protect-additional-assets)
{% endcontent-ref %}


# How to Migrate from an Existing  NGINX Proxy Manager Deployment and Keep Configuration

To migrate from an existing NGINX Proxy Manager installation to a version which provides also open-appsec integration here's some guidance:

{% hint style="info" %}
This is only relevant if you want to keep your existing NGINX Proxy Manager configuration,\
otherwise it is suggested to start fresh with the deployment instructions shown on these pages:

[Deploy NGINX Proxy Manager with open-appsec managed from NPM WebUI](/integrations/nginx-proxy-manager/deploy-nginx-proxy-manager-with-open-appsec-managed-from-npm-webui)\
[Deploy NGINX Proxy Manager with open-appsec managed from central WebUI (SaaS)](/integrations/nginx-proxy-manager/deploy-nginx-proxy-manager-with-open-appsec-managed-from-central-webui-saas)
{% endhint %}

{% hint style="warning" %}
Note that the specific steps can vary based on customizations that you might have done to the original NGINX Proxy Manager's docker compose file.

The below is assuming you did a deployment by using the default docker-compose.yml file similarly as shown here: <https://nginxproxymanager.com/setup/#running-the-app> .
{% endhint %}

* Change into your existing folder that contains the docker-compose.yml file and all related files and folders for your current NGINX Proxy Manager deployment.
* Stop your current deployment with `docker-compose down` in the folder that contains your `docker-compose.yaml` file used for the NGINX Proxy Manager deployment.
* Make a full backup of your existing folder that contains the NGINX Proxy Manager docker compose environment, including any mounted volumes like `./data` and `./letsencrypt`, etc. to a safe location. This will allow you to bring it up with `docker-compose up` later exactly as it was before the migration, if required for some reason.
* Rename the original `docker-compose.yml`  file (so you will still have it as a backup):

```bash
mv ./docker-compose.yml ./docker-compose.npm.orig.yml
```

{% tabs %}
{% tab title="open-appsec managed from NPM WebUI" %}

### **Please carefully read the important considerations below!**

Only then follow the regular instructions for the deployment:

{% content-ref url="/pages/AxlgbZaDcGZZd0Y2C7ey" %}
[Deploy NGINX Proxy Manager with open-appsec managed from NPM WebUI](/integrations/nginx-proxy-manager/deploy-nginx-proxy-manager-with-open-appsec-managed-from-npm-webui)
{% endcontent-ref %}

### **Important considerations:**

* Your existing NGINX Proxy Manager (and Let's Encrypt) configuration will still be available also once migrated to the open-appsec enhanced NGINX Proxy Manager deployment as long as it still resides in the local `./data` and `./letssencrypt` folders.
* If you did any important changes to the original `docker-compose.yml` file from the NGINX Proxy Manager project:\
  Once you downloaded the `docker-compose.yaml` file for deployment of NGINX Proxy Manager with open-appsec, make sure to apply these changes also to this `docker-compose.yaml` file.\
  You can compare the new `docker-compose.yaml` with the renamed `docker-compose.orig.yaml` file of you previous deployment of only NGINX Proxy Manager. Note that for the open-appsec integration a combination of a  `docker-compose.yaml` file with a **.env** file is being used, as this allows for easier customization of commonly used variables.
* Below find the relevant folders typically containing the persistent configuration of NGINX Proxy (NPM) Manager, they will also be mounted as part of the open-appsec NPM integration `docker-compose.yaml` so that all your existing configuration should be kept. \
  \
  Only if for some reason you changed the local folder locations for these specific docker volume mounts in the past, please make sure to adjust those as well in the new `.env` file for the open-appsec NGINX Proxy Manager integration.

  ```bash
  NPM_DATA=./data
  NPM_LETSENCRYPT=./letsencrypt
  ```
* When you perform the first time login with your web browser to the Web UI of the NGINX Proxy Manager (NPM) with open-appsec integration then your existing user credentials for the login should still work, indicating your NPM configuration was kept successfully.

```http
http://[hostname or IP of your host]:81
```

* After switching to and loading the new Nginx Proxy Manager (NPM) pages, make sure to clear your browser’s cache and cookies to ensure the updated configuration is applied correctly.
  {% endtab %}

{% tab title="open-appsec managed from central WebUI" %}

### **Please carefully read the important considerations below!**

Only then follow the regular instructions for the deployment:

{% content-ref url="/pages/XlgYmQShGOt1BNHDYqzR" %}
[Deploy NGINX Proxy Manager with open-appsec managed from central WebUI (SaaS)](/integrations/nginx-proxy-manager/deploy-nginx-proxy-manager-with-open-appsec-managed-from-central-webui-saas)
{% endcontent-ref %}

### **Important considerations:**

* Your existing NGINX Proxy Manager (and Let's Encrypt) configuration will still be available also once migrated to the open-appsec enhanced NGINX Proxy Manager deployment as long as it still resides in the local `./data` and `./letssencrypt` folders.
* If you did any important changes to the original `docker-compose.yml` file from the NGINX Proxy Manager project:\
  Once you downloaded the `docker-compose.yaml` file for deployment of NGINX Proxy Manager with open-appsec, make sure to apply these changes also to this `docker-compose.yaml` file.\
  You can compare the new `docker-compose.yaml` with the renamed `docker-compose.orig.yaml` file of you previous deployment of only NGINX Proxy Manager. Note that for the open-appsec integration a combination of a  `docker-compose.yaml` file with a **.env** file is being used, as this allows for easier customization of commonly used variables.
* Below find the relevant folders typically containing the persistent configuration of NGINX Proxy (NPM) Manager, they will also be mounted as part of the open-appsec NPM integration `docker-compose.yaml` so that all your existing configuration should be kept. \
  \
  Only if for some reason you changed the local folder locations for these specific docker volume mounts in the past, please make sure to adjust those as well in the new `.env` file for the open-appsec NGINX Proxy Manager integration.

  ```
  NPM_DATA=./data
  NPM_LETSENCRYPT=./letsencrypt
  ```
* When you perform the first time login with your web browser to the Web UI of the NGINX Proxy Manager (NPM) with open-appsec integration then your existing user credentials for the login should still work, indicating your NPM configuration was kept successfully.

```http
http://[hostname or IP of your host]:81
```

* After switching to and loading the new Nginx Proxy Manager (NPM) pages, make sure to clear your browser’s cache and cookies to ensure the updated configuration is applied correctly.
  {% endtab %}
  {% endtabs %}


# (OLD VERSION) How to Migrate from an Existing  NGINX Proxy Manager Deployment and Keep Configuration

To migrate from an existing NGINX Proxy Manager installation to a version which provides also open-appsec integration here's some guidance:

{% hint style="info" %}
This is only relevant if you want to keep your existing NGINX Proxy Manager configuration, otherwise we suggest to start fresh with the deployment instructions further above on this page.
{% endhint %}

{% hint style="warning" %}
Note that the specific steps can vary based on customizations that you might have done to the original NGINX Proxy Manager's docker compose file.

The below is assuming you did a deployment by using the default docker-compose.yml file as shown here: <https://nginxproxymanager.com/setup/#running-the-app> .
{% endhint %}

* Change into your existing folder that contains the docker-compose.yml file and all related files and folders for your current NGINX Proxy Manager deployment.
* Stop your current deployment with `docker compose down` in the folder that contains your docker-compose.yaml file used for the NGINX Proxy Manager deployment
* Make a full backup of your existing folder that contains the NGINX Proxy Manager docker compose environment, including any mounted volumes like `./data` and `./letsencrypt`, etc. to a safe location. This will allow you to bring it up with docker-compose up later exactly as it was before the migration, if required for some reason.
* Rename the original docker-compose.yml to docker-compose.orig.yaml.

{% tabs %}
{% tab title="open-appsec managed from NPM WebUI" %}

* Within the directory which you want to use for the deployment:\
  Create a folder `appsec-localconfig` which will hold the appsec declarative configuration file (this will be managed by the enhanced NPM WebUI).

  ```
  mkdir ./appsec-localconfig
  ```
* Download the initial declarative configuration file for open-appsec into that folder:

  ```
  wget https://raw.githubusercontent.com/openappsec/open-appsec-npm/main/deployment/local_policy.yaml -O ./appsec-localconfig/local_policy.yaml
  ```
* Create the new docker-compose.yaml file for the open-appsec NGINX Proxy Manager integration:

  ```
  wget https://raw.githubusercontent.com/openappsec/open-appsec-npm/main/deployment/docker-compose.yaml
  ```
* Edit the docker-compose.yaml file and replace "<user@email.com>" with your own email address, so we can provide assistance in case of any issues with the specific deployment in the future and provide information proactively regarding open-appsec.

  This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future
* If you did any special changes to the original `docker-compose.yml` file now is the time to apply these also to the `docker-compose.yaml` file for the open-appsec NPM integration you just downloaded/created in step 3 of the deployment instructions. For this compare the new `docker-compose.yaml` with the renamed `docker-compose.orig.yaml` file.
* Below find the relevant folders typically containing the persistent configuration of NGINX Proxy (NPM) Manager, they will also be mounted as part of the open-appsec NPM integration `docker-compose.yaml` so that all your existing configuration should be kept. \
  \
  Only if for some reason you changed the local folder locations for these specific docker volume mounts in the past, please make sure to adjust those as well in the new `docker-compose.yaml` file for the open-appsec NGINX Proxy Manager integration.

```
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
```

{% hint style="info" %}
Your existing NGINX Proxy Manager (and Let's Encrypt) configuration will still be available also once migrated to the open-appsec enhanced NGINX Proxy Manager deployment as long as it still resides in the local `./data` and `./letssencrypt` folders\
(see relevant excerpt from the docker-compose.yaml file below).&#x20;
{% endhint %}

* Run docker-compose up to start the deployment of all relevant containers:

  ```
  docker-compose up -d
  ```
* Check if the appsec-npm and the appsec-agent containers are up and running:

  ```
  docker ps
  ```
* Now you can login with your web browser to the WebUI of the NGINX Proxy Manager (NPM) with open-appsec integration as follows:\
  (Note that as you kept your existing NPM configuration your existing user credentials for the login should also still work.)

```
http://[hostname or IP of your host]:81
```

{% hint style="info" %}
After switching to and loading the new Nginx Proxy Manager (NPM) pages, we recommend clearing your browser’s cache and cookies to ensure the updated configuration is applied correctly.
{% endhint %}
{% endtab %}

{% tab title="open-appsec managed from central WebUI" %}

### Prerequisites

* **Access to a SaaS tenant on my.openappsec.io (WebUI for SaaS management)**\
  Follow the instructions available here:

{% content-ref url="/pages/0ty9rMQEgnxS9LBuN7qw" %}
[Sign-Up and Login to Portal](/getting-started/using-the-web-ui-saas/sign-up-and-login-to-portal)
{% endcontent-ref %}

* **Agent profile created for open-appsec Docker deployment in SaaS tenant** \
  Follow the instructions available here.\
  Once done, don't forget to copy the profile token after policy installation as this is needed in the installation steps further below:

{% content-ref url="/pages/WMgZp7bTMiI5PD1ocIKp" %}
[Create a Profile](/getting-started/using-the-web-ui-saas/create-a-profile)
{% endcontent-ref %}

### Instructions

* Create the new docker-compose.yaml file for the open-appsec NGINX Proxy Manager integration:

  ```
  wget https://raw.githubusercontent.com/openappsec/open-appsec-npm/main/deployment/managed-from-open-appsec-ui/docker-compose.yaml
  ```
* Edit the docker-compose.yaml with the Token from the Prerequisites.&#x20;
* If you did any special changes to the original docker-compose.yml file now is the time to apply these also to the docker-compose.yaml file for the open-appsec NPM integration you just downloaded/created in step 3 of the deployment instructions. For this compare the new `docker-compose.yaml` with the renamed `docker-compose.orig.yaml` file.
* Below find the relevant folders typically containing the persistent configuration of NGINX Proxy (NPM) Manager, they will also be mounted as part of the open-appsec NPM integration `docker-compose.yaml` so that all your existing configuration should be kept. \
  \
  Only if for some reason you changed the local folder locations for these specific docker volume mounts in the past, please make sure to adjust those as well in the new docker-compose.yaml file for the open-appsec NGINX Proxy Manager integration.

```
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
```

{% hint style="info" %}
Your existing NGINX Proxy Manager (and Let's Encrypt) configuration will still be available also once migrated to the open-appsec enhanced NGINX Proxy Manager deployment as long as it still resides in the local `./data` and `./letssencrypt` folders\
(see relevant excerpt from the docker-compose.yaml file below).&#x20;
{% endhint %}

* Run docker-compose up to start the deployment of all relevant containers:

  ```
  docker-compose up -d
  ```
* Check if the appsec-npm and the appsec-agent containers are up and running:

  ```
  docker ps
  ```
* Now you can login with your web browser to the WebUI of the NGINX Proxy Manager (NPM) with open-appsec integration as follows:\
  (Note that as you kept your existing NPM configuration your existing user credentials for the login should also still work.)

```
http://[hostname or IP of your host]:81
```

{% hint style="info" %}
After switching to and loading the new Nginx Proxy Manager (NPM) pages, we recommend clearing your browser’s cache and cookies to ensure the updated configuration is applied correctly.
{% endhint %}

{% endtab %}
{% endtabs %}

**Congratulations, you successfully migrated your existing NGINX Proxy Manager deployment to the NGINX Proxy Manager integrated with open-appsec.**


# Frequently Asked Questions

#### **Question: How can I test if open-appsec detects/prevents attacks correctly after enabling it for one of my proxy host objects in NGINX Proxy Manager?**

You can append the following to your http(s) requests to simulate an attack which should be detected/prevented by open-appsec:\
`?shell_cmd=cat/etc/passwd`

Example: `http://localhost/?shell_cmd=cat/etc/passwd`

***

#### **Question: How can I check the status of my open-appsec agent?**

You can run the command `open-appsec-ctl -s` inside the appsec-agent container:\
`docker exec appsec-agent open-appsec-ctl -s`\
\
Status should be “running” for all services in the list and "Policy load status" should show "Success".\
\
Note that the Http Transaction Handler Nano Service will only switch from “ready” to “running” state after it has received some initial packets from the attachment integrated with NPM's included NGINX reverse proxy.\
\
Here’s an example output:

```
---- open-appsec Nano Agent ----
Version: 1.1.3-open-source
Status: Running
Management mode: Local management
Policy files:
    /etc/cp/conf/local_policy.yaml
Policy load status: Success
Last policy update: 2023-12-04T11:33:46.083483
AI model version: Simple model V1.0

---- open-appsec Orchestration Nano Service ----
Type: Public, Version: 1.1.3-open-source, Created at: 2023-10-05T17:46:48+0000
Status: Running

---- open-appsec Attachment Registrator Nano Service ----
Type: Public, Version: 1.1.3-open-source, Created at: 2023-10-05T17:46:48+0000
Status: Running

---- open-appsec Http Transaction Handler Nano Service ----
Type: Public, Version: 1.1.3-open-source, Created at: 2023-10-05T17:46:48+0000
Registered Instances: 2
Status: Running
```

#### **Question:** How can I migrate from an existing installation of NGINX Proxy Manager (NPM) to NPM integrated with open-appsec and keep my existing NPM configuration?

{% content-ref url="/pages/gziQKg4NwfzhvcmjRpxt" %}
[How to Migrate from an Existing  NGINX Proxy Manager Deployment and Keep Configuration](/integrations/nginx-proxy-manager/how-to-migrate-from-an-existing-nginx-proxy-manager-deployment-and-keep-configuration)
{% endcontent-ref %}


# NPMplus

<figure><img src="/files/OvL1oh5OSAJUWOgyEGvI" alt=""><figcaption></figcaption></figure>

**NPMplus** is an enhanced fork of the **nginx-proxy-manager** open-source project and comes as a prebuilt docker image that enables you to easily forward traffic to your websites running at home or otherwise, including free TLS, without having to know too much about Nginx or Certbot.\
\
NPMplus adds many additional features and improvements to the original NGINX Proxy Manager project. You find all details on the project's GitHub repo:\
\
NPMplus project in GitHub: <https://github.com/ZoeyVid/NPMplus>\
NGINX Proxy Manager project on GitHub: <https://github.com/NginxProxyManager/nginx-proxy-manager>

## About the integration of NPMplus with open-appsec&#x20;

NPMplus provides native integration with open-appsec WAF starting from NPMplus version `2025-01-26-r1` and higher.

The `npmplus` container already includes the open-appsec attachment natively, if you want to protect your NPMplus with open-appsec WAF please make sure to activate loading of the attachment module as follows using the relevant environment variable in the NPMplus `compose.yaml` file.

```yaml
environment:
- "NGINX_LOAD_OPENAPPSEC_ATTACHMENT_MODULE=true"
```

Also make sure to uncomment this line in the `npmplus` service to allow the open-appsec attachment module to communicate with the `openappsec-agent` container:

```yaml
ipc: service:openappsec-agent # required when you want to use the openappsec attachment module
```

Learn more about NPMplus and the steps for "Quick Setup" with Docker Compose in the project's GitHub repo: <https://github.com/ZoeyVid/NPMplus?tab=readme-ov-file#quick-setup>

{% hint style="info" %}
This integration of open-appsec WAF and NPMplus is not directly maintained by the open-appsec team, you find the relevant repo here: <https://github.com/ZoeyVid/NPMplus>\
Project maintainers:\
<https://github.com/ZoeyVid>\
<https://github.com/ZoeyVid/NPMplus>\
\
As the NPMplus project is actively maintained make sure to also check out the NPMplus project repo for latest changes, updates and documentation as well (see also comments in the `compose.yaml` file).
{% endhint %}

Below you find the full deployment steps to get you started with NPMplus and open-appsec WAF integration:

## **To deploy NPMplus with open-appsec integration follow the steps below:**

### Prerequisites

* **Linux Docker Host with root permission**
* **Docker-Compose tool installed**
* **(Optional, Recommended) Sign-Up and Login to WebUI Portal**\
  If you want to centrally manage your open-appsec WAF deployment via WebUI (SaaS)\
  OR if you want to locally manage your open-appsec WAF deployment but still connect to central WebUI for viewing the local configuration (in read-only), central monitoring, logging and reporting.\
  \
  Follow the instructions below to sign-up and login to the WebUI available at <https://my.openappsec.io>:

{% content-ref url="/pages/0ty9rMQEgnxS9LBuN7qw" %}
[Sign-Up and Login to Portal](/getting-started/using-the-web-ui-saas/sign-up-and-login-to-portal)
{% endcontent-ref %}

* **(Optional, Recommended) Create deployment profile for the open-appsec deployment in WebUI Portal**\
  If you signed-up and logged in to the WebUI Portal (see prerequisite above), now follow the instructions below to create a new deployment profile for your open-appsec deployment.\
  **Once done, don't forget to copy the profile token after policy installation as this is needed in the installation steps further below.**

{% content-ref url="/pages/WMgZp7bTMiI5PD1ocIKp" %}
[Create a Profile](/getting-started/using-the-web-ui-saas/create-a-profile)
{% endcontent-ref %}

## Deployment

#### To deploy open-appsec with docker-compose and optionally connect to the central WebUI available at <https://my.openappsec.io> follow the steps below:

1. Create a folder for your new open-appsec deployment and switch to that folder, e.g.

```bash
mkdir open-appsec-deployment
cd ./open-appsec-deployment
```

2. Download the docker compose file for NPMplus which includes the open-appsec integration and adjust the configuration:

```bash
wget https://raw.githubusercontent.com/ZoeyVid/NPMplus/develop/compose.yaml
```

{% embed url="<https://raw.githubusercontent.com/ZoeyVid/NPMplus/develop/compose.yaml>" %}

* **Configure loading of the open-appsec attachment module** in npmplus by uncommenting the relevant environment variable in the npmplus container configuration:

  ```yaml
  environment:
  - "NGINX_LOAD_OPENAPPSEC_ATTACHMENT_MODULE=true"
  ```

* **Configure IPC for openappsec-agent**: Uncomment the following line in the `npmplus` service to allow the open-appsec attachment module to communicate with the `openappsec-agent` container:

  ```yaml
  ipc: service:openappsec-agent # required when you want to use the openappsec attachment modu
  ```

* **If you created a deployment profile in the WebUI and copied the Token from it:**

  \
  Edit the `compose.yaml` file and add your token to the env variable `AGENT_TOKEN` of the `openappsec-agent` container:\
  \
  Example (add your own token copied from the deployment profile in the open-appsec WebUI):<br>

  ```yaml
    - "AGENT_TOKEN=11111-22222222222-333" 
  ```

* **If you did not create a deployment profile in the WebUI and do not want to connect your deployment to central WebUI (SaaS) at all:**

  \
  Comment out the following line in the openappsec-agent service definition as shown in the example below:\
  (otherwise you get an error!):<br>

  ```yaml
   # - "AGENT_TOKEN=abc" 
  ```

  \
  In the `compose.yaml`  file uncomment the lines for the deployment of the following additional services/containers: `openappsec-smartsync` `openappsec-shared-storage` `openappsec-tuning-svc` `openappsec-db.`\
  \
  These are required **only** when not connected to the WebUI at all (resulting in standalone, locally, declaratively managed deployment).

* **Configure timezone** by adjusting `TZ` environment variable for setting Timezone in `npmplus` container\
  (Mandatory for successful start of `npmplus` container!)\
  Do this also in same way for the `TZ` environment variables of all other containers you are running\
  Example:

  ```yaml
  - "TZ=Europe/Berlin"
  ```

  Set it to one of the values from the "TZ identifier"\
  <https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List>  &#x20;

* **Configure email for acme** by adjusting ACME\_EMAIL environment variable for the npmplus container for setting email address for acme, optional for letsencrypt, but required for zerossl and google public ca.\
  Example:

  ```yaml
    - "ACME_EMAIL=user@email.com" 
  ```

* **Configure email for open-appsec** (optional):\
  Associate your email address with your specific deployment of open-appsec WAF by replacing `user@email.com` in the `user_email` parameter in `openappsec-agent` container with your own email address (more details on email purpose/usage below)

#### Available environment variables for the `openappsec-agent` service/container in the `compose.yaml` file allowing further customization of the deployment:

**AGENT\_TOKEN:** For connecting your open-appsec deployment to central WebUI  set APPSEC\_AGENT\_TOKEN to your own deployment profile token as copied from profile settings in the open-appsec central WebUI (see section [#prerequisites](#prerequisites "mention") above).

**user\_email:** (Optional) Associate your email address with your specific deployment by replacing `user@email.com` with your own email address.

This allows the open-appsec team to provide you easy assistance in case of any issues you might have with your specific deployment in the future and also to provide you information proactively regarding open-appsec in general or regarding your specific deployment. This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future.

**APPSEC\_HTTPS\_PROXY**: (Optional) Configure an HTTP(S) proxy server to be used by the agent.&#x20;

**APPSEC\_AUTO\_POLICY\_LOAD**: (Optional) When set to `true`, allows you to set the open-appsec agent to automatically apply any new changes in the local\_policy.yaml file without having to restart the agent container or applying the changes with `open-appsec-ctl -ap` (note that this can take up to 30 seconds). This is useful especially in DevOps scenarios with continuous deployment scenarios.

3. **If you want to locally, declaratively manage open-appsec with `local_policy.yaml` file:** \
   \
   Download the initial declarative configuration file for open-appsec into the subfolder `/opt/openappsec/localconf` :

```bash
mkdir /opt/openappsec/localconf
```

```bash
wget https://raw.githubusercontent.com/openappsec/openappsec/main/config/linux/v1beta1/prevent/local_policy.yaml -O /opt/openappsec/localconf/local_policy.yaml
```

{% hint style="info" %}
This example configuration file is already set to `mode: prevent-learn`so that open-appsec will prevent attacks right from the start.\
Here's the path for an alternative local-config.yaml file set to detect-learn mode.\
<https://raw.githubusercontent.com/openappsec/openappsec/main/config/linux/v1beta1/detect/local_policy.yaml>\
(or simply adjust the setting in the `mode` setting in the earlier local\_policy.yaml file to `detect-learn`)\
\
In production environments it's always recommended to start in `detect-learn` mode to allow open-appsec to achieve a certain learning level based on traffic observed before moving to `prevent-learn`for better detection accuracy and strongly reduced false positives.\
\
Read more about this here: \
[Track Learning and Move From Learn/Detect to Prevent](/how-to/configuration-and-learning/track-learning-and-move-from-learn-detect-to-prevent)
{% endhint %}

4. Perform the deployment

```bash
docker-compose up -d
```

Note that the amount of container will vary based between deployments with and without connection to central WebUI.

5. Verify that all containers are up and running by verifying their status in docker ps output. Note that the amount of container will vary based between deployments with and without connection to central WebUI.

```bash
docker ps
```

**Congratulations, you successfully deployed NPM plus integrated with open-appsec WAF!**

{% hint style="info" %}
For Production usage we recommend to switch from using the Basic to the more accurate Advanced Machine Learning model, as described here:&#x20;

[Using the Advanced Machine Learning Model](/getting-started/using-the-advanced-machine-learning-model)
{% endhint %}

## Recommended next steps:

### Configure NPMplus:

Now you can login with your web browser to the WebUI of NGINX Proxy Manager with open-appsec integration as follows:

```
http://[hostname or IP of your host]:81
```

<figure><img src="/files/idyeoDGwE2FV5v0PVp2g" alt=""><figcaption></figcaption></figure>

At first login please use the following default administrator user credentials:

```
Email:    admin@example.org
Password: iArhP1j7p1P6TA92FA2FMbbUGYqwcYzxC4AVEe12Wbi94FY9gNN62aKyF1shrvG4NycjjX9KfmDQiwkLZH1ZDR9xMjiG2QmoHXi
```

\
You will then be prompted to provide your own user details and asked to change the password, before being presented with the NGINX Proxy Manager Dashboard view:

<figure><img src="/files/AQLjVwA0Ze8eKW4C80kp" alt=""><figcaption><p>NPMplus Dashboard</p></figcaption></figure>

{% hint style="info" %}
To learn how to use the WebUI of NPMplus see the NGINX Proxy Manager (NPM) project documentation:\
<https://nginxproxymanager.com> (NPM usage and configuration will not be explained here).
{% endhint %}

### Configure open-appsec WAF:

Once you created a new Proxy Host within NPMplus WebUI you can now configure open-appsec protection for it in the open-appsec WebUI (<https://my.openappsec.io>).&#x20;

* **If you connected to central WebUI AND configured your deployment profile in the WebUI to "This management" mode for centrally managing open-appsec configuration**:\
  \
  **Create one or more assets in the WebUI** which represent web applications and/or Web APIs which you want to be protected by open-appsec WAF and allows you to adjust the open-appsec configuration specifically for each of them. <br>

  Make sure to link your assets to the specific WebUI Profile which you created earlier (General -> Profiles) and adjust the Threat Prevention mode to Detect-Learn or Prevent (Threat Prevention -> Mode), the steps are described here: \
  \
  [Protect Additional Assets](/getting-started/using-the-web-ui-saas/protect-additional-assets)

{% hint style="warning" %}
Don't forget to Enforce policy in the WebUI after you did any changes for those changes to become effective!
{% endhint %}

* **If you decided to locally, declaratively manage open-appsec (with or without connection to central WebUI in "Declarative configuration" mode):**\
  \
  Follow the steps described here to configure your open-appsec deployment using the `local_policy.yaml` file: \
  \
  [Configuration Using Local Policy File (Docker)](/getting-started/start-with-docker/configuration-using-local-policy-file-docker)\
  \
  In case you connected your locally managed deployment also to the central WebUI in "Declarative Configuration" mode, you can check security logs and view agent status and configuration also in the central WebUI at <https://my.openappsec.io> .

{% hint style="warning" %}
Don't forget to apply the policy using `open-appsec-ctl -ap` in the open-appsec-agent container or by setting `APPSEC_AUTO_POLICY_LOAD` in the `.env` file to `true` for automatic  application of any configuration changes done in the `local_policy.yaml` file for the changes to become effective!
{% endhint %}


# Docker SWAG

Deploy and configure open-appsec ML-based WAF integrated with Docker SWAG to preemptively protect your web apps and APIs against zero-day attacks and OWASP Top 10 attacks.

<figure><img src="/files/WNnGdIOAM38UOxHUzBwG" alt="" width="158"><figcaption></figcaption></figure>

{% hint style="warning" %}
open-appsec Docker SWAG integration is deprecated and not being actively maintained anymore.
{% endhint %}

Learn how to deploy “Secure Web Application Gateway” (SWAG) integrated with open-appsec WAF on Docker using docker-compose.

This easy-to-deploy integration enhances and secures your Docker SWAG deployment with automatic and preemptive threat prevention using machine learning to protect the web services exposed by Docker SWAG providing protection against zero-day and OWASP-TOP-10 attacks.

### About Docker SWAG

LinuxServer.io’s [SWAG](https://hub.docker.com/r/linuxserver/swag) docker image (Secure Web Application Gateway) provides users an easy way to deploy an NGINX web server and reverse proxy with PHP support and a built-in certbot client that automates free SSL server certificate generation and renewal processes (“Let's Encrypt” and “ZeroSSL”). Further it contains “fail2ban”, which can block IP addresses with too many failed authentication attempts.&#x20;

Website and Docs: [docs.linuxserver.io/general/swag/](https://docs.linuxserver.io/general/swag/)     Github: [linuxserver/docker-swag](https://github.com/linuxserver/docker-swag)

### Integration of Docker SWAG with open-appsec&#x20;

The SWAG container deployed as part of the docker-compose is using the “swag-attachment” image, provided by the open-appsec team, which is based on the regular SWAG image but also adds the open-appsec attachment to it as an NGINX module. This attachment enables the connection between the SWAG's NGINX reverse proxy and the open-appsec agent and provides the HTTP data for inspection to the agent.\
\
You can read more about open-appsec’s technology here:\
<https://www.openappsec.io/tech>

The resulting architecture with the open-appsec Agent container and the SWAG container then looks like this:

<figure><img src="/files/Hp8hO7WwmiTm9mAfriPZ" alt=""><figcaption></figcaption></figure>

### Management options for open-appsec WAF integrated with SWAG

There are two main ways to manage and monitor open-appsec WAF when integrated with SWAG on Docker.

* Locally manage open-appsec using a declarative configuration file and monitor logs locally using CLI or e.g. a syslog compatible server.\
  (note that even when managing open-appsec locally you can still connect the deployment to the central WebUI for monitoring, security log analysis as well as viewing the local configuration in read-only mode, more info on this later)
* Centrally manage open-appsec configuration and monitor security logs and agent status using the free, easy-to-use WebUI (SaaS) available at <https://my.openappsec.io>\
  \
  Connecting your deployment to the open-appsec central WebUI provides many benefits.\
  Using the WebUI (SaaS) is optional and included in all editions, including open-appsec free community edition.

  &#x20;

  \-       Central WebUI for viewing/managing all open-appsec configuration and functionality

  \-       Store and view your open-appsec security logs

  \-       Monitor your open-appsec deployments

  \-       Monitor learning status of each of your protected assets

  \-       See learning progress and status

  \-       Receive and manage tuning suggestions

  \-       Get cloud-based shared learning between multiple agents (e.g. in HA scenario)

#### You find the deployment guides for both of these options here:

{% content-ref url="/pages/taOhVN6W5P9tYzdOTxfG" %}
[Install Docker SWAG with open-appsec (locally managed)](/integrations/docker-swag/deprecated-deployment-options/install-docker-swag-with-open-appsec-locally-managed)
{% endcontent-ref %}

{% content-ref url="/pages/qTozQ90jdphsUrDjQZgI" %}
[Install Docker SWAG with open-appsec (centrally managed)](/integrations/docker-swag/deprecated-deployment-options/install-docker-swag-with-open-appsec-centrally-managed)
{% endcontent-ref %}

{% hint style="info" %}
You can also start with locally managed open-appsec and connect to central WebUI later on.
{% endhint %}


# How to connect locally managed Docker SWAG with open-appsec to WebUI

Connecting your integrated open-appsec deployment to the open-appsec central WebUI provides many benefits.\
Using the WebUI (SaaS) is optional and included in all editions, including open-appsec free community edition.

* Central WebUI for viewing/managing all open-appsec configuration and functionality
* Store and view your open-appsec security logs
* Monitor your open-appsec deployments
* Monitor learning status of each of your protected assets
* See learning progress and status
* Receive and manage tuning suggestions
* Get cloud-based shared learning between multiple agents (e.g. in HA scenario)

**On this page it will be explained how you can connect your existing locally-managed Docker SWAG deployment with open-appsec to the open-appsec web UI**

## Prerequisites

* Existing SWAG with open-appsec WAF deployment which
  * locally managed
  * not connected to the central web UI yet

## Steps to connect your SWAG with open-appsec WAF deployment to WebUI&#x20;

1. Sign up for a free open-appsec WebUI tenant at <https://my.openappsec.io>
2. Login to the open-appsec WebUI at <https://my.openappsec.io>
3. Create a new Docker Deployment Profile and copy the “Token” from that Profile (you will need it later!).

<figure><img src="/files/QhgUxw98QG4w3FVvbuzG" alt=""><figcaption></figcaption></figure>

4. As subtype select: SWAG + open-appsec
5. Pick your desired management mode in the new WebUI Profile:\
   You have two options:\
   \
   ***“Declarative configuration”***: In this mode after connecting the deployment to WebUI you will still configure everything in the local declarative configuration file, but the WebUI will show you all settings (in read-only) and you can monitoring logs and security events comfortably.\
   \
   ![](/files/gXPempUaGeZ1b9gbmYZt)\
   \
   ***“This management”*****:** In this mode after connecting the deployment to WebUI you will be able to manage all open-appsec settings centrally (local configuration file will not be used by the agent anymore) and to monitor logs and security events comfortably.\
   \
   ![](/files/2Z9D8V2dIzz2zDWdiWWd)<br>
6. Make sure to Enforce the policy in the WebUI (“Enforce” button in top right corner).\
   You find full details about how to create the profile and get the Token [here in our docs.](https://docs.openappsec.io/getting-started/using-the-web-ui-saas/create-agent-profile-docker)
7. In you `.env` file for your docker-compose-based deployment provide your “Token” copied from your WebUI Docker Profile (see Prerequisites above) as the value for the existing AGENT\_TOKEN key.\
   \
   It will then look somewhat similar to this:\
   \
   APPSEC\_AGENT\_TOKEN=cp-123456-1234-678901234556773478592378645\
   \
   Providing the token is critical to allow the agent to connect to the specific deployment profile in the central WebUI, which will allow you use the cloud-hosted central management for assets and policies, cloud logging, graphical dashboards, events analysis, and ability to manage multiple deployments/clusters in a scalable way. If you didn’t create a deployment profile and copy the token earlier, [here](https://docs.openappsec.io/getting-started/using-the-web-ui-saas/create-agent-profile-docker) is how to get it.<br>
8. Run following commands to redeploy your docker-compose file:

```bash
docker-compose down && docker-compose up -d
```

{% hint style="warning" %}
***Note: The following step is only relevant when you picked “This management” as management mode earlier!***\
*Skip this step for the “Declarative management” management mode as in that case the  configuration for open-appsec is done locally in the local\_policy.yaml file!*
{% endhint %}

9. **Create one or more assets in the WebUI** which represent web applications and/or Web APIs which you want to be protected by open-appsec WAF and allows you to adjust the open-appsec configuration specifically for each of them. Make sure the configured web application in your asset(s) matches your public DNS name for the SWAG container (as configure in the compose file here: URL=yourdomain.url)<br>

   Make sure to link your assets to the specific WebUI Profile which you created earlier (General -> Profiles) and adjust the Threat Prevention mode to Detect-Learn or Prevent (Threat Prevention -> Mode).\
   \
   The steps are [described here](https://docs.openappsec.io/getting-started/using-the-web-ui-saas/protect-additional-assets).\
   \
   **Don't forget to Enforce policy in the WebUI after you did any changes!**\ <br>

   <figure><img src="/files/UmNe9EWT0jggEZZ1cXAl" alt=""><figcaption></figcaption></figure>

   <figure><img src="/files/D72HsfkUVyP9pXLYZoIp" alt=""><figcaption></figcaption></figure>
10. You can check open-appsec agent status by running:

```bash
docker exec appsec-agent open-appsec-ctl -s
```

<figure><img src="/files/O5JGrx2Izcd4c0Ey42Lg" alt=""><figcaption></figcaption></figure>

Check what's shown for "Management mode:" to verify that your agent is connected to the central open-appsec WebUI in the mode which you selected within the profile settings.

9. &#x20;Now let’s simulate some attack again to verify that open-appsec is preventing it as expected and see them in Monitoring in the open-appsec WebUI:\
   \
   a)  Make sure the SWAG NGINX reverse proxy is properly set-up to point to some web application backend (see more [details here](https://docs.linuxserver.io/general/swag#reverse-proxy)). The NGINX configuration for the SWAG container is located here (on docker host): ./swag-config/nginx/site-confs/default.conf\
   (and in SWAG container it’s here: /config/nginx/site-confs/default.conf )

{% hint style="info" %}
*Note that for the following simulated attack you can also just run it against the default webpage SWAG returns after deployment and skip the above step.*&#x20;
{% endhint %}

Run following curl request to simulate an attack (replace with your SWAG container DNS name and Port)

```bash
curl -v -k https://<SWAG-CONTAINER-PUBLIC-DNS-NAME>:<PORT>/?shell_cmd=cat/etc/passwd
```

Note: “-k” was added above so this would work even when still using a Let’s Encrypt “staging” certificate.\
\
You can alternatively use your web browser, just open the following URL:

```html
https://<SWAG-CONTAINER-PUBLIC-DNS-NAME>:<PORT>/?shell_cmd=cat/etc/passwd
```

If open-appsec WAF is configured in prevent mode, you should see traffic blocked and error 403 returned. If in detect mode, you will see the security logs appear in security logs.\ <img src="/files/4SkEiw7xjSSlCIRecteA" alt="" data-size="original">\
\
b)  You’ll find the security events related to the request in the [open-appsec portal](https://my.openappsec.io/?utm_medium=doc\&utm_source=gitbook\&utm_content=top-menu#/) under the “Monitoring” tab and in logs.


# Deploy Docker SWAG with open-appsec

## Prerequisites

* **Linux Docker Host with root permission**
* **Docker-Compose tool installed**
* **(Optional, Recommended) Sign-Up and Login to WebUI Portal**\
  If you want to centrally manage your open-appsec WAF deployment via WebUI (SaaS)\
  OR if you want to locally manage your open-appsec WAF deployment but still connect to central WebUI for viewing the local configuration (in read-only), central monitoring, logging and reporting:\
  \
  Follow the instructions below to sign-up and login to the WebUI available at <https://my.openappsec.io>:

{% content-ref url="/pages/0ty9rMQEgnxS9LBuN7qw" %}
[Sign-Up and Login to Portal](/getting-started/using-the-web-ui-saas/sign-up-and-login-to-portal)
{% endcontent-ref %}

* **(Optional, Recommended) Create deployment profile for the open-appsec deployment in WebUI Portal**\
  If you signed-up and logged in to the WebUI Portal (see prerequisite above), now follow the instructions below to create a new deployment profile for your open-appsec deployment.\
  **Once done, don't forget to copy the profile token after policy installation as this is needed in the installation steps further below.**

{% content-ref url="/pages/WMgZp7bTMiI5PD1ocIKp" %}
[Create a Profile](/getting-started/using-the-web-ui-saas/create-a-profile)
{% endcontent-ref %}

## Deployment

#### To deploy open-appsec with docker-compose and optionally connect to the central WebUI available at <https://my.openappsec.io> follow the steps below:

1. Create a folder for your new open-appsec deployment and switch to that folder, e.g.

```bash
mkdir open-appsec-deployment
cd ./open-appsec-deployment
```

2. Download the docker compose file for your desired open-appsec integration

```bash
wget https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/swag/docker-compose.yaml
```

{% embed url="<https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/swag/docker-compose.yaml>" %}

Download the `.env` file for your desired open-appsec integration and adjust the configuration aligned with your own requirements as described below:

Download the default .env file here:

```bash
wget https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/swag/.env
```

{% embed url="<https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/docker-compose/swag/.env>" %}

* **If you created a deployment profile in the WebUI and copied the Token from it:**

  \
  Edit the `.env` file and add your token to the key `APPSEC_AGENT_TOKEN`.
* **If you did not create a deployment profile in the WebUI and do not want to connect your deployment to central WebUI (SaaS) at all:**

  \
  Set the value `standalone` for the key `COMPOSE_PROFILES` which will activate the deployment of additional containers which are required only when not connected to the WebUI at all (resulting in standalone, locally, declaratively managed deployment).
* Replace `user@email.com` in the .env file with your own email. (More details below.)

#### Available settings in the `.env` file allowing further customization of the deployment:

**APPSEC\_AGENT\_TOKEN:** For connecting your open-appsec deployment to central WebUI  set APPSEC\_AGENT\_TOKEN to your own deployment profile token as copied from profile settings in the open-appsec central WebUI (see section [#prerequisites](#prerequisites "mention") above).

**COMPOSE\_PROFILES:** Possible values you can set for this key:\
&#x20;(you can set multiple values, separated by comma)

`standalone` : This will activate the deployment of additional containers which are required **only** when you are not connected to the WebUI at all, resulting in standalone, locally, declaratively managed deployment.

{% hint style="warning" %}
**Only** activate the `standalone` profile in case you did not set a WebUI deployment profile token as value for the APPSEC\_AGENT\_TOKEN key (see above)!
{% endhint %}

{% hint style="info" %}
When deploying in `standalone` mode additional containers are deployed providing some additional functionality, which is relevant for standalone deployments only (this functionality is already available when connected to central management WebUI):\
\- Local syncing of learning between open-appsec processes and agents\
\- View learning progress on CLI with open-appsec-tuning-tool\
\- Receive configuration recommendations based on the learning progress using the open-appsec-tuning-tool\
\- Receive tuning suggestions and manage them (approve/reject) using the open-appsec-tuning-tool\
\
More details on the `open-appsec-tuning-tool` here: [Track Learning and Local Tuning in Standalone Deployments](/how-to/configuration-and-learning/track-learning-and-local-tuning-in-standalone-deployments)
{% endhint %}

`juiceshop` : This will deploy an additional, vulnerable juiceshop-backend container that can be used for demo and testing purposes.\
In the .env file you also find a download link for the proxy-specific configuration allowing you to access the juiceshop backend via the proxy. More info on the OWASP juiceshop project: <https://owasp.org/www-project-juice-shop/>

{% hint style="warning" %}
Do not activate the juiceshop profile in production environments as the juiceshop container is intentionally highly vulnerable and meant for testing in lab environments only!
{% endhint %}

**USER\_EMAIL:** (Optional) Associate your email address with your specific deployment by replacing `user@email.com` with your own email address.

This allows the open-appsec team to provide you easy assistance in case of any issues you might have with your specific deployment in the future and also to provide you information proactively regarding open-appsec in general or regarding your specific deployment. This is an optional parameter and can be removed. If we send automatic emails there will also be an opt-out option included for receiving similar communication in the future.

**APPSEC\_HTTPS\_PROXY**: (Optional) Configure an HTTP(S) proxy server to be used by the agent.&#x20;

**APPSEC\_AUTO\_POLICY\_LOAD**: (Optional) When set to `true`, allows you to set the open-appsec agent to automatically apply any new changes in the local\_policy.yaml file without having to restart the agent container or applying the changes with `open-appsec-ctl -ap` (note that this can take up to 30 seconds). This is useful especially in DevOps scenarios with continuous deployment scenarios.

**APPSEC\_VERSION**: Allows you to specify a specific version for deployment instead of using the default `latest` version for the containers provided by open-appsec (not relevant for postgres container).

**Additional configuration available specifically for this integration type:**

**SWAG\_CONFIG:** Set the directory on the docker host for the volume mount of the SWAG configuration.

**SWAG\_NGINX\_SITE\_CONFS:** Set the directory on the docker host for the volume mount of the NGINX site configuration, this gets mounted to `/config/nginx/proxy-confs` within the appsec-swag container.

**SWAG\_PROXY\_CONFS:** Set the directory on the docker host for the volume mount of the NGINX proxy configurations, this gets mounted to `/config/nginx/proxy-confs` within the appsec-swag container.

**SWAG\_TZ:** Specify a timezone to use, see this [list](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List).

**SWAG\_VALIDATION:** Certbot validation method to use, options are `http` or `dns` (`dns` method also requires `DNSPLUGIN` variable set) **.**

**SWAG\_DNSPLUGIN:** Required if `VALIDATION` is set to `dns`. Options are `acmedns`, `aliyun`, `azure`, `bunny`, `cloudflare`, `cpanel`, `desec`, `digitalocean`, `directadmin`, `dnsimple`, `dnsmadeeasy`, `dnspod`, `do`, `domeneshop`, `dreamhost`, `duckdns`, `dynu`, `freedns`, `gandi`, `gehirn`, `glesys`, `godaddy`, `google`, `he`, `hetzner`, `infomaniak`, `inwx`, `ionos`, `linode`, `loopia`, `luadns`, `namecheap`, `netcup`, `njalla`, `nsone`, `ovh`, `porkbun`, `rfc2136`, `route53`, `sakuracloud`, `standalone`, `transip`, and `vultr`. Also need to enter the credentials into the corresponding ini (or json for some plugins) file under `/config/dns-conf`.

**SWAG\_STAGING:** Set to `true` to retrieve certs in staging mode. Rate limits will be much higher, but the resulting cert will not pass the browser's security test. Only to be used for testing purposes.

**SWAG\_URL:** Top url you have control over (e.g. `example.com` if you own it, or `customsubdomain.example.com` if dynamic dns).

**SWAG\_SUBDOMAINS:** Subdomains you'd like the cert to cover (comma separated, no spaces) ie. `www,ftp,cloud`. For a wildcard cert, set this *exactly* to `wildcard` (wildcard cert is available via `dns` validation only)

**SWAG\_ONLY\_SUBDOMAINS:** If you wish to get certs only for certain subdomains, but not the main domain (main domain may be hosted on another machine and cannot be validated), set this to `true`

{% hint style="info" %}
Here you find additional available env variables that you can use with the appsec-swag container. Those, when required, should be configured directly in the docker-compose file, if they are not listed above. <https://github.com/linuxserver/docker-swag>
{% endhint %}

For testing purposes in a lab environment you can activate the deployment of the vulnerable juiceshop-backend container via `COMPOSE_PROFILES` key (see above) and then deploy the available configuration example for exposing it via the proxy, which is provided by the open-appsec team (download link is provided in the .env file).

{% hint style="info" %}
You find some additional advanced configuration options described within the `docker-compose.yaml` file as comments.
{% endhint %}

4. If you decided to locally, declaratively manage open-appsec with `local_policy.yaml` file: \
   \
   Download the initial declarative configuration file for open-appsec into new subfolder `./appsec-localconfig`:<br>

   ```bash
   mkdir ./appsec-localconfig
   wget https://raw.githubusercontent.com/openappsec/openappsec/main/config/linux/v1beta1/prevent/local_policy.yaml -O ./appsec-localconfig/local_policy.yaml
   ```

{% hint style="info" %}
This example configuration file is already set to `mode: prevent-learn`so that open-appsec will prevent attacks right from the start.\
Here's the path for an alternative local-config.yaml file set to detect-learn mode.\
<https://raw.githubusercontent.com/openappsec/openappsec/main/config/linux/v1beta1/detect/local_policy.yaml>\
(or simply adjust the setting in the `mode` setting in the earlier local\_policy.yaml file to `detect-learn`)\
\
In production environments it's always recommended to start in `detect-learn` mode to allow open-appsec to achieve a certain learning level based on traffic observed before moving to `prevent-learn`for better detection accuracy and strongly reduced false positives.\
\
Read more about this here: \
[Track Learning and Move From Learn/Detect to Prevent](/how-to/configuration-and-learning/track-learning-and-move-from-learn-detect-to-prevent)
{% endhint %}

{% hint style="warning" %}
If you migrate from an existing Docker SWAG deployment to Docker SWAG with open-appsec make sure to make all adjustments you did in your existing docker-compose.yaml for SWAG also in the one above and/or in the .env file before deployment.\
Also make sure to copy your existing SWAG configuration folder contents into `./swag-config` on the docker host.
{% endhint %}

5. Perform the deployment

```bash
docker-compose up -d
```

You will see output similar to the below (example screenshot is from an NGINX deployment).\
Note that the amount of container will vary between deployments with and without connection to central WebUI.\
\
![](/files/n78DmRFlWPu29yOokxla)

6. Verify that all containers are up and running by verifying their status in docker ps output. Note that the amount of container will vary based between deployments with and without connection to central WebUI.

```bash
docker ps
```

You will see output similar to the below (screenshot is from NGINX deployment):

<figure><img src="/files/68gPCyP7G02HskqKHLsz" alt=""><figcaption><p>docker ps example output with all containers up</p></figcaption></figure>

7. Configure SWAG’s NGINX reverse proxy to forward traffic to your backend webserver(s).\
   (if you don’t have experience with this, see SWAG docs: [SWAG - LinuxServer.io](https://docs.linuxserver.io/general/swag/))\
   \
   If you activated deployment of the juiceshop-backend container (not safe for production environments, just use for lab testing purposes) by adding `juiceshop` to the **COMPOSE\_PROFILES** parameter in the .env file, then you can download and use the following two example files into the mounted folders allowing you to easily configure swag to proxy inbound traffic to the juiceshop-backend container:

```bash
wget https://raw.githubusercontent.com/openappsec/openappsec/examples/juiceshop/swag/juiceshop.subfolder.conf -O ./swag-proxy-confs/juiceshop.subfolder.conf
```

```bash
wget https://raw.githubusercontent.com/openappsec/openappsec/examples/juiceshop/swag/default.conf -O ./swag-nginx-site-confs/default.conf
```

8. To verify if the SSL certificate was successfully issued by Let's Encrypt you can use the following command to show logs of the swag-attachment container:

```bash
docker logs swag-attachment
```

9. If certificate was successfully generated in Let’s Encrypt staging mode (recommended for testing, this will generate a non-trusted certificate only but allows for more failed validations before blocking for certain time) you should now change the following line in the docker-compose.yaml file (in the swag-attachment container specification) to disable staging mode and receive a valid, trusted certificate from Let’s Encrypt:\
   \
   Old value: `- STAGING=true` New value:  `- STAGING=false`\
   \
   Redeploy to apply the changes:

```bash
docker compose down && docker compose up -d
```

10. SWAG also contains fail2ban as an additional security layer.\
    You can check the fail2ban status and enabled “jails” as follows:

```bash
docker exec -it swag-attachment fail2ban-client status
```

\
Output should be similar to the following, showing the fail2ban is setup with 5 jails by default:

<figure><img src="/files/elXNkh5fALXQpByrUX9e" alt=""><figcaption></figcaption></figure>

You can read more about fail2ban here:\
[fail2ban/fail2ban: Daemon to ban hosts that cause multiple authentication errors (github.com)](https://github.com/fail2ban/fail2ban)

**Congratulations, you successfully deployed open-appsec WAF integrated with Docker SWAG!**

## Recommended next steps:

* **If you connected to central WebUI AND configured your deployment profile in the WebUI to "This management" mode for centrally managing open-appsec configuration**:\
  \
  **Create one or more assets in the WebUI** which represent web applications and/or Web APIs which you want to be protected by open-appsec WAF and allows you to adjust the open-appsec configuration specifically for each of them. <br>

  Make sure to link your assets to the specific WebUI Profile which you created earlier (General -> Profiles) and adjust the Threat Prevention mode to Detect-Learn or Prevent (Threat Prevention -> Mode), the steps are described here: \
  \
  [Protect Additional Assets](/getting-started/using-the-web-ui-saas/protect-additional-assets)

{% hint style="warning" %}
Don't forget to Enforce policy in the WebUI after you did any changes for those changes to become effective!
{% endhint %}

* **If you decided to locally, declaratively manage open-appsec (with or without connection to central WebUI in "Declarative configuration" mode):**\
  \
  Follow the steps described here to configure your open-appsec deployment using the `local_policy.yaml` file: \
  \
  [Configuration Using Local Policy File (Docker)](/getting-started/start-with-docker/configuration-using-local-policy-file-docker)\
  \
  In case you connected your locally managed deployment also to the central WebUI in "Declarative Configuration" mode, you can check security logs and view agent status and configuration also in the central WebUI at <https://my.openappsec.io> .

{% hint style="warning" %}
Don't forget to apply the policy using `open-appsec-ctl -ap` in the open-appsec-agent container or by setting `APPSEC_AUTO_POLICY_LOAD` in the `.env` file to `true` for automatic  application of any configuration changes done in the `local_policy.yaml` file for the changes to become effective!
{% endhint %}

* **Verify that open-appsec is preventing attacks:**\
  \
  a) Make sure the SWAG NGINX reverse proxy is properly set-up to point to some web application backend (see more [details here](https://docs.linuxserver.io/general/swag#reverse-proxy)). The NGINX configuration for the SWAG container is located here (on docker host): ./swag-config/nginx/site-confs/default.conf (and in SWAG container it’s here: /config/nginx/site-confs/default.conf ) *Note that for the following simulated attack you can also just run it against the default webpage SWAG returns after deployment and skip this step.*\
  \
  b) Run following curl request to simulate an attack (replace with your SWAG container DNS name and Port)

```bash
curl -v -k https://<SWAG-CONTAINER-PUBLIC-DNS-NAME>:<PORT>/?shell_cmd=cat/etc/passwd
```

Note: “-k” was added above so this would work even when still using a Let’s Encrypt “staging” certificate.&#x20;

You can alternatively use your web browser, just open the following URL:

```
https://<SWAG-CONTAINER-PUBLIC-DNS-NAME>:<PORT>/?shell_cmd=cat/etc/passwd
```

If your policy is set to prevent in the local configuration file (default in the file used when following this guide), the request will be blocked with error 403 shown, otherwise it will be detected and you will only see it in the security logs.

![](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FNcZmX14M2KdTBrq9EOnI%2Fuploads%2FFeQilC1LU7xMrTflixmM%2Fimage.png?alt=media\&token=cc0dd6e6-b0f5-438d-a359-c998e2fed9a4)

c) You can view the resulting open-appsec security logs by running:

```bash
docker exec appsec-agent open-appsec-ctl -vl
```

* If required you can further configure open-appsec WAF’s settings using open-appsec’s local declarative policy, see docs for the local policy file configuration options here:

{% content-ref url="/pages/XgfzlOEGSM2hy1w6e94z" %}
[Configuration Using Local Policy File (Docker)](/getting-started/start-with-docker/configuration-using-local-policy-file-docker)
{% endcontent-ref %}


# Frequently Asked Questions

#### **Question: How can I upgrade from an existing Docker SWAG deployment to using Docker SWAG integrated with open-appsec?**

Keeping your existing Docker SWAG configuration when deploying Docker SWAG with open-appsec is simple and straightforward:

**Moke sure to follow these important notes related to the deployment:**

* **Create a new folder** for the Docker SWAG with open-appsec deployment so that you can keep the original one as backup.
* **Copy your existing SWAG configuration** into **./swag-config** within that new folder.\
  The `docker-compose.yaml` by default mounts the config from the folder `./swag-config` on the docker host as a volume into `/config` inside the `swag-attachment` container.
* **Before deployment** of the `docker-compose.yaml` and `.env` file for the SWAG with open-appsec deployment:\
  \
  Make sure to configure all parameters which you had previously adjusted in the `docker-compose.yaml` file of your existing Docker SWAG deployment also within the `docker-compose.yaml` file or respectively in the `.env` file for the Docker SWAG with open-appsec deployment (e.g. env variables URL, VALIDATION, ...)

For the actual deployment follow the steps explained here:

{% content-ref url="/pages/mcpoyz0gThQSQQkIintt" %}
[Deploy Docker SWAG with open-appsec](/integrations/docker-swag/deploy-docker-swag-with-open-appsec)
{% endcontent-ref %}


# Deprecated Deployment Options

In this section you can find deprecated deployment options for Docker SWAG, which are no longer recommended as they have been replaced by newer, improved deployment options since quite a while.\
\
These are still shown here in case you are using these deployments in your environment.\
\
It is suggested to move to the below recommended deployment options soon.

| Deprecated Deployment Type                                                                                                                                                 | Deprecation Date | Deprecation Reason                                                        | Recommended Deployment Type                                                                          |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| [Install Docker SWAG with open-appsec (locally managed)](/integrations/docker-swag/deprecated-deployment-options/install-docker-swag-with-open-appsec-locally-managed)     | 2025-08-25       | Newer, more flexible Docker Compose available (combined with `.env` file) | [Deploy Docker SWAG with open-appsec](/integrations/docker-swag/deploy-docker-swag-with-open-appsec) |
| [Install Docker SWAG with open-appsec (centrally managed)](/integrations/docker-swag/deprecated-deployment-options/install-docker-swag-with-open-appsec-centrally-managed) | 2025-08-25       | Newer, more flexible Docker Compose available (combined with `.env` file) | [Deploy Docker SWAG with open-appsec](/integrations/docker-swag/deploy-docker-swag-with-open-appsec) |


# Install Docker SWAG with open-appsec (locally managed)

{% hint style="warning" %}
These deployment instructions is now deprecated, it is recommended to deploy Docker SWAG integrated with open-appsec using the following instructions: [Deploy Docker SWAG with open-appsec](/integrations/docker-swag/deploy-docker-swag-with-open-appsec)
{% endhint %}

## Prerequisites:

* **Linux machine with:**
  * Docker and Docker Compose installed
  * Root Permissions&#x20;

## Deployment:

#### To deploy SWAG with open-appsec integration and manage open-appsec locally (declarative management) follow the steps below:

1. From within the directory which you want to use for the deployment:\
   \
   Download the initial declarative configuration file for open-appsec into new subfolder `./appsec-localconfig`:

```
mkdir ./appsec-localconfig
wget https://raw.githubusercontent.com/openappsec/openappsec/main/config/linux/v1beta1/prevent/local_policy.yaml -O ./appsec-localconfig/local_policy.yaml
```

2. Create a `docker-compose.yaml` file with the content below, it can be downloaded as follows:

```
wget https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/swag/docker-compose.yaml
```

Here's the content of the `docker-compose.yaml` file:

```yaml
services:
  swag-attachment:
    image: ghcr.io/openappsec/swag-attachment:latest
    ipc: service:appsec-agent
    restart: unless-stopped
    container_name: swag-attachment
    cap_add:
      - NET_ADMIN
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
      - URL=yourdomain.url # replace yourdomain.url with your own domain
      # make sure your domain's public IP resolves to
      # the docker host for Let's Encrypt cert generation to succeed
      - VALIDATION=http
      # see https://docs.linuxserver.io/images/docker-swag/ for
      # more cert generation/validation options
      - STAGING=true # switch to 'false' after successful testing
    volumes:
      - ./swag-config:/config
    ports:
      - 443:443
      - 80:80 #optional

  appsec-agent:
    container_name: appsec-agent
    image: ghcr.io/openappsec/agent:latest
    ipc: shareable
    restart: unless-stopped
    environment:
      - user_email=user@email.com # adjust with your own email
      - registered_server=SWAG Server
      # if autoPolicyLoad is set to true, open-appsec will apply
      # changes in local_policy.yaml automatically
      - autoPolicyLoad=true
      # To connect to open-appsec central management WebUI 
      # create your WebUI profile at https://my.openappsec.io,
      # enforce policy, copy the profile token from WebUI and add it below 
      #- AGENT_TOKEN=
    volumes:
      - ./appsec-config:/etc/cp/conf
      - ./appsec-data:/etc/cp/data
      - ./appsec-logs:/var/log/nano_agent
      - ./appsec-localconfig:/ext/appsec
    command: /cp-nano-agent

```

{% hint style="info" %}
If you migrate from an existing Docker SWAG deployment to Docker SWAG with open-appsec make sure to make all adjustments you did in your existing docker-compose.yaml for SWAG also in the one above before deployment.\
Also make sure to copy your existing SWAG configuration folder contents into `./swag-config` on the docker host.
{% endhint %}

3. Run the docker compose:

```
 docker-compose up -d
```

You will see output similar to the below:

<figure><img src="/files/ksWM9QDRVr3vclwPcns0" alt=""><figcaption></figcaption></figure>

4. Verify that “appsec-agent” and “swag-attachment” containers are both up and running by verifying their status in docker ps output:

```
docker ps
```

<figure><img src="/files/G6g8O494zo98qCxoRKZK" alt=""><figcaption><p>expected output for docker ps</p></figcaption></figure>

5. Configure SWAG’s NGINX reverse proxy to forward traffic to your backend webserver(s).\
   (if you don’t have experience with this, see SWAG docs: [SWAG - LinuxServer.io](https://docs.linuxserver.io/general/swag/))
6. To verify if the SSL certificate was successfully issued by Let's Encrypt you can use the following command to show logs of the swag-attachment container:

```
docker logs swag-attachment
```

7. If certificate was successfully generated in Let’s Encrypt staging mode (recommended for testing, this will generate a non-trusted certificate only but allows for more failed validations before blocking for certain time) you should now change the following line in the docker-compose.yaml file (in the swag-attachment container specification) to disable staging mode and receive a valid, trusted certificate from Let’s Encrypt:\
   \
   Old value: `- STAGING=true` New value:  `- STAGING=false`\
   \
   Redeploy to apply the changes:

```
docker compose down && docker compose up -d
```

8. As SWAG also contains fail2ban as an additional security layer, you can check the fail2ban status and enabled “jails” as follows:

```
docker exec -it swag-attachment fail2ban-client status
```

\
Output should be similar to the following, showing the fail2ban is setup with 5 jails by default:

<figure><img src="/files/elXNkh5fALXQpByrUX9e" alt=""><figcaption></figcaption></figure>

You can read more about fail2ban here:\
[fail2ban/fail2ban: Daemon to ban hosts that cause multiple authentication errors (github.com)](https://github.com/fail2ban/fail2ban)

### Congratulations, you have successfully deployed SWAG Secure Web Application Gateway integrated with:

* **open-appsec WAF** for automatic, machine learning-based threat prevention
* **Let’s Encrypt SSL certificate**
* **fail2ban** preventing different types of brute-force attacks

**Now all HTTP(S) requests that SWAG’s integrated NGINX proxy will forward to your backend web server(s) will be first automatically analyzed and protected by the open-appsec WAF.**

## **Recommended next steps:**

1. Connect your existing locally managed Docker SWAG with open-appsec deployment to the central open-appsec WebUI at <https://my.openappsec.io>:\
   \
   Connecting your deployment to the open-appsec central WebUI provides many benefits.\
   Using the WebUI (SaaS) is optional and included in all editions, including open-appsec free community edition.

   &#x20;

   \-       Central WebUI for viewing/managing all open-appsec configuration and functionality

   \-       Store and view your open-appsec security logs

   \-       Monitor your open-appsec deployments

   \-       Monitor learning status of each of your protected assets

   \-       See learning progress and status

   \-       Receive and manage tuning suggestions

   \-       Get cloud-based shared learning between multiple agents (e.g. in HA scenario)\
   \
   You can find detailed instructions how to do this here:\
   \
   [How to connect locally managed Docker SWAG with open-appsec to WebUI](/integrations/docker-swag/how-to-connect-locally-managed-docker-swag-with-open-appsec-to-webui)<br>
2. You can check open-appsec agent status by running:

```
docker exec appsec-agent open-appsec-ctl -s
```

You  will see output similar to the below:

<figure><img src="/files/ycFNsltz0dCUac5gmxSI" alt=""><figcaption></figcaption></figure>

3. Verify that open-appsec is preventing attacks:\
   \
   a)  Make sure the SWAG NGINX reverse proxy is properly set-up to point to some web application backend (see more [details here](https://docs.linuxserver.io/general/swag#reverse-proxy)). The NGINX configuration for the SWAG container is located here (on docker host): ./swag-config/nginx/site-confs/default.conf\
   (and in SWAG container it’s here: /config/nginx/site-confs/default.conf )\
   \&#xNAN;*Note that for the following simulated attack you can also just run it against the default webpage SWAG returns after deployment and skip this step.*\
   \
   b)  Run following curl request to simulate an attack (replace with your SWAG container DNS name and Port)

```
curl -v -k https://<SWAG-CONTAINER-PUBLIC-DNS-NAME>:<PORT>/?shell_cmd=cat/etc/passwd
```

Note: “-k” was added above so this would work even when still using a Let’s Encrypt “staging” certificate.\
\
You can alternatively use your web browser, just open the following URL:

```
https://<SWAG-CONTAINER-PUBLIC-DNS-NAME>:<PORT>/?shell_cmd=cat/etc/passwd
```

If your policy is set to prevent in the local configuration file (default in the file used when following this guide), the request will be blocked with error 403 shown, otherwise it will be detected and you will only see it in the security logs.

<figure><img src="/files/DsrQXWLpZZGcTy405w9O" alt=""><figcaption></figcaption></figure>

c)  You can view the resulting open-appsec security logs by running:

```
docker exec appsec-agent open-appsec-ctl -vl
```

4. If required you can further configure open-appsec WAF’s settings using open-appsec’s local declarative policy, see docs for the local policy file configuration options here:

{% content-ref url="/pages/N3YqU9OqerYFKTffgBPj" %}
[Configuration Using Local Policy File (Linux)](/getting-started/start-with-linux/configuration-using-local-policy-file-linux)
{% endcontent-ref %}


# Install Docker SWAG with open-appsec (centrally managed)

{% hint style="warning" %}
These deployment instructions is now deprecated, it is recommended to deploy Docker SWAG integrated with open-appsec using the following instructions: [Deploy Docker SWAG with open-appsec](/integrations/docker-swag/deploy-docker-swag-with-open-appsec)
{% endhint %}

## Prerequisites:

* **Access to a SaaS tenant on my.openappsec.io (WebUI for SaaS management)**\
  Follow the instructions available here:

{% content-ref url="/pages/0ty9rMQEgnxS9LBuN7qw" %}
[Sign-Up and Login to Portal](/getting-started/using-the-web-ui-saas/sign-up-and-login-to-portal)
{% endcontent-ref %}

* **Agent profile created for open-appsec Docker deployment in SaaS tenant** \
  Follow the instructions available here.\
  Once done, don't forget to copy the profile token after policy installation as this is needed in the installation steps further below:

{% content-ref url="/pages/WMgZp7bTMiI5PD1ocIKp" %}
[Create a Profile](/getting-started/using-the-web-ui-saas/create-a-profile)
{% endcontent-ref %}

* **Linux machine with:**
  * Docker and Docker Compose installed
  * Root Permissions&#x20;

## Deployment

#### To deploy SWAG with open-appsec integration and manage open-appsec centrally with the open-appsec central WebUI (available at <https://my.openappsec.io>) follow the steps below:

1. Create a docker-compose.yaml file with the content below, it can be downloaded as follows:

```
wget https://raw.githubusercontent.com/openappsec/openappsec/main/deployment/swag/docker-compose.yaml
```

Here's the content of the docker-compose.yaml file:

```yaml
services:
  swag-attachment:
    image: ghcr.io/openappsec/swag-attachment:latest
    ipc: service:appsec-agent
    restart: unless-stopped
    container_name: swag-attachment
    cap_add:
      - NET_ADMIN
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Etc/UTC
      - URL=yourdomain.url # replace yourdomain.url with your own domain
      # make sure your domain's public IP resolves to
      # the docker host for Let's Encrypt cert generation to succeed
      - VALIDATION=http
      # see https://docs.linuxserver.io/images/docker-swag/ for
      # more cert generation/validation options
      - STAGING=true # switch to 'false' after successful testing
    volumes:
      - ./swag-config:/config
    ports:
      - 443:443
      - 80:80 #optional

  appsec-agent:
    container_name: appsec-agent
    image: ghcr.io/openappsec/agent:latest
    ipc: shareable
    restart: unless-stopped
    environment:
      - user_email=user@email.com # adjust with your own email
      - registered_server=SWAG Server
      # if autoPolicyLoad is set to true, open-appsec will apply
      # changes in local_policy.yaml automatically
      # this setting is only relevant when using local, declarative management
      - autoPolicyLoad=true
      # To connect to open-appsec central management WebUI 
      # create your WebUI profile at https://my.openappsec.io,
      # enforce policy, copy the profile token from WebUI and add it below 
      #- AGENT_TOKEN=
    volumes:
      - ./appsec-config:/etc/cp/conf
      - ./appsec-data:/etc/cp/data
      - ./appsec-logs:/var/log/nano_agent
      # following line is only relevant when using local, declarative management
      - ./appsec-localconfig:/ext/appsec
    command: /cp-nano-agent

```

2. In your docker-compose.yaml provide your “Token” copied from your WebUI Docker Profile (see Prerequisites above) as the value for the existing AGENT\_TOKEN key.\
   \
   It will then look somewhat similar to this:\
   \
   \- AGENT\_TOKEN=cp-123456-1234-678901234556773478592378645\
   \
   Providing the token is critical to allow the agent to connect to the specific deployment profile in the central WebUI, which will allow you use the cloud-hosted central management for assets and policies, cloud logging, graphical dashboards, events analysis, and ability to manage multiple deployments/clusters in a scalable way. If you didn’t create a deployment profile and copy the token earlier, [here](https://docs.openappsec.io/getting-started/using-the-web-ui-saas/create-agent-profile-docker) is how to get it.

{% hint style="info" %}
If you migrate from an existing Docker SWAG deployment to Docker SWAG with open-appsec make sure to make all adjustments you did in your existing docker-compose.yaml for SWAG also in the one above before deployment.\
Also make sure to copy your existing SWAG configuration folder contents into `./swag-config` on the docker host.
{% endhint %}

3. Run the docker compose:

```
 docker-compose up -d
```

You will see output similar to the below:

<figure><img src="/files/ksWM9QDRVr3vclwPcns0" alt=""><figcaption></figcaption></figure>

4. Verify that “appsec-agent” and “swag-attachment” containers are both up and running by verifying their status in docker ps output:

```
docker ps
```

You will see output similar to the below:

<figure><img src="/files/G6g8O494zo98qCxoRKZK" alt=""><figcaption></figcaption></figure>

5. Configure SWAG’s NGINX reverse proxy to forward traffic to your backend webserver(s).\
   (if you don’t have experience with this, see SWAG docs: [SWAG - LinuxServer.io](https://docs.linuxserver.io/general/swag/))
6. To verify if the SSL certificate was successfully issued by Let's Encrypt you can use following command to show logs of the swag-attachment container:

```
docker logs swag-attachment
```

7. If certificate was successfully generated in Let’s Encrypt staging mode (recommended for testing, this will generate a non-trusted certificate only but allows for more failed validations before blocking for certain time) you should now change the following line in the docker-compose.yaml file (in the swag-attachment container specification) to disable staging mode and receive a valid, trusted certificate from Let’s Encrypt:\
   \
   Old value: `- STAGING=true` New value:  `- STAGING=false`\
   \
   Redeploy to apply the changes:

```
docker-compose down && docker compose up -d
```

8. As SWAG also contains fail2ban as an additional security layer, you can check the fail2ban status and enabled “jails” as follows:

```
docker exec -it swag-attachment fail2ban-client status
```

\
Output should be similar to the following, showing the fail2ban is setup with 5 jails by default:

<figure><img src="/files/elXNkh5fALXQpByrUX9e" alt=""><figcaption></figcaption></figure>

You can read more about fail2ban here:\
[fail2ban/fail2ban: Daemon to ban hosts that cause multiple authentication errors (github.com)](https://github.com/fail2ban/fail2ban)

9. **Create one or more assets in the WebUI** which represent web applications and/or Web APIs which you want to be protected by open-appsec WAF and allows you to adjust the open-appsec configuration specifically for each of them. Make sure the configured web application in your asset(s) matches your public DNS name for the SWAG container (as configure in the compose file here: URL=yourdomain.url)<br>

   Make sure to link your assets to the specific WebUI Profile which you created earlier (General -> Profiles) and adjust the Threat Prevention mode to Detect-Learn or Prevent (Threat Prevention -> Mode).\
   \
   The steps are [described here](https://docs.openappsec.io/getting-started/using-the-web-ui-saas/protect-additional-assets).\
   \
   **Don't forget to Enforce policy in the WebUI after you did any changes!**<br>

   <figure><img src="/files/UmNe9EWT0jggEZZ1cXAl" alt=""><figcaption></figcaption></figure>

   <figure><img src="/files/D72HsfkUVyP9pXLYZoIp" alt=""><figcaption></figcaption></figure>

### Congratulations, you have successfully deployed SWAG Secure Web Application Gateway integrated with:

* **open-appsec WAF** for automatic, machine learning-based threat prevention
* **Let’s Encrypt SSL certificate**
* **fail2ban** preventing different types of brute-force attacks
* **open-appsec WebUI** (SaaS) for central management

**Now all HTTP(S) requests that SWAG’s integrated NGINX proxy will forward to your backend web server(s) will be first automatically analyzed and protected by the open-appsec WAF.**

## **Recommended next steps:**

1. You can check open-appsec agent status by running:

```
docker exec appsec-agent open-appsec-ctl -s
```

You  will see output similar to the below:

<figure><img src="/files/ycFNsltz0dCUac5gmxSI" alt=""><figcaption></figcaption></figure>

Check what's shown for "Management mode:" to verify that your agent is connected to the central open-appsec WebUI in the mode which you selected within the profile settings.

2. Verify that open-appsec is preventing attacks:

a)  If you didn't do this yet make sure the SWAG NGINX reverse proxy is properly set-up to point to some web application backend (see more [details here](https://docs.linuxserver.io/general/swag#reverse-proxy)) for which also a matching asset in the open-appsec WebUI is defined and that policy was enforced in WebUI. The NGINX configuration for the SWAG container is located here (on docker host):\
./swag-config/nginx/site-confs/default.conf\
(and in SWAG container it’s here: /config/nginx/site-confs/default.conf )\
\
*Note that for the following simulated attack you can also just run it against the default webpage SWAG returns after deployment and skip this step.*

b)  Run following curl request to simulate an attack (replace with your SWAG container DNS name and Port)

```
curl -v -k https://<SWAG-CONTAINER-PUBLIC-DNS-NAME>:<PORT>/?shell_cmd=cat/etc/passwd
```

Note: “-k” was added above so this would work even when still using a Let’s Encrypt “staging” certificate.\
\
You can alternatively use your web browser, just open the following URL:

```
https://<SWAG-CONTAINER-PUBLIC-DNS-NAME>:<PORT>/?shell_cmd=cat/etc/passwd
```

If your policy is set to prevent in the local configuration file (default in the file used when following this guide), the request will be blocked with error 403 shown, otherwise it will be detected and you will only see it in the security logs.

<figure><img src="/files/DsrQXWLpZZGcTy405w9O" alt=""><figcaption></figcaption></figure>

c)  You’ll find the security events related to the request in the [open-appsec portal](https://my.openappsec.io/?utm_medium=doc\&utm_source=gitbook\&utm_content=top-menu#/) under the “Monitoring” tab and in logs.


# Prometheus

Integrate open-appsec with [Prometheus](https://prometheus.io/) to collect and monitor key metrics related to WAF performance and behavior.

{% hint style="warning" %}
Prometheus integration is currently in **beta**. Features and behavior may change in future releases.
{% endhint %}

## Configuration

#### Prerequisites

* Access to a SaaS tenant on [my.openappsec.io](https://my.openappsec.io)
* An open-appsec Agent connected to a **centrally managed** Profile
  * If you don't have an agent see instructions on how to get started [here](/getting-started/getting-started).
  * If the agent is running as a container, ensure Prometheus port `7465` is open.
* Prometheus Server

#### Instructions Centrally managed mode:

1. In the Web UI, go to the **Profiles** page
2. Click the profile assigned to your agent and switch to **Advanced** tab
3. Under **Advanced Settings**, add:
   * **Key:** `prometheus`
   * **Value:** `true`
4. Click **Enforce Policy** to apply changes

<figure><img src="/files/RbLQJjKZSdSCvWuLrn6F" alt=""><figcaption></figcaption></figure>

4. Add a Job in your Prometheus Server configure the agent IP and Port, see example:&#x20;

```
scrape_configs:
  - job_name: 'openappsec'
    static_configs:
      - targets: ['<agent-ip>:7465']
```

#### Instructions locally managed mode:

1. Enable Prometheus Metrics:

**Linux:**

To enable Prometheus metrics collection, set the following environment variable **before running the installation script**:

```bash
export PROMETHEUS=true
```

**Docker (`docker-compose.yml`)**

Add the environment variable to your service definition:

```yaml
services:
  open-appsec-agent:
    image: <agent-image>
    environment:
      - PROMETHEUS=true
```

**Kubernetes:**&#x20;

```
env:
  PROMETHEUS: "true"

```

2. Add a Job in your Prometheus Server configure the agent IP and Port, see example:&#x20;

```
scrape_configs:
  - job_name: 'openappsec'
    static_configs:
      - targets: ['<agent-ip>:7465']
```

#### Disabling Prometheus

If you need to disable Prometheus after installation:

1. Edit the configuration file:

   ```bash
   sudo vi /etc/cp/conf/environment-details.cfg
   ```
2. Locate the `PROMETHEUS` entry and change its value from:

   ```bash
   PROMETHEUS=true
   ```

   to:

   ```bash
   PROMETHEUS=false
   ```
3. Restart the agent.

{% hint style="info" %}
Disabling Prometheus is only effective **about 30 minutes after the initial installation**.
{% endhint %}

## Supported Parameters

<table><thead><tr><th width="375">Display Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>nano_service_restarts_counter</td><td>LastReportedValue</td><td>watchdog process restart counter</td></tr><tr><td>total_requests_counter</td><td>Counter</td><td>total requests</td></tr><tr><td>unique_sources_counter</td><td>Counter</td><td>sources</td></tr><tr><td>requests_blocked_by_force_and_exception_counter</td><td>Counter</td><td>override: force exception and force block</td></tr><tr><td>requests_blocked_by_waf_counter</td><td>Counter</td><td>WAF blocked requests</td></tr><tr><td>requests_blocked_by_open_api_counter</td><td>Counter</td><td>API blocked requests</td></tr><tr><td>requests_blocked_by_bot_protection_counter</td><td>Counter</td><td>bot protection blocked requests</td></tr><tr><td>requests_threat_level_info_and_no_threat_counter</td><td>Counter</td><td>requests identified as info threat + none threat</td></tr><tr><td>requests_threat_level_low_counter</td><td>Counter</td><td>request identified as low threat</td></tr><tr><td>requests_threat_level_medium_counter</td><td>Counter</td><td>request identified as medium threat</td></tr><tr><td>requests_threat_level_high_counter</td><td>Average</td><td>request identified as high threat</td></tr><tr><td>post_requests_counter</td><td>Counter</td><td>post requests</td></tr><tr><td>get_requests_counter</td><td>Counter</td><td>get requests</td></tr><tr><td>put_requests_counter</td><td>Counter</td><td>put requests</td></tr><tr><td>patch_requests_counter</td><td>Counter</td><td>patch requests</td></tr><tr><td>delete_requests_counter</td><td>Counter</td><td>delete requests</td></tr><tr><td>other_requests_counter</td><td>Counter</td><td>other requests</td></tr><tr><td>2xx_status_code_responses_counter</td><td>Counter</td><td>response 2xx</td></tr><tr><td>4xx_status_code_responses_counter</td><td>Counter</td><td>response 4xx</td></tr><tr><td>5xx_status_code_responses_counter</td><td>Counter</td><td>response 5xx</td></tr><tr><td>requests_time_latency_average</td><td>Average</td><td>average latency</td></tr><tr><td>sql_injection_attacks_type_counter</td><td>Counter</td><td>SQL Injection</td></tr><tr><td>vulnerability_scanning_attacks_type_counter</td><td>Counter</td><td>Vulnerability Scanning</td></tr><tr><td>path_traversal_attacks_type_counter</td><td>Counter</td><td>Path Traversal</td></tr><tr><td>ldap_injection_attacks_type_counter</td><td>Counter</td><td>LDAP Injection</td></tr><tr><td>evasion_techniques_attacks_type_counter</td><td>Counter</td><td>Evasion Techniques</td></tr><tr><td>remote_code_execution_attacks_type_counter</td><td>Counter</td><td>Remote Code Execution</td></tr><tr><td>xml_extern_entity_attacks_type_counter</td><td>Counter</td><td>XML External Entity</td></tr><tr><td>cross_site_scripting_attacks_type_counter</td><td>Counter</td><td>Cross Site Scripting</td></tr><tr><td>general_attacks_type_counter</td><td>Counter</td><td>General</td></tr><tr><td>all_assets_counter</td><td>LastReportedValue</td><td>number of protected assets</td></tr><tr><td>prevent_action_matches_counter</td><td>Counter</td><td>prevent engine matches</td></tr><tr><td>detect_action_matches_counter</td><td>Counter</td><td>detect engine matches</td></tr><tr><td>ignore_action_matches_counter</td><td>Counter</td><td>ignore engine matches</td></tr><tr><td>cpu_usage_percentage_max</td><td>Max</td><td>Max CPU usage</td></tr><tr><td>cpu_usage_percentage_average</td><td>Average</td><td>Average CPU usage</td></tr><tr><td>cpu_usage_percentage_last_value</td><td>LastReportedValue</td><td>last CPU usage reported</td></tr><tr><td>service_virtual_memory_size_kb_max</td><td>Max</td><td>max service virtual memory size</td></tr><tr><td>service_virtual_memory_size_kb_min</td><td>Min</td><td>min service virtual memory size</td></tr><tr><td>service_virtual_memory_size_kb_average</td><td>Average</td><td>average service virtual memory size</td></tr><tr><td>service_physical_memory_size_kb_max</td><td>Max</td><td>max service RSS memory size</td></tr><tr><td>service_physical_memory_size_kb_min</td><td>Min</td><td>min service RSS memory size</td></tr><tr><td>service_physical_memory_size_kb_average</td><td>Average</td><td>average service RSS memory size</td></tr><tr><td>general_total_used_memory_max</td><td>Max</td><td>max general total memory size</td></tr><tr><td>general_total_used_memory_min</td><td>Min</td><td>min general total memory size</td></tr><tr><td>general_total_used_memory_average</td><td>Average</td><td>average  general total memory size</td></tr></tbody></table>




---

[Next Page](/llms-full.txt/1)

