diff --git a/content/includes/nap-waf/config/common/nginx-app-protect-waf-terminology.md b/content/includes/nap-waf/config/common/nginx-app-protect-waf-terminology.md index f1f28bb0c..2630c54ec 100644 --- a/content/includes/nap-waf/config/common/nginx-app-protect-waf-terminology.md +++ b/content/includes/nap-waf/config/common/nginx-app-protect-waf-terminology.md @@ -1,5 +1,8 @@ --- nd-docs: "DOCS-1605" +files: + - content/nap-waf/v5/configuration-guide/configuration.md + - content/nginx-one/glossary.md --- This guide assumes that you have some familiarity with various Layer 7 (L7) Hypertext Transfer Protocol (HTTP) concepts, such as Uniform Resource Identifier (URI)/Uniform Resource Locator (URL), method, header, cookie, status code, request, response, and parameters. @@ -26,4 +29,4 @@ This guide assumes that you have some familiarity with various Layer 7 (L7) Hype |Tuning | Making manual changes to an existing security policy to reduce false positives and increase the policy’s security level. | |URI/URL | The Uniform Resource Identifier (URI) specifies the name of a web object in a request. A Uniform Resource Locator (URL) specifies the location of an object on the Internet. For example, in the web address, `http://www.siterequest.com/index.html`, index.html is the URI, and the URL is `http://www.siterequest.com/index.html`. In NGINX App Protect WAF, the terms URI and URL are used interchangeably. | |Violation | Violations occur when some aspect of a request or response does not comply with the security policy. You can configure the blocking settings for any violation in a security policy. When a violation occurs, the system can Alarm or Block a request (blocking is only available when the enforcement mode is set to Blocking). | -{{}} \ No newline at end of file +{{}} diff --git a/content/nginx-one/_index.md b/content/nginx-one/_index.md index 3cfd13708..34a88e88e 100644 --- a/content/nginx-one/_index.md +++ b/content/nginx-one/_index.md @@ -19,6 +19,7 @@ F5 NGINX One Console makes it easy to manage NGINX instances across locations an [//]: # "You can add a maximum of three cards: any extra will not display." [//]: # "One card will take full width page: two will take half width each. Three will stack like an inverse pyramid." [//]: # "Some examples of content could be the latest release note, the most common install path, and a popular new feature." + {{}} {{}} {{}} @@ -36,6 +37,9 @@ F5 NGINX One Console makes it easy to manage NGINX instances across locations an {{}} Manage one instance or groups of instances. Monitor certificates. Set up metrics. {{}} + {{}} + Manage one instance or groups of instances. Monitor certificates. Set up metrics. + {{}} {{}} Assign responsibilities with role-based access control {{}} @@ -58,10 +62,23 @@ F5 NGINX One Console makes it easy to manage NGINX instances across locations an {{}} {{}} +### More information + +{{}} + {{}} + {{}} + See latest updates: New features, improvements, and bug fixes + {{}} + {{}} + See latest updates: New features, improvements, and bug fixes + {{}} + {{}} +{{}} + ## NGINX One components [//]: # "You can add any extra content for the page here, such as additional cards, diagrams or text." -{{< card-layout >}} +{{}} {{< card-section title="Kubernetes Solutions">}} {{< card title="NGINX Ingress Controller" titleUrl="/nginx-ingress-controller/" brandIcon="NGINX-Ingress-Controller-product-icon">}} Kubernetes traffic management with API gateway, identity, and observability features. diff --git a/content/nginx-one/changelog.md b/content/nginx-one/changelog.md index dd9cf1216..1c38199b4 100644 --- a/content/nginx-one/changelog.md +++ b/content/nginx-one/changelog.md @@ -30,6 +30,17 @@ h2 { Stay up-to-date with what's new and improved in the F5 NGINX One Console. +## July 15, 2025 + +### Set up F5 NGINX App Protect WAF security policies + +You can now incorporate [NGINX App Protect WAF]({{< ref "/nap-waf/" >}}) in NGINX One Console UI. For details, see [Secure with NGINX App Protect]({{< ref "/nginx-one/nap-integration/" >}}). + +In NGINX One Console, you can: + +- Toggle between [Default policy bundles]({{< ref "/nap-waf/v5/configuration-guide/configuration/#updating-default-policy-bundles" >}}) +- Set a blocking or transparant [Policy enforcement mode]({{< ref "/nap-waf/v5/configuration-guide/configuration/#policy-enforcement-modes" >}}) + ## July 1, 2025 ### NGINX Agent version 3 support diff --git a/content/nginx-one/glossary.md b/content/nginx-one/glossary.md index 69c264c63..fe3608390 100644 --- a/content/nginx-one/glossary.md +++ b/content/nginx-one/glossary.md @@ -10,6 +10,7 @@ type: This glossary defines terms used in the F5 NGINX One Console and F5 Distributed Cloud. +## General terms {{}} | Term | Definition | @@ -24,6 +25,10 @@ This glossary defines terms used in the F5 NGINX One Console and F5 Distributed | **Tenant** | A tenant in F5 Distributed Cloud is an entity that owns a specific set of configuration and infrastructure. It is fundamental for isolation, meaning a tenant cannot access objects or infrastructure of other tenants. Tenants can be either individual or enterprise, with the latter allowing multiple users with role-based access control (RBAC). | {{}} +## NGINX App Protect WAF terminology + +{{< include "nap-waf/config/common/nginx-app-protect-waf-terminology.md" >}} + ## Legal notice: Licensing agreements for NGINX products Using NGINX One is subject to our End User Service Agreement (EUSA). For [NGINX Plus]({{< ref "/nginx" >}}), usage is governed by the End User License Agreement (EULA). Open source projects, including [NGINX Agent](https://github.com/nginx/agent) and [NGINX Open Source](https://github.com/nginx/nginx), are covered under their respective licenses. For more details on these licenses, follow the provided links. diff --git a/content/nginx-one/nap-integration/_index.md b/content/nginx-one/nap-integration/_index.md new file mode 100644 index 000000000..b21ffdf45 --- /dev/null +++ b/content/nginx-one/nap-integration/_index.md @@ -0,0 +1,6 @@ +--- +title: Secure with NGINX App Protect +description: +weight: 400 +url: /nginx-one/nap-integration +--- diff --git a/content/nginx-one/nap-integration/configure-policy.md b/content/nginx-one/nap-integration/configure-policy.md new file mode 100644 index 000000000..da58de0c8 --- /dev/null +++ b/content/nginx-one/nap-integration/configure-policy.md @@ -0,0 +1,48 @@ +--- +# We use sentence case and present imperative tone +title: "Add and configure a policy" +# Weights are assigned in increments of 100: determines sorting order +weight: 200 +# Creates a table of contents and sidebar, useful for large documents +toc: false +# Types have a 1:1 relationship with Hugo archetypes, so you shouldn't need to change this +nd-content-type: how-to +# Intended for internal catalogue and search, case sensitive: +# Agent, N4Azure, NIC, NIM, NGF, NAP-DOS, NAP-WAF, NGINX One, NGINX+, Solutions, Unit +nd-product: NGINX One +--- + +This document describes how you can configure a security policy in the F5 NGINX One Console. When you add a policy, NGINX One Console includes several UI-based options and presets, based on NGINX App Protect WAF. + + +If you already know NGINX App Protect WAF, you can go beyond the options available in the UI. + +## Add a policy + +From NGINX One Console, select App Protect > Policies. In the screen that appears, select **Add Policy**. That action opens a screen where you can: + +- In General Settings, name and describe the policy. + - You can also set one of the following enforcement modes: + - Transparent + - Blocking + +For details, see the [Glossary]({{< ref "/nginx-one/glossary.md#nginx-app-protect-waf-terminology" >}}), specifically the entry: **Enforcement mode**. You'll see this in the associated configuration file, +with the `enforcementMode` property. + +You can also set a character encoding. The default encoding is `Unicode (utf-8)`. To set a different character encoding, select **Show Advanced Fields** and select the **Application Language** of your choice. + +## Configure a policy + +With NGINX One Console User Interface, you get a default policy. You can also select **NGINX Strict** for a more rigorous policy: + +### Basic Configuration and the Default Policy + +{{< include "/nap-waf/concept/basic-config-default-policy.md" >}} + +## Save your policy + +NGINX One Console includes a Policy JSON section which displays your policy in JSON format. What you configure here is written to your instance of NGINX App Protect WAF. + +With the **Edit** option, you can customize this policy. It opens the JSON file in a local editor. When you select **Save Policy**, it saves the latest version of what you've configured. You'll see your new policy under the name you used. + +From NGINX One Console, you can review the policies that you've saved, along with their versions. Select **App Protect** > **Policies**. Select the policy that you want to review or modify. diff --git a/content/nginx-one/nap-integration/deploy-policy.md b/content/nginx-one/nap-integration/deploy-policy.md new file mode 100644 index 000000000..884c1a86f --- /dev/null +++ b/content/nginx-one/nap-integration/deploy-policy.md @@ -0,0 +1,28 @@ +--- +# We use sentence case and present imperative tone +title: "Deploy policy" +# Weights are assigned in increments of 100: determines sorting order +weight: 400 +# Creates a table of contents and sidebar, useful for large documents +toc: false +# Types have a 1:1 relationship with Hugo archetypes, so you shouldn't need to change this +nd-content-type: how-to +# Intended for internal catalogue and search, case sensitive: +# Agent, N4Azure, NIC, NIM, NGF, NAP-DOS, NAP-WAF, NGINX One, NGINX+, Solutions, Unit +nd-product: NGINX One +--- + +After you've set up a policy, it won't do anything, until you deploy it to one or more instances and Config Sync Groups. + +This page assumes you've created a policy in NGINX One Console that you're ready to deploy. + +## Deploy a policy + +To deploy a policy from NGINX One Console, take the following steps: + +1. Select **App Protect** > **Policies**. +1. Select the policy that you're ready to deploy. +1. Select the **Details** tab. +1. In the **Deploy Policy** window that appears, you can confirm the name of the current policy and the version to deploy. NGINX One Console defaults to the selected policy and latest version. +1. In the **Target** section, select Instance or Config Sync Group. +1. In the drop-down menu that appears, select the instance or Config Sync Group available in the current NGINX One Console. diff --git a/content/nginx-one/nap-integration/overview.md b/content/nginx-one/nap-integration/overview.md new file mode 100644 index 000000000..f3c628333 --- /dev/null +++ b/content/nginx-one/nap-integration/overview.md @@ -0,0 +1,56 @@ +--- +# We use sentence case and present imperative tone +title: "NGINX App Protect integration overview" +# Weights are assigned in increments of 100: determines sorting order +weight: 100 +# Creates a table of contents and sidebar, useful for large documents +toc: false +# Types have a 1:1 relationship with Hugo archetypes, so you shouldn't need to change this +nd-content-type: concept +# Intended for internal catalogue and search, case sensitive: +# Agent, N4Azure, NIC, NIM, NGF, NAP-DOS, NAP-WAF, NGINX One, NGINX+, Solutions, Unit +nd-product: NGINX One +--- + +You can now integrate the features of F5 NGINX App Protect WAF v4 and v5 in F5 NGINX One Console. NGINX App Protect offers advanced Web Application Firewall (WAF) capabilities. +Through the NGINX One Console UI, you can now set up the [NGINX App Protect WAF]({{< ref "/nap-waf/" >}}) firewall. This solution provides robust security and scalability. + +## Features + +Once you've connected to the NGINX One Console, select **App Protect > Policies**. You can add new policies or edit existing policies, as defined in the [NGINX App Protect WAF Administration Guide]({{< ref "/nap-waf/v5/admin-guide/overview.md" >}}) + +Through the NGINX One Console UI, you can: + +- [Add and configure a policy]({{< ref "/nginx-one/nap-integration/configure-policy.md/" >}}) +- [Review existing policies]({{< ref "/nginx-one/nap-integration/review-policy.md/" >}}) +- [Deploy policies]({{< ref "/nginx-one/nap-integration/deploy-policy.md/" >}}) on instances and Config Sync Groups + +You can also set up policies through the [NGINX One Console API]({{< ref "/nginx-one/nap-integration/security-policy-api.md/" >}}). + +## Set up NGINX App Protect + +You can install and upgrade NGINX App Protect: + +Version 4: + +- [Install]({{< ref "/nap-waf/v4/admin-guide/install.md" >}}) +- [Upgrade]({{< ref "/nap-waf/v4/admin-guide/upgrade-nap-waf.md" >}}) + +Version 5: + +- [Install]({{< ref "/nap-waf/v5/admin-guide/install.md" >}}) +- [Upgrade]({{< ref "/nap-waf/v5/admin-guide/upgrade-nap-waf.md" >}}) + +### Container-related configuration requirements + +NGINX App Protect WAF Version 5 has specific requirements for the configuration with Docker containers: + +- Directory associated with the volume, which you may configure in a `docker-compose.yaml` file. + - You may set it up with the `volumes` directive with a directory like `/etc/nginx/app_protect_policies`. + - You need to set up the container volume. So when the policy bundle is referenced in the `nginx` directive, the file path is what the container sees. + - You need to also include an `app_protect_policy_file`, as described in [App Protect Specific Directives]({{< ref "/nap-waf/v5/configuration-guide/configuration.md#app-protect-specific-directives" >}}) + + - You'll need to set a policy bundle (in compressed tar format) in a configured `volume`. + - Make sure the directory for [NGINX Agent]({{< ref "/agent/configuration/" >}}) includes `/etc/nginx/app_protect_policies`. + +When you deploy NAP policy through NGINX One Console, do not also use plain JSON policy in the same NGINX instance. diff --git a/content/nginx-one/nap-integration/review-policy.md b/content/nginx-one/nap-integration/review-policy.md new file mode 100644 index 000000000..5ab824b2e --- /dev/null +++ b/content/nginx-one/nap-integration/review-policy.md @@ -0,0 +1,40 @@ +--- +# We use sentence case and present imperative tone +title: "Review policy" +# Weights are assigned in increments of 100: determines sorting order +weight: 300 +# Creates a table of contents and sidebar, useful for large documents +toc: false +# Types have a 1:1 relationship with Hugo archetypes, so you shouldn't need to change this +nd-content-type: how-to +# Intended for internal catalogue and search, case sensitive: +# Agent, N4Azure, NIC, NIM, NGF, NAP-DOS, NAP-WAF, NGINX One, NGINX+, Solutions, Unit +nd-product: NGINX One +--- + +Before you implement a policy on an NGINX instance or Config Sync Group, you may want to review it. F5 NGINX One Console creates a policy for your NGINX App Protect WAF system. + +## Review NGINX App Protect policies + +From NGINX One Console, select **App Protect** > **Policies**. Select the name of the policy that you want to review. You'll see the following tabs: + +- Details, which includes: + - Policy Details: Descriptions, status, enforcement type, latest version, and last deployed time. + - Deployments: List of instances and Config Sync Groups where the NGINX App Protect policy is deployed. +- Policy JSON: The policy, in JSON format. With the **Edit** button, you can modify this policy. +- Versions: Policy versions that you've written. You can apply an older policy to your deployments. + +## Modify existing policies + +From the NGINX One Console, you can also manage existing policies. In the Policies screen, identify a policy, and select **Actions**. From the menu that appears, you can: + +- **Edit** an existing policy. +- **Save As** to save an existing policy with a new name. You can use an existing policy as a baseline for further customization. +- **Deploy Latest Version** to apply the latest revision of an existing policy to the configured instances and Config Sync Groups. +- **Export** the policy in JSON format. +- **Delete** the policy. Once confirmed, you'll lose all work you've done on that policy. + +{{< note >}} +If you use **Save As** to create a new policy, include the `app_protect_cookie_seed` [directive]({{< ref "/nap-waf/v5/configuration-guide/configuration.md#directives" >}}). +{{< /note >}} + diff --git a/content/nginx-one/nap-integration/security-policy-api.md b/content/nginx-one/nap-integration/security-policy-api.md new file mode 100644 index 000000000..3a9b91d36 --- /dev/null +++ b/content/nginx-one/nap-integration/security-policy-api.md @@ -0,0 +1,26 @@ +--- +title: "Set security policies through the API" +weight: 700 +toc: true +type: reference +product: NGINX One +docs: DOCS-000 +--- + +You can use F5 NGINX One Console API to manage security policies. With our API, you can: + +- [List existing policies]({{< ref "/nginx-one/api/api-reference-guide/#operation/listNapPolicies" >}}) + - You can set parameters to sort policies by type. +- [Create a new policy]({{< ref "/nginx-one/api/api-reference-guide/#operation/createNapPolicy" >}}) + - You need to translate the desired policy.json file to base64 format. +- [Get policy details]({{< ref "/nginx-one/api/api-reference-guide/#operation/getNapPolicy" >}}) + - Returns details of the policy you identified with the policy `object_id`. +- [List NGINX App Protect Deployments]({{< ref "/nginx-one/api/api-reference-guide/#operation/listNapPolicyDeployments" >}}) + - The output includes: + - Target of the deployment + - Time of deployment + - Enforcement mode + - Policy version + - Threat campaign + - Attack signature + - Bot signature diff --git a/static/nginx-one/api/one.json b/static/nginx-one/api/one.json index 3dcfbf8f4..00e9d81bb 100644 --- a/static/nginx-one/api/one.json +++ b/static/nginx-one/api/one.json @@ -53,8 +53,14 @@ }, { "name": "Staged Configs", + "description": "The `StagedConfigs` object represents a NGINX staged config which users can save to publish at a later time.\n", "x-displayName": "Staged Configs" }, + { + "name": "Control Planes", + "description": "The `Control Planes` object represents an external control plane such as NGINX Ingress Controller.\nFrom this endpoint, you can get detailed information about each control plane, including its Nginx instances, configurations, security advisories, and operational status.\n", + "x-displayName": "Control Planes" + }, { "name": "Metrics", "x-displayName": "Metrics" @@ -63,6 +69,11 @@ "name": "Settings", "description": "Configuration option for different aspect of NGINX One service.\nYou can set NGINX Instance cleanup preferences.\n", "x-displayName": "Settings" + }, + { + "name": "NGINX App Protect", + "description": "Manage and publish security policies on your NGINX data plane instances.\n", + "x-displayName": "NGINX App Protect" } ], "paths": { @@ -1197,6 +1208,11 @@ "application/json": { "schema": { "$ref": "#/components/schemas/ConfigSyncGroupDetails" + }, + "examples": { + "ConfigSyncGroupDetails": { + "$ref": "#/components/examples/ConfigSyncGroupDetails" + } } } } @@ -1894,6 +1910,151 @@ } ] }, + "/control-planes": { + "get": { + "tags": [ + "Control Planes" + ], + "x-feature-flag": "control_planes_m1", + "summary": "List control planes", + "operationId": "listControlPlanes", + "description": "Returns a paginated list of control planes.\n", + "parameters": [ + { + "$ref": "#/components/parameters/Paginated" + }, + { + "$ref": "#/components/parameters/Limit" + }, + { + "$ref": "#/components/parameters/Offset" + }, + { + "$ref": "#/components/parameters/SortDirection" + }, + { + "$ref": "#/components/parameters/SortNameControlPlanes" + }, + { + "$ref": "#/components/parameters/FilterOperands" + }, + { + "$ref": "#/components/parameters/FilterValues" + }, + { + "$ref": "#/components/parameters/FilterFieldControlPlanes" + } + ], + "responses": { + "200": { + "description": "Successfully retrieved the list of control planes.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ControlPlaneListResponse" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "500": { + "$ref": "#/components/responses/InternalServerErr" + } + } + } + }, + "/control-planes/{controlPlaneObjectID}": { + "delete": { + "x-nginx-one-action": "delete", + "x-nginx-one-entity": "Control Plane", + "tags": [ + "Control Planes" + ], + "summary": "Delete a control plane", + "description": "Delete a control plane from the NGINX One Console. You can delete a control plane, only if it contains no NGINX instances.\n", + "operationId": "deleteControlPlane", + "responses": { + "204": { + "description": "Successfully deleted the control plane" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalServerErr" + } + } + }, + "get": { + "tags": [ + "Control Planes" + ], + "summary": "Retrieve a control plane", + "description": "Retrieve the details for a control plane, including:\n* Object ID\n* Product name and version\n* Cluster UUID\n* Kubernetes namespace\n* Deployment UUID\n* Data plane key\n* Certificate summary referenced by control plane instances\n* Instance status summary\n", + "operationId": "getControlPlane", + "responses": { + "200": { + "description": "Successfully retrieved the details of the control plane.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ControlPlaneDetails" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalServerErr" + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/ControlPlaneParamObjectID" + } + ], + "x-feature-flag": "control_planes_m1" + }, + "/control-planes/summary": { + "get": { + "tags": [ + "Control Planes" + ], + "summary": "Retrieve a summary for all Control Planes.", + "description": "Retrieves details for all control planes, including:\n * Number of control planes for each product name/version\n", + "operationId": "getControlPlaneSummary", + "responses": { + "200": { + "description": "Successfully retrieved the summary of control planes.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ControlPlaneSummary" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "500": { + "$ref": "#/components/responses/InternalServerErr" + } + } + }, + "x-feature-flag": "control_planes_m1" + }, "/cves": { "get": { "tags": [ @@ -2377,7 +2538,7 @@ "Instances" ], "summary": "Retrieve an instance", - "description": "Retrieves the details for an NGINX instance, including\n* Hostname\n* System status\n* Timestamps of key actions (registration, last reported, etc.)\n* NGINX build information\n* Certificate data\n* Operating system version\n* NGINX Agent version\n* Config Sync Group membership details\n", + "description": "Retrieves the details for an NGINX instance, including\n* Hostname\n* System status\n* Timestamps of key actions (registration, last reported, etc.)\n* NGINX build information\n* Certificate data\n* Operating system version\n* NGINX Agent version\n* Config Sync Group membership details\n* Control plane object ID, name, product and version\n", "operationId": "getInstance", "parameters": [ { @@ -3223,59 +3384,6 @@ } } }, - "patch": { - "x-nginx-one-action": "bulk", - "x-nginx-one-entity": "NGINX staged configs", - "x-feature-flag": "staged-configs-phase-2", - "tags": [ - "Staged Configs" - ], - "summary": "Bulk operation on multiple staged configs", - "operationId": "bulkStagedConfigs", - "description": "Performs bulk operation on one or more staged configs, only delete is supported.", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StagedConfigBulkRequest" - } - } - } - }, - "responses": { - "200": { - "description": "Batch request completed.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StagedConfigBulkResponse" - } - } - } - }, - "401": { - "description": "Access denied.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "500": { - "description": "An unexpected error occurred on the server. Please try the request again later.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - } - } - }, "post": { "x-feature-flag": "staged-configs", "x-nginx-one-action": "create", @@ -3782,37 +3890,49 @@ } } }, - "/staged-configs/{stagedConfigObjectID}/export": { - "get": { - "parameters": [ - { - "$ref": "#/components/parameters/StagedConfigParamObjectID" - } - ], + "/monitor/metrics_query_topx": { + "post": { "tags": [ - "Staged Configs" + "Metrics" ], - "x-feature-flag": "staged-configs-phase-2", - "x-nginx-one-action": "export", - "x-nginx-one-entity": "NGINX staged config", - "summary": "Export staged configuration", - "description": "Exports staged configuration as a gzipped tar archive. Does not include sensitive data such as SSL certificates. [Learn more](https://docs.nginx.com/nginx-one/how-to/staged-configs/import-export-staged-config/).\n", - "operationId": "exportStagedConfig", + "summary": "Retrieve system metrics for instances with series limit", + "operationId": "queryMetricsInputTopX", + "description": "Returns (up to 10,000) system metrics for NGINX instances with series limit based on query parameters.\n\nYou can filter metrics by name and timestamp, aggregate metrics over a configurable period of time, and group metrics by dimension.\n", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetricTopXQueryRequest" + }, + "example": { + "start_time": "now-1h", + "end_time": "now", + "resolution": "1m", + "metrics": [ + { + "aggregate": "sum", + "name": "nginx.http.request.count" + } + ], + "series_limit": 1, + "group_series_by": "instance_object_id" + } + } + } + }, "responses": { "200": { - "description": "Successfully exported the staged configuration.", + "description": "Successfully retrieved system metrics.", "content": { - "application/gzip": { + "application/json": { "schema": { - "type": "string", - "format": "binary", - "example": "my-staged-config-2025-01-01T20_25_03.tar.gz" + "$ref": "#/components/schemas/MetricQueryResultEx" } } } }, - "401": { - "description": "Access denied", + "400": { + "description": "Request cannot be processed due to invalid input or parameters. Verify the request format and provided data.", "content": { "application/json": { "schema": { @@ -3822,7 +3942,7 @@ } }, "404": { - "description": "The NGINX staged config with the specified object_id was not found. Check that the object_id provided is correct and corresponds to an existing resource.", + "description": "The requested metric resource was not found. Check that the resource name provided is correct and corresponds to an existing resource.", "content": { "application/json": { "schema": { @@ -3844,54 +3964,660 @@ } } }, - "/staged-configs/import": { - "post": { + "/settings/instance-cleanup": { + "get": { "tags": [ - "Staged Configs" + "Settings" ], - "x-feature-flag": "staged-configs-phase-2", - "x-nginx-one-action": "import", - "x-nginx-one-entity": "NGINX staged config", - "summary": "Import staged configuration\n", - "description": "Imports a gzipped tar archive (.tar.gz) containing configuration and aux files into NGINX One. \nOnly non-hidden files are included in the import.\n\nMaximum compressed archive size: **5 MB**\nMaximum uncompressed individual file size: **10 MB**\n\nIf `parse_only` is set to `true`, the configuration is only validated and not staged.\nBy default, validation is performed and a staged configuration is created upon success.\n", - "parameters": [ - { - "$ref": "#/components/parameters/StagedConfigImportParseOnly" + "summary": "Retrieve settings", + "description": "Retrieves settings for NGINX Instance cleanup\n", + "operationId": "getSettingInstanceCleanup", + "responses": { + "200": { + "description": "Successfully retrieved the setting for NGINX Instance cleanup.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SettingsInstanceCleanup" + } + } + } + }, + "400": { + "$ref": "#/components/responses/InvalidRequest" + }, + "500": { + "$ref": "#/components/responses/InternalServerErr" } + } + }, + "put": { + "x-nginx-one-action": "update", + "x-nginx-one-entity": "NGINX Instance Cleanup Setting", + "tags": [ + "Settings" ], - "operationId": "importStagedConfig", + "summary": "Update settings", + "description": "Update settings for NGINX Instance cleanup\n", + "operationId": "updateSettingInstanceCleanup", "requestBody": { "required": true, "content": { - "multipart/form-data": { + "application/json": { "schema": { - "$ref": "#/components/schemas/StagedConfigImportRequest" - }, - "encoding": { - "file": { - "contentType": "application/gzip, application/x-gzip" - } + "$ref": "#/components/schemas/SettingsInstanceCleanup" } } } }, "responses": { "200": { - "description": "Return if `parse_only` is `true`: Returns data matching `StagedConfigCreateRequest` that can be used to create the staged config later. \n", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StagedConfigCreateRequest" - } - } - } - }, - "201": { - "description": "Return if `parse_only` is `false` or omitted: Confirms the import parsed successfully and the staged config was created.\n", + "description": "Successfully updated settings for NGINX Instance cleanup.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/StagedConfigCreateResponse" + "$ref": "#/components/schemas/SettingsInstanceCleanup" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalServerErr" + } + } + } + }, + "/app-protect/policies": { + "get": { + "x-feature-flag": "nap-waf", + "tags": [ + "NGINX App Protect" + ], + "summary": "List NGINX App Protect policies", + "description": "Returns a list of NGINX App Protect policies along with deployment details.", + "operationId": "listNapPolicies", + "parameters": [ + { + "$ref": "#/components/parameters/Paginated" + }, + { + "$ref": "#/components/parameters/Limit" + }, + { + "$ref": "#/components/parameters/Offset" + }, + { + "$ref": "#/components/parameters/SortDirection" + }, + { + "$ref": "#/components/parameters/SortNameNapPolicies" + }, + { + "$ref": "#/components/parameters/FilterOperands" + }, + { + "$ref": "#/components/parameters/FilterValues" + }, + { + "$ref": "#/components/parameters/FilterFieldNapPolicy" + } + ], + "responses": { + "200": { + "description": "Successfully returned NGINX App Protect policies.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NapPolicyListResponse" + } + } + } + }, + "400": { + "description": "Request cannot be processed due to invalid input or parameters. Verify the request format and provided data.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Access denied.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "An unexpected error occurred on the server. Please try the request again later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "patch": { + "x-nginx-one-action": "bulk", + "x-nginx-one-entity": "NGINX Nap Policies", + "x-feature-flag": "nap-waf", + "tags": [ + "NGINX App Protect" + ], + "summary": "Bulk operation on multiple Nap policy", + "operationId": "bulkNAPPolicy", + "description": "Performs bulk operation on one or more Nap policy, only delete is supported.", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NapPolicyBulkRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Batch request completed.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NapBulkResponse" + } + } + } + }, + "401": { + "description": "Access denied.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "An unexpected error occurred on the server. Please try the request again later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "post": { + "x-feature-flag": "nap-waf", + "tags": [ + "NGINX App Protect" + ], + "summary": "Create NGINX App Protect policy", + "description": "Creates NGINX App Protect policy.", + "operationId": "createNapPolicy", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NapPolicy" + } + } + } + }, + "responses": { + "201": { + "description": "Successfully created NGINX App Protect policy.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NapPolicyMetadata" + } + } + } + }, + "400": { + "description": "Request cannot be processed due to invalid input or parameters. Verify the request format and provided data.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Access denied.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "An unexpected error occurred on the server. Please try the request again later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/app-protect/policies/{nap_policy_object_id}": { + "delete": { + "x-feature-flag": "nap-waf", + "tags": [ + "NGINX App Protect" + ], + "summary": "Delete NGINX App Protect policy", + "description": "Deletes NGINX App Protect policy.", + "operationId": "deleteNapPolicy", + "parameters": [ + { + "$ref": "#/components/parameters/NapPolicyParamObjectID" + } + ], + "responses": { + "204": { + "description": "Successfully deleted NGINX App Protect policy." + }, + "400": { + "description": "Request cannot be processed due to invalid input or parameters. Verify the request format and provided data.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Access denied.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "The NGINX App Protect policy with the specified nap_policy_object_id was not found. Check that the nap_policy_object_id provided is correct and corresponds to an existing resource.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "An unexpected error occurred on the server. Please try the request again later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "get": { + "x-feature-flag": "nap-waf", + "tags": [ + "NGINX App Protect" + ], + "summary": "Get NGINX App Protect policy details", + "description": "Returns NGINX App Protect policy summary.", + "operationId": "getNapPolicy", + "parameters": [ + { + "$ref": "#/components/parameters/NapPolicyParamObjectID" + } + ], + "responses": { + "200": { + "description": "Successfully returned NGINX App Protect policy details.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NapPolicyObject" + } + } + } + }, + "400": { + "description": "Request cannot be processed due to invalid input or parameters. Verify the request format and provided data.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Access denied.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "The NGINX App Protect policy with the specified nap_policy_object_id was not found. Check that the nap_policy_object_id provided is correct and corresponds to an existing resource.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "An unexpected error occurred on the server. Please try the request again later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "put": { + "x-feature-flag": "nap-waf", + "tags": [ + "NGINX App Protect" + ], + "summary": "Update NGINX App Protect policy details", + "description": "Update NGINX App Protect policy details.", + "operationId": "updateNapPolicy", + "parameters": [ + { + "$ref": "#/components/parameters/NapPolicyParamObjectID" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NapPolicy" + } + } + } + }, + "responses": { + "201": { + "description": "Successfully created an NGINX App Protect policy version.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NapPolicyMetadata" + } + } + } + }, + "400": { + "description": "Request cannot be processed due to invalid input or parameters. Verify the request format and provided data.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Access denied.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "The NGINX App Protect policy with the specified nap_policy_object_id was not found. Check that the nap_policy_object_id provided is correct and corresponds to an existing resource.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "An unexpected error occurred on the server. Please try the request again later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/app-protect/policies/{nap_policy_object_id}/deployments": { + "get": { + "x-feature-flag": "nap-waf", + "tags": [ + "NGINX App Protect" + ], + "summary": "List NGINX App Protect deployments", + "description": "Returns NGINX App Protect deployments, providing details such as:\n * Target of the deployment\n * Time of deployment\n * Enforcement mode\n * Policy version\n * Threat campaign\n * Attack signature\n * Bot signature\n", + "operationId": "listNapPolicyDeployments", + "parameters": [ + { + "$ref": "#/components/parameters/NapPolicyParamObjectID" + }, + { + "$ref": "#/components/parameters/Paginated" + }, + { + "$ref": "#/components/parameters/Limit" + }, + { + "$ref": "#/components/parameters/Offset" + }, + { + "$ref": "#/components/parameters/SortDirection" + }, + { + "$ref": "#/components/parameters/SortNameNapPolicyDeployments" + }, + { + "$ref": "#/components/parameters/FilterOperands" + }, + { + "$ref": "#/components/parameters/FilterValues" + }, + { + "$ref": "#/components/parameters/FilterFieldNapPolicyDeployment" + } + ], + "responses": { + "200": { + "description": "Successfully returned NGINX App Protect deployments.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NapPolicyDeploymentsListResponse" + } + } + } + }, + "400": { + "description": "Request cannot be processed due to invalid input or parameters. Verify the request format and provided data.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Access denied.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "The NGINX App Protect policy with the specified nap_policy_object_id was not found. Check that the nap_policy_object_id provided is correct and corresponds to an existing resource.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "An unexpected error occurred on the server. Please try the request again later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/app-protect/policies/{nap_policy_object_id}/version": { + "get": { + "x-feature-flag": "nap-waf", + "tags": [ + "NGINX App Protect" + ], + "summary": "Get the latest NGINX App Protect policy version details", + "description": "Returns the latest NGINX App Protect policy version details.", + "operationId": "getLatestNapPolicyVersion", + "parameters": [ + { + "$ref": "#/components/parameters/NapPolicyParamObjectID" + } + ], + "responses": { + "200": { + "description": "Successfully returned NGINX App Protect policy version details.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NapPolicyVersionDetails" + } + } + } + }, + "401": { + "description": "Access denied.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "The NGINX App Protect policy version with the specified nap_policy_object_id was not found. Check that the nap_policy_object_id provided is correct and corresponds to an existing resource.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "An unexpected error occurred on the server. Please try the request again later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/app-protect/policies/{nap_policy_object_id}/versions": { + "get": { + "x-feature-flag": "nap-waf", + "tags": [ + "NGINX App Protect" + ], + "summary": "List NGINX App Protect policy versions", + "description": "Returns NGINX App Protect policy versions.", + "operationId": "listNapPolicyVersions", + "parameters": [ + { + "$ref": "#/components/parameters/NapPolicyParamObjectID" + }, + { + "$ref": "#/components/parameters/Paginated" + }, + { + "$ref": "#/components/parameters/Limit" + }, + { + "$ref": "#/components/parameters/Offset" + }, + { + "$ref": "#/components/parameters/SortDirection" + }, + { + "$ref": "#/components/parameters/SortNameNapPolicyVersions" + }, + { + "$ref": "#/components/parameters/FilterOperands" + }, + { + "$ref": "#/components/parameters/FilterValues" + }, + { + "$ref": "#/components/parameters/FilterFieldNapPolicyVersion" + } + ], + "responses": { + "200": { + "description": "Successfully returned the NGINX App Protect policy versions.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NapPolicyVersionsListResponse" } } } @@ -3907,7 +4633,17 @@ } }, "401": { - "description": "Access denied", + "description": "Access denied.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "The NGINX App Protect policy with the specified nap_policy_object_id was not found. Check that the nap_policy_object_id provided is correct and corresponds to an existing resource.", "content": { "application/json": { "schema": { @@ -3929,49 +4665,29 @@ } } }, - "/monitor/metrics_query_topx": { - "post": { + "/app-protect/policies/{nap_policy_object_id}/versions/{nap_policy_version_object_id}": { + "delete": { + "x-feature-flag": "nap-waf", "tags": [ - "Metrics" + "NGINX App Protect" ], - "summary": "Retrieve system metrics for instances with series limit", - "operationId": "queryMetricsInputTopX", - "description": "Returns (up to 10,000) system metrics for NGINX instances with series limit based on query parameters.\n\nYou can filter metrics by name and timestamp, aggregate metrics over a configurable period of time, and group metrics by dimension.\n", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/MetricTopXQueryRequest" - }, - "example": { - "start_time": "now-1h", - "end_time": "now", - "resolution": "1m", - "metrics": [ - { - "aggregate": "sum", - "name": "nginx.http.request.count" - } - ], - "series_limit": 1, - "group_series_by": "instance_object_id" - } - } + "summary": "Delete NGINX App Protect policy version", + "description": "Deletes the NGINX App Protect policy version.", + "operationId": "deleteNapPolicyVersion", + "parameters": [ + { + "$ref": "#/components/parameters/NapPolicyParamObjectID" + }, + { + "$ref": "#/components/parameters/NapPolicyVersionParamObjectID" } - }, + ], "responses": { - "200": { - "description": "Successfully retrieved system metrics.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/MetricQueryResultEx" - } - } - } + "204": { + "description": "Successfully deleted the NGINX App Protect policy version." }, - "400": { - "description": "Request cannot be processed due to invalid input or parameters. Verify the request format and provided data.", + "401": { + "description": "Access denied.", "content": { "application/json": { "schema": { @@ -3981,7 +4697,7 @@ } }, "404": { - "description": "The requested metric resource was not found. Check that the resource name provided is correct and corresponds to an existing resource.", + "description": "The NGINX App Protect policy version with the specified nap_policy_version_object_id and nap_policy_version_object_id was not found. Check that the object IDs provided are correct and corresponds to existing resources.", "content": { "application/json": { "schema": { @@ -4001,67 +4717,63 @@ } } } - } - }, - "/settings/instance-cleanup": { + }, "get": { + "x-feature-flag": "nap-waf", "tags": [ - "Settings" + "NGINX App Protect" + ], + "summary": "Get the specified NGINX App Protect policy version details", + "description": "Returns the specified NGINX App Protect policy version details.", + "operationId": "getNapPolicyVersion", + "parameters": [ + { + "$ref": "#/components/parameters/NapPolicyParamObjectID" + }, + { + "$ref": "#/components/parameters/NapPolicyVersionParamObjectID" + } ], - "summary": "Retrieve settings", - "description": "Retrieves settings for NGINX Instance cleanup\n", - "operationId": "getSettingInstanceCleanup", "responses": { "200": { - "description": "Successfully retrieved the setting for NGINX Instance cleanup.", + "description": "Successfully returned NGINX App Protect policy version details.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SettingsInstanceCleanup" + "$ref": "#/components/schemas/NapPolicyVersionDetails" } } } }, - "400": { - "$ref": "#/components/responses/InvalidRequest" - }, - "500": { - "$ref": "#/components/responses/InternalServerErr" - } - } - }, - "put": { - "x-nginx-one-action": "update", - "x-nginx-one-entity": "NGINX Instance Cleanup Setting", - "tags": [ - "Settings" - ], - "summary": "Update settings", - "description": "Update settings for NGINX Instance cleanup\n", - "operationId": "updateSettingInstanceCleanup", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SettingsInstanceCleanup" + "401": { + "description": "Access denied.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } } } - } - }, - "responses": { - "200": { - "description": "Successfully updated settings for NGINX Instance cleanup.", + }, + "404": { + "description": "The NGINX App Protect policy version with the specified nap_policy_version_object_id and nap_policy_version_object_id was not found. Check that the object IDs provided are correct and corresponds to existing resources.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SettingsInstanceCleanup" + "$ref": "#/components/schemas/Error" } } } }, "500": { - "$ref": "#/components/responses/InternalServerErr" + "description": "An unexpected error occurred on the server. Please try the request again later.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } } } } @@ -4290,6 +5002,43 @@ "description": "A globally unique identifier for a Publication.\n", "required": true }, + "SortNameControlPlanes": { + "name": "sort_control_planes", + "in": "query", + "description": "Sort control planes by enumerate value(s). Ordinal position determines primary, secondary, etc.\n", + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "name" + ], + "x-enum-varnames": [ + "sort_name_control_plane_name" + ] + } + } + }, + "FilterFieldControlPlanes": { + "name": "filter_fields", + "in": "query", + "description": "An array of strings. Identifies the fields to filter by (for example, `name`, `product`). This parameter works in conjunction with `filter_values` and `filter_ops`.\n", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FilterNameControlPlanes" + } + } + }, + "ControlPlaneParamObjectID": { + "name": "controlPlaneObjectID", + "in": "path", + "schema": { + "$ref": "#/components/schemas/ControlPlaneObjectID" + }, + "description": "A globally unique identifier for the control plane.\n", + "required": true + }, "SortNameCVEs": { "name": "sort_cves", "in": "query", @@ -4362,102 +5111,220 @@ "description": "A globally unique identifier for an event.\n", "required": true }, - "FilterFieldInstances": { + "FilterFieldInstances": { + "name": "filter_fields", + "in": "query", + "description": "An array of strings indicating which fields to filter by (for example, `hostname`, `nginx_version`). This parameter works in conjunction with `filter_values` and `filter_ops`.\n", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FilterNameInstances" + } + } + }, + "SortNameInstances": { + "name": "sort_instances", + "in": "query", + "description": "Sort instances by enumerate value(s). Ordinal position determines primary, secondary, etc.\n", + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "hostname", + "status", + "last_reported" + ], + "x-enum-varnames": [ + "sort_name_instance_hostname", + "sort_name_instance_status", + "sort_name_instance_last_reported" + ] + } + } + }, + "InstanceParamObjectID": { + "name": "instanceObjectID", + "in": "path", + "schema": { + "$ref": "#/components/schemas/InstanceObjectID" + }, + "description": "A globally unique identifier for the NGINX instance.\n", + "required": true + }, + "InstanceConfigurationParamObjectID": { + "name": "instanceConfigurationObjectID", + "in": "path", + "schema": { + "$ref": "#/components/schemas/NginxConfigObjectID" + }, + "description": "A globally unique identifier for the NGINX instance configuration.\n", + "required": true + }, + "FilterFieldStagedConfigs": { + "name": "filter_fields", + "in": "query", + "description": "An array of strings indicating which fields to filter by (for example, `name`). This parameter works in conjunction with `filter_values` and `filter_ops`.\n", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FilterStagedConfigs" + } + } + }, + "SortNameStagedConfigs": { + "name": "sort_staged_configs", + "in": "query", + "description": "Sort staged configs by enumerate value(s). Ordinal position determines primary, secondary, etc.\n", + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "name" + ], + "x-enum-varnames": [ + "sort_name_staged_config_name" + ] + } + } + }, + "StagedConfigParamObjectID": { + "name": "stagedConfigObjectID", + "in": "path", + "schema": { + "$ref": "#/components/schemas/StagedConfigObjectID" + }, + "description": "A globally unique identifier for the NGINX staged config.\n", + "required": true + }, + "SortNameNapPolicies": { + "name": "sort_nap_policies", + "in": "query", + "description": "Sort NGINX App Protect policies by enumerate value(s). Ordinal position determines primary, secondary, etc.\n", + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "name", + "deployment_count", + "enforcement_mode", + "last_deployed" + ], + "x-enum-varnames": [ + "sort_name_nap_policies_name", + "sort_name_nap_policies_deployment_count", + "sort_name_nap_policies_enforcement_mode", + "sort_name_nap_policies_last_deployed" + ] + } + } + }, + "FilterFieldNapPolicy": { "name": "filter_fields", "in": "query", - "description": "An array of strings indicating which fields to filter by (for example, `hostname`, `nginx_version`). This parameter works in conjunction with `filter_values` and `filter_ops`.\n", + "description": "An array of strings indicating which fields to filter by (for example, `name`). This parameter works in conjunction with `filter_values` and `filter_ops`.\n", "schema": { "type": "array", "items": { - "$ref": "#/components/schemas/FilterNameInstances" + "$ref": "#/components/schemas/FilterNameNapPolicy" } } }, - "SortNameInstances": { - "name": "sort_instances", + "NapPolicyParamObjectID": { + "name": "nap_policy_object_id", + "in": "path", + "schema": { + "$ref": "#/components/schemas/NapPolicyObjectID" + }, + "description": "A globally unique identifier for the App Protect policy.\n", + "required": true + }, + "SortNameNapPolicyDeployments": { + "name": "sort_nap_deployments", "in": "query", - "description": "Sort instances by enumerate value(s). Ordinal position determines primary, secondary, etc.\n", + "description": "Sort NGINX App Protect deployments by enumerate value(s). Ordinal position determines primary, secondary, etc.\n", "schema": { "type": "array", "items": { "type": "string", "enum": [ - "hostname", + "name", + "type", + "policy_version", "status", - "last_reported" + "deployed_on", + "threat_campaign_version", + "attack_signature_version", + "bot_signature_version" ], "x-enum-varnames": [ - "sort_name_instance_hostname", - "sort_name_instance_status", - "sort_name_instance_last_reported" + "sort_name_nap_policy_deployments_name", + "sort_name_nap_policy_deployments_type", + "sort_name_nap_policy_deployments_policy_version", + "sort_name_nap_policy_deployments_status", + "sort_name_nap_policy_deployments_deployed_on", + "sort_name_nap_policy_deployments_threat_campaign_version", + "sort_name_nap_policy_deployments_attack_signature_version", + "sort_name_nap_policy_deployments_bot_sigature_version" ] } } }, - "InstanceParamObjectID": { - "name": "instanceObjectID", - "in": "path", - "schema": { - "$ref": "#/components/schemas/InstanceObjectID" - }, - "description": "A globally unique identifier for the NGINX instance.\n", - "required": true - }, - "InstanceConfigurationParamObjectID": { - "name": "instanceConfigurationObjectID", - "in": "path", - "schema": { - "$ref": "#/components/schemas/NginxConfigObjectID" - }, - "description": "A globally unique identifier for the NGINX instance configuration.\n", - "required": true - }, - "FilterFieldStagedConfigs": { + "FilterFieldNapPolicyDeployment": { "name": "filter_fields", "in": "query", "description": "An array of strings indicating which fields to filter by (for example, `name`). This parameter works in conjunction with `filter_values` and `filter_ops`.\n", "schema": { "type": "array", "items": { - "$ref": "#/components/schemas/FilterStagedConfigs" + "$ref": "#/components/schemas/FilterNameNapPolicyDeployment" } } }, - "SortNameStagedConfigs": { - "name": "sort_staged_configs", + "SortNameNapPolicyVersions": { + "name": "sort_nap_policy_versions", "in": "query", - "description": "Sort staged configs by enumerate value(s). Ordinal position determines primary, secondary, etc.\n", + "description": "Sort NGINX App Protect policy versions by enumerate value(s). Ordinal position determines primary, secondary, etc.\n", "schema": { "type": "array", "items": { "type": "string", "enum": [ - "name" + "created_at", + "deployment_status", + "deployment_count", + "enforcement_mode" ], "x-enum-varnames": [ - "sort_name_staged_config_name" + "sort_name_nap_policy_versions_created_at", + "sort_name_nap_policy_versions_deployment_status", + "sort_name_nap_policy_versions_deployment_count", + "sort_name_nap_policy_versions_enforcement_mode" ] } } }, - "StagedConfigParamObjectID": { - "name": "stagedConfigObjectID", - "in": "path", + "FilterFieldNapPolicyVersion": { + "name": "filter_fields", + "in": "query", + "description": "An array of strings indicating which fields to filter by (for example, `name`). This parameter works in conjunction with `filter_values` and `filter_ops`.\n", "schema": { - "$ref": "#/components/schemas/StagedConfigObjectID" - }, - "description": "A globally unique identifier for the NGINX staged config.\n", - "required": true + "type": "array", + "items": { + "$ref": "#/components/schemas/FilterNameNapPolicyVersion" + } + } }, - "StagedConfigImportParseOnly": { - "name": "parseOnly", - "in": "query", + "NapPolicyVersionParamObjectID": { + "name": "nap_policy_version_object_id", + "in": "path", "schema": { - "type": "boolean", - "default": false + "$ref": "#/components/schemas/NapPolicyVersionObjectID" }, - "description": "Optional flag to control how the request is processed.\n - When `false` or omitted (by default), the request creates a Staged Config directly. (`StagedConfigCreateResponse`)\n - When `true`, the request parses the import and returns metadata you can use to create a Staged Config through a POST. ( `StagedConfigCreateRequest`)\n", - "required": false + "description": "A globally unique identifier for the App Protect policy version.\n", + "required": true } }, "schemas": { @@ -4579,6 +5446,10 @@ "instances_count": { "type": "integer", "description": "The number of registered instances using this data plane key. If field not populated, user should see the key has `unknown` key count" + }, + "control_planes_count": { + "type": "integer", + "description": "The number of observed control planes using this data plane key." } } }, @@ -5707,7 +6578,8 @@ "description": "Meta information of the NGINX config sync group including:\n* NGINX config sync group object ID\n* unique name of the config sync group in the tenant namespace\n* last publication timestamp\n", "required": [ "object_id", - "name" + "name", + "created_at" ], "properties": { "object_id": { @@ -5721,6 +6593,11 @@ "description": "The date and time of the most recent config sync group publication.", "type": "string", "format": "date-time" + }, + "created_at": { + "description": "The date and time when the config sync group was created.", + "type": "string", + "format": "date-time" } }, "example": { @@ -5761,8 +6638,8 @@ } } }, - "NginxAppProtectDetails": { - "description": "Information regarding NGINX App Protect.\n", + "NginxAppProtectVersions": { + "description": "Version information regarding NGINX App Protect.\n", "type": "object", "required": [ "engine_version" @@ -5778,6 +6655,54 @@ } } }, + "NginxAppProtectDeploymentCounts": { + "type": "object", + "description": "Summary count of NAP policy version deployment statues.", + "required": [ + "total", + "deployed", + "deploying", + "failed" + ], + "properties": { + "total": { + "description": "Total count of NAP policy versions across the NGINX data plane.", + "type": "integer" + }, + "deployed": { + "description": "The number of NAP policy versions that have deployed.", + "type": "integer" + }, + "deploying": { + "description": "The number of NAP policy versions that are deploying.", + "type": "integer" + }, + "failed": { + "description": "The number of NAP policy versions that have failed deployment.", + "type": "integer" + } + } + }, + "NginxAppProtectSummary": { + "description": "Summary information regarding NGINX App Protect.\n", + "type": "object", + "allOf": [ + { + "$ref": "#/components/schemas/NginxAppProtectVersions" + }, + { + "type": "object", + "required": [ + "deployments" + ], + "properties": { + "deployments": { + "$ref": "#/components/schemas/NginxAppProtectDeploymentCounts" + } + } + } + ] + }, "CveSeverityType": { "type": "string", "description": "Severity ratings:\n * `high` - High severity.\n * `medium` - Moderate severity.\n * `low` - Least severe.\n * `none` - Not severe.\n * `other` - Severity that does not fit the other categories.\n", @@ -5846,6 +6771,40 @@ } } }, + "ControlPlaneObjectID": { + "description": "A globally unique identifier for the control plane.", + "type": "string", + "format": "object_id", + "pattern": "^ecp_.*", + "x-go-type": "objects.ID" + }, + "ControlPlaneBaseInfo": { + "type": "object", + "description": "Base information of a control plane, which includes name, product version and optionally an object ID.", + "required": [ + "name", + "product_version", + "created_at" + ], + "properties": { + "object_id": { + "$ref": "#/components/schemas/ControlPlaneObjectID" + }, + "name": { + "description": "Control plane name.", + "type": "string" + }, + "product_version": { + "description": "Control plane product name and version.", + "type": "string" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "The date and time when the control plane was created." + } + } + }, "Instance": { "type": "object", "description": "Summary information about a NGINX instance.", @@ -5890,7 +6849,7 @@ "example": "ubuntu_jammy" }, "nginx_app_protect": { - "$ref": "#/components/schemas/NginxAppProtectDetails" + "$ref": "#/components/schemas/NginxAppProtectSummary" }, "registered_at": { "description": "The date and time when the NGINX instance first registered with NGINX One.", @@ -5928,6 +6887,9 @@ "items": { "$ref": "#/components/schemas/IssueDetails" } + }, + "control_plane": { + "$ref": "#/components/schemas/ControlPlaneBaseInfo" } } }, @@ -5964,79 +6926,209 @@ "partially_succeeded" ], "x-enum-varnames": [ - "publication_config_sync_group_status_pending", - "publication_config_sync_group_status_failed", - "publication_config_sync_group_status_succeeded", - "publication_config_sync_group_status_partially_succeeded" + "publication_config_sync_group_status_pending", + "publication_config_sync_group_status_failed", + "publication_config_sync_group_status_succeeded", + "publication_config_sync_group_status_partially_succeeded" + ] + }, + "CertAssociation": { + "type": "object", + "description": "Details for a certificate that's associated with an instance or a config sync group.", + "required": [ + "name", + "object_id", + "cert_type", + "subject_name", + "not_before", + "not_after", + "cert_status", + "deployment_status" + ], + "properties": { + "name": { + "type": "string", + "description": "A friendly name for the certificate." + }, + "object_id": { + "$ref": "#/components/schemas/CertificateObjectID" + }, + "cert_type": { + "$ref": "#/components/schemas/CertificateType" + }, + "cert_paths": { + "type": "array", + "description": "The list of file system paths where the certificate file is installed. \nSince a single certificate file may be applied in multiple contexts, all relevant paths are included.\n", + "example": [ + "/etc/ssl/cert.pem", + "/etc/ssl/cert.crt" + ], + "items": { + "type": "string" + } + }, + "key_paths": { + "type": "array", + "description": "The list of file system paths where the private key file is installed.\nSince a single key file may be applied in multiple contexts, all relevant paths are included.\n", + "example": [ + "/etc/nginx/key.pem", + "/etc/ssl/server.key" + ], + "items": { + "type": "string" + } + }, + "deployment_status": { + "$ref": "#/components/schemas/CertificateDeploymentStatus" + }, + "subject_name": { + "type": "string", + "description": "Hostname or domain for the certificate. Usually the subject-alt-name (SAN) value for the certificate.\nif SAN is not present, this will be the certificate subject's common name.\n", + "example": "nginx.com" + }, + "cert_status": { + "$ref": "#/components/schemas/CertificateStatus" + }, + "not_before": { + "type": "string", + "format": "date-time", + "description": "the effective date of the certificate." + }, + "not_after": { + "type": "string", + "format": "date-time", + "description": "The expiration date for the certificate." + } + } + }, + "NapPolicyObjectID": { + "description": "A globally unique identifier for the App Protect policy.", + "type": "string", + "format": "object_id", + "pattern": "^pol_.*", + "x-go-type": "objects.ID", + "x-go-type-import": { + "name": "objects", + "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" + } + }, + "NapPolicyVersionObjectID": { + "description": "A globally unique identifier for the App Protect policy version.", + "type": "string", + "format": "object_id", + "pattern": "^pv_.*", + "x-go-type": "objects.ID", + "x-go-type-import": { + "name": "objects", + "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" + } + }, + "PublicationObjectID": { + "description": "A globally unique identifier for the publication.", + "type": "string", + "format": "object_id", + "example": "pub_72pGHoGsSICL_THZrs964g", + "pattern": "^pub_.*", + "x-go-type": "objects.ID", + "x-go-type-import": { + "name": "objects", + "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" + } + }, + "NapPolicyEnforcementMode": { + "description": "The current enforcement mode of the NGINX App Protect policy, with the following possible values:\n* `blocking` - Any illegal or suspicious requests are logged and blocked.\n* `transparent` - Any illegal or suspicious requests are logged but not blocked.\n", + "type": "string", + "enum": [ + "blocking", + "transparent" + ], + "x-enum-varnames": [ + "nap_enforcement_mode_blocking", + "nap_enforcement_mode_transparent" + ] + }, + "NapDeploymentStatus": { + "description": "The current enforcement mode of the NGINX App Protect policy, with the following possible values:\n* `deployed` - The NGINX App Protect policy has been deployed.\n* `not_deployed` - The NGINX App Protect policy has not been deployed.\n* `deploying` - The NGINX App Protect policy is currently being deployed.\n* `failed` - The NGINX App Protect policy failed deploying.\n", + "type": "string", + "enum": [ + "deployed", + "not_deployed", + "deploying", + "failed" + ], + "x-enum-varnames": [ + "nap_deployment_status_deployed", + "nap_deployment_status_not_deployed", + "nap_deployment_status_deploying", + "nap_deployment_status_failed" ] }, - "CertAssociation": { - "type": "object", - "description": "Details for a certificate that's associated with an instance or a config sync group.", + "NapAssociation": { + "description": "Details for a NGINX App Protect policy version that's associated with an instance or a config sync group.", "required": [ "name", - "object_id", - "cert_type", - "subject_name", - "not_before", - "not_after", - "cert_status", - "deployment_status" + "version", + "policy_object_id", + "policy_version_object_id", + "paths", + "deployment_status", + "publication_object_id", + "deployed_on", + "enforcement_mode" ], "properties": { "name": { "type": "string", - "description": "A friendly name for the certificate." + "description": "Name of the policy at the time of the deployment." }, - "object_id": { - "$ref": "#/components/schemas/CertificateObjectID" + "version": { + "type": "string", + "description": "Version of the policy at the time of the deployment." }, - "cert_type": { - "$ref": "#/components/schemas/CertificateType" + "policy_object_id": { + "$ref": "#/components/schemas/NapPolicyObjectID" }, - "cert_paths": { - "type": "array", - "description": "The list of file system paths where the certificate file is installed. \nSince a single certificate file may be applied in multiple contexts, all relevant paths are included.\n", - "example": [ - "/etc/ssl/cert.pem", - "/etc/ssl/cert.crt" - ], - "items": { - "type": "string" - } + "policy_version_object_id": { + "$ref": "#/components/schemas/NapPolicyVersionObjectID" }, - "key_paths": { + "publication_object_id": { + "$ref": "#/components/schemas/PublicationObjectID" + }, + "enforcement_mode": { + "$ref": "#/components/schemas/NapPolicyEnforcementMode" + }, + "paths": { "type": "array", - "description": "The list of file system paths where the private key file is installed.\nSince a single key file may be applied in multiple contexts, all relevant paths are included.\n", + "description": "The list of file system paths where the compiled NAP policy version bundle file is installed. \nSince a single compiled NAP policy version bundle file may be applied in multiple contexts, all relevant paths are included.\n", "example": [ - "/etc/nginx/key.pem", - "/etc/ssl/server.key" + "/etc/nginx/default_policy.tgz", + "/etc/nginx/default_policy_server_2.tgz" ], "items": { "type": "string" } }, "deployment_status": { - "$ref": "#/components/schemas/CertificateDeploymentStatus" - }, - "subject_name": { - "type": "string", - "description": "Hostname or domain for the certificate. Usually the subject-alt-name (SAN) value for the certificate.\nif SAN is not present, this will be the certificate subject's common name.\n", - "example": "nginx.com" - }, - "cert_status": { - "$ref": "#/components/schemas/CertificateStatus" - }, - "not_before": { - "type": "string", - "format": "date-time", - "description": "the effective date of the certificate." + "$ref": "#/components/schemas/NapDeploymentStatus" }, - "not_after": { + "deployed_on": { + "description": "Date and time of the deployment.", "type": "string", - "format": "date-time", - "description": "The expiration date for the certificate." + "format": "date-time" } + }, + "example": { + "name": "default_policy", + "version": "2025.05.01", + "policy_object_id": "pol_panEdeY-Sh2rWm365y7wsw", + "policy_version_object_id": "pv_kem7SCosTTOL9mMlNyY2GQ", + "publication_object_id": "pub_72pGHoGsSICL_THZrs964g", + "paths": [ + "/etc/nginx/default_policy.tgz" + ], + "deployment_status": "deployed", + "enforcement_mode": "transparent", + "deployed_on": "2023-12-06T22:37:24.120114Z" } }, "ConfigSyncGroup": { @@ -6071,6 +7163,20 @@ "items": { "$ref": "#/components/schemas/CertAssociation" } + }, + "nginx_app_protect": { + "type": "object", + "required": [ + "deployments" + ], + "properties": { + "deployments": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NapAssociation" + } + } + } } } } @@ -6078,7 +7184,6 @@ "example": { "object_id": "csg_-uvR3F2TQGm18jnl7bpaGw", "name": "test-config-sync-group", - "last_reported": "2023-12-06T22:37:24.120114Z", "config_status": "in_sync", "config_version": "uvR3F2TQGm18jnl7bpaGw", "instances": [ @@ -6476,18 +7581,6 @@ } ] }, - "PublicationObjectID": { - "description": "A globally unique identifier for the publication.", - "type": "string", - "format": "object_id", - "example": "pub_72pGHoGsSICL_THZrs964g", - "pattern": "^pub_.*", - "x-go-type": "objects.ID", - "x-go-type-import": { - "name": "objects", - "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" - } - }, "PublicationStatusCause": { "description": "Cause of the failure, provided only if the status is `failed`.", "type": "object", @@ -6632,115 +7725,341 @@ "status": "pending" } }, - "NginxConfigProblem": { + "NginxConfigProblem": { + "type": "object", + "description": "Representation of a problem found during NGINX configuration analysis.", + "properties": { + "directive": { + "description": "Directive in the NGINX configuration where the issue is identified.", + "type": "string" + }, + "file": { + "description": "File where the issue is detected.", + "type": "string" + }, + "line": { + "description": "Line number in the configuration where the issue is found.", + "type": "integer" + } + } + }, + "NginxConfigReport": { + "type": "object", + "description": "An analysis of the NGINX configuration, highlighting issues and their severity, and offering recommendations.", + "properties": { + "rule": { + "description": "The name of the configuration rule that was violated.", + "type": "string" + }, + "info": { + "description": "A detailed description of the issue.", + "type": "string" + }, + "severity": { + "description": "The severity level of the issue.", + "type": "string" + }, + "category": { + "description": "Classification category of the issue.", + "type": "string" + }, + "documentation": { + "description": "Links to documentation that can assist in resolving the identified issue.", + "type": "array", + "items": { + "type": "string" + } + }, + "where": { + "description": "Specific locations in the configuration where issues were detected.", + "type": "array", + "items": { + "$ref": "#/components/schemas/NginxConfigProblem" + } + } + } + }, + "NginxConfigReports": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NginxConfigReport" + } + }, + "NginxConfigMeta": { + "type": "object", + "description": "Meta data of an NGINX configuration, including its unique identifier, the config_version.\n", + "required": [ + "object_id", + "config_version", + "created_at", + "modified_at", + "config_source" + ], + "properties": { + "object_id": { + "$ref": "#/components/schemas/NginxConfigObjectID" + }, + "config_version": { + "type": "string", + "description": "A hash that uniquely identifies the contents of the config object.\n" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "The date and time when the NGINX configuration object was created for the instance." + }, + "modified_at": { + "type": "string", + "format": "date-time", + "description": "The date and time when the NGINX configuration object was last modified for the instance." + }, + "config_source": { + "type": "string", + "enum": [ + "NGINX One", + "Other", + "Unspecified" + ], + "x-enum-varnames": [ + "config_source_nginx_one", + "config_source_other", + "config_source_unspecified" + ], + "description": "The source from which the config was created:\n- `NGINX One`: The config was created from NGINX One.\n- `Other`: The config was created from data plane.\n- `Unspecified`: The source of the config is unspecified.\n" + } + }, + "example": { + "object_id": "nc_AamgWtYSSb6OWGljx3wNDA", + "config_version": "Cm1hcCAkdXJpICRtYXBwZWRfc2V", + "created_at": "2023-08-10T16:59:15Z", + "modified_at": "2023-08-10T16:59:15Z", + "config_source": "NGINX One" + } + }, + "FilterNameControlPlanes": { + "type": "string", + "description": "Keywords for control plane filters.\nWhen filtering on `product`, only the following `filter_values` are supported:\n * nic\n", + "enum": [ + "name", + "product_version", + "object_id" + ], + "x-enum-varnames": [ + "filter_name_control_plane_name", + "filter_name_control_plane_product_version", + "filter_name_control_plane_object_id" + ] + }, + "ListControlPlaneObject": { + "allOf": [ + { + "$ref": "#/components/schemas/ControlPlaneBaseInfo" + }, + { + "type": "object", + "description": "Summary information about a control plane.", + "required": [ + "object_id", + "instances_count", + "online_instances_count" + ], + "properties": { + "object_id": { + "$ref": "#/components/schemas/ControlPlaneObjectID" + }, + "instances_count": { + "description": "Total number of instances in the control plane.", + "type": "integer" + }, + "online_instances_count": { + "description": "Total number of online instances in the control plane.", + "type": "integer" + } + } + } + ] + }, + "ControlPlaneListResponse": { + "allOf": [ + { + "$ref": "#/components/schemas/PaginationResponse" + }, + { + "type": "object", + "description": "List of control planes.", + "required": [ + "items" + ], + "properties": { + "items": { + "description": "An array of control plane objects.", + "type": "array", + "items": { + "$ref": "#/components/schemas/ListControlPlaneObject" + } + } + } + } + ], + "example": { + "total": 10, + "count": 1, + "start_index": 1, + "items_per_page": 100, + "items": [ + { + "object_id": "ecp_tgfVM3KQTxCyiDXgV38G7A", + "name": "nginx-ingress-001", + "product_version": "nginx-ingress-controller-4.0.1", + "instances_count": 5, + "online_instances_count": 3 + }, + { + "object_id": "ecp_-bRQlhscTKmbUIdJaYhGJA", + "name": "nginx-ingress-002", + "product_version": "nginx-ingress-controller-4.0.1", + "instances_count": 3, + "online_instances_count": 1 + } + ] + } + }, + "StatusSummary": { + "description": "An overview of the status for each NGINX instance, indicating availability.", "type": "object", - "description": "Representation of a problem found during NGINX configuration analysis.", + "required": [ + "online", + "offline", + "unavailable" + ], "properties": { - "directive": { - "description": "Directive in the NGINX configuration where the issue is identified.", - "type": "string" + "online": { + "description": "The number of NGINX instances reporting as `online`.\nThe NGINX Agent is connected to NGINX One, and the NGINX instance is online.\n", + "type": "integer" }, - "file": { - "description": "File where the issue is detected.", - "type": "string" + "offline": { + "description": "The number of NGINX instances reporting as `offline`.\nThe NGINX Agent is connected to NGINX One, but the NGINX instance is offline.\n", + "type": "integer" }, - "line": { - "description": "Line number in the configuration where the issue is found.", + "unavailable": { + "description": "The number of NGINX instances reporting as `unavailable`.\nThe NGINX Agent has lost connection to NGINX One, rendering the NGINX instance unavailable.\n", "type": "integer" } } }, - "NginxConfigReport": { + "ControlPlane": { "type": "object", - "description": "An analysis of the NGINX configuration, highlighting issues and their severity, and offering recommendations.", + "description": "Information on control plane including:\n* Control plane object ID\n* Cluster UUID\n* Deployment UUID\n* Kubernetes namespace\n* Data plane key object ID\n* Certificate summary\n* Instance status summary\n", + "required": [ + "object_id", + "cluster_uuid", + "deployment_uuid", + "kubernetes_namespace" + ], "properties": { - "rule": { - "description": "The name of the configuration rule that was violated.", - "type": "string" + "object_id": { + "$ref": "#/components/schemas/ControlPlaneObjectID" }, - "info": { - "description": "A detailed description of the issue.", + "cluster_uuid": { + "description": "The Kubernetes UID assigned to the cluster that the product is running in.", "type": "string" }, - "severity": { - "description": "The severity level of the issue.", + "deployment_uuid": { + "description": "The Kubernetes UID assigned to the control plane.", "type": "string" }, - "category": { - "description": "Classification category of the issue.", + "key_object_id": { + "$ref": "#/components/schemas/DataPlaneKeyObjectID" + }, + "kubernetes_namespace": { + "description": "The kubernetes namespace that the product is running in.", "type": "string" }, - "documentation": { - "description": "Links to documentation that can assist in resolving the identified issue.", - "type": "array", - "items": { - "type": "string" - } + "cert_summary": { + "$ref": "#/components/schemas/CertificateInstanceSummary" }, - "where": { - "description": "Specific locations in the configuration where issues were detected.", - "type": "array", - "items": { - "$ref": "#/components/schemas/NginxConfigProblem" - } + "statuses": { + "$ref": "#/components/schemas/StatusSummary" } } }, - "NginxConfigReports": { - "type": "array", - "items": { - "$ref": "#/components/schemas/NginxConfigReport" + "ControlPlaneDetails": { + "type": "object", + "description": "Detailed information of control plane.", + "allOf": [ + { + "$ref": "#/components/schemas/ControlPlaneBaseInfo" + }, + { + "$ref": "#/components/schemas/ControlPlane" + } + ], + "example": { + "name": "foo", + "object_id": "ecp_-uvR3F2TQGm18jnl7bpaGw", + "product_version": "nginx-ingress-controller-1.0.0", + "cluster_uuid": "d1ced6c7-8980-467e-a1db-dcdfec16b1f7", + "deployment_uuid": "b9b00e37-5ee4-4361-8c61-1329f3828dd3", + "key_object_id": "key_6AT9LXyUQHyhC8kF7bVMgg", + "kubernetes_namespace": "nginx-ingress-controller", + "cert_summary": { + "total": 9, + "valid": 1, + "expired": 5, + "expiring": 3, + "not_ready": 0 + }, + "statuses": { + "offline": 0, + "online": 3, + "unavailable": 0 + } } }, - "NginxConfigMeta": { + "SummaryDisplayCount": { + "description": "The name, the total count, and an optional user-friendly display name of the resource being summarized.", "type": "object", - "description": "Meta data of an NGINX configuration, including its unique identifier, the config_version.\n", "required": [ - "object_id", - "config_version", - "created_at", - "modified_at", - "config_source" + "name", + "count" ], "properties": { - "object_id": { - "$ref": "#/components/schemas/NginxConfigObjectID" - }, - "config_version": { - "type": "string", - "description": "A hash that uniquely identifies the contents of the config object.\n" - }, - "created_at": { - "type": "string", - "format": "date-time", - "description": "The date and time when the NGINX configuration object was created for the instance." + "name": { + "description": "Identifies the category of data being reported, such as an operating system, NGINX version, or another type.", + "type": "string" }, - "modified_at": { - "type": "string", - "format": "date-time", - "description": "The date and time when the NGINX configuration object was last modified for the instance." + "count": { + "description": "The number of resources matching the given type.", + "type": "integer" }, - "config_source": { - "type": "string", - "enum": [ - "NGINX One", - "Other", - "Unspecified" - ], - "x-enum-varnames": [ - "config_source_nginx_one", - "config_source_other", - "config_source_unspecified" - ], - "description": "The source from which the config was created:\n- `NGINX One`: The config was created from NGINX One.\n- `Other`: The config was created from data plane.\n- `Unspecified`: The source of the config is unspecified.\n" + "display": { + "description": "A user-friendly label for the category count, intended for display purposes where a more descriptive or readable format is preferred.", + "type": "string" + } + } + }, + "ControlPlaneProductVersionSummary": { + "description": "An array of control plane product names/versions.", + "type": "array", + "items": { + "$ref": "#/components/schemas/SummaryDisplayCount" + } + }, + "ControlPlaneSummary": { + "description": "A summary of control planes including their product names/version details.", + "type": "object", + "properties": { + "product_versions": { + "$ref": "#/components/schemas/ControlPlaneProductVersionSummary" } }, "example": { - "object_id": "nc_AamgWtYSSb6OWGljx3wNDA", - "config_version": "Cm1hcCAkdXJpICRtYXBwZWRfc2V", - "created_at": "2023-08-10T16:59:15Z", - "modified_at": "2023-08-10T16:59:15Z", - "config_source": "NGINX One" + "product_versions": [ + { + "count": 10, + "name": "nginx-ingress-controller-1.0.0" + } + ] } }, "NginxCVEObject": { @@ -7020,12 +8339,14 @@ "enum": [ "instance_cleanup", "certificates", - "publications" + "publications", + "nap_compilation_jobs" ], "x-enum-varnames": [ "event_type_instance_cleanup", "event_type_certificates", - "event_type_publications" + "event_type_publications", + "event_type_nap_compilation_jobs" ] }, "object_id": { @@ -7248,6 +8569,77 @@ } ] }, + "NapSignatureVersion": { + "description": "The version of the NGINX App Protect resource.", + "type": "string", + "example": "2023.12.06" + }, + "NapInstanceAssociation": { + "allOf": [ + { + "$ref": "#/components/schemas/NapAssociation" + }, + { + "type": "object", + "required": [ + "threat_campaign_version", + "attack_signature_version", + "bot_signature_version" + ], + "properties": { + "threat_campaign_version": { + "$ref": "#/components/schemas/NapSignatureVersion" + }, + "attack_signature_version": { + "$ref": "#/components/schemas/NapSignatureVersion" + }, + "bot_signature_version": { + "$ref": "#/components/schemas/NapSignatureVersion" + } + } + } + ], + "example": { + "name": "default_policy", + "version": "2025.05.01", + "policy_object_id": "pol_panEdeY-Sh2rWm365y7wsw", + "policy_version_object_id": "pv_kem7SCosTTOL9mMlNyY2GQ", + "publication_object_id": "pub_72pGHoGsSICL_THZrs964g", + "paths": [ + "/etc/nginx/default_policy.tgz" + ], + "deployment_status": "deployed", + "enforcement_mode": "transparent", + "deployed_on": "2023-12-06T22:37:24.120114Z", + "threat_campaign_version": "2025.01.23", + "attack_signature_version": "2025.01.19", + "bot_signature_version": "2025.01.19" + } + }, + "NginxAppProtectDetails": { + "description": "Information regarding NGINX App Protect. Includes version and deployments.\n", + "type": "object", + "required": [ + "engine_version", + "deployments" + ], + "properties": { + "release_version": { + "description": "The release version of NGINX App Protect.", + "type": "string" + }, + "engine_version": { + "description": "The version of the App Protect enforcement engine.", + "type": "string" + }, + "deployments": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NapInstanceAssociation" + } + } + } + }, "InstanceDetails": { "type": "object", "description": "Detailed information about an NGINX instance.", @@ -7270,6 +8662,12 @@ }, "config_sync_group": { "$ref": "#/components/schemas/ConfigSyncGroupInstanceMeta" + }, + "nginx_app_protect": { + "$ref": "#/components/schemas/NginxAppProtectDetails" + }, + "control_plane": { + "$ref": "#/components/schemas/ControlPlaneBaseInfo" } } } @@ -7293,6 +8691,11 @@ ], "hostname": "4d116619f106", "key": "key_wN3IhLCmR3qmwybG_6ptEg", + "control_plane": { + "object_id": "ecp_CO1DdBxZToWmr3pTcaQ8QA", + "name": "nginx-ingress-001", + "product_version": "nginx-ingress-controller-4.0.1" + }, "last_reported": "2023-12-06T22:37:24.120114Z", "nginx_build": { "conf_path": "/etc/nginx/nginx.conf", @@ -7348,78 +8751,33 @@ "affected_instances" ], "properties": { - "status": { - "$ref": "#/components/schemas/CertificateStatus" - }, - "count": { - "description": "The total number of SSL certificates for each status category.", - "type": "integer" - }, - "affected_instances": { - "description": "Indicates the total number of SSL/TLS certificates corresponding to the status provided.", - "type": "integer" - } - } - }, - "SummaryDisplayCount": { - "description": "The name, the total count, and an optional user-friendly display name of the resource being summarized.", - "type": "object", - "required": [ - "name", - "count" - ], - "properties": { - "name": { - "description": "Identifies the category of data being reported, such as an operating system, NGINX version, or another type.", - "type": "string" - }, - "count": { - "description": "The number of resources matching the given type.", - "type": "integer" - }, - "display": { - "description": "A user-friendly label for the category count, intended for display purposes where a more descriptive or readable format is preferred.", - "type": "string" - } - } - }, - "OperatingSystemVersionSummary": { - "description": "An array summarizing the operating systems and their versions on the NGINX data plane.", - "type": "array", - "items": { - "$ref": "#/components/schemas/SummaryDisplayCount" - } - }, - "NGINXVersionSummary": { - "description": "An array summarizing the versions of NGINX installed across the NGINX data plane.", - "type": "array", - "items": { - "$ref": "#/components/schemas/SummaryDisplayCount" - } - }, - "StatusSummary": { - "description": "An overview of the status for each NGINX instance, indicating availability.", - "type": "object", - "required": [ - "online", - "offline", - "unavailable" - ], - "properties": { - "online": { - "description": "The number of NGINX instances reporting as `online`.\nThe NGINX Agent is connected to NGINX One, and the NGINX instance is online.\n", - "type": "integer" + "status": { + "$ref": "#/components/schemas/CertificateStatus" }, - "offline": { - "description": "The number of NGINX instances reporting as `offline`.\nThe NGINX Agent is connected to NGINX One, but the NGINX instance is offline.\n", + "count": { + "description": "The total number of SSL certificates for each status category.", "type": "integer" }, - "unavailable": { - "description": "The number of NGINX instances reporting as `unavailable`.\nThe NGINX Agent has lost connection to NGINX One, rendering the NGINX instance unavailable.\n", + "affected_instances": { + "description": "Indicates the total number of SSL/TLS certificates corresponding to the status provided.", "type": "integer" } } }, + "OperatingSystemVersionSummary": { + "description": "An array of operating systems and their versions on the NGINX data plane.", + "type": "array", + "items": { + "$ref": "#/components/schemas/SummaryDisplayCount" + } + }, + "NGINXVersionSummary": { + "description": "An array of NGINX versions installed across the NGINX data plane.", + "type": "array", + "items": { + "$ref": "#/components/schemas/SummaryDisplayCount" + } + }, "CveSummary": { "description": "A summary of Common Vulnerabilities and Exposures (CVEs) across the NGINX data plane.", "type": "object", @@ -7689,51 +9047,6 @@ "object_id": "sc_Tet21AeYTHCj7taOwVfzyw" } }, - "StagedConfigBulkRequestData": { - "type": "object", - "description": "Part of bulk operation on a staged config, only `delete` is supported.", - "required": [ - "action", - "object_id" - ], - "properties": { - "object_id": { - "$ref": "#/components/schemas/StagedConfigObjectID" - }, - "action": { - "$ref": "#/components/schemas/BulkRequestAction" - } - }, - "example": { - "object_id": "sc_-uvR3F2TQGm18jnl7bpaGw", - "action": "delete" - } - }, - "StagedConfigBulkRequest": { - "type": "array", - "items": { - "$ref": "#/components/schemas/StagedConfigBulkRequestData" - }, - "minItems": 1, - "maxItems": 50, - "example": [ - { - "object_id": "sc_-uvR3F2TQGm18jnl7bpaGw", - "action": "delete" - }, - { - "object_id": "sc_PL0c1XodRemmzVEjiXSsTg", - "action": "delete" - } - ] - }, - "StagedConfigBulkResponse": { - "description": "The staged config bulk outcome.", - "type": "array", - "items": { - "$ref": "#/components/schemas/BulkRequestObjectStatus" - } - }, "StagedConfigResponse": { "description": "Get an NGINX staged config.", "required": [ @@ -7812,35 +9125,6 @@ } } }, - "StagedConfigImportRequest": { - "type": "object", - "description": "Body to import a NGINX staged config", - "required": [ - "name", - "file", - "conf_path" - ], - "properties": { - "name": { - "$ref": "#/components/schemas/StagedConfigName" - }, - "file": { - "type": "string", - "format": "binary", - "example": "my-staged-config.tar.gz", - "maxLength": 5242880 - }, - "conf_path": { - "$ref": "#/components/schemas/ConfigPath" - } - }, - "example": { - "name": "my-nginx-config", - "file": "my-staged-config.tar.gz", - "conf_path": "/etc/nginx/nginx.conf", - "parse_only": true - } - }, "MetricQueryResultEx": { "type": "object", "required": [ @@ -8626,39 +9910,6 @@ "k8s.cluster.nodes" ] }, - "NapPolicyEnforcementMode": { - "description": "The current enforcement mode of the NGINX App Protect policy, with the following possible values:\n* `blocking` - Any illegal or suspicious requests are logged and blocked.\n* `transparent` - Any illegal or suspicious requests are logged but not blocked.\n", - "type": "string", - "enum": [ - "blocking", - "transparent" - ], - "x-enum-varnames": [ - "nap_enforcement_mode_blocking", - "nap_enforcement_mode_transparent" - ] - }, - "NapDeploymentStatus": { - "description": "The current enforcement mode of the NGINX App Protect policy, with the following possible values:\n* `deployed` - The NGINX App Protect policy has been deployed.\n* `not_deployed` - The NGINX App Protect policy has not been deployed.\n* `deploying` - The NGINX App Protect policy is currently being deployed.\n* `failed` - The NGINX App Protect policy failed deploying.\n", - "type": "string", - "enum": [ - "deployed", - "not_deployed", - "deploying", - "failed" - ], - "x-enum-varnames": [ - "nap_deployment_status_deployed", - "nap_deployment_status_not_deployed", - "nap_deployment_status_deploying", - "nap_deployment_status_failed" - ] - }, - "Version": { - "description": "The version of the NGINX App Protect resource.", - "type": "string", - "example": "2023.12.06" - }, "VersionsList": { "type": "object", "required": [ @@ -8669,21 +9920,18 @@ "description": "An array of versions.", "type": "array", "items": { - "$ref": "#/components/schemas/Version" + "$ref": "#/components/schemas/NapSignatureVersion" } } } }, "ThreatCampaignVersionsListResponse": { - "description": "List of Threat Campaign versions.", "$ref": "#/components/schemas/VersionsList" }, "AttackSignatureVersionsListResponse": { - "description": "List of Attack Signature versions.", "$ref": "#/components/schemas/VersionsList" }, "BotSignatureVersionsListResponse": { - "description": "List of Bot Signature versions.", "$ref": "#/components/schemas/VersionsList" }, "NapPolicy": { @@ -8778,7 +10026,7 @@ "latest": { "object_id": "pv_-uvR3F2TQGm18jnl7bpaGw", "version": "2023-12-06 22:37:24", - "created_on": "2023-12-06T22:37:24.120114Z", + "created_at": "2023-12-06T22:37:24.120114Z", "deployment_status": "deployed", "enforcement_mode": "blocking" } @@ -8839,7 +10087,7 @@ "$ref": "#/components/schemas/NapDeploymentStatus" }, "deployed_on": { - "description": "Date and time.", + "description": "Date and time of the deployment.", "type": "string", "format": "date-time" } @@ -8944,13 +10192,13 @@ "type": "object", "properties": { "threat_campaign_version": { - "$ref": "#/components/schemas/Version" + "$ref": "#/components/schemas/NapSignatureVersion" }, "attack_signature_version": { - "$ref": "#/components/schemas/Version" + "$ref": "#/components/schemas/NapSignatureVersion" }, "bot_signature_version": { - "$ref": "#/components/schemas/Version" + "$ref": "#/components/schemas/NapSignatureVersion" } } } @@ -9018,19 +10266,19 @@ "object_id", "version", "enforcement_mode", - "created_on" + "created_at" ], "properties": { "object_id": { "$ref": "#/components/schemas/NapPolicyVersionObjectID" }, "version": { - "$ref": "#/components/schemas/Version" + "$ref": "#/components/schemas/NapSignatureVersion" }, "enforcement_mode": { "$ref": "#/components/schemas/NapPolicyEnforcementMode" }, - "created_on": { + "created_at": { "description": "The date and time when the NGINX App Protect policy version was created.", "type": "string", "format": "date-time" @@ -9045,7 +10293,7 @@ "object_id", "version", "enforcement_mode", - "created_on" + "created_at" ], "allOf": [ { @@ -9108,7 +10356,7 @@ { "version": "2023-12-06 22:37:24", "object_id": "pv_-uvR3F2TQGm18jnl7bpaGw", - "created_on": "2023-12-06T22:37:24.120114Z", + "created_at": "2023-12-06T22:37:24.120114Z", "enforcement_mode": "blocking", "latest": false } @@ -9243,28 +10491,101 @@ } } }, - "NapPolicyObjectID": { - "description": "A globally unique identifier for the App Protect policy.", - "type": "string", - "format": "object_id", - "pattern": "^pol_.*", - "x-go-type": "objects.ID", - "x-go-type-import": { - "name": "objects", - "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" + "NapPolicyBulkRequest": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NapPolicyBulkRequestData" + }, + "minItems": 1, + "maxItems": 50, + "example": [ + { + "object_id": "pol_-uvR3F2TQGm18jnl7bpaGw", + "action": "delete" + }, + { + "object_id": "pol_PL0c1XodRemmzVEjiXSsTg", + "action": "delete" + } + ] + }, + "NapPolicyBulkRequestData": { + "type": "object", + "description": "Part of bulk operation on a Nap policy, only `delete` is supported.", + "required": [ + "action", + "object_id" + ], + "properties": { + "object_id": { + "$ref": "#/components/schemas/NapPolicyObjectID" + }, + "action": { + "$ref": "#/components/schemas/BulkRequestAction" + } + }, + "example": { + "object_id": "pol_-uvR3F2TQGm18jnl7bpaGw", + "action": "delete" } }, - "NapPolicyVersionObjectID": { - "description": "A globally unique identifier for the App Protect policy version.", - "type": "string", - "format": "object_id", - "pattern": "^pv_.*", - "x-go-type": "objects.ID", - "x-go-type-import": { - "name": "objects", - "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" + "NapBulkResponse": { + "description": "The Nap policy bulk outcome.", + "type": "array", + "items": { + "$ref": "#/components/schemas/BulkRequestObjectStatus" } }, + "FilterNameNapPolicy": { + "type": "string", + "description": "Keywords for NGINX App Protect policy filters.\nWhen filtering on `enforcement_mode`, only the following `filter_values` are supported:\n * blocking\n * transparent\nWhen filtering on `object_id`, both NAP Policy and NAP Policy version object id prefixes are supported.\n", + "enum": [ + "name", + "enforcement_mode", + "object_id", + "deployment_enforcement_mode", + "deployment_status" + ], + "x-enum-varnames": [ + "filter_name_nap_policy_name", + "filter_name_nap_policy_enforcement_mode", + "filter_name_nap_policy_object_id", + "filter_name_nap_policy_deployment_enforcement_mode", + "filter_name_nap_policy_deployment_status" + ] + }, + "FilterNameNapPolicyDeployment": { + "type": "string", + "description": "Keywords for NGINX App Protect deployment filters.\nWhen filtering on `type`, only the following `filter_values` are supported:\n * instance\n * config_sync_group\nWhen filtering on `status`, only the following `filter_values` are supported:\n * deployed\n * deploying\n * failed\n", + "enum": [ + "name", + "type", + "policy_version", + "status", + "object_id" + ], + "x-enum-varnames": [ + "filter_name_nap_deployment_name", + "filter_name_nap_deployment_type", + "filter_name_nap_deployment_policy_version", + "filter_name_nap_deployment_status", + "filter_name_nap_deployment_object_id" + ] + }, + "FilterNameNapPolicyVersion": { + "type": "string", + "description": "Keywords for NGINX App Protect policy version filters.\nWhen filtering on `deployment_status`, only the following `filter_values` are supported:\n * deployed\n * not_deployed\n * deploying\n * failed\nWhen filtering on `enforcement_mode`, only the following `filter_values` are supported:\n * blocking\n * transparent\n", + "enum": [ + "deployment_status", + "enforcement_mode", + "object_id" + ], + "x-enum-varnames": [ + "filter_name_nap_policy_version_deployment_status", + "filter_name_nap_policy_version_enforcement_mode", + "filter_name_nap_policy_version_object_id" + ] + }, "NapLogProfileObjectID": { "description": "A globally unique identifier for the App Protect log profile.", "type": "string", @@ -9303,7 +10624,8 @@ "revoked": false, "name": "my-data-plane-key", "object_id": "key_wN3IhLCmR3qmwybG_6ptEg", - "instances_count": 3 + "instances_count": 3, + "control_planes_count": 1 }, { "expires_at": "2023-12-01T00:00:00Z", @@ -9312,7 +10634,8 @@ "revoked": false, "name": "my-data-plane-key", "object_id": "key_Tet21AeYTHCj7taOwVfzyw", - "instances_count": 3 + "instances_count": 3, + "control_planes_count": 1 } ] } @@ -9339,13 +10662,57 @@ "revoked": false, "name": "my-data-plane-key", "object_id": "key_wN3IhLCmR3qmwybG_6ptEg", - "instances_count": 3 + "instances_count": 3, + "control_planes_count": 1 + } + }, + "ConfigSyncGroupDetails": { + "value": { + "object_id": "csg_-uvR3F2TQGm18jnl7bpaGw", + "name": "test-config-sync-group", + "last_reported": "2023-12-06T22:37:24.120114Z", + "config_status": "in_sync", + "config_version": "uvR3F2TQGm18jnl7bpaGw", + "instances": [ + { + "object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", + "hostname": "816e3c194d59", + "system_id": "6066aad2-211e-3718-be5d-fcc01ffc5cc8", + "agent_version": "v2.33.0", + "registered_at": "2024-05-16T18:26:40.556048Z", + "last_reported": "2023-12-06T22:37:24.120114Z", + "status": "unavailable", + "nginx_build": { + "conf_path": "/etc/nginx/nginx.conf", + "version": "1.25.3" + }, + "os_version": "Ubuntu 22.04", + "nginx_id": "b636d4376dea15405589692d3c5d3869ff3a9b26b0e7bb4bb1aa7e658ace1437", + "config_status": "in_sync", + "config_version": "abc123def456" + } + ], + "certs": [ + { + "subject_name": "test.com", + "name": "client", + "cert_type": "cert_key", + "not_after": "2024-01-06T00:01:30Z", + "not_before": "2023-12-07T00:01:30Z", + "cert_paths": [ + "/etc/nginx/client.pem" + ], + "cert_status": "expiring", + "deployment_status": "latest", + "object_id": "cert_Tet21AeYTHCj7taOwVfzyw" + } + ] } } }, "responses": { - "InvalidRequest": { - "description": "Request cannot be processed due to invalid input or parameters. Verify the request format and provided data.", + "Unauthorized": { + "description": "Client is not authorized to perform the requested operation.", "content": { "application/json": { "schema": { @@ -9363,6 +10730,26 @@ } } } + }, + "NotFound": { + "description": "Requested resource was not found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "InvalidRequest": { + "description": "Request cannot be processed due to invalid input or parameters. Verify the request format and provided data.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } } }, "securitySchemes": { @@ -9388,7 +10775,8 @@ "Certificates", "CVEs", "Events", - "Staged Configs" + "Staged Configs", + "Control Planes" ] }, { @@ -9402,6 +10790,12 @@ "tags": [ "Settings" ] + }, + { + "name": "NGINX One App Protect", + "tags": [ + "NGINX App Protect" + ] } ] } \ No newline at end of file