---
title: Configure NGINX Plus for PingIntelligence
description: Configure the nginx.conf to setup NGINX Plus and PingIntelligence sideband integration. Following is a summary of steps to configure NGINX Plus for PingIntelligence:
component: pingintelligence
version: 5.1
page_id: pingintelligence:pingintelligence_integrations:yju1578545062207
canonical_url: https://docs.pingidentity.com/pingintelligence/5.1/pingintelligence_integrations/yju1578545062207.html
revdate: March 25, 2024
section_ids:
  create-modules-directory-and-download-pingintelligence-modules: Create modules directory and download PingIntelligence modules
  configure-nginx-conf-file: Configure nginx.conf file
  final-configuration-steps: Final configuration steps
---

# Configure NGINX Plus for PingIntelligence

Configure the `nginx.conf` to setup NGINX Plus and PingIntelligence sideband integration. Following is a summary of steps to configure NGINX Plus for PingIntelligence:

1. Create `modules` directory inside NGINX working directory

2. Download PingIntelligence modules

3. Copy PingIntelligence modules in the `modules` directory

4. Edit `nginx.conf` for PingIntelligence

## Create `modules` directory and download PingIntelligence modules

1. Create a `modules` directory in NGINX Plus:

   ```
   # mkdir /etc/nginx/modules
   ```

2. Download the NGINX Plus - PingIntelligence modules from the [download](https://www.pingidentity.com/en/resources/downloads/pingintelligence.html) site

3. Untar the downloaded file.

   ```
   # tar -xvzf pi-api-nginx-plus-policy-4.3.tar.gz
   ```

   The PingIntelligence modules are:

   * `ngx_ase_integration_module.so`

   * `ngx_http_ase_integration_request_module.so`

   * `ngx_http_ase_integration_response_module.so`

     The `pi-pf.conf` file has the OAuth policy details.

4. Copy the PingIntelligence modules files for Ubuntu to the `modules` directory of NGINX Plus and`pi-pf.conf` file to `/usr/local/nginx/conf/` directory.

   ```
   # cp ngx_ase_integration_module.so /etc/nginx/modules
   # cp ngx_http_ase_integration_request_module.so /etc/nginx/modules
   # cp ngx_http_ase_integration_response_module.so /etc/nginx/modules
   # cp pi-pf.conf /usr/local/nginx/conf/
   ```

5. Change to `root` user:

   ```
   # sudo su
   ```

6. Export client credentials as environment variables:

   ```
   # export PF_ID=<ID>
   # export PF_SECRET=<SECRET>
   ```

   Here `PF_ID` and `PF_SECRET` are PingFederate client ID and secret.

## Configure nginx.conf file

Complete the following steps to configure `nginx.conf` for PingIntelligence. Make sure that the PingIntelligence module and other configurations are added at the correct place in `nginx.conf` as shown in the sample file at the end of the section.

1. **Load PingIntelligence modules:** Edit the `nginx.conf` file to load the PingIntelligence modules. Following is a snippet of `nginx.conf` file showing the loaded PingIntelligence modules:

   ```
   worker_processes  4;

   error_log  /usr/local/nginx/logs/error.log debug;
   worker_rlimit_core  500M;
   working_directory  /usr/local/nginx;

   pid        /usr/local/nginx/pid/nginx.pid;
   env PF_ID;
   env PF_SECRET;

   load_module modules/ngx_ase_integration_module.so; load_module modules/ngx_http_ase_integration_request_module.so; load_module modules/ngx_http_ase_integration_response_module.so; load_module modules/ndk_http_module.so; load_module modules/ngx_http_lua_module.so;

   events {
       worker_connections  1024;
   }
    truncated nginx.conf file
   ```

2. **Configure ASE primary and secondary node**: Configure ASE primary and secondary node IP address by replacing IP:PORT in the `nginx.conf file` snippet show below:

   ```
   http {

       keepalive_timeout  65;
       upstream ase.pi {
          server  IP:PORT  max_fails=1 max_conns=100 fail_timeout=10;
          server  IP:PORT  max_fails=1 max_conns=100 fail_timeout=10 backup;
          keepalive 32;
          #keepalive_timeout 3600s; # NOT allowed < 1.15.3
      }

   truncated nginx.conf file
   ```

3. **Configure introspect server IP address**: Configure introspect server IP address by replacing IP:PORT in the `nginx.conf file` snippet show below:

   ```
   upstream introspect_server {
           server  IP:PORT  max_fails=1 max_conns=100 fail_timeout=10;
           server  IP:PORT  max_fails=1 max_conns=100 fail_timeout=10 backup;
           keepalive 32;
       }

   truncated nginx.conf file
   ```

4. **Configure username and client ID key**: Configure the username and client ID keys in `nginx.conf`. These are the keys for username and client ID that you have configured in PingFederate.

   ```
   set $oauth_username_key  Username;
   set $oauth_client_id_key  ClientID;

   truncated nginx.conf file
   ```

5. **Configure token parameter name**: Configure the token parameter name after `$arg_` and in `ase/request`:

   ```
   # Set the token parameter name below after $arg_ and inside /ase/request.
       set $oauth_key_param $arg_access_token;
       set $oauth_token_param $arg_access_token;
   	#ASE Request Proxy Configuration
          location = /ase/request {
          internal;
          ase_integration https://test.ase.pi;
          ase_integration_method "POST";
          ase_integration_http_version 1.1;
          ase_integration_ase_token $ase_token;
          ase_integration_correlation_id $correlationid;
          ase_integration_host $ase_host;
          # set token key here.
          ase_integration_token_key  access_token;
          ase_integration_ssl_trusted_certificate $certificate;
          ase_integration_ssl_verify    off;
          ase_integration_ssl_verify_depth 1;
          ase_integration_ssl_server_name off;
          ase_integration_ssl_name $ase_ssl_host;
          ase_integration_next_upstream error timeout non_idempotent;
       }

   truncated nginx.conf file
   ```

6. **Configure introspection URL**: Configure the URL of the introspection server:

   ```
   # Set introspection URL
       set $oauth_url https://introspect_server/as/introspect.oauth2;

   truncated nginx.conf file
   ```

7. **Configure ASE Sideband token**: The sideband authentication token was created as part of the[Prerequisites](pingintelligence_nginx_plus_prepare.html) in the PingIntelligence section. Following is a snippet the showing certificate location and sideband authentication token:

8. **Configure ASE request and response:** Configure ASE request and response API endpoints in `nginx.conf`. Following snippet of `nginx.conf` shows ASE request and response:

   ```
    #ASE Request Proxy Configuration
       location = /ase/request {
          internal;
          ase_integration https://test.ase.pi;
          ase_integration_method "POST";
          ase_integration_http_version 1.1;
          ase_integration_ase_token $ase_token;
          ase_integration_correlation_id $correlationid;
          ase_integration_host $ase_host;
          # set token key here.
          ase_integration_token_key access_token;
          ase_integration_ssl_trusted_certificate $certificate;
          ase_integration_ssl_verify    off;
          ase_integration_ssl_verify_depth 1;
          ase_integration_ssl_server_name off;
          ase_integration_ssl_name $ase_ssl_host;
          ase_integration_next_upstream error timeout non_idempotent;
       }
       #ASE Response Proxy Configuration
       location = /ase/response {
          internal;
          ase_integration https://test.ase.pi;
          ase_integration_method "POST";
          ase_integration_http_version 1.1;
          ase_integration_ase_token $ase_token;
          ase_integration_correlation_id $correlationid;
          ase_integration_host $ase_host;
          ase_integration_ssl_trusted_certificate $certificate;
          ase_integration_ssl_verify    off;
          ase_integration_ssl_verify_depth 1;
          ase_integration_ssl_server_name off;
          ase_integration_ssl_name $ase_ssl_host;
          ase_integration_next_upstream error timeout non_idempotent;
       }

   truncated nginx.conf file
   ```

9. **Apply PingIntelligence policy**: You can apply PingIntelligence policy at the global level, that is, for all the APIs in your environment or for an individual API.

   |   |                                                                                                                                                                       |
   | - | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
   |   | If the authorization header in the request has multiple tokens, the PingIntelligence policy extracts only the first valid bearer token from the authorization header. |

   * **Apply PingIntelligence policy globally**: To apply PingIntelligence policy globally, add `ase_integration_request` and `ase_integration_response` in the `server`section of `nginx.conf` as shown below:

     ```
     server {
         listen              4443 ssl bind;
         server_name         localhost;
         ssl_certificate     /usr/local/nginx/ssl/cert.pem;
         ssl_certificate_key /usr/local/nginx/ssl/key.pem;
         ssl_password_file   /usr/local/nginx/ssl/password_file;
         ssl_protocols       TLSv1.2;
         ssl_ciphers         HIGH:!aNULL:!MD5;
         resolver 8.8.8.8 ipv6=off;
          ase_integration_request; ase_integration_response;

         # Set OAuth Client details
      truncated nginx.conf file
     ```

   * **Apply PingIntelligence policy for a specific API**: Apply PingIntelligence modules for APIs by configuring `location` in `nginx.conf`. `ase_integration_request` should be the first and a `ase_integration_response` should be the last.

     |   |                                                                                                                                         |
     | - | --------------------------------------------------------------------------------------------------------------------------------------- |
     |   | Comment-out the `ase_integration_request` and `ase_integration_response` that was configured to apply PingIntelligence policy globally. |

     ```
     location / {
            include /usr/local/nginx/conf/pi-pf.conf;
            ase_integration_request;
            proxy_pass http://localhost:8080/;
            ase_integration_response;
     }

     truncated nginx.conf file
     ```

10. **Verify syntactical correctness of nginx.conf**: To verify the syntactical correctness of nginx.conf, run the following command:

    ```
    # /usr/local/nginx/sbin/nginx -t
    nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
    nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
    ```

## Final configuration steps

Complete the following steps to configure PingIntelligence policy for NGINX Plus:

1. Restart NGINX by entering the following command:

   ```
   # /usr/local/nginx/sbin/nginx -s stop
   # /usr/local/nginx/sbin/nginx
   ```

2. Run the following command to verify if `--with-compat` and `--with-http_ssl_module` is in the list of flags under configured arguments.

   ```
   # sudo /usr/local/nginx/sbin/nginx -V
   nginx version: nginx/1.15.2 (nginx-plus-r16)
   built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
   built with OpenSSL 1.0.2g  1 Mar 2016
   TLS SNI support enabled
   configure arguments: --with-compat --with-http_ssl_module
   ```

3. Verify that NGINX has restarted by entering the following command:

   ```
   # netstat -tulpn | grep 4443
   ```

Following is a sample `nginx.conf` file:

```
worker_processes  4;

error_log  /usr/local/nginx/logs/error.log debug;
worker_rlimit_core  500M;
working_directory  /usr/local/nginx;

pid        /usr/local/nginx/pid/nginx.pid;
env PF_ID;
env PF_SECRET;

load_module modules/ngx_ase_integration_module.so;
load_module modules/ngx_http_ase_integration_request_module.so;
load_module modules/ngx_http_ase_integration_response_module.so;
load_module modules/ndk_http_module.so;
load_module modules/ngx_http_lua_module.so;

events {
    worker_connections  1024;
}

http {

    keepalive_timeout  65;
    upstream test.ase.pi {
       server IP:PORT max_fails=1 max_conns=100 fail_timeout=10;
       server IP:PORT max_fails=1 max_conns=100 fail_timeout=10 backup;
       keepalive 32;
#      keepalive_timeout 3600s; # NOT allowed < 1.15.3
   }

    upstream introspect_server {
        server IP:PORT max_fails=1 max_conns=100 fail_timeout=10;
        server IP:PORT max_fails=1 max_conns=100 fail_timeout=10 backup;
        keepalive 32;
    }

    lua_shared_dict cache_dict 128m;

server {
    listen              4443 ssl bind;
    server_name         localhost;
    ssl_certificate     /usr/local/nginx/ssl/cert.pem;
    ssl_certificate_key /usr/local/nginx/ssl/key.pem;
    ssl_password_file   /usr/local/nginx/ssl/password_file;
    ssl_protocols       TLSv1.2;
    ssl_ciphers         HIGH:!aNULL:!MD5;
    resolver 8.8.8.8 ipv6=off;
    ase_integration_request;
    ase_integration_response;

    # Set OAuth Client details

    # Set env variable PF_ID &PF_SECRET
    set_by_lua $client_id 'return os.getenv("PF_ID")';
    set_by_lua $client_secret 'return os.getenv("PF_SECRET")';

    # Uncomment next 2 lines to set client credentials here.
    # set $client_id nginx_client;
    # set $client_secret nginx_secret;

    set $oauth_username_key Username;
    set $oauth_client_id_key ClientID;

    # Set the token parameter name below after $arg_ and inside /ase/request.
    set $oauth_key_param $arg_access_token;
    set $oauth_token_param $arg_access_token;

    # Set cache lifetime, default is 120s.
    set $oauth_cache_timeout 120;

    # Set introspection URL
    set $oauth_url https://introspect_server/as/introspect.oauth2;

    location /introspect {
        internal;
        proxy_method    POST;
        if ($arg_auth_token) {
            set $auth_token $arg_auth_token;
        }
         if ($http_authorization ~* .*?(bearer)(\s+)([-a-zA-Z0-9._~+/]+)(,|\s|$)) {
            set $auth_token $3;
        }
        proxy_set_header  Content-Type "application/x-www-form-urlencoded";
        proxy_set_body  "client_id=${client_id}&client_secret=${client_secret}&token=${auth_token}";
        proxy_pass_request_body off;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_pass      $oauth_url;
    }

    location /shop {
       include /usr/local/nginx/conf/pi-pf.conf;
       proxy_pass http://18.209.173.37:4100/shop;

    }
    #DO NOT EDIT BELOW VARIABLE
    set $correlationid $pid-$request_id-$server_addr-$remote_addr-$remote_port-$request_length-$connection;
    #Certificate location of ASE
    set $certificate /usr/local/nginx/ssl/test.ase.pi;
    #ASE Token for sideband authentication
    set $ase_token <ASE_TOKEN>;
    #Host header which should be send to ASE
    set $ase_host test.ase.pi;
    #SNI value to use for ASE
    set $ase_ssl_host test.ase.pi;
    #ASE Request Proxy Configuration
    location = /ase/request {
       internal;
       ase_integration https://test.ase.pi;
       ase_integration_method "POST";
       ase_integration_http_version 1.1;
       ase_integration_ase_token $ase_token;
       ase_integration_correlation_id $correlationid;
       ase_integration_host $ase_host;
       # set token key here.
       ase_integration_token_key access_token;
       ase_integration_ssl_trusted_certificate $certificate;
       ase_integration_ssl_verify    off;
       ase_integration_ssl_verify_depth 1;
       ase_integration_ssl_server_name off;
       ase_integration_ssl_name $ase_ssl_host;
       ase_integration_next_upstream error timeout non_idempotent;
    }
    #ASE Response Proxy Configuration
    location = /ase/response {
       internal;
       ase_integration https://test.ase.pi;
       ase_integration_method "POST";
       ase_integration_http_version 1.1;
       ase_integration_ase_token $ase_token;
       ase_integration_correlation_id $correlationid;
       ase_integration_host $ase_host;
       ase_integration_ssl_trusted_certificate $certificate;
       ase_integration_ssl_verify    off;
       ase_integration_ssl_verify_depth 1;
       ase_integration_ssl_server_name off;
       ase_integration_ssl_name $ase_ssl_host;
       ase_integration_next_upstream error timeout non_idempotent;
    }
}

}
```
