diff --git a/content/nginx-one-console/api/query-events-api.md b/content/nginx-one-console/api/query-events-api.md new file mode 100644 index 0000000000..1a2f6ad9cc --- /dev/null +++ b/content/nginx-one-console/api/query-events-api.md @@ -0,0 +1,44 @@ +--- +nd-content-type: reference +nd-docs: DOCS-000 +nd-product: NONECO +title: Query security events through the API +description: "List F5 WAF for NGINX security events and run analytics queries through the NGINX One Console API." +weight: 200 +toc: true +nd-keywords: "security events API, analytics API, F5 WAF for NGINX, app-protect, NGINX One Console API" +nd-summary: > + Use the NGINX One Console API to list F5 WAF for NGINX security events and run analytics queries against the same data store the security dashboard uses. + This article lists the available operations and points to the API reference for request and response details. + The same filter fields and group-by dimensions used by the dashboard apply to every operation here. +nd-audience: developer +--- + +## Overview + +Use the NGINX One Console API to query F5 WAF for NGINX security events programmatically. The API exposes the same security event store the security monitoring dashboard reads from, so any view you can build in the dashboard can also be reproduced through the API. Use the API to integrate WAF activity into your own dashboards, automated reports, Security Information and Event Management (SIEM) enrichment pipelines, or alerting workflows. + +For the full request and response schema of each operation, including the supported filter fields and group-by dimensions, see the [API reference guide]({{< ref "/nginx-one-console/api/api-reference-guide.md" >}}). + +## Operations + +| Category | Operation | Purpose | +|---|---|---| +| Events | [List security events]({{< ref "/nginx-one-console/api/api-reference-guide/#operation/listSecurityEvents" >}}) | Returns a paginated list of F5 WAF for NGINX security events. Accepts `filter_fields`, a time range, and standard pagination parameters. | +| Events | [Get security event details]({{< ref "/nginx-one-console/api/api-reference-guide/#operation/getSecurityEvent" >}}) | Returns the full detail for a single security event by ID, including all triggered violations, signatures, threat campaign matches, and the raw matched request when available. | +| Attack analytics | [Query attack analytics]({{< ref "/nginx-one-console/api/api-reference-guide/#operation/queryAttackAnalytics" >}}) | Returns event counts grouped by an event-level dimension (`request_status`, `ip`, `country`, `policy`, `url`, `hostname`, and others). Supports filter fields, time range, group-by, and limit. | +| Attack analytics | [Query attack analytics time series]({{< ref "/nginx-one-console/api/api-reference-guide/#operation/queryAttackAnalyticsTimeSeries" >}}) | Returns the same counts bucketed over time. Use this to drive time-series widgets and trend reports. | +| Signature analytics | [Query signature analytics]({{< ref "/nginx-one-console/api/api-reference-guide/#operation/querySignatureAnalytics" >}}) | Returns event counts grouped by a signature-level dimension (`signature`, `accuracy`, `risk`, `cve`, `request_status`). Filtering on signature-level fields narrows results to events whose matching signatures pass the filter. | +| Signature analytics | [Query signature analytics time series]({{< ref "/nginx-one-console/api/api-reference-guide/#operation/querySignatureAnalyticsTimeSeries" >}}) | Returns the same counts bucketed over time. | +| Violation analytics | [Query violation analytics]({{< ref "/nginx-one-console/api/api-reference-guide/#operation/queryViolationAnalytics" >}}) | Returns event counts grouped by a violation-level dimension (`violation`, `sub_violation`, `context`, `context_key`, `context_value`). | + +--- + +## References + +For more information, see: + +- [API reference guide]({{< ref "/nginx-one-console/api/api-reference-guide.md" >}}) +- [Authentication]({{< ref "/nginx-one-console/api/authentication.md" >}}) +- [Dashboard metrics reference]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/dashboard-metrics-reference.md" >}}) +- [Security monitoring overview]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/security-monitoring-overview.md" >}}) \ No newline at end of file diff --git a/content/nginx-one-console/changelog.md b/content/nginx-one-console/changelog.md index 488f41bb0e..59f0fe6eea 100644 --- a/content/nginx-one-console/changelog.md +++ b/content/nginx-one-console/changelog.md @@ -9,6 +9,12 @@ nd-docs: DOCS-1394 Stay up-to-date with what's new and improved in the F5 NGINX One Console. +## April 7, 2026 + +### Observability: F5 WAF for NGINX security dashboard + +The new Security Monitoring module gives you real-time visibility into F5 WAF for NGINX security events. You can monitor attack counts, violation types, and triggered signatures across your WAF instances by using customizable dashboards and global filters. + ## March 18, 2026 ### F5 WAF for NGINX: Log profile management diff --git a/content/nginx-one-console/waf-integration/_index.md b/content/nginx-one-console/waf-integration/_index.md index 8f700d1a04..1a4b0b85fb 100644 --- a/content/nginx-one-console/waf-integration/_index.md +++ b/content/nginx-one-console/waf-integration/_index.md @@ -1,6 +1,8 @@ --- -title: Secure with F5 WAF for NGINX +title: Secure your fleet with F5 WAF for NGINX description: weight: 400 url: /nginx-one-console/waf-integration --- + +Integrate F5 WAF for NGINX with NGINX One Console to centralize security monitoring, log profile management, and WAF policy configuration. diff --git a/content/nginx-one-console/waf-integration/waf-security-dashboard/_index.md b/content/nginx-one-console/waf-integration/waf-security-dashboard/_index.md new file mode 100644 index 0000000000..09958ef21f --- /dev/null +++ b/content/nginx-one-console/waf-integration/waf-security-dashboard/_index.md @@ -0,0 +1,17 @@ +--- +title: F5 WAF for NGINX security monitoring +description: Monitor F5 WAF for NGINX security events in NGINX One Console. +weight: 425 +url: /nginx-one-console/waf-integration/waf-security-dashboard +--- + +Use the security monitoring module in NGINX One Console to collect, visualize, and query security events from F5 WAF for NGINX running on NGINX Plus instances. Review attacks, violations, and triggered signatures to assess threats and fine-tune your policies. + +This section covers: + +- [Security monitoring overview]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/security-monitoring-overview.md" >}}) — what the security dashboard is, the data pipeline behind it, and what you can do with it. +- [secops_dashboard log profile]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/default-log-profile.md" >}}) — the immutable, pre-compiled log profile the dashboard depends on. +- [Set up security monitoring]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/set-up-security-monitoring.md" >}}) — install F5 WAF for NGINX, configure the log profile, and forward events through NGINX Agent. +- [Security dashboard reference]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/dashboard-metrics-reference.md" >}}) — dashboard tabs, global controls, and how each widget maps to an underlying dimension. +- [Find a security event by Support ID]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/find-event-by-support-id.md" >}}) — look up a single security event by its Support ID for quick triage. +- [Query security events through the API]({{< ref "/nginx-one-console/api/query-events-api.md" >}}) — list events and run analytics queries programmatically. diff --git a/content/nginx-one-console/waf-integration/waf-security-dashboard/dashboard-metrics-reference.md b/content/nginx-one-console/waf-integration/waf-security-dashboard/dashboard-metrics-reference.md new file mode 100644 index 0000000000..2bcf7cc48a --- /dev/null +++ b/content/nginx-one-console/waf-integration/waf-security-dashboard/dashboard-metrics-reference.md @@ -0,0 +1,176 @@ +--- +nd-content-type: reference +nd-docs: DOCS-000 +nd-product: NONECO +title: Security dashboard reference +description: "Tabs, global controls, and widget-to-dimension mapping for the F5 WAF for NGINX security monitoring dashboard." +weight: 400 +toc: true +nd-keywords: "security dashboard, tabs, global filters, widgets, dimensions, F5 WAF for NGINX" +nd-summary: > + Use this reference to look up how the security monitoring dashboard is organized and which underlying dimension each widget reads from. + This article covers the dashboard tabs, the global filter and time controls, and the mapping from widget to API dimension. + Each widget has an in-product tooltip explaining what its values mean; this article focuses on what is not in those tooltips. +nd-audience: operator +--- + +## Overview + +Use this reference to look up how the F5 WAF for NGINX security monitoring dashboard is organized and which underlying dimension each widget reads from. Every widget in the dashboard has an in-product tooltip that explains what the displayed values mean. This article mainly covers the dashboard structure, the global controls that affect every widget, and the mapping you need when you want to reproduce a widget's view through the [analytics API]({{< ref "/nginx-one-console/api/query-events-api.md" >}}). + +--- + +## Dashboard layout + +The security dashboard is organized into three tabs. All three tabs share the same global filter bar and time window control at the top of the page, so any filter or time change applies to every widget on every tab. + +| Tab | Purpose | +|:--- |:--- | +| **Main** | High-level summary of WAF activity in the selected window. Shows attack counts, threat intelligence, attack volume over time, and top-N breakdowns by geolocation, policy, IP, violation, and signature. This is the landing tab for triage. | +| **Advanced** | Deeper analytics for tuning and investigation. Use this tab to drill into signature attributes (risk, accuracy, CVE), violation context, and other dimensions that are too detailed for the Main tab. | +| **Event Logs** | A filterable list of individual security events. Open an event to see its support ID, full violation and signature detail, request context, and the raw matched request. This tab is the drill-down target when you want to inspect specific events behind a metric. | + +--- + +## Global controls + +Two controls at the top of the page apply to every widget on every tab. + +### Time window + +Selects the query window for all widgets. The picker offers preset windows from **Last 5 minutes** to **Last 60 days**. You can also select a custom range by highlighting an area of interest on any time-series chart. + +Time-series widgets bucket their data automatically based on the selected window — shorter windows produce finer buckets. + +{{< call-out "note" >}}Security events are retained for **90 days**, but the dashboard time window picker tops out at the **last 60 days**. To query the full retention window, use the [analytics API]({{< ref "/nginx-one-console/api/query-events-api.md" >}}), which accepts any time range up to 90 days.{{< /call-out >}} + +### Add Filter + +Applies one or more filter expressions to every widget on every tab. The dashboard supports the following filters: + +| Filter | Description | +|:--- |:--- | +| **Config Sync Group** | Scope events to instances belonging to a specific Config Sync Group. | +| **Country** | Two-letter country code derived from the client IP. | +| **Destination Hostname** | The HTTP `Host` header sent by the client. Use this to scope by the application being attacked. | +| **Hostname** | The NGINX instance hostname (the data plane host). Use this to scope by the data plane producing the events. | +| **Instance** | Scope events to a specific NGINX instance by object identity rather than hostname. | +| **IP Address** | The originating client IP. | +| **Outcome Reason** | The reason F5 WAF for NGINX produced its decision, such as a matched violation or a blocking rule. | +| **Policy** | The F5 WAF for NGINX policy that produced the event. | +| **Request Method** | The HTTP request method (`GET`, `POST`, and so on). | +| **Response Code** | The HTTP response code returned for the request. | +| **Signature Accuracy** | The accuracy level of a triggered signature: `low`, `medium`, or `high`. | +| **Signature CVE** | A CVE identifier referenced by a triggered signature. | +| **Signature ID** | The numeric F5 WAF for NGINX signature ID. | +| **Signature Name** | The name of a triggered signature. | +| **Signature Risk** | The risk level of a triggered signature: `low`, `medium`, or `high`. | +| **Status** | The final WAF decision: `blocked`, `alerted`, or `passed`. | +| **Subviolation** | The sub-violation name within a violation. | +| **Support ID** | The unique identifier F5 WAF for NGINX assigns to each event. | +| **Threat Campaign** | The name of a matched threat campaign. | +| **URI** | The request URI path. | +| **Violation** | The name of a triggered violation. | +| **Violation Context** | Where in the request the violation occurred: `cookie`, `header`, `parameter`, `request`, or `URI`. | +| **Violation Context Key** | The field name (for example, the parameter or header name) where the violation occurred. | +| **Violation Context Value** | The field value where the violation occurred. | +| **Violation Rating** | The numeric severity rating (0–5) F5 WAF for NGINX assigned to the violation. | + +Use filters to scope the dashboard to a specific policy, instance, hostname, country, IP, signature, violation, or any combination. To go from a metric on the dashboard to the underlying events, apply the relevant filter and switch to the **Event Logs** tab. + +Every dashboard filter is also available through the analytics API. To call the same filters from the API, see the [API reference guide]({{< ref "/nginx-one-console/api/api-reference-guide.md" >}}). + +--- + +## Main tab widgets + +Each widget on the Main tab has a tooltip describing what it displays. The table below adds context the tooltips do not cover, such as how rows are counted and what distinct counts each Top-N table reports. + +| Widget | Notes | +|:--- |:--- | +| **All Web Attacks** | Total count of security events for the selected window and filters. | +| **Threat Intelligence** | Unique counts of threat campaigns and signatures observed in the window. | +| **Attack Requests Over Time** | Stacked time series of `blocked` and `alerted` events. Bucket size depends on the selected window. | +| **Top Attack Geolocations** | Highest-volume client countries in the window. | +| **Top WAF Policies** | Each row shows hits, distinct URIs, IPs, and violations for the policy. | +| **Top Attack IP Addresses** | Each row shows hits, distinct URIs, violations, and policies for the client IP. | +| **Top Violations** | Each row shows hits, distinct IPs, URIs, and policies for the violation. | +| **Top Signatures** | Each row shows hits, distinct URIs, IPs, violations, and policies for the signature. | +| **Top Subviolations** | Each row shows hits, distinct IPs, URIs, and policies for the sub-violation. | +| **Top Attack URIs** | Each row shows hits, distinct IPs, violations, and policies for the URI. | +| **Request Methods** | Donut chart showing the share of events for each HTTP method observed in the window. | +| **Response Codes** | Donut chart showing the share of events for each response code observed in the window. | + +To reproduce these widgets through the analytics API, see [Query security events through the API]({{< ref "/nginx-one-console/api/query-events-api.md" >}}). + +--- + +## Advanced tab widgets + +The Advanced tab exposes signature- and violation-level analytics for tuning and deeper investigation. Widgets on this tab read from the same data store as the Main tab and respect the same global filters and time window. + +| Widget | Notes | +|:--- |:--- | +| **Signatures** | Total signature hits and unique signature count, with distributions across signature accuracy and risk levels. | +| **Signature Hits Request Status** | Donut chart of `blocked`, `alerted`, and `passed` shares of signature hits. | +| **Violation Context** | Donut chart showing where in the request the violation occurred (`cookie`, `header`, `parameter`, `request`, `URI`). | +| **Signature Hits Over Time** | Time series of signature hit volume. Bucket size depends on the selected window. | +| **Top Signatures** | Same as the Top Signatures widget on the Main tab. Each row shows hits, distinct URIs, IPs, violations, and policies. | +| **Top Signature CVEs** | Each row shows hits, distinct URIs, IPs, violations, and policies for signatures that reference the CVE. | +| **Top Threat Campaigns** | Each row shows hits, distinct URIs, IPs, violations, and policies for the threat campaign. | +| **Top Attacked Instances** | Each row shows hits, distinct URIs, IPs, violations, and policies, scoped to the NGINX instance hostname (not the HTTP `Host` header). | + +To reproduce these widgets through the analytics API, see [Query security events through the API]({{< ref "/nginx-one-console/api/query-events-api.md" >}}). + +--- + +## Event Logs tab + +The Event Logs tab lists individual security events matching the global filters and time window. The tab has two parts: + +- A **Security Events** time-series chart at the top showing event volume by request status (`blocked` and `alerted`), the same view as the **Attack Requests Over Time** widget on the Main tab. +- A paginated **events table** below the chart, where each row corresponds to one security event. + +### Events table columns + +| Column | Description | +|:--- |:--- | +| **Status** | The final WAF decision: `blocked`, `alerted`, or `passed`. | +| **URI** | The request URI that triggered the event. | +| **Policy** | The F5 WAF for NGINX policy that produced the event. | +| **Time** | When F5 WAF for NGINX produced the event. | +| **Source Location** | Country derived from the client IP, when available. | +| **Source IP** | The originating client IP. | +| **Violation Rating** | Numeric severity rating (0–5) assigned by F5 WAF for NGINX. | +| **Support ID** | The unique identifier F5 WAF for NGINX assigns to the event. Use this to correlate with raw F5 WAF for NGINX logs on the data plane. | + +To list events with the same columns through the analytics API, see [Query security events through the API]({{< ref "/nginx-one-console/api/query-events-api.md" >}}). + +### Pagination + +The table is paginated. Use the controls in the bottom-right of the table to: + +- Change the page size (default `50` rows per page). +- Navigate to a specific page or step through pages with the arrow controls. + +The total event count for the current filter and time window is shown in the bottom-left of the table. + +### Event detail panel + +Selecting a row opens the event detail panel. The panel surfaces every field stored on the event, including: + +- **Triggered violations and signatures** — every violation and signature that fired on the event, with their full attributes. +- **Request context** — method, URL, host, client IP, X-Forwarded-For chain, country, response code, and request status. +- **Raw matched request** — the captured request payload, when available. + + +--- + +## References + +For more information, see: + +- [Security monitoring overview]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/security-monitoring-overview.md" >}}) +- [Set up security monitoring]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/set-up-security-monitoring.md" >}}) +- [Find a security event by Support ID]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/find-event-by-support-id.md" >}}) +- [Query security events through the API]({{< ref "/nginx-one-console/api/query-events-api.md" >}}) diff --git a/content/nginx-one-console/waf-integration/waf-security-dashboard/default-log-profile.md b/content/nginx-one-console/waf-integration/waf-security-dashboard/default-log-profile.md new file mode 100644 index 0000000000..4137375cdc --- /dev/null +++ b/content/nginx-one-console/waf-integration/waf-security-dashboard/default-log-profile.md @@ -0,0 +1,87 @@ +--- +nd-content-type: concept +nd-docs: DOCS-000 +nd-product: NONECO +title: secops_dashboard log profile +description: "An immutable, pre-compiled F5 WAF for NGINX log profile that captures the security telemetry the security dashboard needs." +weight: 200 +toc: true +nd-keywords: "secops_dashboard, default log profile, security dashboard, F5 WAF for NGINX, log profile, security telemetry, NAP log profile, system-managed profile, pre-compiled, immutable log profile, NGINX One Console, WAF log profile" +nd-summary: > + The `secops_dashboard` log profile is a pre-configured F5 WAF for NGINX log profile that captures security violations in a standardized format for the security monitoring dashboard. It is the default log profile used by the security dashboard. + Use it to send security telemetry from your NGINX Plus data planes to NGINX One Console without authoring or compiling a custom log profile. + This document covers what the `secops_dashboard` log profile is, when to use it, and how it differs from custom log profiles. +nd-audience: operator +--- + +The security monitoring dashboard depends on a consistent set of fields being present on every security event. The `secops_dashboard` log profile is the guarantee of that consistency: it ensures every data plane forwards the same set of fields, so the dashboard can render every event correctly. + +## What is the `secops_dashboard` log profile? + +The `secops_dashboard` log profile is a pre-configured, system-managed F5 WAF for NGINX log profile that captures the security telemetry fields the NGINX One Console security monitoring dashboard expects. It is the default log profile used by the security dashboard. NGINX One Console maintains it as a system asset; you cannot edit or delete it. + +It is similar in structure and function to other [log profiles]({{< ref "/nginx-one-console/waf-integration/log-profiles/_index.md" >}}), but it is treated as a system asset rather than a user-managed resource. The `secops_dashboard` log profile is the only log profile guaranteed to produce data the security dashboard can render correctly. Custom log profiles can coexist with it and continue to serve other logging destinations such as Security Information and Event Management (SIEM) systems, file logs, or custom syslog endpoints, but they are not interpreted by the security dashboard. + +This document covers what the `secops_dashboard` log profile is and when to use it. For the steps to deploy it as part of setting up an instance, see [Set up security monitoring]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/set-up-security-monitoring.md" >}}). + +--- + +## How to identify it in the console + +In NGINX One Console, go to **WAF** > **Log Profiles**. The `secops_dashboard` log profile appears in the list with an **F5** badge next to its name. The badge marks it as a system-managed profile created and maintained by F5. + +The available **Actions** on the `secops_dashboard` log profile are limited compared to a user-created log profile. You can **Deploy**, **Download JSON**, **Manage Bundle**, and **Make a copy**, but **Edit** and **Delete** are not exposed — the profile is system-managed and cannot be modified or removed. + +To see the compiled bundles for the `secops_dashboard` log profile, open the profile and select **Actions** > **Manage Bundle**. The **Bundles** tab lists every available WAF compiler version with its compilation status (`Compiled` or `Compiling`) and a **Download** action for each compiled bundle. NGINX One Console keeps these bundles up to date automatically — you do not need to compile them yourself. + +If you need a log profile with a different field set or filter rules, use **Make a copy** to create an editable, user-owned log profile based on `secops_dashboard`. The copy is a regular custom log profile and is not used by the security dashboard. + +--- + +## Key characteristics + +The `secops_dashboard` log profile has three properties that distinguish it from user-created log profiles. + +- **Immutable**: You cannot edit or delete the `secops_dashboard` log profile. NGINX One Console manages it as a system resource so the security monitoring data format remains consistent across every instance and tenant. +- **Pre-compiled**: NGINX One Console automatically compiles the `secops_dashboard` log profile for every available WAF compiler version. Deployment completes immediately without an on-demand compilation step. +- **Standardized field set**: It captures every field the security dashboard reads, including the support ID, violation details, signature information, threat campaign matches, request context, and client geolocation. Filters and analytics in the dashboard assume these fields are present. + +--- + +## Use cases + +### Operator: enable security monitoring for an NGINX Plus fleet + +A platform operator wants central visibility into F5 WAF for NGINX events across a fleet of NGINX Plus instances. They deploy the `secops_dashboard` log profile to every instance, knowing that every event will land in NGINX One Console with the same field set, so dashboard widgets, filters, and analytics behave the same regardless of which instance produced the event. They do not need to author, compile, or version-control a log profile to get the dashboard working. + +### Security engineer: rolling out a policy change without touching telemetry + +A security engineer is rolling out a new WAF policy to a subset of instances and wants the security dashboard to continue showing comparable metrics across the migration. Because the `secops_dashboard` log profile is immutable and shared, the data format does not change with the policy, and the engineer can compare attack counts and signature trends before and after the rollout without normalizing fields. + +### Operator: combine dashboard monitoring with a custom SIEM pipeline + +An operator already forwards security logs to an external SIEM with a custom log profile that uses a different field layout. They deploy the `secops_dashboard` log profile alongside the existing custom profile so that NGINX One Console gets the standardized format the dashboard requires, while the SIEM continues to receive the custom format unchanged. + +--- + +## Comparison with custom log profiles + +| | Default log profile | Custom log profile | +|:--- |:--- |:--- | +| **Editable** | No | Yes | +| **Deletable** | No | Yes | +| **Compilation** | Pre-compiled for all WAF compiler versions | Compiled on demand for the target compiler version | +| **Field layout** | Fixed; matches the security dashboard | User-defined | +| **Used by the security dashboard** | Yes | No | +| **Best for** | Sending data to the NGINX One Console security dashboard | Forwarding to SIEMs, custom syslog endpoints, or file logs with a non-standard field set | + +--- + +## References + +For more information, see: + +- [Set up security monitoring]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/set-up-security-monitoring.md" >}}) +- [F5 WAF for NGINX security monitoring overview]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/security-monitoring-overview.md" >}}) +- [Log profiles]({{< ref "/nginx-one-console/waf-integration/log-profiles/_index.md" >}}) +- [Deploy log profiles]({{< ref "/nginx-one-console/waf-integration/log-profiles/deploy-log-profiles.md" >}}) diff --git a/content/nginx-one-console/waf-integration/waf-security-dashboard/find-event-by-support-id.md b/content/nginx-one-console/waf-integration/waf-security-dashboard/find-event-by-support-id.md new file mode 100644 index 0000000000..b1751e1a97 --- /dev/null +++ b/content/nginx-one-console/waf-integration/waf-security-dashboard/find-event-by-support-id.md @@ -0,0 +1,102 @@ +--- +nd-content-type: how-to +nd-docs: DOCS-000 +nd-product: NONECO +title: Find a security event by Support ID +description: "Look up an F5 WAF for NGINX security event in NGINX One Console using its Support ID." +weight: 500 +toc: true +nd-keywords: "support ID, security event, F5 WAF for NGINX, security dashboard, event lookup, Support ID Details, getSecurityEvent, listSecurityEvents, WAF block, rejection page, triage, 90-day retention" +nd-summary: > + Use the Support ID Details page in NGINX One Console to look up a single F5 WAF for NGINX security event by its Support ID. + This is the fastest way to drill from a customer report, an upstream log line, or an alert into the full WAF event record. + This guide covers what a Support ID is, where to find one, and how to use the lookup page. +nd-audience: operator +--- + +## Overview + +Use the Support ID Details page in NGINX One Console to look up a single F5 WAF for NGINX security event by its Support ID. F5 WAF for NGINX assigns a unique Support ID to every inspected request, and that ID travels through every system that touches the request: security logs, NGINX access logs, upstream application logs, and the security monitoring dashboard. + +Use this page when you already know the ID of the event you want to inspect — for example, from a customer support case, a raw F5 WAF for NGINX log line, an alert payload, or an upstream application that captured the ID from a request header. To explore events without a known ID, use the Event Logs tab on the [security monitoring dashboard]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/dashboard-metrics-reference.md#event-logs-tab" >}}) instead. + +--- + +## Before you begin + +Before you begin, ensure you have: + +- **A Support ID**: A numeric Support ID for the event you want to inspect. See [Where to find a Support ID](#where-to-find-a-support-id) below. +- **Security monitoring set up**: F5 WAF for NGINX security events must already be flowing into NGINX One Console for the event to be available. See [Set up security monitoring]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/set-up-security-monitoring.md" >}}). + +--- + +## Look up an event by Support ID + +1. In NGINX One Console, go to **WAF** > **Support ID Details**. +2. Paste the Support ID into the **Enter a Support ID** field. +3. The page displays the **Security Event** detail panel for the matching event, including the request, source, and raw request data. + + {{< call-out "note" >}}Security events are retained for 90 days. Events older than 90 days are no longer available.{{< /call-out >}} + +### Troubleshooting + +If no event is found, the most likely causes are: + +- The Support ID does not belong to a WAF-inspected request +- The event is older than the 90-day retention window +- The Support ID was mistyped + +--- + +## What the detail panel shows + +The Security Event detail panel surfaces every field stored on the event: + +- **Request** — request method, URI, host, headers, and the **Raw Request** payload as captured by F5 WAF for NGINX. The raw request is the same payload that would appear in a NAP security log on the data plane. +- **Source** — client IP, X-Forwarded-For chain, and a geolocation map showing the country derived from the client IP. +- **Time of Request** — when F5 WAF for NGINX produced the event. +- **Triggered violations and signatures** — every violation and signature that fired on the event, with their full attributes (name, accuracy, risk, CVE, context). +- **Threat campaigns** — any threat campaigns matched by the event. +- **Policy and outcome** — the F5 WAF for NGINX policy that produced the event, the request status (`blocked`, `alerted`, or `passed`), and the outcome reason. + +--- + +## Where to find a Support ID + +A Support ID can come from any system that observed the request: + +- **NGINX One Console Event Logs tab** — every row in the Event Logs table on the [security dashboard]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/dashboard-metrics-reference.md#event-logs-tab" >}}) includes the Support ID. Copy a Support ID from there to share in a ticket, support case, or follow-up message. +- **F5 WAF for NGINX security logs on the data plane** — the Support ID is the first field in every log line emitted by the [`secops_dashboard` log profile]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/default-log-profile.md" >}}). +- **F5 WAF for NGINX rejection page** — when F5 WAF for NGINX blocks a request, the response page typically includes the Support ID so the user can quote it back to support. +- **Customer support cases** — end users who hit a Request Rejected page can be asked to provide the Support ID from that page. + +--- + +## Use cases + +### Operator: triage a customer-reported block + +A customer reports that their request was rejected and provides the Support ID from the rejection page. The operator opens **WAF** > **Support ID Details**, pastes the ID, and sees the full event record, including which signature fired and which policy was in effect — enough to decide whether the block was a true positive or a candidate for policy tuning. + +### Security engineer: correlate an upstream incident with WAF activity + +An upstream service surfaces an incident referencing a Support ID extracted from request headers. The engineer pastes the ID into the Support ID Details page to see whether the request was blocked, alerted, or passed by F5 WAF for NGINX, and which violations or signatures it triggered, before deciding whether the incident is WAF-related. + +--- + +## Querying by Support ID through the API + +The same lookup is available through the analytics API. Use the [`getSecurityEvent`]({{< ref "/nginx-one-console/api/api-reference-guide/#operation/getSecurityEvent" >}}) operation to fetch a single event, or [`listSecurityEvents`]({{< ref "/nginx-one-console/api/api-reference-guide/#operation/listSecurityEvents" >}}) with `support_id` in `filter_fields` to look up by Support ID programmatically. + +For more on querying events through the API, see [Query security events through the API]({{< ref "/nginx-one-console/api/query-events-api.md" >}}). + +--- + +## References + +For more information, see: + +- [Security dashboard reference]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/dashboard-metrics-reference.md" >}}) +- [Query security events through the API]({{< ref "/nginx-one-console/api/query-events-api.md" >}}) +- [Set up security monitoring]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/set-up-security-monitoring.md" >}}) diff --git a/content/nginx-one-console/waf-integration/waf-security-dashboard/security-monitoring-overview.md b/content/nginx-one-console/waf-integration/waf-security-dashboard/security-monitoring-overview.md new file mode 100644 index 0000000000..fd6639e2d9 --- /dev/null +++ b/content/nginx-one-console/waf-integration/waf-security-dashboard/security-monitoring-overview.md @@ -0,0 +1,88 @@ +--- +nd-content-type: concept +nd-docs: DOCS-000 +nd-product: NONECO +title: Security monitoring overview +description: "What the F5 WAF for NGINX security monitoring module is, the data pipeline behind it, and what you can do with the data." +weight: 100 +toc: true +nd-keywords: "security monitoring, security dashboard, F5 WAF for NGINX, security events, analytics, NGINX One Console" +nd-summary: > + Security monitoring in NGINX One Console centralizes security events from F5 WAF for NGINX instances and exposes them through dashboards and an analytics API. + Use this document to understand what the dashboard shows, where the data comes from, and how it is scoped and retained. + This document is conceptual; for setup steps see Set up security monitoring. +nd-audience: operator +--- + +Security monitoring brings F5 WAF for NGINX events from every connected instance into a single place in NGINX One Console. This page explains what data the system collects, how it flows, and how it is organized. + +## What is security monitoring? + +Security monitoring is the NGINX One Console module that ingests F5 WAF for NGINX security events from your data planes, stores them centrally, and exposes them through a security dashboard and an analytics API. It gives you a single view of attacks, violations, and triggered signatures across every NGINX Plus instance you have connected to NGINX One Console. + +This document covers what the module is and how data flows through it. For deployment steps, see [Set up security monitoring]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/set-up-security-monitoring.md" >}}). For details on what each dashboard widget shows, see the [dashboard metrics reference]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/dashboard-metrics-reference.md" >}}). + +--- + +## How security events reach the dashboard + +The data pipeline has four stages: + +1. **Detection.** F5 WAF for NGINX inspects requests on the data plane and produces a security log entry whenever a request matches a violation, signature, or threat campaign. +2. **Forwarding.** F5 WAF for NGINX writes the entry over syslog (port `1514` on localhost) using the [`secops_dashboard` log profile]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/default-log-profile.md" >}}). NGINX Agent's OpenTelemetry collector receives it through the `tcplog/nginx_app_protect` receiver. +3. **Transport.** The collector batches events and exports them to NGINX One Console through the `otlp/default` exporter. Batching keeps the upstream call rate low while keeping per-event delivery latency under a minute. +4. **Storage and query.** NGINX One Console parses, indexes, and stores the events. The security dashboard and the analytics API both read from the same store. + +Every event carries the support ID, the policy that matched it, the violation and signature details, and the request context (method, URL, host, client IP, X-Forwarded-For, geolocation). Those fields are what the dashboard groups and filters on. + +--- + +## Data scoping + +Every security event carries enough context to attribute it to a specific data plane, a specific policy, and the application it targeted. + +- **Instance**: Each event records the NGINX instance hostname that produced it. Use this to scope by data plane. +- **Policy**: Each event records the F5 WAF for NGINX policy that produced it, so you can compare activity across policy versions or rollouts — useful for measuring the impact of a policy change before promoting it. +- **Destination hostname**: Each event records the HTTP `Host` header sent by the client — the *application* being attacked, not the instance hostname (which identifies the data plane). Use this when one data plane fronts multiple applications and you need to scope by app rather than by infrastructure. + +--- + +## Retention + +Security events are retained for **90 days**. Queries that reach further back than 90 days return no results. If you need long-term retention, forward events to an external Security Information and Event Management (SIEM) system with a [custom log profile]({{< ref "/nginx-one-console/waf-integration/log-profiles/_index.md" >}}) in addition to the `secops_dashboard` log profile. + +--- + +## Use cases + +### Operator: triage an active attack + +An operator notices a spike in attack volume on the security dashboard. The operator uses the global filters to narrow down to the affected policy and time window, then drills into the top signatures and attacked endpoints to identify which signatures fired and which URLs were targeted. From a single event, the operator pulls the Support ID, the X-Forwarded-For chain, and the raw request to confirm the source and decide whether to tighten the policy. + +### Security engineer: tune a noisy policy + +A security engineer suspects a policy is producing false positives. The engineer opens the security dashboard, filters by policy and blocked requests, and reviews the breakdown of triggered signatures. The high-volume signatures with low risk and accuracy stand out as candidates for tuning. The engineer cross-checks a few events against the raw requests to confirm the signature is firing on legitimate traffic before adjusting the policy. + +### Platform team: report on WAF activity across the fleet + +A platform team needs a weekly summary of WAF activity across hundreds of instances. The team uses the analytics API to pull attack counts, top signatures, and top violations grouped by instance, then renders the result in their own reporting tool. The dashboard remains the interactive surface for ad-hoc investigation; the API is the integration point for automation. + +--- + +## What security monitoring does not cover + +- **Access logs and performance metrics** — security monitoring only ingests F5 WAF for NGINX security events. NGINX access logs and performance telemetry are handled by other parts of NGINX One Console. +- **Policy authoring** — use [WAF policies]({{< ref "/nginx-one-console/waf-integration/policy/_index.md" >}}) to create and deploy F5 WAF for NGINX policies. Security monitoring shows you the effect of those policies, not the policies themselves. +- **Long-term archival** — events expire after 90 days. Forward to an external SIEM if you need longer retention. + +--- + +## References + +For more information, see: + +- [Set up security monitoring]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/set-up-security-monitoring.md" >}}) +- [secops_dashboard log profile]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/default-log-profile.md" >}}) +- [Dashboard metrics reference]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/dashboard-metrics-reference.md" >}}) +- [Find a security event by Support ID]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/find-event-by-support-id.md" >}}) +- [Query security events through the API]({{< ref "/nginx-one-console/api/query-events-api.md" >}}) diff --git a/content/nginx-one-console/waf-integration/waf-security-dashboard/set-up-security-monitoring.md b/content/nginx-one-console/waf-integration/waf-security-dashboard/set-up-security-monitoring.md new file mode 100644 index 0000000000..62ad89a3ab --- /dev/null +++ b/content/nginx-one-console/waf-integration/waf-security-dashboard/set-up-security-monitoring.md @@ -0,0 +1,131 @@ +--- +nd-content-type: how-to +nd-docs: DOCS-000 +nd-product: NONECO +title: Set up security monitoring +description: "Forward F5 WAF for NGINX security events to the NGINX One Console security monitoring dashboard." +weight: 300 +toc: true +nd-keywords: "F5 WAF for NGINX, security monitoring, security dashboard, default log profile, security events" +nd-summary: > + Forward F5 WAF for NGINX security events from an NGINX Plus instance to the NGINX One Console security monitoring dashboard. + You deploy the `secops_dashboard` log profile through the console, add the WAF directives to your NGINX configuration, and verify events flow into the dashboard. + Repeat these steps for each data plane you want to monitor. +nd-audience: operator +--- + +## Overview + +Use this guide to enable F5 WAF for NGINX security monitoring on an NGINX Plus instance that is already connected to NGINX One Console. After completing the steps, security events appear in the [security monitoring dashboard]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/_index.md" >}}), where you can review attacks, violations, and triggered signatures. + +You deploy the [`secops_dashboard` log profile]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/default-log-profile.md" >}}) to the instance through NGINX One Console. You then add the F5 WAF for NGINX directives to the NGINX configuration using the console's config editor, and verify the pipeline by triggering test violations. NGINX Agent automatically configures its OpenTelemetry collector to forward security events to NGINX One Console when it detects the correct directives in the NGINX configuration. You do not need to edit the NGINX Agent configuration by hand. + +--- + +## Before you begin + +Before you begin, ensure you have: + +- **NGINX Plus**: NGINX Plus installed and running on your data plane. See the [NGINX Plus installation guide]({{< ref "/nginx/admin-guide/installing-nginx/installing-nginx-plus.md" >}}). +- **F5 WAF for NGINX installed and loaded**: F5 WAF for NGINX installed on the same host as NGINX Plus, with the `load_module` directive added to `nginx.conf` and `app_protect_enable on;` set in the contexts you want WAF to inspect. See [Install F5 WAF for NGINX]({{< ref "/waf/install/virtual-environment.md" >}}) and [Update configuration files]({{< ref "/waf/install/virtual-environment.md#update-configuration-files" >}}). +- **A WAF policy deployed to the instance**: An F5 WAF for NGINX policy referenced by an `app_protect_policy_file` directive in the same context where you enable WAF. See [WAF policies]({{< ref "/nginx-one-console/waf-integration/policy/_index.md" >}}) for how to create and deploy a policy through NGINX One Console. +- **Instance connected to NGINX One Console**: The data plane is registered with NGINX One Console and NGINX Agent is running on it. See [Add an instance]({{< ref "/nginx-one-console/connect-instances/add-instance.md" >}}). +- **NGINX Agent 3.9.0 or later**: Security event forwarding to NGINX One Console requires NGINX Agent 3.9.0 or later. See the [NGINX Agent install and upgrade guide]({{< ref "/nginx-one-console/agent/install-upgrade/_index.md" >}}) to upgrade an existing agent. + +--- + +## Deploy the `secops_dashboard` log profile + +The security dashboard relies on the `secops_dashboard` log profile to capture security violations in a standardized format. It is created and maintained by F5, immutable, and pre-compiled for every available WAF compiler version, so it deploys exactly the same way as a custom log profile but completes immediately without an on-demand compile. For background, see [secops_dashboard log profile]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/default-log-profile.md" >}}). + +1. In NGINX One Console, go to **WAF** > **Log Profiles** and select **`secops_dashboard`**. + +2. From **Actions**, select **Deploy**. The **Deploy Log Profile** wizard opens. + +3. In the wizard: + + - Confirm `secops_dashboard` is selected under **Log Profile**. + - Under **Target**, choose **Instance** or **Config Sync Group** and select your target. + - In **Log Profile File Path**, specify the path where NGINX One Console should deploy the compiled bundle on the data plane (for example, `/etc/nginx/secops_dashboard.tgz`). + +4. Select **Next**. The wizard displays the F5 WAF for NGINX directive snippet to paste into your NGINX configuration. The wizard also opens the config editor for the target instance. + +5. Open the server block where you want to enable F5 WAF for NGINX (for example, `/etc/nginx/conf.d/default.conf`) and paste the snippet into the `server`, `http`, or `location` context. The snippet looks like this: + + ```nginx + app_protect_security_log_enable on; + app_protect_security_log /etc/nginx/secops_dashboard.tgz syslog:server=127.0.0.1:1514; + ``` + + `app_protect_enable on;` and `app_protect_policy_file` must be present in the same context. These are covered in [Before you begin](#before-you-begin). + +6. Review the configuration diff the console shows for the affected files, then select **Publish**. NGINX One Console pushes the updated configuration to the instance and reloads NGINX. + +For more on the deployment wizard and the alternative **Add File** > **Existing Log Profile** flow, see [Deploy log profiles]({{< ref "/nginx-one-console/waf-integration/log-profiles/deploy-log-profiles.md" >}}). + +--- + +## Verify the setup + +When you select **Publish** in the previous step, NGINX One Console pushes the configuration change to the instance and displays a confirmation message. At that point, the F5 WAF for NGINX policy and the `secops_dashboard` log profile are in place on the data plane, and the security log directive is wired to NGINX Agent. + +Any request that F5 WAF for NGINX inspects on the instance produces a security event that flows to NGINX One Console. To see security events in the dashboard: + +1. In NGINX One Console, go to **WAF** > **Security Dashboard**. +2. As your instance handles traffic, attacks, violations, and triggered signatures appear on the dashboard within about a minute of the request being processed. + +For details on how the dashboard is organized and how to read each widget, see the [security dashboard reference]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/dashboard-metrics-reference.md" >}}). + +--- + +## Troubleshooting + +### Publish fails with a configuration validation error + +**Symptom**: When you select **Publish** in the deployment wizard, NGINX One Console reports a configuration validation error such as `unknown directive "app_protect_enable"`, `unknown directive "app_protect_security_log"`, or a parser error referencing the WAF directives. + +**Cause**: One or more of the F5 WAF for NGINX prerequisites is not in place on the instance — typically the `load_module` line is missing from `nginx.conf`, `app_protect_enable on;` is not set in the context where the security log directive was pasted, or `app_protect_policy_file` references a path the data plane cannot resolve. + +**Fix**: Re-check the items in [Before you begin](#before-you-begin): + +- Confirm `load_module modules/ngx_http_app_protect_module.so;` is present in the main context of `nginx.conf`. See [Update configuration files]({{< ref "/waf/install/virtual-environment.md#update-configuration-files" >}}). +- Confirm `app_protect_enable on;` is set in the same `server`, `http`, or `location` context where you pasted the security log snippet. +- Confirm an `app_protect_policy_file` directive references a policy already deployed to the instance. See [WAF policies]({{< ref "/nginx-one-console/waf-integration/policy/_index.md" >}}). + +Re-run the deployment wizard after fixing the configuration. + +### Publish succeeded but no events appear in the dashboard + +**Symptom**: The publish toast confirmed success, the instance is online in NGINX One Console, but the **WAF > Security Dashboard** shows no events for your instance. + +**Cause**: The most common causes are that NGINX Agent on the instance is older than 3.9.0 and does not include the auto-configured security event pipeline, the `secops_dashboard` log profile is not deployed to that instance, the `app_protect_security_log` directive is in a context that does not handle traffic, or the instance has not yet processed any requests F5 WAF for NGINX would inspect. + +**Fix**: + +1. Confirm NGINX Agent on the instance is **3.9.0 or later**. Earlier 3.x releases publish the configuration successfully but do not forward security events to NGINX One Console. See the [NGINX Agent install and upgrade guide]({{< ref "/nginx-one-console/agent/install-upgrade/_index.md" >}}) to upgrade. +2. Go to **WAF** > **Log Profiles** and confirm `secops_dashboard` is listed as deployed to the target instance under **Deployed To**. +3. Open the instance configuration and confirm the `app_protect_security_log` directive sits in a `server` or `location` block that actually handles request traffic — not in a context the data plane never enters. +4. Confirm the instance is receiving traffic. Until F5 WAF for NGINX inspects a request, the dashboard has nothing to display. +5. Apply a global filter on the dashboard to scope to your instance hostname or policy, in case events are present but hidden by an existing filter. + +If events still do not appear after a request is processed, contact F5 support with the instance hostname and the time window you tested. + +--- + +## References + +**Conceptual background** + +- [Security monitoring overview]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/security-monitoring-overview.md" >}}) + +**Reference** + +- [secops_dashboard log profile]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/default-log-profile.md" >}}) +- [Dashboard metrics reference]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/dashboard-metrics-reference.md" >}}) + +**Related how-to guides** + +- [Deploy log profiles]({{< ref "/nginx-one-console/waf-integration/log-profiles/deploy-log-profiles.md" >}}) +- [Add an instance]({{< ref "/nginx-one-console/connect-instances/add-instance.md" >}}) +- [Find a security event by Support ID]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/find-event-by-support-id.md" >}}) +- [Query security events through the API]({{< ref "/nginx-one-console/api/query-events-api.md" >}}) diff --git a/static/nginx-one-console/api/one.json b/static/nginx-one-console/api/one.json index e9a1c7a9c5..9b77dfb083 100644 --- a/static/nginx-one-console/api/one.json +++ b/static/nginx-one-console/api/one.json @@ -92,6 +92,11 @@ "name": "Templates", "description": "**⚠️ Experimental API** - This API is in active development and subject to breaking changes.\n\n* Import, list, and retrieve NGINX configuration templates.\n* Generate and preview full NGINX configurations by composing templates, before saving it as a staged config.\n", "x-displayName": "Templates" + }, + { + "name": "NGINX One App Protect", + "description": "Security analytics endpoints for NGINX One App Protect.\n", + "x-displayName": "NGINX One App Protect" } ], "paths": { @@ -4405,14 +4410,14 @@ } } }, - "/app-protect/policies": { + "/app-protect/log-profiles": { "get": { "tags": [ - "NGINX App Protect" + "WAF Log Profiles" ], - "summary": "List NGINX App Protect policies", - "description": "Returns a list of NGINX App Protect policies along with deployment details.", - "operationId": "listNapPolicies", + "summary": "List WAF log profiles", + "description": "Returns a list of WAF log profiles.", + "operationId": "listWafLogProfiles", "parameters": [ { "$ref": "#/components/parameters/Paginated" @@ -4427,10 +4432,10 @@ "$ref": "#/components/parameters/SortDirection" }, { - "$ref": "#/components/parameters/SortNameNapPoliciesDep" + "$ref": "#/components/parameters/SortNameNapLogProfilesDep" }, { - "$ref": "#/components/parameters/SortNameNapPolicies" + "$ref": "#/components/parameters/SortNameNapLogProfiles" }, { "$ref": "#/components/parameters/FilterOperands" @@ -4439,78 +4444,16 @@ "$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" - } - } - } + "$ref": "#/components/parameters/FilterFieldNapLogProfile" } - } - }, - "patch": { - "x-nginx-one-action": "bulk", - "x-nginx-one-entity": "NGINX App Protect Policies", - "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.", + "description": "Successfully returned WAF log profiles.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NapBulkResponse" + "$ref": "#/components/schemas/NapLogProfileListResponse" } } } @@ -4538,31 +4481,29 @@ } }, "post": { - "x-nginx-one-action": "create", - "x-nginx-one-entity": "NGINX App Protect Policies", "tags": [ - "NGINX App Protect" + "WAF Log Profiles" ], - "summary": "Create NGINX App Protect policy", - "description": "Creates NGINX App Protect policy.", - "operationId": "createNapPolicy", + "summary": "Create WAF log profile", + "description": "Creates a WAF log profile.", + "operationId": "createWafLogProfile", "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NapPolicy" + "$ref": "#/components/schemas/NapLogProfileCreateRequest" } } } }, "responses": { "201": { - "description": "Successfully created NGINX App Protect policy.", + "description": "Successfully created WAF log profile.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NapPolicyMetadata" + "$ref": "#/components/schemas/NapLogProfileMetadata" } } } @@ -4600,24 +4541,22 @@ } } }, - "/app-protect/policies/{nap_policy_object_id}": { + "/app-protect/log-profiles/{nap_log_profile_object_id}": { "delete": { "tags": [ - "NGINX App Protect" + "WAF Log Profiles" ], - "x-nginx-one-action": "delete", - "x-nginx-one-entity": "NGINX App Protect Policies", - "summary": "Delete NGINX App Protect policy", - "description": "Deletes NGINX App Protect policy.", - "operationId": "deleteNapPolicy", + "summary": "Delete WAF log profile", + "description": "Deletes a WAF log profile.", + "operationId": "deleteWafLogProfile", "parameters": [ { - "$ref": "#/components/parameters/NapPolicyParamObjectID" + "$ref": "#/components/parameters/NapLogProfileParamObjectID" } ], "responses": { "204": { - "description": "Successfully deleted NGINX App Protect policy." + "description": "Successfully deleted WAF log profile." }, "400": { "description": "Request cannot be processed due to invalid input or parameters. Verify the request format and provided data.", @@ -4640,7 +4579,7 @@ } }, "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.", + "description": "The WAF log profile with the specified nap_log_profile_object_id was not found. Check that the nap_log_profile_object_id provided is correct and corresponds to an existing resource.", "content": { "application/json": { "schema": { @@ -4663,23 +4602,23 @@ }, "get": { "tags": [ - "NGINX App Protect" + "WAF Log Profiles" ], - "summary": "Get NGINX App Protect policy details", - "description": "Returns NGINX App Protect policy summary.", - "operationId": "getNapPolicy", + "summary": "Get WAF log profile details", + "description": "Returns WAF log profile details.", + "operationId": "getWafLogProfile", "parameters": [ { - "$ref": "#/components/parameters/NapPolicyParamObjectID" + "$ref": "#/components/parameters/NapLogProfileParamObjectID" } ], "responses": { "200": { - "description": "Successfully returned NGINX App Protect policy details.", + "description": "Successfully returned WAF log profile details.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NapPolicyObject" + "$ref": "#/components/schemas/NapLogProfileObjectDetails" } } } @@ -4705,7 +4644,7 @@ } }, "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.", + "description": "The WAF log profile with the specified nap_log_profile_object_id was not found. Check that the nap_log_profile_object_id provided is correct and corresponds to an existing resource.", "content": { "application/json": { "schema": { @@ -4728,16 +4667,14 @@ }, "put": { "tags": [ - "NGINX App Protect" + "WAF Log Profiles" ], - "x-nginx-one-action": "update", - "x-nginx-one-entity": "NGINX App Protect Policies", - "summary": "Update NGINX App Protect policy details", - "description": "Update NGINX App Protect policy details.", - "operationId": "updateNapPolicy", + "summary": "Update WAF log profile details", + "description": "Updates WAF log profile details.", + "operationId": "updateWafLogProfile", "parameters": [ { - "$ref": "#/components/parameters/NapPolicyParamObjectID" + "$ref": "#/components/parameters/NapLogProfileParamObjectID" } ], "requestBody": { @@ -4745,18 +4682,18 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NapPolicy" + "$ref": "#/components/schemas/NapLogProfileUpdateRequest" } } } }, "responses": { - "201": { - "description": "Successfully created an NGINX App Protect policy version.", + "200": { + "description": "Successfully updated WAF log profile details.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NapPolicyMetadata" + "$ref": "#/components/schemas/NapLogProfileMetadata" } } } @@ -4782,7 +4719,7 @@ } }, "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.", + "description": "The WAF log profile with the specified nap_log_profile_object_id was not found. Check that the nap_log_profile_object_id provided is correct and corresponds to an existing resource.", "content": { "application/json": { "schema": { @@ -4804,17 +4741,95 @@ } } }, - "/app-protect/policies/{nap_policy_object_id}/deployments": { + "/app-protect/log-profiles/{nap_log_profile_object_id}/compile": { "get": { + "x-feature-flag": "log-profile-deployment", "tags": [ - "NGINX App Protect" + "WAF Log Profiles" ], - "summary": "List NGINX App Protect deployments", - "description": "Returns NGINX App Protect deployments, providing details such as:\n * Target of the deployment, either an instance or CSG\n * Time of deployment\n * Enforcement mode\n * Policy version\n * Threat campaign\n * Attack signature\n * Bot signature\n", - "operationId": "listNapPolicyDeployments", + "summary": "Compile WAF log profile", + "description": "Compiles a WAF log profile and returns the request status or compiled bundle.", + "operationId": "compileWafLogProfile", "parameters": [ { - "$ref": "#/components/parameters/NapPolicyParamObjectID" + "$ref": "#/components/parameters/NapCompileNapRelease" + }, + { + "$ref": "#/components/parameters/NapCompileDownload" + }, + { + "$ref": "#/components/parameters/NapLogProfileParamObjectID" + } + ], + "responses": { + "200": { + "description": "WAF log profile compiled successfully, when `download` is `true`.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NapCompileStatus" + } + }, + "application/gzip": { + "schema": { + "type": "string", + "format": "binary", + "example": "log_all.tar.gz" + } + } + } + }, + "202": { + "description": "Accepted the WAF log profile compile request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NapCompileStatus" + } + } + } + }, + "400": { + "description": "WAF log profile compilation failed, when `download` is `true`.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NapCompileStatus" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "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/log-profiles/{nap_log_profile_object_id}/deployments": { + "get": { + "x-feature-flag": "log-profile-deployment", + "tags": [ + "WAF Log Profiles" + ], + "summary": "List WAF log profile deployments", + "description": "Returns a list of WAF log profile deployments, providing details such as:\n * Target of the deployment, either an instance or CSG\n * Time of deployment\n * Deployment status\n", + "operationId": "listWafLogProfileDeployments", + "parameters": [ + { + "$ref": "#/components/parameters/NapLogProfileParamObjectID" }, { "$ref": "#/components/parameters/Paginated" @@ -4829,10 +4844,7 @@ "$ref": "#/components/parameters/SortDirection" }, { - "$ref": "#/components/parameters/SortNameNapPolicyDeploymentsDep" - }, - { - "$ref": "#/components/parameters/SortNameNapPolicyDeployments" + "$ref": "#/components/parameters/SortNameNapLogProfileDeployments" }, { "$ref": "#/components/parameters/FilterOperands" @@ -4841,16 +4853,16 @@ "$ref": "#/components/parameters/FilterValues" }, { - "$ref": "#/components/parameters/FilterFieldNapPolicyDeployment" + "$ref": "#/components/parameters/FilterFieldNapLogProfileDeployment" } ], "responses": { "200": { - "description": "Successfully returned NGINX App Protect deployments.", + "description": "Successfully returned WAF log profile deployments.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NapPolicyDeploymentsListResponse" + "$ref": "#/components/schemas/NapLogProfileDeploymentsListResponse" } } } @@ -4876,7 +4888,7 @@ } }, "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.", + "description": "The WAF log profile with the specified nap_log_profile_object_id was not found. Check that the nap_log_profile_object_id provided is correct and corresponds to an existing resource.", "content": { "application/json": { "schema": { @@ -4898,32 +4910,56 @@ } } }, - "/app-protect/policies/{nap_policy_object_id}/version": { + "/app-protect/policies": { "get": { "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", + "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/NapPolicyParamObjectID" + "$ref": "#/components/parameters/Paginated" + }, + { + "$ref": "#/components/parameters/Limit" + }, + { + "$ref": "#/components/parameters/Offset" + }, + { + "$ref": "#/components/parameters/SortDirection" + }, + { + "$ref": "#/components/parameters/SortNameNapPoliciesDep" + }, + { + "$ref": "#/components/parameters/SortNameNapPolicies" + }, + { + "$ref": "#/components/parameters/FilterOperands" + }, + { + "$ref": "#/components/parameters/FilterValues" + }, + { + "$ref": "#/components/parameters/FilterFieldNapPolicy" } ], "responses": { "200": { - "description": "Successfully returned NGINX App Protect policy version details.", + "description": "Successfully returned NGINX App Protect policies.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NapPolicyVersionDetails" + "$ref": "#/components/schemas/NapPolicyListResponse" } } } }, - "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": { @@ -4932,8 +4968,8 @@ } } }, - "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.", + "401": { + "description": "Access denied.", "content": { "application/json": { "schema": { @@ -4953,61 +4989,39 @@ } } } - } - }, - "/app-protect/policies/{nap_policy_object_id}/versions": { - "get": { + }, + "patch": { + "x-nginx-one-action": "bulk", + "x-nginx-one-entity": "NGINX App Protect Policies", "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/SortNameNapPolicyVersionsDep" - }, - { - "$ref": "#/components/parameters/SortNameNapPolicyVersions" - }, - { - "$ref": "#/components/parameters/FilterOperands" - }, - { - "$ref": "#/components/parameters/FilterValues" - }, - { - "$ref": "#/components/parameters/FilterFieldNapPolicyVersion" + "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": "Successfully returned the NGINX App Protect policy versions.", + "description": "Batch request completed.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NapPolicyVersionsListResponse" + "$ref": "#/components/schemas/NapBulkResponse" } } } }, - "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": { @@ -5016,8 +5030,50 @@ } } }, - "401": { - "description": "Access denied.", + "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-nginx-one-action": "create", + "x-nginx-one-entity": "NGINX App Protect Policies", + "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": { @@ -5026,8 +5082,8 @@ } } }, - "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.", + "401": { + "description": "Access denied.", "content": { "application/json": { "schema": { @@ -5049,27 +5105,34 @@ } } }, - "/app-protect/policies/{nap_policy_object_id}/versions/{nap_policy_version_object_id}": { + "/app-protect/policies/{nap_policy_object_id}": { "delete": { - "x-nginx-one-action": "delete", - "x-nginx-one-entity": "NGINX App Protect Policy Version", "tags": [ "NGINX App Protect" ], - "summary": "Delete NGINX App Protect policy version", - "description": "Deletes the NGINX App Protect policy version.", - "operationId": "deleteNapPolicyVersion", + "x-nginx-one-action": "delete", + "x-nginx-one-entity": "NGINX App Protect Policies", + "summary": "Delete NGINX App Protect policy", + "description": "Deletes NGINX App Protect policy.", + "operationId": "deleteNapPolicy", "parameters": [ { "$ref": "#/components/parameters/NapPolicyParamObjectID" - }, - { - "$ref": "#/components/parameters/NapPolicyVersionParamObjectID" } ], "responses": { "204": { - "description": "Successfully deleted the NGINX App Protect policy version." + "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.", @@ -5082,7 +5145,7 @@ } }, "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.", + "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": { @@ -5107,24 +5170,31 @@ "tags": [ "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", + "summary": "Get NGINX App Protect policy details", + "description": "Returns NGINX App Protect policy summary.", + "operationId": "getNapPolicy", "parameters": [ { "$ref": "#/components/parameters/NapPolicyParamObjectID" - }, - { - "$ref": "#/components/parameters/NapPolicyVersionParamObjectID" } ], "responses": { "200": { - "description": "Successfully returned NGINX App Protect policy version details.", + "description": "Successfully returned NGINX App Protect policy details.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NapPolicyVersionDetails" + "$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" } } } @@ -5140,7 +5210,7 @@ } }, "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.", + "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": { @@ -5160,140 +5230,97 @@ } } } - } - }, - "/app-protect/signature-sets": { - "get": { + }, + "put": { "tags": [ "NGINX App Protect" ], - "summary": "List NGINX App Protect signature sets", - "description": "Returns NGINX App Protect signature sets. Signature sets are predefined or user-defined groups of detection mechanisms (signatures) \nthat identify specific attack types, such as SQL injection, Cross-Site Scripting (XSS), or other web-based threats.\n", - "operationId": "listSignatureSets", + "x-nginx-one-action": "update", + "x-nginx-one-entity": "NGINX App Protect Policies", + "summary": "Update NGINX App Protect policy details", + "description": "Update NGINX App Protect policy details.", + "operationId": "updateNapPolicy", "parameters": [ { - "$ref": "#/components/parameters/Paginated" - }, - { - "$ref": "#/components/parameters/Limit" - }, - { - "$ref": "#/components/parameters/Offset" - }, - { - "$ref": "#/components/parameters/SortDirection" - }, - { - "$ref": "#/components/parameters/SortNameNapSignatureSets" - }, - { - "$ref": "#/components/parameters/FilterOperands" - }, - { - "$ref": "#/components/parameters/FilterValues" - }, - { - "$ref": "#/components/parameters/FilterFieldNapSignatureSets" + "$ref": "#/components/parameters/NapPolicyParamObjectID" } ], - "responses": { - "200": { - "description": "Successfully returned signature sets.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NapSignatureSetListResponse" - } + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NapPolicy" } } - }, - "401": { - "$ref": "#/components/responses/Unauthorized" - }, - "500": { - "$ref": "#/components/responses/InternalServerErr" - } - } - } - }, - "/app-protect/signature-sets/{signatureSetObjectID}": { - "get": { - "tags": [ - "NGINX App Protect" - ], - "summary": "Retrieve a NGINX App Protect signature set", - "description": "Returns a NGINX App Protect signature set. Signature sets are predefined or user-defined groups of detection \nmechanisms (signatures) that identify specific attack types, such as SQL injection, Cross-Site Scripting (XSS), \nor other web-based threats.\n", - "operationId": "getSignatureSet", - "parameters": [ - { - "$ref": "#/components/parameters/NapSignatureSetObjectID" } - ], + }, "responses": { - "200": { - "description": "Successfully returned Signature Sets.", + "201": { + "description": "Successfully created an NGINX App Protect policy version.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NapSignatureSet" + "$ref": "#/components/schemas/NapPolicyMetadata" } } } }, - "401": { - "$ref": "#/components/responses/Unauthorized" - }, - "500": { - "$ref": "#/components/responses/InternalServerErr" - } - } - } - }, - "/app-protect/signature-sets/{signatureSetObjectID}/signatures": { - "get": { - "tags": [ - "NGINX App Protect" - ], - "summary": "List NGINX App Protect signatures in the specified signature set.", - "description": "Returns a list of signatures in the NGINX App Protect signature set.\n", - "operationId": "listSignatureSetSignatures", - "parameters": [ - { - "$ref": "#/components/parameters/NapSignatureSetObjectID" - } - ], - "responses": { - "200": { - "description": "Successfully returned signatures for signature set.", + "400": { + "description": "Request cannot be processed due to invalid input or parameters. Verify the request format and provided data.", "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/NapSignatureMeta" - } + "$ref": "#/components/schemas/Error" } } } }, "401": { - "$ref": "#/components/responses/Unauthorized" + "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": { - "$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" + } + } + } } } } }, - "/app-protect/signatures": { + "/app-protect/policies/{nap_policy_object_id}/deployments": { "get": { "tags": [ "NGINX App Protect" ], - "summary": "List Signatures", - "description": "Returns signatures. A signature is a predefined detection rule that identifies specific attack patterns or\ncharacteristics commonly associated with web application security threats.\n", - "operationId": "listSignatures", + "summary": "List NGINX App Protect deployments", + "description": "Returns NGINX App Protect deployments, providing details such as:\n * Target of the deployment, either an instance or CSG\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" }, @@ -5307,7 +5334,10 @@ "$ref": "#/components/parameters/SortDirection" }, { - "$ref": "#/components/parameters/SortNameNapSignatures" + "$ref": "#/components/parameters/SortNameNapPolicyDeploymentsDep" + }, + { + "$ref": "#/components/parameters/SortNameNapPolicyDeployments" }, { "$ref": "#/components/parameters/FilterOperands" @@ -5316,71 +5346,132 @@ "$ref": "#/components/parameters/FilterValues" }, { - "$ref": "#/components/parameters/FilterFieldNapSignatures" + "$ref": "#/components/parameters/FilterFieldNapPolicyDeployment" } ], "responses": { "200": { - "description": "Successfully returned list of signatures.", + "description": "Successfully returned NGINX App Protect deployments.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NapSignatureListResponse" + "$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": { - "$ref": "#/components/responses/Unauthorized" + "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": { - "$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" + } + } + } } } } }, - "/app-protect/signatures/{signatureID}": { + "/app-protect/policies/{nap_policy_object_id}/version": { "get": { "tags": [ "NGINX App Protect" ], - "summary": "Retrieve a NGINX App Protect signature.", - "description": "A signature is a predefined detection rule that identifies specific attack patterns or characteristics commonly \nassociated with web application security threats.\n", + "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/NapSignatureID" + "$ref": "#/components/parameters/NapPolicyParamObjectID" } ], - "operationId": "getSignature", "responses": { "200": { - "description": "Successfully returned the specified signature.", + "description": "Successfully returned NGINX App Protect policy version details.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NapSignature" + "$ref": "#/components/schemas/NapPolicyVersionDetails" } } } }, "401": { - "$ref": "#/components/responses/Unauthorized" + "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": { - "$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" + } + } + } } } } }, - "/app-protect/log-profiles": { + "/app-protect/policies/{nap_policy_object_id}/versions": { "get": { "tags": [ - "WAF Log Profiles" + "NGINX App Protect" ], - "summary": "List WAF log profiles", - "description": "Returns a list of WAF log profiles.", - "operationId": "listWafLogProfiles", + "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" }, @@ -5394,10 +5485,10 @@ "$ref": "#/components/parameters/SortDirection" }, { - "$ref": "#/components/parameters/SortNameNapLogProfilesDep" + "$ref": "#/components/parameters/SortNameNapPolicyVersionsDep" }, { - "$ref": "#/components/parameters/SortNameNapLogProfiles" + "$ref": "#/components/parameters/SortNameNapPolicyVersions" }, { "$ref": "#/components/parameters/FilterOperands" @@ -5406,16 +5497,26 @@ "$ref": "#/components/parameters/FilterValues" }, { - "$ref": "#/components/parameters/FilterFieldNapLogProfile" + "$ref": "#/components/parameters/FilterFieldNapPolicyVersion" } ], "responses": { "200": { - "description": "Successfully returned WAF log profiles.", + "description": "Successfully returned the NGINX App Protect policy versions.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NapLogProfileListResponse" + "$ref": "#/components/schemas/NapPolicyVersionsListResponse" + } + } + } + }, + "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" } } } @@ -5430,6 +5531,16 @@ } } }, + "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": { @@ -5441,37 +5552,32 @@ } } } - }, - "post": { + } + }, + "/app-protect/policies/{nap_policy_object_id}/versions/{nap_policy_version_object_id}": { + "delete": { + "x-nginx-one-action": "delete", + "x-nginx-one-entity": "NGINX App Protect Policy Version", "tags": [ - "WAF Log Profiles" + "NGINX App Protect" ], - "summary": "Create WAF log profile", - "description": "Creates a WAF log profile.", - "operationId": "createWafLogProfile", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NapLogProfileCreateRequest" - } - } + "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": { - "201": { - "description": "Successfully created WAF log profile.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NapLogProfileMetadata" - } - } - } + "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": { @@ -5480,8 +5586,8 @@ } } }, - "401": { - "description": "Access denied.", + "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": { @@ -5501,31 +5607,29 @@ } } } - } - }, - "/app-protect/log-profiles/{nap_log_profile_object_id}": { - "delete": { + }, + "get": { "tags": [ - "WAF Log Profiles" + "NGINX App Protect" ], - "summary": "Delete WAF log profile", - "description": "Deletes a WAF log profile.", - "operationId": "deleteWafLogProfile", + "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/NapLogProfileParamObjectID" + "$ref": "#/components/parameters/NapPolicyParamObjectID" + }, + { + "$ref": "#/components/parameters/NapPolicyVersionParamObjectID" } ], "responses": { - "204": { - "description": "Successfully deleted WAF log profile." - }, - "400": { - "description": "Request cannot be processed due to invalid input or parameters. Verify the request format and provided data.", + "200": { + "description": "Successfully returned NGINX App Protect policy version details.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Error" + "$ref": "#/components/schemas/NapPolicyVersionDetails" } } } @@ -5541,7 +5645,7 @@ } }, "404": { - "description": "The WAF log profile with the specified nap_log_profile_object_id was not found. Check that the nap_log_profile_object_id 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": { @@ -5561,238 +5665,140 @@ } } } - }, + } + }, + "/app-protect/signature-sets": { "get": { "tags": [ - "WAF Log Profiles" + "NGINX App Protect" ], - "summary": "Get WAF log profile details", - "description": "Returns WAF log profile details.", - "operationId": "getWafLogProfile", + "summary": "List NGINX App Protect signature sets", + "description": "Returns NGINX App Protect signature sets. Signature sets are predefined or user-defined groups of detection mechanisms (signatures) \nthat identify specific attack types, such as SQL injection, Cross-Site Scripting (XSS), or other web-based threats.\n", + "operationId": "listSignatureSets", "parameters": [ { - "$ref": "#/components/parameters/NapLogProfileParamObjectID" + "$ref": "#/components/parameters/Paginated" + }, + { + "$ref": "#/components/parameters/Limit" + }, + { + "$ref": "#/components/parameters/Offset" + }, + { + "$ref": "#/components/parameters/SortDirection" + }, + { + "$ref": "#/components/parameters/SortNameNapSignatureSets" + }, + { + "$ref": "#/components/parameters/FilterOperands" + }, + { + "$ref": "#/components/parameters/FilterValues" + }, + { + "$ref": "#/components/parameters/FilterFieldNapSignatureSets" } ], "responses": { "200": { - "description": "Successfully returned WAF log profile details.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NapLogProfileObjectDetails" - } - } - } - }, - "400": { - "description": "Request cannot be processed due to invalid input or parameters. Verify the request format and provided data.", + "description": "Successfully returned signature sets.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Error" + "$ref": "#/components/schemas/NapSignatureSetListResponse" } } } }, "401": { - "description": "Access denied.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "404": { - "description": "The WAF log profile with the specified nap_log_profile_object_id was not found. Check that the nap_log_profile_object_id provided is correct and corresponds to an existing resource.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } + "$ref": "#/components/responses/Unauthorized" }, "500": { - "description": "An unexpected error occurred on the server. Please try the request again later.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } + "$ref": "#/components/responses/InternalServerErr" } } - }, - "put": { + } + }, + "/app-protect/signature-sets/{signatureSetObjectID}": { + "get": { "tags": [ - "WAF Log Profiles" + "NGINX App Protect" ], - "summary": "Update WAF log profile details", - "description": "Updates WAF log profile details.", - "operationId": "updateWafLogProfile", + "summary": "Retrieve a NGINX App Protect signature set", + "description": "Returns a NGINX App Protect signature set. Signature sets are predefined or user-defined groups of detection \nmechanisms (signatures) that identify specific attack types, such as SQL injection, Cross-Site Scripting (XSS), \nor other web-based threats.\n", + "operationId": "getSignatureSet", "parameters": [ { - "$ref": "#/components/parameters/NapLogProfileParamObjectID" + "$ref": "#/components/parameters/NapSignatureSetObjectID" } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NapLogProfileUpdateRequest" - } - } - } - }, "responses": { "200": { - "description": "Successfully updated WAF log profile details.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NapLogProfileMetadata" - } - } - } - }, - "400": { - "description": "Request cannot be processed due to invalid input or parameters. Verify the request format and provided data.", + "description": "Successfully returned Signature Sets.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Error" + "$ref": "#/components/schemas/NapSignatureSet" } } } }, "401": { - "description": "Access denied.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "404": { - "description": "The WAF log profile with the specified nap_log_profile_object_id was not found. Check that the nap_log_profile_object_id provided is correct and corresponds to an existing resource.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } + "$ref": "#/components/responses/Unauthorized" }, "500": { - "description": "An unexpected error occurred on the server. Please try the request again later.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } + "$ref": "#/components/responses/InternalServerErr" } } } }, - "/app-protect/log-profiles/{nap_log_profile_object_id}/compile": { + "/app-protect/signature-sets/{signatureSetObjectID}/signatures": { "get": { - "x-feature-flag": "log-profile-deployment", "tags": [ - "WAF Log Profiles" + "NGINX App Protect" ], - "summary": "Compile WAF log profile", - "description": "Compiles a WAF log profile and returns the request status or compiled bundle.", - "operationId": "compileWafLogProfile", + "summary": "List NGINX App Protect signatures in the specified signature set.", + "description": "Returns a list of signatures in the NGINX App Protect signature set.\n", + "operationId": "listSignatureSetSignatures", "parameters": [ { - "$ref": "#/components/parameters/NapLogProfileCompileNapRelease" - }, - { - "$ref": "#/components/parameters/NapLogProfileCompileDownload" - }, - { - "$ref": "#/components/parameters/NapLogProfileParamObjectID" + "$ref": "#/components/parameters/NapSignatureSetObjectID" } ], "responses": { "200": { - "description": "WAF log profile compiled successfully, when `download` is `true`.", + "description": "Successfully returned signatures for signature set.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NapCompileStatus" - } - }, - "application/gzip": { - "schema": { - "type": "string", - "format": "binary", - "example": "log_all.tar.gz" + "type": "array", + "items": { + "$ref": "#/components/schemas/NapSignatureMeta" + } } } } }, - "202": { - "description": "Accepted the WAF log profile compile request.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NapCompileStatus" - } - } - } - }, - "400": { - "description": "WAF log profile compilation failed, when `download` is `true`.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NapCompileStatus" - } - } - } - }, - "401": { - "$ref": "#/components/responses/Unauthorized" - }, - "404": { - "$ref": "#/components/responses/NotFound" + "401": { + "$ref": "#/components/responses/Unauthorized" }, "500": { - "description": "An unexpected error occurred on the server. Please try the request again later.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } + "$ref": "#/components/responses/InternalServerErr" } } } }, - "/app-protect/log-profiles/{nap_log_profile_object_id}/deployments": { + "/app-protect/signatures": { "get": { - "x-feature-flag": "log-profile-deployment", "tags": [ - "WAF Log Profiles" + "NGINX App Protect" ], - "summary": "List WAF log profile deployments", - "description": "Returns a list of WAF log profile deployments, providing details such as:\n * Target of the deployment, either an instance or CSG\n * Time of deployment\n * Deployment status\n", - "operationId": "listWafLogProfileDeployments", + "summary": "List Signatures", + "description": "Returns signatures. A signature is a predefined detection rule that identifies specific attack patterns or\ncharacteristics commonly associated with web application security threats.\n", + "operationId": "listSignatures", "parameters": [ - { - "$ref": "#/components/parameters/NapLogProfileParamObjectID" - }, { "$ref": "#/components/parameters/Paginated" }, @@ -5806,7 +5812,7 @@ "$ref": "#/components/parameters/SortDirection" }, { - "$ref": "#/components/parameters/SortNameNapLogProfileDeployments" + "$ref": "#/components/parameters/SortNameNapSignatures" }, { "$ref": "#/components/parameters/FilterOperands" @@ -5815,59 +5821,58 @@ "$ref": "#/components/parameters/FilterValues" }, { - "$ref": "#/components/parameters/FilterFieldNapLogProfileDeployment" + "$ref": "#/components/parameters/FilterFieldNapSignatures" } ], "responses": { "200": { - "description": "Successfully returned WAF log profile deployments.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NapLogProfileDeploymentsListResponse" - } - } - } - }, - "400": { - "description": "Request cannot be processed due to invalid input or parameters. Verify the request format and provided data.", + "description": "Successfully returned list of signatures.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Error" + "$ref": "#/components/schemas/NapSignatureListResponse" } } } }, "401": { - "description": "Access denied.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } + "$ref": "#/components/responses/Unauthorized" }, - "404": { - "description": "The WAF log profile with the specified nap_log_profile_object_id was not found. Check that the nap_log_profile_object_id provided is correct and corresponds to an existing resource.", + "500": { + "$ref": "#/components/responses/InternalServerErr" + } + } + } + }, + "/app-protect/signatures/{signatureID}": { + "get": { + "tags": [ + "NGINX App Protect" + ], + "summary": "Retrieve a NGINX App Protect signature.", + "description": "A signature is a predefined detection rule that identifies specific attack patterns or characteristics commonly \nassociated with web application security threats.\n", + "parameters": [ + { + "$ref": "#/components/parameters/NapSignatureID" + } + ], + "operationId": "getSignature", + "responses": { + "200": { + "description": "Successfully returned the specified signature.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Error" + "$ref": "#/components/schemas/NapSignature" } } } }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, "500": { - "description": "An unexpected error occurred on the server. Please try the request again later.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } + "$ref": "#/components/responses/InternalServerErr" } } } @@ -6012,6 +6017,11 @@ } } }, + "/templates/{templateObjectID}/copy": {}, + "/templates/{templateObjectID}/submissions": {}, + "/templates/{templateObjectID}/versions": {}, + "/templates/{templateObjectID}/versions/{templateVersionObjectID}": {}, + "/templates/{templateVersionObjectID}/config": {}, "/templates/import": { "post": { "tags": [ @@ -6074,7 +6084,7 @@ "Templates" ], "summary": "Submit templates for previewing NGINX configuration.", - "description": "Submits a set of templates for rendering NGINX configuration.\n\nThe `preview_only` query parameter controls how the request is processed:\n - When `preview_only` is `true`, the API validates template parameters and renders the full NGINX configuration for preview **without creating a template submission object**. (**Currently, only this mode is supported.**)\n - When `preview_only` is `false` or omitted, the API is intended to render and create a submission. This feature is **not supported yet**.\n\n**Note:** Currently, only preview mode is implemented. Submission creation will be supported in a future release.\n", + "description": "Submits a set of templates for rendering NGINX configuration.\n\nThe `preview_only` query parameter controls how the request is processed:\n - When `preview_only` is `true`, the API validates template parameters and renders the full NGINX configuration for preview **without creating a template submission object**. (**Currently, only this mode is supported.**)\n - When `preview_only` is `false` or omitted, the API is intended to render and create a submission. \n - If no target object ID is provided, a new staged config will be created.\n", "parameters": [ { "$ref": "#/components/parameters/TemplateSubmissionPreviewOnly" @@ -6087,13 +6097,24 @@ "application/json": { "schema": { "$ref": "#/components/schemas/TemplateSubmissionRequest" + }, + "examples": { + "SubmissionWithPreviewOnly": { + "$ref": "#/components/examples/SubmissionWithPreviewOnly" + }, + "SubmissionForCreateNewStagedConfig": { + "$ref": "#/components/examples/SubmissionForCreateNewStagedConfig" + }, + "SubmissionForUpdateExistingStagedConfigTarget": { + "$ref": "#/components/examples/SubmissionForUpdateExistingStagedConfigTarget" + } } } } }, "responses": { "200": { - "description": "Returned only when the `preview_only` flag is set to `true`.\nResponds with the rendered NGINX configuration that can be used for preview or to create/replace a staged configuration manually.\n\nNote: If `preview_only` is `false` or omitted, this operation is not yet supported and will return an error instead.\n", + "description": "Returned only when the `preview_only` flag is set to `true`.\nResponds with the rendered NGINX configuration that can be used for preview or to create/replace a staged configuration manually.\n", "content": { "application/json": { "schema": { @@ -6102,14 +6123,40 @@ } } }, + "202": { + "description": "The template submission has been accepted and is being processed.\nPublication status(es) can be retrieved by querying the appropriate publications endpoint for the target object.\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TemplateSubmissionResponse" + }, + "examples": { + "staged_config_outcome": { + "summary": "Example successful response for a target submission that creates a staged config", + "value": { + "object_id": "tmplsm_frBobKIAQ_21grAwV83VYz", + "target_results": [ + { + "staged_config_status": { + "status": "succeeded" + }, + "target_object_id": "sc_cEoiYCVJRuekVpYOvV1raA" + } + ] + } + } + } + } + } + }, "400": { "$ref": "#/components/responses/InvalidRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, - "405": { - "description": "This operation is not yet implemented. Please use the action for preview (`action=preview`) or partial (`action=partial`).\n", + "409": { + "description": "The submission cannot be completed due to one or more template validation errors. See the error details for more information.\n", "content": { "application/json": { "schema": { @@ -6123,67 +6170,1632 @@ } } } - } - }, - "components": { - "parameters": { - "Paginated": { - "name": "paginated", - "in": "query", - "schema": { - "type": "boolean", - "default": true - }, - "description": "A boolean indicating if the results should be presented as a paginated list. Defaults to `true`. \nWhen set to `false` a maximum of 3000 results are returned.\n", - "required": false - }, - "Limit": { - "name": "limit", - "in": "query", - "schema": { - "type": "integer", - "minimum": 0 - }, - "description": "An integer that specifies the maximum number of items to be returned. \nSetting this to `0` will result in no items being returned, but a total count will still be provided. \nThis parameter is not applicable if `paginated` is `false`.\n", - "required": false - }, - "Offset": { - "name": "offset", - "in": "query", - "schema": { - "type": "integer", - "minimum": 1 + }, + "/app-protect/analytics/attacks": { + "post": { + "tags": [ + "NGINX One App Protect" + ], + "summary": "Query attack analytics", + "operationId": "queryAttackAnalytics", + "description": "Returns attack analytics with optional dimensional breakdown.\n\n**Response behavior:**\n- Without `group_by`: Returns `total` count for the time range\n- With `group_by`: Returns breakdown for that dimension, `total` is omitted\n\n**Response structure by dimension type:**\n- **Fixed enum dimensions** (`request_status`, `request_method`): Returns object with known keys and counts\n- **Dynamic dimensions** (`ip`, `country`, `policy`, `url`, etc.): Returns array of items with cross-dimension context in `distinct` object\n\n**Filter behavior:**\n- All filters are combined with AND logic\n- Use the `in` operator to achieve OR within a single dimension\n", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AttacksQueryRequest" + }, + "examples": { + "total_only": { + "summary": "Get total attack count (no group_by)", + "value": { + "start_time": "now-24h" + } + }, + "by_request_status": { + "summary": "Get breakdown by request status", + "value": { + "start_time": "now-24h", + "group_by": "request_status" + } + }, + "by_request_outcome_reason": { + "summary": "Get breakdown by request outcome reason", + "value": { + "start_time": "now-24h", + "group_by": "request_outcome_reason" + } + }, + "top_ips": { + "summary": "Top 10 attacking IPs", + "value": { + "start_time": "now-24h", + "group_by": "ip", + "limit": 10 + } + }, + "filtered_top_ips": { + "summary": "Top 10 attacking IPs for blocked requests", + "value": { + "start_time": "now-24h", + "group_by": "ip", + "filter": [ + { + "field": "request_status", + "operator": "=", + "values": [ + "blocked" + ] + } + ], + "order_by": { + "field": "count", + "direction": "desc" + }, + "limit": 10 + } + } + } + } + } }, - "description": "An integer that specifies the starting position of the results, starting at `1`.\nThis parameter is not applicable if `paginated` is `false`.\n" - }, - "FilterFieldDataPlaneKeys": { - "name": "filter_fields", - "in": "query", - "description": "Filter options for data plane keys; used in conjunction with other filter parameters having the same array length.\n\nWhen filtering on `status`, only the following `filter_values` are supported:\n * revoked\n * expired\n * valid\n", - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/FilterNameDataPlaneKeys" + "responses": { + "200": { + "description": "Successfully returned attack analytics.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AttacksQueryResponse" + }, + "examples": { + "without_group_by": { + "summary": "Without group_by - returns total and threat_campaigns", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T23:59:59Z" + }, + "total": 1500, + "threat_campaigns": 3 + } + }, + "by_request_status": { + "summary": "With group_by=request_status (fixed enum)", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T23:59:59Z" + }, + "request_status": { + "blocked": 1200, + "alerted": 200, + "passed": 100 + } + } + }, + "by_request_outcome_reason": { + "summary": "With group_by=request_outcome_reason (fixed enum)", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T23:59:59Z" + }, + "request_outcome_reason": { + "SECURITY_NGINX_VIOLATION": 121, + "SECURITY_WAF_BYPASS": 100, + "SECURITY_WAF_FLAGGED": 200, + "SECURITY_WAF_OK": 0, + "SECURITY_WAF_VIOLATION": 88, + "SECURITY_WAF_VIOLATION_TRANSPARENT": 0 + } + } + }, + "by_ip": { + "summary": "With group_by=ip (dynamic dimension with distinct counts)", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T23:59:59Z" + }, + "ip": [ + { + "value": "203.0.113.42", + "count": 450, + "distinct": { + "ips": 1, + "urls": 3, + "violations": 5, + "policies": 1 + }, + "country": "CN" + }, + { + "value": "198.51.100.7", + "count": 320, + "distinct": { + "ips": 1, + "urls": 2, + "violations": 3, + "policies": 1 + }, + "country": "RU" + } + ] + } + }, + "by_country": { + "summary": "With group_by=country (dynamic dimension)", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T23:59:59Z" + }, + "country": [ + { + "value": "CN", + "count": 500, + "distinct": { + "ips": 15, + "urls": 8, + "violations": 12, + "policies": 3 + } + }, + { + "value": "RU", + "count": 300, + "distinct": { + "ips": 8, + "urls": 5, + "violations": 7, + "policies": 2 + } + } + ] + } + }, + "by_policy": { + "summary": "With group_by=policy (Top WAF Policies)", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T23:59:59Z" + }, + "policy": [ + { + "value": "strict-policy", + "count": 850, + "distinct": { + "ips": 42, + "urls": 15, + "violations": 18, + "policies": 1 + } + }, + { + "value": "default-policy", + "count": 450, + "distinct": { + "ips": 28, + "urls": 10, + "violations": 12, + "policies": 1 + } + } + ] + } + }, + "by_request_method": { + "summary": "With group_by=request_method (Request Methods)", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T23:59:59Z" + }, + "request_method": { + "get": 800, + "post": 500, + "put": 50, + "delete": 20 + } + } + }, + "by_response_code": { + "summary": "With group_by=response_code (simple array)", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T23:59:59Z" + }, + "response_code": [ + { + "code": "403", + "count": 450 + }, + { + "code": "200", + "count": 320 + }, + { + "code": "500", + "count": 80 + } + ] + } + }, + "by_url": { + "summary": "With group_by=url (Top Attack URIs)", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T23:59:59Z" + }, + "url": [ + { + "value": "/api/login", + "count": 320, + "distinct": { + "ips": 15, + "urls": 1, + "violations": 8, + "policies": 2 + } + }, + { + "value": "/admin", + "count": 180, + "distinct": { + "ips": 8, + "urls": 1, + "violations": 5, + "policies": 1 + } + } + ] + } + }, + "by_hostname": { + "summary": "With group_by=hostname", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T23:59:59Z" + }, + "hostname": [ + { + "value": "nginx-host-01.example.com", + "count": 854, + "distinct": { + "ips": 543, + "urls": 768, + "violations": 312, + "policies": 816 + } + }, + { + "value": "nginx-host-02.example.com", + "count": 96, + "distinct": { + "ips": 753, + "urls": 351, + "violations": 232, + "policies": 96 + } + } + ] + } + }, + "by_threat_campaign": { + "summary": "With group_by=threat_campaign", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T23:59:59Z" + }, + "threat_campaign": [ + { + "value": "CVE-2021-44228", + "count": 1240, + "distinct": { + "ips": 34, + "urls": 12, + "violations": 8, + "policies": 3 + } + }, + { + "value": "Log4Shell", + "count": 870, + "distinct": { + "ips": 21, + "urls": 7, + "violations": 5, + "policies": 2 + } + } + ] + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/InvalidRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "500": { + "$ref": "#/components/responses/InternalServerErr" } } - }, - "FilterOperands": { - "name": "filter_ops", - "in": "query", - "description": "An array of strings defining the operands for filtering, to be used in conjunction with `filter_fields` and `filter_values`. \nAll filter parameters must have matching array lengths. Currently, the only supported operand is `\"IN\"`.\n", - "schema": { - "$ref": "#/components/schemas/FilterOperands" - } - }, - "FilterValues": { - "name": "filter_values", - "in": "query", - "description": "An array of strings containing the keywords for filtering. \nMultiple keywords can be chained using the `|` character. \nEnsure this parameter's array length matches those of `filter_fields` and `filter_ops` for effective filtering.\nThe total length of the filter string should not exceed 1024 characters.\n", - "schema": { - "type": "array", - "items": { - "type": "string", - "example": "value1|value2|value3", + } + }, + "/app-protect/analytics/attacks/time-series": { + "post": { + "tags": [ + "NGINX One App Protect" + ], + "summary": "Query attack analytics time series", + "operationId": "queryAttackAnalyticsTimeSeries", + "description": "Returns attack analytics as time-series data for charting.\n\n**Response behavior:**\n- Without `group_by`: Returns `total` series (aggregate counts over time)\n- With `group_by`: Returns dimensional breakdown series, `total` is omitted\n\nData is returned with each dimension value as a separate series array,\nmaking it easy to plot directly. The bucket size is determined by the\n`resolution` field or auto-selected based on the time range.\n\n**Supported dimensions for time-series:**\n- `request_status` - Returns `blocked`, `alerted`, `passed` series\n\n**Time alignment:** All series arrays contain the same timestamps, aligned to the\nresolution boundary. Buckets with no events are zero-filled.\n\n**Filter behavior:**\n- All filters are combined with AND logic\n- Use the `in` operator to achieve OR within a single dimension\n", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AttacksTimeSeriesQueryRequest" + }, + "examples": { + "total_over_time": { + "summary": "Total attacks over time (no group_by)", + "value": { + "start_time": "now-6h", + "resolution": "15m" + } + }, + "by_request_status": { + "summary": "Breakdown by request status", + "value": { + "start_time": "now-6h", + "resolution": "15m", + "group_by": "request_status" + } + }, + "by_request_outcome_reason": { + "summary": "Breakdown by request outcome reason", + "value": { + "start_time": "now-6h", + "resolution": "15m", + "group_by": "request_outcome_reason" + } + }, + "filtered_blocked": { + "summary": "Blocked attacks only (filtered, no breakdown)", + "value": { + "start_time": "now-6h", + "resolution": "15m", + "filter": [ + { + "field": "request_status", + "operator": "=", + "values": [ + "blocked" + ] + } + ] + } + }, + "filtered_reason_transparent": { + "summary": "Attacks with transparent reason only", + "value": { + "start_time": "now-6h", + "resolution": "15m", + "filter": [ + { + "field": "request_outcome_reason", + "operator": "=", + "values": [ + "SECURITY_WAF_VIOLATION_TRANSPARENT" + ] + } + ] + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Successfully returned attack analytics time series.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AttacksTimeSeriesQueryResponse" + }, + "examples": { + "without_group_by": { + "summary": "Without group_by - returns total series only", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T06:00:00Z", + "resolution": "1h" + }, + "total": [ + { + "timestamp": "2024-01-15T00:00:00Z", + "count": 150 + }, + { + "timestamp": "2024-01-15T01:00:00Z", + "count": 180 + }, + { + "timestamp": "2024-01-15T02:00:00Z", + "count": 95 + }, + { + "timestamp": "2024-01-15T03:00:00Z", + "count": 210 + }, + { + "timestamp": "2024-01-15T04:00:00Z", + "count": 175 + }, + { + "timestamp": "2024-01-15T05:00:00Z", + "count": 130 + } + ] + } + }, + "with_group_by": { + "summary": "With group_by=request_status - returns dimensional breakdown", + "description": "All series have aligned timestamps. Note the zero-filled bucket at 02:00\nfor `passed` where no events occurred.\n", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T03:00:00Z", + "resolution": "1h" + }, + "request_status": { + "blocked": [ + { + "timestamp": "2024-01-15T00:00:00Z", + "count": 120 + }, + { + "timestamp": "2024-01-15T01:00:00Z", + "count": 150 + }, + { + "timestamp": "2024-01-15T02:00:00Z", + "count": 80 + } + ], + "passed": [ + { + "timestamp": "2024-01-15T00:00:00Z", + "count": 10 + }, + { + "timestamp": "2024-01-15T01:00:00Z", + "count": 15 + }, + { + "timestamp": "2024-01-15T02:00:00Z", + "count": 0 + } + ], + "alerted": [ + { + "timestamp": "2024-01-15T00:00:00Z", + "count": 20 + }, + { + "timestamp": "2024-01-15T01:00:00Z", + "count": 15 + }, + { + "timestamp": "2024-01-15T02:00:00Z", + "count": 10 + } + ] + } + } + }, + "no_data": { + "summary": "No data in time range - returns zero-filled buckets", + "description": "When no attacks occurred in the queried time range, time buckets are still\ngenerated based on the resolution with count as 0.\n", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T03:00:00Z", + "resolution": "1h" + }, + "total": [ + { + "timestamp": "2024-01-15T00:00:00Z", + "count": 0 + }, + { + "timestamp": "2024-01-15T01:00:00Z", + "count": 0 + }, + { + "timestamp": "2024-01-15T02:00:00Z", + "count": 0 + } + ] + } + }, + "no_data_with_group_by": { + "summary": "No data with group_by - returns zero-filled series for each dimension", + "description": "All dimension values have aligned timestamps with count: 0.\nThis ensures charts can render empty series correctly.\n", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T03:00:00Z", + "resolution": "1h" + }, + "request_status": { + "blocked": [ + { + "timestamp": "2024-01-15T00:00:00Z", + "count": 0 + }, + { + "timestamp": "2024-01-15T01:00:00Z", + "count": 0 + }, + { + "timestamp": "2024-01-15T02:00:00Z", + "count": 0 + } + ], + "alerted": [ + { + "timestamp": "2024-01-15T00:00:00Z", + "count": 0 + }, + { + "timestamp": "2024-01-15T01:00:00Z", + "count": 0 + }, + { + "timestamp": "2024-01-15T02:00:00Z", + "count": 0 + } + ], + "passed": [ + { + "timestamp": "2024-01-15T00:00:00Z", + "count": 0 + }, + { + "timestamp": "2024-01-15T01:00:00Z", + "count": 0 + }, + { + "timestamp": "2024-01-15T02:00:00Z", + "count": 0 + } + ] + } + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/InvalidRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "500": { + "$ref": "#/components/responses/InternalServerErr" + } + } + } + }, + "/app-protect/analytics/signatures": { + "post": { + "tags": [ + "NGINX One App Protect" + ], + "summary": "Query signature analytics", + "operationId": "querySignatureAnalytics", + "description": "Returns signature analytics with optional dimensional breakdown.\n\n**Response behavior:**\n- Without `group_by`: Returns `total` (signature hits) and `unique` (distinct signatures) for the time range\n- With `group_by`: Returns breakdown for that dimension, `total` and `unique` are omitted\n\n**Response structure by dimension type:**\n- **Fixed enum dimensions** (`request_status`, `accuracy`, `risk`): Returns object with known keys and counts\n- **Dynamic dimensions** (`signature`, `cve`): Returns array of items sorted by count descending\n\n**Filter behavior:**\n- All filters are combined with AND logic\n- Use the `in` operator to achieve OR within a single dimension\n", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SignaturesQueryRequest" + }, + "examples": { + "total_only": { + "summary": "Get total signature hits and unique count (no group_by)", + "value": { + "start_time": "now-24h" + } + }, + "by_request_status": { + "summary": "Signature hits by request status", + "value": { + "start_time": "now-24h", + "group_by": "request_status" + } + }, + "by_accuracy": { + "summary": "Signature hits by accuracy level", + "value": { + "start_time": "now-24h", + "group_by": "accuracy" + } + }, + "by_risk": { + "summary": "Signature hits by risk level", + "value": { + "start_time": "now-24h", + "group_by": "risk" + } + }, + "top_signatures": { + "summary": "Top 5 signatures by hit count", + "value": { + "start_time": "now-24h", + "group_by": "signature", + "limit": 5 + } + }, + "top_cves": { + "summary": "Top 5 CVEs by hit count", + "value": { + "start_time": "now-24h", + "group_by": "cve", + "limit": 5 + } + }, + "filtered_blocked_signatures": { + "summary": "Top signatures for blocked requests only", + "value": { + "start_time": "now-24h", + "group_by": "signature", + "filter": [ + { + "field": "request_status", + "operator": "=", + "values": [ + "blocked" + ] + } + ], + "limit": 10 + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Successfully returned signature analytics.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SignaturesQueryResponse" + }, + "examples": { + "without_group_by": { + "summary": "Without group_by - returns total and unique only", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T06:00:00Z" + }, + "total": 1270, + "unique": 19 + } + }, + "by_request_status": { + "summary": "With group_by=request_status", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T06:00:00Z" + }, + "request_status": { + "blocked": 1080, + "alerted": 122, + "passed": 68 + } + } + }, + "by_accuracy": { + "summary": "With group_by=accuracy", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T06:00:00Z" + }, + "accuracy": { + "low": 150, + "medium": 420, + "high": 700 + } + } + }, + "by_risk": { + "summary": "With group_by=risk", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T06:00:00Z" + }, + "risk": { + "low": 200, + "medium": 350, + "high": 520, + "critical": 200 + } + } + }, + "by_signature": { + "summary": "With group_by=signature", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T06:00:00Z" + }, + "signature": [ + { + "signature_id": "200001834", + "name": "Unix hidden (dot-file)", + "count": 141, + "accuracy": "high", + "risk": "medium" + }, + { + "signature_id": "200001475", + "name": "PHP injection attempt", + "count": 99, + "accuracy": "high", + "risk": "high" + }, + { + "signature_id": "200000098", + "name": "XSS script tag end (Parameter)", + "count": 85, + "accuracy": "medium", + "risk": "high" + }, + { + "signature_id": "200001088", + "name": "Directory Traversal attempt", + "count": 72, + "accuracy": "high", + "risk": "critical" + }, + { + "signature_id": "200002550", + "name": "SQL injection attempt", + "count": 65, + "accuracy": "high", + "risk": "critical" + } + ] + } + }, + "by_cve": { + "summary": "With group_by=cve (Top Signature CVEs table)", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T06:00:00Z" + }, + "cve": [ + { + "value": "CVE-2021-44228", + "count": 450 + }, + { + "value": "CVE-2021-1234", + "count": 320 + }, + { + "value": "CVE-2021-5678", + "count": 180 + }, + { + "value": "CVE-2020-9484", + "count": 95 + }, + { + "value": "CVE-2019-11043", + "count": 72 + } + ] + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/InvalidRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "500": { + "$ref": "#/components/responses/InternalServerErr" + } + } + } + }, + "/app-protect/analytics/signatures/time-series": { + "post": { + "tags": [ + "NGINX One App Protect" + ], + "summary": "Query signature analytics time series", + "operationId": "querySignatureAnalyticsTimeSeries", + "description": "Returns signature analytics as time-series data for charting.\n\n**Response behavior:**\n- Without `group_by`: Returns `total` series (aggregate signature hits over time)\n- With `group_by`: Returns dimensional breakdown series, `total` is omitted\n\nData is returned with each dimension value as a separate series array,\nmaking it easy to plot directly. The bucket size is determined by the\n`resolution` field or auto-selected based on the time range.\n\n**Supported dimensions for time-series:**\n- `request_status` - Returns `blocked`, `alerted`, `passed` series\n- `accuracy` - Returns `low`, `medium`, `high` series\n- `risk` - Returns `low`, `medium`, `high`, `critical` series\n\n**Time alignment:** All series arrays contain the same timestamps, aligned to the\nresolution boundary. Buckets with no events are zero-filled.\n\n**Filter behavior:**\n- All filters are combined with AND logic\n- Use the `in` operator to achieve OR within a single dimension\n", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SignaturesTimeSeriesQueryRequest" + }, + "examples": { + "total_over_time": { + "summary": "Total signature hits over time (no group_by)", + "value": { + "start_time": "now-6h", + "resolution": "15m" + } + }, + "by_request_status": { + "summary": "Signature hits by request status over time", + "value": { + "start_time": "now-6h", + "resolution": "1h", + "group_by": "request_status" + } + }, + "by_accuracy": { + "summary": "Signature hits by accuracy over time", + "value": { + "start_time": "now-6h", + "resolution": "1h", + "group_by": "accuracy" + } + }, + "by_risk": { + "summary": "Signature hits by risk over time", + "value": { + "start_time": "now-6h", + "resolution": "1h", + "group_by": "risk" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Successfully returned signature analytics time series.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SignaturesTimeSeriesQueryResponse" + }, + "examples": { + "without_group_by": { + "summary": "Without group_by - returns total series only", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T06:00:00Z", + "resolution": "1h" + }, + "total": [ + { + "timestamp": "2024-01-15T00:00:00Z", + "count": 150 + }, + { + "timestamp": "2024-01-15T01:00:00Z", + "count": 180 + }, + { + "timestamp": "2024-01-15T02:00:00Z", + "count": 95 + }, + { + "timestamp": "2024-01-15T03:00:00Z", + "count": 210 + }, + { + "timestamp": "2024-01-15T04:00:00Z", + "count": 175 + }, + { + "timestamp": "2024-01-15T05:00:00Z", + "count": 130 + } + ] + } + }, + "by_request_status": { + "summary": "With group_by=request_status", + "description": "All series have aligned timestamps. Note the zero-filled bucket at 02:00\nfor `passed` where no events occurred.\n", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T03:00:00Z", + "resolution": "1h" + }, + "request_status": { + "blocked": [ + { + "timestamp": "2024-01-15T00:00:00Z", + "count": 120 + }, + { + "timestamp": "2024-01-15T01:00:00Z", + "count": 150 + }, + { + "timestamp": "2024-01-15T02:00:00Z", + "count": 80 + } + ], + "passed": [ + { + "timestamp": "2024-01-15T00:00:00Z", + "count": 10 + }, + { + "timestamp": "2024-01-15T01:00:00Z", + "count": 15 + }, + { + "timestamp": "2024-01-15T02:00:00Z", + "count": 0 + } + ], + "alerted": [ + { + "timestamp": "2024-01-15T00:00:00Z", + "count": 20 + }, + { + "timestamp": "2024-01-15T01:00:00Z", + "count": 15 + }, + { + "timestamp": "2024-01-15T02:00:00Z", + "count": 10 + } + ] + } + } + }, + "by_accuracy": { + "summary": "With group_by=accuracy", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T03:00:00Z", + "resolution": "1h" + }, + "accuracy": { + "low": [ + { + "timestamp": "2024-01-15T00:00:00Z", + "count": 15 + }, + { + "timestamp": "2024-01-15T01:00:00Z", + "count": 20 + }, + { + "timestamp": "2024-01-15T02:00:00Z", + "count": 12 + } + ], + "medium": [ + { + "timestamp": "2024-01-15T00:00:00Z", + "count": 45 + }, + { + "timestamp": "2024-01-15T01:00:00Z", + "count": 55 + }, + { + "timestamp": "2024-01-15T02:00:00Z", + "count": 38 + } + ], + "high": [ + { + "timestamp": "2024-01-15T00:00:00Z", + "count": 90 + }, + { + "timestamp": "2024-01-15T01:00:00Z", + "count": 105 + }, + { + "timestamp": "2024-01-15T02:00:00Z", + "count": 40 + } + ] + } + } + }, + "by_risk": { + "summary": "With group_by=risk", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T03:00:00Z", + "resolution": "1h" + }, + "risk": { + "low": [ + { + "timestamp": "2024-01-15T00:00:00Z", + "count": 20 + }, + { + "timestamp": "2024-01-15T01:00:00Z", + "count": 25 + }, + { + "timestamp": "2024-01-15T02:00:00Z", + "count": 15 + } + ], + "medium": [ + { + "timestamp": "2024-01-15T00:00:00Z", + "count": 40 + }, + { + "timestamp": "2024-01-15T01:00:00Z", + "count": 50 + }, + { + "timestamp": "2024-01-15T02:00:00Z", + "count": 30 + } + ], + "high": [ + { + "timestamp": "2024-01-15T00:00:00Z", + "count": 60 + }, + { + "timestamp": "2024-01-15T01:00:00Z", + "count": 75 + }, + { + "timestamp": "2024-01-15T02:00:00Z", + "count": 35 + } + ], + "critical": [ + { + "timestamp": "2024-01-15T00:00:00Z", + "count": 30 + }, + { + "timestamp": "2024-01-15T01:00:00Z", + "count": 30 + }, + { + "timestamp": "2024-01-15T02:00:00Z", + "count": 10 + } + ] + } + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/InvalidRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "500": { + "$ref": "#/components/responses/InternalServerErr" + } + } + } + }, + "/app-protect/analytics/violations": { + "post": { + "tags": [ + "NGINX One App Protect" + ], + "summary": "Query violation analytics", + "operationId": "queryViolationAnalytics", + "description": "Returns violation analytics with optional dimensional breakdown.\n\n**Response behavior:**\n- Without `group_by`: Returns `total` (violation occurrences) and `unique` (distinct violation types)\n- With `group_by`: Returns breakdown for that dimension, `total` and `unique` are omitted\n\n**Response structure by dimension type:**\n- **Fixed enum dimensions** (`context`): Returns object with known keys (header, cookie, parameter, uri, request, other)\n- **Dynamic dimensions** (`violation`, `sub_violation`): Returns array of items with cross-dimension context\n\n**Filter behavior:**\n- All filters are combined with AND logic\n- Use the `in` operator to achieve OR within a single dimension\n", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViolationsQueryRequest" + }, + "examples": { + "total_only": { + "summary": "Get total violation occurrences and unique count (no group_by)", + "value": { + "start_time": "now-24h" + } + }, + "by_violation": { + "summary": "Top violations by occurrence count", + "value": { + "start_time": "now-24h", + "group_by": "violation", + "limit": 10 + } + }, + "by_sub_violation": { + "summary": "Top sub-violations by occurrence count", + "value": { + "start_time": "now-24h", + "group_by": "sub_violation", + "limit": 10 + } + }, + "by_context": { + "summary": "Violation context breakdown", + "value": { + "start_time": "now-24h", + "group_by": "context" + } + }, + "filtered_by_policy": { + "summary": "Top violations for a specific policy", + "value": { + "start_time": "now-24h", + "group_by": "violation", + "filter": [ + { + "field": "policy", + "operator": "=", + "values": [ + "app_protect_default_policy" + ] + } + ], + "limit": 10 + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Successfully returned violation analytics.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ViolationsQueryResponse" + }, + "examples": { + "without_group_by": { + "summary": "Without group_by - returns total and unique only", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T23:59:59Z" + }, + "total": 4320, + "unique": 5 + } + }, + "by_violation": { + "summary": "With group_by=violation", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T23:59:59Z" + }, + "violation": [ + { + "value": "Bot Client Detected", + "count": 1080, + "distinct": { + "ips": 1, + "urls": 1, + "policies": 1 + } + }, + { + "value": "Violation Rating Threat detected", + "count": 960, + "distinct": { + "ips": 1, + "urls": 1, + "policies": 1 + } + }, + { + "value": "Attack signature detected", + "count": 840, + "distinct": { + "ips": 1, + "urls": 1, + "policies": 1 + } + }, + { + "value": "Illegal meta character in value", + "count": 480, + "distinct": { + "ips": 1, + "urls": 1, + "policies": 1 + } + }, + { + "value": "Illegal HTTP status in response", + "count": 120, + "distinct": { + "ips": 1, + "urls": 1, + "policies": 1 + } + } + ] + } + }, + "by_sub_violation": { + "summary": "With group_by=sub_violation", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T23:59:59Z" + }, + "sub_violation": [ + { + "value": "N/A", + "count": 1080, + "distinct": { + "ips": 1, + "urls": 1, + "policies": 1 + } + } + ] + } + }, + "by_context": { + "summary": "With group_by=context", + "value": { + "query_metadata": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T23:59:59Z" + }, + "context": { + "cookie": 0, + "header": 130, + "parameter": 1426, + "request": 302, + "uri": 0, + "other": 2462 + } + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/InvalidRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "500": { + "$ref": "#/components/responses/InternalServerErr" + } + } + } + }, + "/app-protect/events": { + "get": { + "tags": [ + "NGINX One App Protect" + ], + "summary": "List security events", + "operationId": "listSecurityEvents", + "description": "Returns a paginated list of security events.\n\n**Filtering:**\n- Use the `filter_fields`, `filter_values`, and `filter_ops` parameters to filter events by various dimensions\n- All filter parameters must have matching array lengths\n- `support_id` is unique per event, so filtering by it returns a single-item list\n- Time range filtering via `start_time` and `end_time` is recommended to limit results\n- Multiple filter values can be chained using the `|` character (e.g., `blocked|alerted`)\n\n**Pagination:**\n- Results are paginated using standard Nginx One Console pagination\n- Results are sorted by timestamp descending (most recent first) by default\n\n**Response:**\n- Returns summary fields suitable for list display\n- Use `GET /app-protect/events/{id}` for full event details including raw request\n", + "parameters": [ + { + "name": "start_time", + "in": "query", + "description": "Beginning of the time range (inclusive).\nAccepts ISO 8601 format or relative offset (e.g., `now-24h`).\n", + "schema": { + "type": "string" + }, + "example": "now-24h" + }, + { + "name": "end_time", + "in": "query", + "description": "End of the time range (exclusive).\nDefaults to current time if not specified.\n", + "schema": { + "type": "string" + }, + "example": "now" + }, + { + "$ref": "#/components/parameters/FilterFieldSecurityEvents" + }, + { + "$ref": "#/components/parameters/FilterValues" + }, + { + "$ref": "#/components/parameters/FilterOperands" + }, + { + "$ref": "#/components/parameters/Paginated" + }, + { + "$ref": "#/components/parameters/Offset" + }, + { + "$ref": "#/components/parameters/Limit" + } + ], + "responses": { + "200": { + "description": "Successfully returned list of security events.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SecurityEventListResponse" + }, + "example": { + "total": 1080, + "count": 1, + "start_index": 1, + "items_per_page": 100, + "items": [ + { + "timestamp": "2024-01-22T12:13:25Z", + "support_id": "1844305495056427365", + "request_status": "blocked", + "policy_name": "app_protect_default_policy", + "client_ip": "192.168.1.100", + "url": "/api/users", + "method": "POST", + "response_code": 403, + "country_code": "US", + "violation_rating": 5, + "instance_object_id": "inst_8Iwn7dT7RF-PRLxkSt5EYQ", + "csg_object_id": "csg_-uvR3F2TQGm18jnl7bpaGw" + } + ] + } + } + } + }, + "400": { + "$ref": "#/components/responses/InvalidRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "500": { + "$ref": "#/components/responses/InternalServerErr" + } + } + } + }, + "/app-protect/events/{id}": { + "get": { + "tags": [ + "NGINX One App Protect" + ], + "summary": "Get security event by supportID", + "operationId": "getSecurityEvent", + "description": "Returns a specific security event by its support ID.\n\n**Response:**\n- Returns full event details including:\n - Request metadata (headers, method, URL, response code)\n - WAF enforcement details (policy, outcome, violation_rating)\n - All triggered violations with context\n - All matched signatures with details\n - Raw HTTP request (if available and not truncated)\n - Threat campaign associations\n", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "The support ID of the security event.", + "schema": { + "type": "string", + "minLength": 1 + }, + "example": "1844305495056427365" + } + ], + "responses": { + "200": { + "description": "Successfully returned the security event.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SecurityEvent" + }, + "example": { + "id": "d1cd4806-3519-4c72-a0e4-63fd611ee6fb", + "timestamp": "2024-01-22T12:13:25Z", + "support_id": "1844305495056427365", + "version": "v1.0", + "system_id": "31ed9d05-9cb0-48c3-9f97-d63b1b6dd342", + "parent_hostname": "nginx-host-01", + "instance_object_id": "inst_8Iwn7dT7RF-PRLxkSt5EYQ", + "csg_object_id": "csg_-uvR3F2TQGm18jnl7bpaGw", + "http": { + "hostname": "example.com", + "remote_addr": "192.168.1.100", + "remote_port": 54321, + "server_addr": "10.0.0.1", + "server_port": 443, + "uri": "/", + "request_method": "GET", + "response_code": 403 + }, + "x_forwarded_for_header_value": "203.0.113.42", + "country_code": "US", + "policy_name": "app_protect_default_policy", + "request_status": "blocked", + "request_outcome": "rejected", + "request_outcome_reason": "SECURITY_WAF_VIOLATION", + "violation_rating": 5, + "blocking_exception_reason": "", + "is_truncated": false, + "signatures": [ + { + "id": 200001834, + "name": "XSS script tag end (Parameter)", + "accuracy": "high", + "risk": "high", + "cve": "", + "blocking_mask": "0x0", + "buffer": "param", + "offset": 0, + "length": 42 + } + ], + "violations": [ + { + "name": "Illegal meta character in value", + "sub_name": "", + "context": "parameter", + "detail_name": "VIOL_PARAMETER_VALUE_METACHAR", + "detail_context": "parameter", + "field_name": "param", + "field_value": "" + }, + { + "name": "Attack signature detected", + "sub_name": "", + "context": "parameter", + "detail_name": "VIOL_ATTACK_SIGNATURE", + "detail_context": "parameter", + "field_name": "param", + "field_value": "" + }, + { + "name": "Violation Rating Threat detected", + "sub_name": "", + "context": "other", + "detail_name": "", + "detail_context": "", + "field_name": "", + "field_value": "" + }, + { + "name": "Bot Client Detected", + "sub_name": "", + "context": "other", + "detail_name": "", + "detail_context": "", + "field_name": "", + "field_value": "" + } + ], + "threat_campaign_names": [], + "request": "GET /?param=%3Cscript%3Ealert%27xss%27%3C%2Fscript%3E HTTP/1.1\r\nHost: example.com\r\nUser-Agent: curl/7.68.0\r\nAccept: */*\r\n\r\n" + } + } + } + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/billing-usage/events": {} + }, + "components": { + "parameters": { + "Paginated": { + "name": "paginated", + "in": "query", + "schema": { + "type": "boolean", + "default": true + }, + "description": "A boolean indicating if the results should be presented as a paginated list. Defaults to `true`. \nWhen set to `false` a maximum of 3000 results are returned.\n", + "required": false + }, + "Limit": { + "name": "limit", + "in": "query", + "schema": { + "type": "integer", + "minimum": 0 + }, + "description": "An integer that specifies the maximum number of items to be returned. \nSetting this to `0` will result in no items being returned, but a total count will still be provided. \nThis parameter is not applicable if `paginated` is `false`.\n", + "required": false + }, + "Offset": { + "name": "offset", + "in": "query", + "schema": { + "type": "integer", + "minimum": 1 + }, + "description": "An integer that specifies the starting position of the results, starting at `1`.\nThis parameter is not applicable if `paginated` is `false`.\n" + }, + "FilterFieldDataPlaneKeys": { + "name": "filter_fields", + "in": "query", + "description": "Filter options for data plane keys; used in conjunction with other filter parameters having the same array length.\n\nWhen filtering on `status`, only the following `filter_values` are supported:\n * revoked\n * expired\n * valid\n", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FilterNameDataPlaneKeys" + } + } + }, + "FilterOperands": { + "name": "filter_ops", + "in": "query", + "description": "An array of strings defining the operands for filtering, to be used in conjunction with `filter_fields` and `filter_values`. \nAll filter parameters must have matching array lengths. Currently, the only supported operand is `\"IN\"`.\n", + "schema": { + "$ref": "#/components/schemas/FilterOperands" + } + }, + "FilterValues": { + "name": "filter_values", + "in": "query", + "description": "An array of strings containing the keywords for filtering. \nMultiple keywords can be chained using the `|` character. \nEnsure this parameter's array length matches those of `filter_fields` and `filter_ops` for effective filtering.\nThe total length of the filter string should not exceed 1024 characters.\n", + "schema": { + "type": "array", + "items": { + "type": "string", + "example": "value1|value2|value3", "minLength": 1, "maxLength": 1024 } @@ -6702,7 +8314,7 @@ "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 }, - "NapLogProfileCompileNapRelease": { + "NapCompileNapRelease": { "name": "nap_release", "in": "query", "schema": { @@ -6712,14 +8324,14 @@ "required": true, "example": "5.10.0" }, - "NapLogProfileCompileDownload": { + "NapCompileDownload": { "name": "download", "in": "query", "schema": { "type": "boolean", "default": false }, - "description": "Whether to download the NGINX App Protect log profile bundle. When `true`, the request blocks until the bundle is ready and returns the bundle content. The request may take longer depending on the bundle's compilation status.\n", + "description": "Whether to download the compiled bundle. When `true`, the request blocks until the bundle is ready and returns the bundle content. The request may take longer depending on the bundle's compilation status.\n", "required": false, "example": true }, @@ -7020,664 +8632,1175 @@ } } }, - "FilterFieldNapPolicyDeployment": { + "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/FilterNameNapPolicyDeployment" + } + } + }, + "SortNameNapPolicyVersionsDep": { + "name": "sort_nap_policy_versions", + "in": "query", + "deprecated": true, + "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": [ + "created_at", + "deployment_status", + "deployment_count", + "enforcement_mode" + ], + "x-enum-varnames": [ + "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" + ] + } + } + }, + "SortNameNapPolicyVersions": { + "name": "sort_fields", + "in": "query", + "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": [ + "created_at", + "deployment_status", + "deployment_count", + "enforcement_mode" + ], + "x-enum-varnames": [ + "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" + ] + } + } + }, + "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": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FilterNameNapPolicyVersion" + } + } + }, + "NapPolicyVersionParamObjectID": { + "name": "nap_policy_version_object_id", + "in": "path", + "schema": { + "$ref": "#/components/schemas/NapPolicyVersionObjectID" + }, + "description": "A globally unique identifier for the App Protect policy version.\n", + "required": true + }, + "TemplateParamObjectID": { + "name": "templateObjectID", + "in": "path", + "schema": { + "$ref": "#/components/schemas/TemplateObjectID" + }, + "description": "A globally unique identifier for the template.\n", + "required": true + }, + "SortNameTemplates": { + "name": "sort_fields", + "in": "query", + "description": "Sort the list of templates by the specified fields.\nThe default sort order is ascending. To sort in descending order, use the `sort_dir` parameter.\n", + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "name", + "type" + ], + "x-enum-varnames": [ + "sort_name_templates_name", + "sort_name_templates_type" + ] + } + } + }, + "TemplateSubmissionPreviewOnly": { + "name": "preview_only", + "in": "query", + "schema": { + "type": "boolean", + "default": false + }, + "description": "Optional flag to control how a template submission request is processed.\n - When `true`, the request renders the full NGINX configuration for preview **without creating a template submission object** (this is currently the only supported mode).\n - When `false` or omitted (the default), the request is intended to render the configuration **and create a submission object**, but this feature is **not supported yet** and will return an error.\nNote: Currently, only preview (stateless render) mode is supported. Submission creation is not yet implemented.\n", + "required": false + }, + "FilterFieldTemplates": { "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", + "description": "An array of strings indicating which fields to filter by (for example, `name`, `type`). This parameter works in conjunction with `filter_values` and `filter_ops`.\n", "schema": { "type": "array", "items": { - "$ref": "#/components/schemas/FilterNameNapPolicyDeployment" + "$ref": "#/components/schemas/FilterNameTemplates" } } }, - "SortNameNapPolicyVersionsDep": { - "name": "sort_nap_policy_versions", + "FilterFieldSecurityEvents": { + "name": "filter_fields", "in": "query", - "deprecated": true, - "description": "Sort NGINX App Protect policy versions by enumerate value(s). Ordinal position determines primary, secondary, etc.\n", + "description": "An array of field names to filter by. Works in conjunction with `filter_values` and `filter_ops`.\n", "schema": { "type": "array", "items": { + "$ref": "#/components/schemas/AnalyticsFilterField" + } + } + } + }, + "schemas": { + "FilterNameDataPlaneKeys": { + "type": "string", + "description": "Keywords for data plane key filters.\nWhen filtering on `status`, only the following `filter_values` are supported:\n * revoked\n * valid\n", + "enum": [ + "name", + "status", + "object_id" + ], + "x-enum-varnames": [ + "filter_name_data_plane_key_name", + "filter_name_data_plane_key_status", + "filter_name_data_plane_key_object_id" + ] + }, + "FilterOperand": { + "type": "string", + "enum": [ + "IN" + ], + "x-enum-varnames": [ + "filter_operands_in" + ] + }, + "FilterOperands": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FilterOperand" + } + }, + "PaginationResponse": { + "type": "object", + "description": "Outlines pagination details for list responses, including total results, start index, and items per page.", + "required": [ + "total", + "count" + ], + "properties": { + "total": { + "type": "integer", + "description": "The absolute total number of the resource in the NGINX One Console, ignoring any filter(s).\n" + }, + "count": { + "type": "integer", + "description": "The total number of results generated by the list or query operation, accounting for any filter(s).\nThis number can be greater than the number of returned resources when pagination is in effect and a page size limit (or maximum allowed) is reached.\n" + }, + "start_index": { + "type": "integer", + "description": "The first result's starting position in the list. This is disregarded when `paginated=false`.\n" + }, + "items_per_page": { + "type": "integer", + "description": "The number of items to display per page. This is disregarded when `paginated=false`.\n" + } + }, + "example": { + "total": 101, + "count": 1, + "start_index": 1, + "items_per_page": 100 + } + }, + "DataPlaneKeyObjectID": { + "description": "A globally unique identifier for the data plane key.", + "type": "string", + "format": "object_id", + "pattern": "^key_.*", + "x-go-type": "objects.ID", + "x-go-type-import": { + "name": "objects", + "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" + } + }, + "DataPlaneKey": { + "type": "object", + "description": "Represents a data plane key with details such as object_id, name, and timestamps.", + "required": [ + "object_id", + "name", + "revoked", + "expires_at", + "created_at", + "modified_at" + ], + "properties": { + "object_id": { + "$ref": "#/components/schemas/DataPlaneKeyObjectID" + }, + "name": { + "description": "The name given to the data plane key.", + "type": "string" + }, + "revoked": { + "description": "Indicates whether the data plane key has been revoked or not.", + "type": "boolean" + }, + "revoked_at": { "type": "string", - "enum": [ - "created_at", - "deployment_status", - "deployment_count", - "enforcement_mode" + "format": "date-time", + "description": "The date and time when the data plane key was revoked." + }, + "expires_at": { + "type": "string", + "format": "date-time", + "description": "The date and time when the data plane key expires." + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "The date and time when the data plane key was created." + }, + "modified_at": { + "type": "string", + "format": "date-time", + "description": "The date and time when the data plane key was last modified." + }, + "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." + } + } + }, + "DataPlaneKeyListResponse": { + "allOf": [ + { + "$ref": "#/components/schemas/PaginationResponse" + }, + { + "type": "object", + "description": "List of data plane keys.", + "required": [ + "items" ], - "x-enum-varnames": [ - "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" - ] + "properties": { + "items": { + "description": "An array of DataPlaneKey objects.", + "type": "array", + "items": { + "$ref": "#/components/schemas/DataPlaneKey" + } + } + } + } + ] + }, + "Error": { + "description": "This object contains details about the errors that are returned when API requests fail.", + "type": "object", + "required": [ + "message", + "request_id", + "timestamp" + ], + "properties": { + "message": { + "description": "The error message describing the problem.", + "type": "string" + }, + "request_id": { + "description": "The unique identifier of the API request that failed.", + "type": "string" + }, + "timestamp": { + "description": "The date and time (in UTC) when the error happened.", + "type": "string" + }, + "detail": { + "description": "Additional information about the error, if available.", + "type": "string" } } }, - "SortNameNapPolicyVersions": { - "name": "sort_fields", - "in": "query", - "description": "Sort NGINX App Protect policy versions by enumerate value(s). Ordinal position determines primary, secondary, etc.\n", - "schema": { - "type": "array", - "items": { + "DataPlaneKeyCreateRequest": { + "type": "object", + "description": "Request structure for creating a new data plane key.", + "required": [ + "name" + ], + "properties": { + "name": { + "description": "Give the data plane key a name so you can tell it apart from others.", "type": "string", - "enum": [ - "created_at", - "deployment_status", - "deployment_count", - "enforcement_mode" - ], - "x-enum-varnames": [ - "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" - ] + "minLength": 1, + "maxLength": 128 + }, + "expires_at": { + "type": "string", + "format": "date-time", + "description": "Set an expiration date and time for the data plane key in ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ. \nIf an expiration date isn't specified, the key will expire one year after it's created. \n\nYou can use the _Update a data plane key_ endpoint to extend the expiration date.\nIt's not possible to update the expiration date once the data plane key has expired.\n" + } + } + }, + "DataPlaneKeyResponse": { + "type": "object", + "description": "Response structure containing details of the created or retrieved data plane key.", + "required": [ + "key", + "object_id", + "expires_at" + ], + "properties": { + "name": { + "description": "The name to be give to the new data plane key.", + "type": "string" + }, + "object_id": { + "$ref": "#/components/schemas/DataPlaneKeyObjectID" + }, + "key": { + "description": "The data plane key value. Save this key somewhere secure as it isn't saved and is shown only once.", + "type": "string" + }, + "expires_at": { + "type": "string", + "format": "date-time", + "description": "The date and time when the data plane key will expire." } } }, - "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": { - "type": "array", - "items": { - "$ref": "#/components/schemas/FilterNameNapPolicyVersion" + "BulkRequestAction": { + "type": "string", + "default": "modify", + "description": "Bulk action to perform:\n * `create` creates a new object given all required elements.\n * `modify` updates one or more elements of an existing object.\n * `delete` removes the existing object.\n", + "enum": [ + "create", + "modify", + "delete" + ], + "x-enum-varnames": [ + "bulk_action_create", + "bulk_action_modify", + "bulk_action_delete" + ] + }, + "DataPlaneKeyBulkRequestData": { + "type": "object", + "description": "Part of bulk operation on a data plane key, only `delete` is supported.", + "required": [ + "action", + "object_id" + ], + "properties": { + "object_id": { + "$ref": "#/components/schemas/DataPlaneKeyObjectID" + }, + "action": { + "$ref": "#/components/schemas/BulkRequestAction" } + }, + "example": { + "object_id": "key_-uvR3F2TQGm18jnl7bpaGw", + "action": "delete" } }, - "NapPolicyVersionParamObjectID": { - "name": "nap_policy_version_object_id", - "in": "path", - "schema": { - "$ref": "#/components/schemas/NapPolicyVersionObjectID" + "DataPlaneKeyBulkRequest": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DataPlaneKeyBulkRequestData" }, - "description": "A globally unique identifier for the App Protect policy version.\n", - "required": true + "minItems": 1, + "maxItems": 50, + "example": [ + { + "object_id": "key_-uvR3F2TQGm18jnl7bpaGw", + "action": "delete" + }, + { + "object_id": "key_PL0c1XodRemmzVEjiXSsTg", + "action": "delete" + } + ] }, - "TemplateParamObjectID": { - "name": "templateObjectID", - "in": "path", - "schema": { - "$ref": "#/components/schemas/TemplateObjectID" - }, - "description": "A globally unique identifier for the template.\n", - "required": true + "ObjectID": { + "description": "A globally unique identifier.", + "type": "string", + "format": "object_id", + "pattern": "^\\w+_.*", + "x-go-type": "objects.ID", + "x-go-type-import": { + "name": "objects", + "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" + } }, - "SortNameTemplates": { - "name": "sort_fields", - "in": "query", - "description": "Sort the list of templates by the specified fields.\nThe default sort order is ascending. To sort in descending order, use the `sort_dir` parameter.\n", - "schema": { - "type": "array", - "items": { + "BulkRequestObjectStatus": { + "type": "object", + "required": [ + "outcome" + ], + "properties": { + "object_id": { + "$ref": "#/components/schemas/ObjectID" + }, + "name": { + "type": "string", + "description": "this is the user facing name of the object." + }, + "outcome": { "type": "string", + "description": "This is the outcome that corresponds to the action.\n* deleted - the object deletion was processed, and the object was deleted.\n* accepted - the request was accepted, and will be processed.\n* failed - the request failed, see failure_reason for more details.\n* invalid - the request was invalid, see failure_reason for more details.\n", "enum": [ - "name", - "type" + "deleted", + "accepted", + "failed", + "invalid" ], "x-enum-varnames": [ - "sort_name_templates_name", - "sort_name_templates_type" + "build_request_object_status_deleted", + "build_request_object_status_accepted", + "build_request_object_status_failed", + "build_request_object_status_invalid" ] + }, + "failure_reason": { + "type": "string", + "description": "this is the failure reason populated when outcome is 'failed' or 'invalid'." } } }, - "TemplateSubmissionPreviewOnly": { - "name": "preview_only", - "in": "query", - "schema": { - "type": "boolean", - "default": false - }, - "description": "Optional flag to control how a template submission request is processed.\n - When `true`, the request renders the full NGINX configuration for preview **without creating a template submission object** (this is currently the only supported mode).\n - When `false` or omitted (the default), the request is intended to render the configuration **and create a submission object**, but this feature is **not supported yet** and will return an error.\nNote: Currently, only preview (stateless render) mode is supported. Submission creation is not yet implemented.\n", - "required": false + "DataPlaneKeyBulkResponse": { + "description": "The data plane key bulk outcome.", + "type": "array", + "items": { + "$ref": "#/components/schemas/BulkRequestObjectStatus" + } }, - "FilterFieldTemplates": { - "name": "filter_fields", - "in": "query", - "description": "An array of strings indicating which fields to filter by (for example, `name`, `type`). This parameter works in conjunction with `filter_values` and `filter_ops`.\n", - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/FilterNameTemplates" + "DataPlaneKeyUpdateRequest": { + "type": "object", + "description": "Request structure for updating an existing data plane key.", + "properties": { + "name": { + "description": "Give the data plane key a new name so you can tell it apart from others.", + "type": "string", + "minLength": 1, + "maxLength": 128 + }, + "expires_at": { + "type": "string", + "format": "date-time", + "description": "Adjust the expiration date and time for the data plane key in ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ. \n\nIt's not possible to update the expiration date once the data plane key has expired.\n" } } - } - }, - "schemas": { - "FilterNameDataPlaneKeys": { + }, + "FilterNameCertificates": { "type": "string", - "description": "Keywords for data plane key filters.\nWhen filtering on `status`, only the following `filter_values` are supported:\n * revoked\n * valid\n", + "description": "Keywords for certificates filters.\nWhen filtering on `management`, only the following `filter_values` are supported:\n * managed\n * unmanaged\nWhen filtering on `type`, only the following `filter_values` are supported:\n * cert_key\n * ca_bundle\n * unknown\nWhen filtering on `status`, only the following `filter_values` are supported:\n * valid\n * expiring\n * expired\n * not_ready\n", "enum": [ "name", + "management", + "type", + "subject_name", "status", "object_id" ], "x-enum-varnames": [ - "filter_name_data_plane_key_name", - "filter_name_data_plane_key_status", - "filter_name_data_plane_key_object_id" + "filter_name_certificates_name", + "filter_name_certificates_management", + "filter_name_certificates_type", + "filter_name_certificates_subject_name", + "filter_name_certificates_status", + "filter_name_certificates_object_id" + ] + }, + "CertificateObjectID": { + "description": "A globally unique identifier for the certificates.", + "type": "string", + "format": "object_id", + "pattern": "^cert_.*", + "x-go-type": "objects.ID", + "x-go-type-import": { + "name": "objects", + "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" + } + }, + "CertificateManagement": { + "type": "string", + "description": "Management type:\n * `managed` - Certificate managed by NGINX One Console.\n * `unmanaged` - Certificate that only exists on a data plane instance, detected from its NGINX configuration.\n", + "enum": [ + "managed", + "unmanaged" + ], + "x-enum-varnames": [ + "certificate_management_managed", + "certificate_management_unmanaged" + ] + }, + "CertificateType": { + "type": "string", + "description": "Certificate type:\n * `ca_bundle` - This certificate object is a CA bundle.\n * `cert_key` - This certificate object is consisted of public certificates and key.\n * `unmanaged` - This certificate is not managed by NGINX One console and its type is unmanaged.\n", + "enum": [ + "ca_bundle", + "cert_key", + "unmanaged" + ], + "x-enum-varnames": [ + "certificate_type_ca_bundle", + "certificate_type_pem_cert_key", + "certificate_type_unmanaged" ] }, - "FilterOperand": { + "CertificateObjectMetadata": { + "required": [ + "management", + "type" + ], + "properties": { + "name": { + "description": "Name of the certificate, optionally specified upon creation", + "type": "string" + }, + "object_id": { + "$ref": "#/components/schemas/CertificateObjectID" + }, + "management": { + "$ref": "#/components/schemas/CertificateManagement" + }, + "type": { + "$ref": "#/components/schemas/CertificateType" + }, + "certs_count": { + "description": "The number of public certificates under this certificate object.", + "type": "integer", + "format": "int64" + } + }, + "example": { + "name": "example-ca-bundle", + "object_id": "cert_Tet21AeYTHCj7taOwVfzyw", + "management": "managed", + "type": "ca_bundle", + "certs_count": 5 + } + }, + "CertificateStatus": { "type": "string", + "description": "Status of the certificate:\n * `valid` - The certificate is currently valid and operational.\n * `expiring` - The certificate will expire within the next 30 days. Consider renewing it to maintain uninterrupted service.\n * `expired` - The certificate is no longer valid. Immediate renewal is recommended to ensure secure connections.\n * `not_ready` - The certificate is not ready to be used, based on the start date of its validity period.\n", "enum": [ - "IN" + "valid", + "expiring", + "expired", + "not_ready" ], "x-enum-varnames": [ - "filter_operands_in" + "certificate_status_valid", + "certificate_status_expiring", + "certificate_status_expired", + "certificate_status_not_ready" ] }, - "FilterOperands": { - "type": "array", - "items": { - "$ref": "#/components/schemas/FilterOperand" - } - }, - "PaginationResponse": { + "CertificateDisplayMetadata": { + "description": "This represents the essential metadata of a public certificate.", "type": "object", - "description": "Outlines pagination details for list responses, including total results, start index, and items per page.", "required": [ - "total", - "count" + "subject_name", + "status", + "not_before", + "not_after" ], "properties": { - "total": { - "type": "integer", - "description": "The absolute total number of the resource in the NGINX One Console, ignoring any filter(s).\n" + "subject_name": { + "type": "string", + "example": "www.example.com", + "description": "DNS name that identifies the certificate. If DNS is not present in the SAN extension, this will be the common name.\n" }, - "count": { - "type": "integer", - "description": "The total number of results generated by the list or query operation, accounting for any filter(s).\nThis number can be greater than the number of returned resources when pagination is in effect and a page size limit (or maximum allowed) is reached.\n" + "status": { + "$ref": "#/components/schemas/CertificateStatus" }, - "start_index": { - "type": "integer", - "description": "The first result's starting position in the list. This is disregarded when `paginated=false`.\n" + "not_before": { + "type": "string", + "format": "date-time", + "example": "2023-06-12T09:12:33.001Z", + "description": "The start of the validity period for the certificate." }, - "items_per_page": { - "type": "integer", - "description": "The number of items to display per page. This is disregarded when `paginated=false`.\n" + "not_after": { + "type": "string", + "format": "date-time", + "example": "2029-12-25T09:12:33.001Z", + "description": "The end of the validity period for the certificate." } }, "example": { - "total": 101, - "count": 1, + "subject_name": "self_ca_signed", + "status": "valid", + "not_before": "2023-08-10T16:59:15Z", + "not_after": "2024-08-14T16:59:15Z" + } + }, + "CertificateOverviewMetadata": { + "description": "Represents an overview of all the public certificates under a single cert object.\nIf multiple public certificates on the same CA chain, including the leaf certificate and key are provided, \nthis includes `status`, `subject_name`, `not_before` and `not_after` for the leaf certificate.\nIf a CA bundle is provided, the above mentioned certificate metadata is for the Certificate Authority that\nexpires the soonest in the bundle.\n", + "type": "object", + "allOf": [ + { + "$ref": "#/components/schemas/CertificateObjectMetadata" + }, + { + "$ref": "#/components/schemas/CertificateDisplayMetadata" + } + ], + "example": { + "name": "example-ca-bundle", + "object_id": "cert_Tet21AeYTHCj7taOwVfzyw", + "management": "managed", + "type": "ca_bundle", + "subject_name": "self_ca_signed", + "status": "valid", + "not_before": "2023-08-10T16:59:15Z", + "not_after": "2024-08-14T16:59:15Z", + "certs_count": 5 + } + }, + "CertificateListResponse": { + "allOf": [ + { + "$ref": "#/components/schemas/PaginationResponse" + }, + { + "type": "object", + "description": "List of SSL certificates.", + "required": [ + "items" + ], + "properties": { + "items": { + "description": "An array of basic metadata for all the SSL certificates in NGINX One Console. \nFor a CA bundle, an overview with metadata on the first Certificate Authority in the bundle will be displayed.\nOtherwise, an overview with metadata on the leaf certificate will be displayed.\n", + "type": "array", + "items": { + "$ref": "#/components/schemas/CertificateOverviewMetadata" + } + } + } + } + ], + "example": { + "total": 10, + "count": 2, "start_index": 1, - "items_per_page": 100 + "items_per_page": 100, + "items": [ + { + "name": "example-cert_key", + "object_id": "cert_Tet21AeYTHCj7taOwVfzyw", + "management": "managed", + "type": "cert_key", + "status": "valid", + "subject_name": "www.example.com", + "not_before": "2023-08-10T16:59:15Z", + "not_after": "2024-08-14T16:59:15Z", + "certs_count": 1 + }, + { + "name": "example-ca-bundle", + "object_id": "cert_Tet21AeYTHCj7taOwVfzyw", + "management": "managed", + "type": "ca_bundle", + "subject_name": "self_ca_signed", + "status": "valid", + "not_before": "2023-08-10T16:59:15Z", + "not_after": "2024-08-14T16:59:15Z", + "certs_count": 5 + } + ] } }, - "DataPlaneKeyObjectID": { - "description": "A globally unique identifier for the data plane key.", - "type": "string", - "format": "object_id", - "pattern": "^key_.*", - "x-go-type": "objects.ID", - "x-go-type-import": { - "name": "objects", - "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" + "CertificateContent": { + "type": "object", + "description": "Defines the PEM-formatted certificate content which includes the certificates and corresponding private key, all encoded in base64.\n", + "required": [ + "public_certs" + ], + "properties": { + "public_certs": { + "type": "string", + "format": "base64", + "maxLength": 3145728, + "description": "Base64-encoded PEM-formatted certificate information. \nThe `public_certs` field can include a leaf certificate along with its full chain of trust or a CA bundle. \nFor leaf certificates, the accompanying `private_key` is required to authenticate the certificate's validity. \nCA bundles contain trusted CA certificates and may consist of certificates from different CA chains. A private\nkey should not be included in a CA bundle.\n" + }, + "private_key": { + "type": "string", + "format": "base64", + "maxLength": 3145728, + "description": "Base64-encoded private key string for the leaf certificate, required only for certificate-key pairs to \nverify the certificate's authenticity.\n" + } + }, + "example": { + "public_certs": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUUzb3lkdWVPQU5KSGh2TDN5dkpkVHBob2V2NUdPN2dvK0J5WU9PL2w1NHU1TzJQeE1lWCtBakFiNkF4bXEKbGl2SXVodz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQ==" } }, - "DataPlaneKey": { + "CertificateRequest": { "type": "object", - "description": "Represents a data plane key with details such as object_id, name, and timestamps.", + "description": "Request structure for parsing or upserting certificates with an optional private key.\n", "required": [ - "object_id", - "name", - "revoked", - "expires_at", - "created_at", - "modified_at" + "content" ], "properties": { - "object_id": { - "$ref": "#/components/schemas/DataPlaneKeyObjectID" + "name": { + "description": "A name for the certificate, making it identifiable among others.", + "type": "string", + "minLength": 1, + "maxLength": 128 + }, + "content": { + "$ref": "#/components/schemas/CertificateContent" + } + }, + "example": { + "name": "example-ca-bundle", + "content": { + "public_certs": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUUzb3lkdWVPQU5KSGh2TDN5dkpkVHBob2V2NUdPN2dvK0J5WU9PL2w1NHU1TzJQeE1lWCtBakFiNkF4bXEKbGl2SXVodz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQ==", + "private_key": "" + } + } + }, + "CertificateMetadata": { + "description": "A comprehensive list of all the metadata for a public certificate.", + "type": "object", + "required": [ + "status", + "serial_number", + "signature_algorithm", + "not_before", + "not_after", + "public_key_type", + "thumbprint" + ], + "properties": { + "status": { + "$ref": "#/components/schemas/CertificateStatus" + }, + "version": { + "type": "integer", + "format": "int64", + "example": 3, + "description": "The version of the certificate, typically 3 for X.509 certificates." + }, + "serial_number": { + "type": "string", + "example": "16469416336579571270", + "description": "A unique identifier for the certificate." + }, + "signature_algorithm": { + "type": "string", + "example": "SHA-256", + "description": "Identifies the algorithm used to sign the certificate." + }, + "issuer": { + "type": "string", + "example": "CN=Example CA, O=Certificate Authority Inc., OU=CA Department, L=City, ST=State, C=Country", + "description": "Identifies the entity who signed and issued the certificate." + }, + "not_before": { + "type": "string", + "format": "date-time", + "example": "2023-06-12T09:12:33.001Z", + "description": "The start of the validity period for the certificate." + }, + "not_after": { + "type": "string", + "format": "date-time", + "example": "2029-12-25T09:12:33.001Z", + "description": "The end of the validity period for the certificate." + }, + "subject": { + "type": "string", + "example": "CN=www.example.com, O=Example Inc., OU=IT Department, L=City, ST=State, C=Country", + "description": "Identifies the primary entity to which the certificate is issued. Typically, it contains information\nsuch as the Common Name (CN), Organization (O), Organizational Unit (OU), Country (C), etc.\n" }, - "name": { - "description": "The name given to the data plane key.", - "type": "string" + "subject_alternative_name": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "DNS:www.example.com", + "DNS:example.com", + "email:info@example.com" + ], + "description": "Defines additional identifies bound to the subject of the certificate. \nFor example, the DNS name is used to add additional domain names to a certificate.\n" }, - "revoked": { - "description": "Indicates whether the data plane key has been revoked or not.", - "type": "boolean" + "public_key_type": { + "type": "string", + "example": "RSA (2048 Bits)", + "description": "Identifies the encryption algorithm used to create the public key for the certificate." }, - "revoked_at": { + "common_name": { "type": "string", - "format": "date-time", - "description": "The date and time when the data plane key was revoked." + "example": "www.example.com", + "description": "The Common Name (CN) for the certificate, used when DNS name is not present in the SAN extension.\n" }, - "expires_at": { + "authority_key_identifier": { "type": "string", - "format": "date-time", - "description": "The date and time when the data plane key expires." + "example": "2B D0 69 47 94 76 09 FE F4 6B 8D 2E 40 A6 F7 47 4D 7F 08 5E", + "description": "The identifier of the signing authority for the certificate." }, - "created_at": { + "subject_key_identifier": { "type": "string", - "format": "date-time", - "description": "The date and time when the data plane key was created." + "example": "31 EA 76 A9 23 74 A5 DF D4 FD EE A0 C1 A6 9E C6 11 0E 11 EC", + "description": "A hash value of the SSL certificate that can be used to identify certificates that \ncontain a particular public key.\n" }, - "modified_at": { + "thumbprint_algorithm": { "type": "string", - "format": "date-time", - "description": "The date and time when the data plane key was last modified." + "example": "SHA-1", + "description": "Defines the algorithm used to hash the certificate." }, - "instances_count": { + "thumbprint": { + "type": "string", + "example": "E6 A7 87 96 E0 C7 A3 E5 43 78 35 CA 16 78 5B 48 5A A9 DD C4 5C CD 0A 65 AA 89 33 E3 C3 D0 89 71", + "description": "A hash to ensure that the certificate has not been modified." + } + }, + "example": { + "status": "valid", + "version": 3, + "serial_number": "71283929", + "signature_algorithm": "SHA256-RSA", + "issuer": "C=US, ST=WA, L=Seattle, O=F5 Networks, OU=nginx.test, CN=eg3bsriq_cert_bundle_CA", + "not_before": "2023-02-10T16:59:15Z", + "not_after": "2024-08-14T16:59:15Z", + "subject": "C=US, ST=WA, L=Seattle, O=F5 Networks, OU=nginx.test, CN=self_ca_signed", + "subject_alternative_name": [], + "public_key_type": "RSA (2048 bit)", + "common_name": "self_ca_signed", + "authority_key_identifier": "3A:79:E0:3E:61:CD:94:29:1D:BB:45:37:0B:E9:78:E9:2F:40:67:CA", + "subject_key_identifier": "93:35:2B:75:09:B9:FF:01:1B:63:F1:0E:50:71:9C:4E:B4:E2:02:BA", + "thumbprint_algorithm": "SHA-256", + "thumbprint": "C1:EB:E8:CE:35:77:63:75:D3:C0:E7:97:5F:02:8C:D3:D8:C4:12:34:40:45:D3:98:67:39:BE:8A:33:CE:1F:B2" + } + }, + "PrivateKeyMetadata": { + "type": "object", + "description": "Metadata for a private key.", + "properties": { + "key_size": { + "description": "Size of the private key in bits.", "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" + "format": "int64" }, - "control_planes_count": { - "type": "integer", - "description": "The number of observed control planes using this data plane key." + "encryption_algorithm": { + "description": "The encryption algorithm used for the private key.", + "type": "string" } + }, + "example": { + "key_size": 512, + "encryption_algorithm": "RSA" } }, - "DataPlaneKeyListResponse": { + "CertificateResponse": { + "type": "object", + "description": "Response structure containing details of the created, updated or retrieved SSL certificate. In general, \nthe response should contain:\n * an overview of all the public certificates\n * `warnings` whether any issue is found after parsing the certificates and key\n * `certs`\n * `key_metadata` if key provided in the request body\n * timestamps that represent when this cert object was created or modified\n", "allOf": [ { - "$ref": "#/components/schemas/PaginationResponse" + "$ref": "#/components/schemas/CertificateOverviewMetadata" }, { "type": "object", - "description": "List of data plane keys.", - "required": [ - "items" - ], "properties": { - "items": { - "description": "An array of DataPlaneKey objects.", + "warnings": { + "type": "string", + "description": "Warnings indicate whether there are any issues with the stored cert object. Empty when no issues were found.\n" + }, + "certs": { + "description": "An array of metadata for all the public certificates under the cert object.", "type": "array", "items": { - "$ref": "#/components/schemas/DataPlaneKey" + "$ref": "#/components/schemas/CertificateMetadata" } + }, + "key": { + "$ref": "#/components/schemas/PrivateKeyMetadata" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "The date and time when the SSL certificate was created." + }, + "modified_at": { + "type": "string", + "format": "date-time", + "description": "The date and time when the SSL certificate was last modified." } } } - ] - }, - "Error": { - "description": "This object contains details about the errors that are returned when API requests fail.", - "type": "object", - "required": [ - "message", - "request_id", - "timestamp" - ], - "properties": { - "message": { - "description": "The error message describing the problem.", - "type": "string" - }, - "request_id": { - "description": "The unique identifier of the API request that failed.", - "type": "string" - }, - "timestamp": { - "description": "The date and time (in UTC) when the error happened.", - "type": "string" - }, - "detail": { - "description": "Additional information about the error, if available.", - "type": "string" - } - } - }, - "DataPlaneKeyCreateRequest": { - "type": "object", - "description": "Request structure for creating a new data plane key.", - "required": [ - "name" - ], - "properties": { - "name": { - "description": "Give the data plane key a name so you can tell it apart from others.", - "type": "string", - "minLength": 1, - "maxLength": 128 - }, - "expires_at": { - "type": "string", - "format": "date-time", - "description": "Set an expiration date and time for the data plane key in ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ. \nIf an expiration date isn't specified, the key will expire one year after it's created. \n\nYou can use the _Update a data plane key_ endpoint to extend the expiration date.\nIt's not possible to update the expiration date once the data plane key has expired.\n" - } - } - }, - "DataPlaneKeyResponse": { - "type": "object", - "description": "Response structure containing details of the created or retrieved data plane key.", - "required": [ - "key", - "object_id", - "expires_at" ], - "properties": { - "name": { - "description": "The name to be give to the new data plane key.", - "type": "string" - }, - "object_id": { - "$ref": "#/components/schemas/DataPlaneKeyObjectID" - }, + "example": { + "name": "example-cert_key", + "object_id": "cert_Tet21AeYTHCj7taOwVfzyw", + "management": "managed", + "type": "cert_key", + "status": "valid", + "subject_name": "www.example.com", + "not_before": "2023-08-10T16:59:15Z", + "not_after": "2024-08-14T16:59:15Z", + "warnings": "The provided private key does not match the certificate's signing key.", + "certs_count": 1, + "certs": [ + { + "status": "valid", + "version": 3, + "serial_number": "71283929", + "signature_algorithm": "SHA256-RSA", + "issuer": "C=US, ST=WA, L=Seattle, O=F5 Networks, OU=nginx.test, CN=eg3bsriq_cert_A", + "not_before": "2023-02-10T16:59:15Z", + "not_after": "2024-08-14T16:59:15Z", + "subject": "C=US, ST=WA, L=Seattle, O=F5 Networks, OU=nginx.test, CN=eg3bsriq_cert_B", + "subject_alternative_name": [], + "public_key_type": "RSA (2048 bit)", + "common_name": "eg3bsriq_cert_B", + "authority_key_identifier": "3A:79:E0:3E:61:CD:94:29:1D:BB:45:37:0B:E9:78:E9:2F:40:67:CA", + "subject_key_identifier": "93:35:2B:75:09:B9:FF:01:1B:63:F1:0E:50:71:9C:4E:B4:E2:02:BA", + "thumbprint_algorithm": "SHA-256", + "thumbprint": "C1:EB:E8:CE:35:77:63:75:D3:C0:E7:97:5F:02:8C:D3:D8:C4:12:34:40:45:D3:98:67:39:BE:8A:33:CE:1F:B2" + } + ], "key": { - "description": "The data plane key value. Save this key somewhere secure as it isn't saved and is shown only once.", - "type": "string" + "key_size": 512, + "encryption_algorithm": "RSA" }, - "expires_at": { - "type": "string", - "format": "date-time", - "description": "The date and time when the data plane key will expire." - } + "modified_at": "2023-11-01T00:00:00Z", + "created_at": "2023-10-01T00:00:00Z" } }, - "BulkRequestAction": { - "type": "string", - "default": "modify", - "description": "Bulk action to perform:\n * `create` creates a new object given all required elements.\n * `modify` updates one or more elements of an existing object.\n * `delete` removes the existing object.\n", - "enum": [ - "create", - "modify", - "delete" - ], - "x-enum-varnames": [ - "bulk_action_create", - "bulk_action_modify", - "bulk_action_delete" - ] - }, - "DataPlaneKeyBulkRequestData": { + "CertificateBulkRequestData": { "type": "object", - "description": "Part of bulk operation on a data plane key, only `delete` is supported.", + "description": "Part of bulk operation on a certificate, only `delete` is supported.", "required": [ "action", "object_id" ], "properties": { "object_id": { - "$ref": "#/components/schemas/DataPlaneKeyObjectID" + "$ref": "#/components/schemas/CertificateObjectID" }, "action": { "$ref": "#/components/schemas/BulkRequestAction" } }, "example": { - "object_id": "key_-uvR3F2TQGm18jnl7bpaGw", + "object_id": "cert_-uvR3F2TQGm18jnl7bpaGw", "action": "delete" } }, - "DataPlaneKeyBulkRequest": { + "CertificateBulkRequest": { "type": "array", "items": { - "$ref": "#/components/schemas/DataPlaneKeyBulkRequestData" + "$ref": "#/components/schemas/CertificateBulkRequestData" }, "minItems": 1, "maxItems": 50, "example": [ { - "object_id": "key_-uvR3F2TQGm18jnl7bpaGw", + "object_id": "cert_-uvR3F2TQGm18jnl7bpaGw", "action": "delete" }, { - "object_id": "key_PL0c1XodRemmzVEjiXSsTg", + "object_id": "cert_PL0c1XodRemmzVEjiXSsTg", "action": "delete" } ] }, - "ObjectID": { - "description": "A globally unique identifier.", - "type": "string", - "format": "object_id", - "pattern": "^\\w+_.*", - "x-go-type": "objects.ID", - "x-go-type-import": { - "name": "objects", - "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" + "CertificateBulkResponse": { + "description": "The certificate bulk operation outcome.", + "type": "array", + "items": { + "$ref": "#/components/schemas/BulkRequestObjectStatus" } }, - "BulkRequestObjectStatus": { + "PublicationBulkResponse": { + "description": "The publication bulk operation outcome.\n", + "type": "array", + "items": { + "$ref": "#/components/schemas/BulkRequestObjectStatus" + } + }, + "CertificateUpdateContent": { "type": "object", - "required": [ - "outcome" - ], + "description": "Defines the PEM-formatted certificate content which includes the certificates and corresponding private key, all encoded in base64.\n", "properties": { - "object_id": { - "$ref": "#/components/schemas/ObjectID" - }, - "name": { - "type": "string", - "description": "this is the user facing name of the object." - }, - "outcome": { + "public_certs": { "type": "string", - "description": "This is the outcome that corresponds to the action.\n* deleted - the object deletion was processed, and the object was deleted.\n* accepted - the request was accepted, and will be processed.\n* failed - the request failed, see failure_reason for more details.\n* invalid - the request was invalid, see failure_reason for more details.\n", - "enum": [ - "deleted", - "accepted", - "failed", - "invalid" - ], - "x-enum-varnames": [ - "build_request_object_status_deleted", - "build_request_object_status_accepted", - "build_request_object_status_failed", - "build_request_object_status_invalid" - ] + "format": "base64", + "maxLength": 3145728, + "description": "Base64-encoded PEM-formatted certificate information. \nThis is used for updating an existing certificate object. The schema is the same as `CertificateContent`,\nthe only difference is that both `public_certs` and `private_key` fields are optional. There are three use\ncases for this schema:\n* the below update can be done on either a Cert Key Pair or a CA Bundle:\n * when only `public_certs` is populated, update the public certificates on a certificate object. \n The updated public certificates will be validated against the existing private key.\n* the below update can be done only on a Cert Key Pair:\n * when only `private_key` is populated, update only the private key on a certificate object. \n The updated private key will be validated against the existing public certificates.\n * when both `public_certs` and `private_key` fields are populated, update both of them on a certificate \n object.\n" }, - "failure_reason": { + "private_key": { "type": "string", - "description": "this is the failure reason populated when outcome is 'failed' or 'invalid'." + "format": "base64", + "maxLength": 3145728, + "description": "Base64-encoded private key string for the leaf certificate, required only for certificate-key pairs to \nverify the certificate's authenticity.\n" } + }, + "example": { + "private_key": "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFM295ZHVlT0FOSkhodkwzeXZKZFRwaG9ldjVHTzdnbytCeVlPTy9sNTR1NU8yUHhNZVgrQWpBYjZBeG1xCmxpdkl1aHc9Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0t" } }, - "DataPlaneKeyBulkResponse": { - "description": "The data plane key bulk outcome.", - "type": "array", - "items": { - "$ref": "#/components/schemas/BulkRequestObjectStatus" - } - }, - "DataPlaneKeyUpdateRequest": { + "CertificateUpdateRequest": { "type": "object", - "description": "Request structure for updating an existing data plane key.", + "description": "Request structure for updating a certificate object. If key provided, it will be validated against the \nexisting leaf certificate stored under the certificate object.\n* Update for an unmanaged certificate object:\n * This converts the unmanaged certificate object to managed.\n * `public_certs` should always be provided during the conversion.\n * When key is provided, this certificate object is converted to a managed Cert Key Pair. Otherwise, it is\n converted to a managed CA Bundle.\n", "properties": { "name": { - "description": "Give the data plane key a new name so you can tell it apart from others.", + "description": "A name for the certificate, making it identifiable among others.", "type": "string", "minLength": 1, "maxLength": 128 }, - "expires_at": { - "type": "string", - "format": "date-time", - "description": "Adjust the expiration date and time for the data plane key in ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ. \n\nIt's not possible to update the expiration date once the data plane key has expired.\n" + "content": { + "$ref": "#/components/schemas/CertificateUpdateContent" + } + }, + "example": { + "name": "example-cert-object", + "content": { + "public_certs": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUUzb3lkdWVPQU5KSGh2TDN5dkpkVHBob2V2NUdPN2dvK0J5WU9PL2w1NHU1TzJQeE1lWCtBakFiNkF4bXEKbGl2SXVodz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQ==" } } }, - "FilterNameCertificates": { + "FilterNameCertificateDeployments": { "type": "string", - "description": "Keywords for certificates filters.\nWhen filtering on `management`, only the following `filter_values` are supported:\n * managed\n * unmanaged\nWhen filtering on `type`, only the following `filter_values` are supported:\n * cert_key\n * ca_bundle\n * unknown\nWhen filtering on `status`, only the following `filter_values` are supported:\n * valid\n * expiring\n * expired\n * not_ready\n", + "description": "Keywords for certificate deployment filters.\nWhen filtering on `association_type`, only the following `filter_values` are supported:\n * instance\n * config_sync_group\nWhen filtering on `deployment_status`, only the following `filter_values` are supported:\n * latest\n * stale\n", "enum": [ "name", - "management", - "type", - "subject_name", - "status", - "object_id" + "association_type", + "deployment_status" ], "x-enum-varnames": [ - "filter_name_certificates_name", - "filter_name_certificates_management", - "filter_name_certificates_type", - "filter_name_certificates_subject_name", - "filter_name_certificates_status", - "filter_name_certificates_object_id" + "filter_name_certificate_deployments_name", + "filter_name_certificate_deployments_association_type", + "filter_name_certificate_deployments_deployment_status" ] }, - "CertificateObjectID": { - "description": "A globally unique identifier for the certificates.", - "type": "string", - "format": "object_id", - "pattern": "^cert_.*", - "x-go-type": "objects.ID", - "x-go-type-import": { - "name": "objects", - "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" - } - }, - "CertificateManagement": { + "DeploymentAssociatedType": { "type": "string", - "description": "Management type:\n * `managed` - Certificate managed by NGINX One Console.\n * `unmanaged` - Certificate that only exists on a data plane instance, detected from its NGINX configuration.\n", + "description": "The type of the deployment association, with the following values:\n * `instance`\n * `config_sync_group`\n", "enum": [ - "managed", - "unmanaged" + "instance", + "config_sync_group" ], "x-enum-varnames": [ - "certificate_management_managed", - "certificate_management_unmanaged" + "deployment_associated_type_instance", + "deployment_associated_type_config_sync_group" ] }, - "CertificateType": { + "DeploymentAssociatedName": { "type": "string", - "description": "Certificate type:\n * `ca_bundle` - This certificate object is a CA bundle.\n * `cert_key` - This certificate object is consisted of public certificates and key.\n * `unmanaged` - This certificate is not managed by NGINX One console and its type is unmanaged.\n", - "enum": [ - "ca_bundle", - "cert_key", - "unmanaged" - ], - "x-enum-varnames": [ - "certificate_type_ca_bundle", - "certificate_type_pem_cert_key", - "certificate_type_unmanaged" - ] - }, - "CertificateObjectMetadata": { - "required": [ - "management", - "type" - ], - "properties": { - "name": { - "description": "Name of the certificate, optionally specified upon creation", - "type": "string" - }, - "object_id": { - "$ref": "#/components/schemas/CertificateObjectID" - }, - "management": { - "$ref": "#/components/schemas/CertificateManagement" - }, - "type": { - "$ref": "#/components/schemas/CertificateType" - }, - "certs_count": { - "description": "The number of public certificates under this certificate object.", - "type": "integer", - "format": "int64" - } - }, - "example": { - "name": "example-ca-bundle", - "object_id": "cert_Tet21AeYTHCj7taOwVfzyw", - "management": "managed", - "type": "ca_bundle", - "certs_count": 5 - } + "description": "Based on deployment type:\n * `instance`\n * `config_sync_group`\n" }, - "CertificateStatus": { + "CertificateDeploymentStatus": { "type": "string", - "description": "Status of the certificate:\n * `valid` - The certificate is currently valid and operational.\n * `expiring` - The certificate will expire within the next 30 days. Consider renewing it to maintain uninterrupted service.\n * `expired` - The certificate is no longer valid. Immediate renewal is recommended to ensure secure connections.\n * `not_ready` - The certificate is not ready to be used, based on the start date of its validity period.\n", + "description": "Certificate deployment status:\n * `latest` - This certificate deployment is up to date with the latest certificates and key.\n * `stale` - This certificate deployment is outdated and needs to deploy the latest certificates and key.\n * `unmanaged` - This certificate deployment is unmanaged by NGINX One Console.\n", "enum": [ - "valid", - "expiring", - "expired", - "not_ready" + "latest", + "stale", + "unmanaged" ], "x-enum-varnames": [ - "certificate_status_valid", - "certificate_status_expiring", - "certificate_status_expired", - "certificate_status_not_ready" + "certificate_deployment_status_latest", + "certificate_deployment_status_stale", + "certificate_deployment_status_unmanaged" ] }, - "CertificateDisplayMetadata": { - "description": "This represents the essential metadata of a public certificate.", + "CertificateDeployment": { "type": "object", + "description": "Response structure containing certificate deployment details for an SSL certificate, which include\n * `association_type` represents type of the object affected by this certificate deployment, which is either\n an instance or config sync group\n * `object_id` represents the object ID for the associated instance or config sync group\n * `name` for either the host name of an instance or the name of a config sync group\n * `deployment_status`:\n * `latest`: deployment is up to date with the latest updated certificate and key contents\n * `stale`: deployment for either certificates or key is outdated, requires a redeployment with the latest contents\n * `cert_paths` represents the file paths used for deploying public certificates of this certificate object\n * `key_paths` represents the file paths used for deploying the private key of this certificate object, if a\n private key is present\n", "required": [ - "subject_name", - "status", - "not_before", - "not_after" + "association_type", + "object_id", + "name", + "deployment_status" ], "properties": { - "subject_name": { - "type": "string", - "example": "www.example.com", - "description": "DNS name that identifies the certificate. If DNS is not present in the SAN extension, this will be the common name.\n" + "association_type": { + "$ref": "#/components/schemas/DeploymentAssociatedType" }, - "status": { - "$ref": "#/components/schemas/CertificateStatus" + "object_id": { + "$ref": "#/components/schemas/ObjectID" }, - "not_before": { - "type": "string", - "format": "date-time", - "example": "2023-06-12T09:12:33.001Z", - "description": "The start of the validity period for the certificate." + "name": { + "$ref": "#/components/schemas/DeploymentAssociatedName" }, - "not_after": { - "type": "string", - "format": "date-time", - "example": "2029-12-25T09:12:33.001Z", - "description": "The end of the validity period for the certificate." - } - }, - "example": { - "subject_name": "self_ca_signed", - "status": "valid", - "not_before": "2023-08-10T16:59:15Z", - "not_after": "2024-08-14T16:59:15Z" - } - }, - "CertificateOverviewMetadata": { - "description": "Represents an overview of all the public certificates under a single cert object.\nIf multiple public certificates on the same CA chain, including the leaf certificate and key are provided, \nthis includes `status`, `subject_name`, `not_before` and `not_after` for the leaf certificate.\nIf a CA bundle is provided, the above mentioned certificate metadata is for the Certificate Authority that\nexpires the soonest in the bundle.\n", - "type": "object", - "allOf": [ - { - "$ref": "#/components/schemas/CertificateObjectMetadata" + "deployment_status": { + "$ref": "#/components/schemas/CertificateDeploymentStatus" }, - { - "$ref": "#/components/schemas/CertificateDisplayMetadata" + "cert_paths": { + "description": "Deployment file paths for public certificates.", + "type": "array", + "items": { + "type": "string" + } + }, + "key_paths": { + "description": "Deployment file paths for the private key.", + "type": "array", + "items": { + "type": "string" + } } - ], + }, "example": { - "name": "example-ca-bundle", - "object_id": "cert_Tet21AeYTHCj7taOwVfzyw", - "management": "managed", - "type": "ca_bundle", - "subject_name": "self_ca_signed", - "status": "valid", - "not_before": "2023-08-10T16:59:15Z", - "not_after": "2024-08-14T16:59:15Z", - "certs_count": 5 + "association_type": "instance", + "name": "instance-host-name", + "object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", + "deployment_status": "latest", + "cert_paths": [ + "/etc/nginx/example.crt", + "/etc/nginx/certs/cert.crt" + ], + "key_paths": [ + "/etc/nginx/example.key" + ] } }, - "CertificateListResponse": { + "CertificateDeploymentListResponse": { "allOf": [ { "$ref": "#/components/schemas/PaginationResponse" }, { "type": "object", - "description": "List of SSL certificates.", + "description": "List of certificate deployments for a SSL certificate.", "required": [ "items" ], "properties": { "items": { - "description": "An array of basic metadata for all the SSL certificates in NGINX One Console. \nFor a CA bundle, an overview with metadata on the first Certificate Authority in the bundle will be displayed.\nOtherwise, an overview with metadata on the leaf certificate will be displayed.\n", + "description": "An array of certificate deployments for an SSL certificate. If this certificate object represents a \nCA bundle, there will be only public certificate file paths in the certificate deployment details.\n", "type": "array", "items": { - "$ref": "#/components/schemas/CertificateOverviewMetadata" + "$ref": "#/components/schemas/CertificateDeployment" } } } @@ -7690,494 +9813,433 @@ "items_per_page": 100, "items": [ { - "name": "example-cert_key", - "object_id": "cert_Tet21AeYTHCj7taOwVfzyw", - "management": "managed", - "type": "cert_key", - "status": "valid", - "subject_name": "www.example.com", - "not_before": "2023-08-10T16:59:15Z", - "not_after": "2024-08-14T16:59:15Z", - "certs_count": 1 + "association_type": "instance", + "name": "instance-host-name", + "object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", + "deployment_status": "latest", + "cert_paths": [ + "/etc/nginx/example.crt", + "/etc/nginx/certs/cert.crt" + ], + "key_paths": [ + "/etc/nginx/example.key" + ] }, { - "name": "example-ca-bundle", - "object_id": "cert_Tet21AeYTHCj7taOwVfzyw", - "management": "managed", - "type": "ca_bundle", - "subject_name": "self_ca_signed", - "status": "valid", - "not_before": "2023-08-10T16:59:15Z", - "not_after": "2024-08-14T16:59:15Z", - "certs_count": 5 + "association_type": "config_sync_group", + "name": "group1", + "object_id": "csg_vfr5Oqv-AhxGzyqTXW-Ubw", + "deployment_status": "stale", + "cert_paths": [ + "/etc/nginx/cert.crt" + ], + "key_paths": [ + "/etc/nginx/server.key" + ] } ] } }, - "CertificateContent": { - "type": "object", - "description": "Defines the PEM-formatted certificate content which includes the certificates and corresponding private key, all encoded in base64.\n", - "required": [ - "public_certs" - ], - "properties": { - "public_certs": { - "type": "string", - "format": "base64", - "maxLength": 3145728, - "description": "Base64-encoded PEM-formatted certificate information. \nThe `public_certs` field can include a leaf certificate along with its full chain of trust or a CA bundle. \nFor leaf certificates, the accompanying `private_key` is required to authenticate the certificate's validity. \nCA bundles contain trusted CA certificates and may consist of certificates from different CA chains. A private\nkey should not be included in a CA bundle.\n" - }, - "private_key": { - "type": "string", - "format": "base64", - "maxLength": 3145728, - "description": "Base64-encoded private key string for the leaf certificate, required only for certificate-key pairs to \nverify the certificate's authenticity.\n" - } - }, - "example": { - "public_certs": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUUzb3lkdWVPQU5KSGh2TDN5dkpkVHBob2V2NUdPN2dvK0J5WU9PL2w1NHU1TzJQeE1lWCtBakFiNkF4bXEKbGl2SXVodz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQ==" - } + "ConfigPath": { + "type": "string", + "minLength": 1, + "maxLength": 4096, + "description": "The full path to the main NGINX configuration file. This corresponds to the `--conf-path` parameter used in the NGINX binary.\n", + "example": "/etc/nginx/nginx.conf" }, - "CertificateRequest": { + "FileDataRequest": { "type": "object", - "description": "Request structure for parsing or upserting certificates with an optional private key.\n", + "description": "Details about a file, name, and content.", "required": [ - "content" + "name" ], "properties": { "name": { - "description": "A name for the certificate, making it identifiable among others.", "type": "string", + "description": "The file's relative path to the parent directory, absolute path also accepted.", "minLength": 1, - "maxLength": 128 + "maxLength": 4096 }, - "content": { - "$ref": "#/components/schemas/CertificateContent" - } - }, - "example": { - "name": "example-ca-bundle", - "content": { - "public_certs": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUUzb3lkdWVPQU5KSGh2TDN5dkpkVHBob2V2NUdPN2dvK0J5WU9PL2w1NHU1TzJQeE1lWCtBakFiNkF4bXEKbGl2SXVodz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQ==", - "private_key": "" + "contents": { + "type": "string", + "format": "byte", + "description": "The base64-encoded contents of the file.", + "maxLength": 3145728 } } }, - "CertificateMetadata": { - "description": "A comprehensive list of all the metadata for a public certificate.", + "DirectoryRequestWithFileContent": { "type": "object", + "description": "Represents a directory and its contents, detailing the directory's full path, and the files within it.", "required": [ - "status", - "serial_number", - "signature_algorithm", - "not_before", - "not_after", - "public_key_type", - "thumbprint" + "name", + "files" ], "properties": { - "status": { - "$ref": "#/components/schemas/CertificateStatus" - }, - "version": { - "type": "integer", - "format": "int64", - "example": 3, - "description": "The version of the certificate, typically 3 for X.509 certificates." - }, - "serial_number": { - "type": "string", - "example": "16469416336579571270", - "description": "A unique identifier for the certificate." - }, - "signature_algorithm": { - "type": "string", - "example": "SHA-256", - "description": "Identifies the algorithm used to sign the certificate." - }, - "issuer": { - "type": "string", - "example": "CN=Example CA, O=Certificate Authority Inc., OU=CA Department, L=City, ST=State, C=Country", - "description": "Identifies the entity who signed and issued the certificate." - }, - "not_before": { - "type": "string", - "format": "date-time", - "example": "2023-06-12T09:12:33.001Z", - "description": "The start of the validity period for the certificate." - }, - "not_after": { - "type": "string", - "format": "date-time", - "example": "2029-12-25T09:12:33.001Z", - "description": "The end of the validity period for the certificate." - }, - "subject": { + "name": { "type": "string", - "example": "CN=www.example.com, O=Example Inc., OU=IT Department, L=City, ST=State, C=Country", - "description": "Identifies the primary entity to which the certificate is issued. Typically, it contains information\nsuch as the Common Name (CN), Organization (O), Organizational Unit (OU), Country (C), etc.\n" + "minLength": 1, + "description": "The complete path of the directory." }, - "subject_alternative_name": { + "files": { "type": "array", - "items": { - "type": "string" - }, - "example": [ - "DNS:www.example.com", - "DNS:example.com", - "email:info@example.com" - ], - "description": "Defines additional identifies bound to the subject of the certificate. \nFor example, the DNS name is used to add additional domain names to a certificate.\n" - }, - "public_key_type": { - "type": "string", - "example": "RSA (2048 Bits)", - "description": "Identifies the encryption algorithm used to create the public key for the certificate." - }, - "common_name": { - "type": "string", - "example": "www.example.com", - "description": "The Common Name (CN) for the certificate, used when DNS name is not present in the SAN extension.\n" - }, - "authority_key_identifier": { - "type": "string", - "example": "2B D0 69 47 94 76 09 FE F4 6B 8D 2E 40 A6 F7 47 4D 7F 08 5E", - "description": "The identifier of the signing authority for the certificate." - }, - "subject_key_identifier": { - "type": "string", - "example": "31 EA 76 A9 23 74 A5 DF D4 FD EE A0 C1 A6 9E C6 11 0E 11 EC", - "description": "A hash value of the SSL certificate that can be used to identify certificates that \ncontain a particular public key.\n" - }, - "thumbprint_algorithm": { - "type": "string", - "example": "SHA-1", - "description": "Defines the algorithm used to hash the certificate." - }, - "thumbprint": { - "type": "string", - "example": "E6 A7 87 96 E0 C7 A3 E5 43 78 35 CA 16 78 5B 48 5A A9 DD C4 5C CD 0A 65 AA 89 33 E3 C3 D0 89 71", - "description": "A hash to ensure that the certificate has not been modified." - } - }, - "example": { - "status": "valid", - "version": 3, - "serial_number": "71283929", - "signature_algorithm": "SHA256-RSA", - "issuer": "C=US, ST=WA, L=Seattle, O=F5 Networks, OU=nginx.test, CN=eg3bsriq_cert_bundle_CA", - "not_before": "2023-02-10T16:59:15Z", - "not_after": "2024-08-14T16:59:15Z", - "subject": "C=US, ST=WA, L=Seattle, O=F5 Networks, OU=nginx.test, CN=self_ca_signed", - "subject_alternative_name": [], - "public_key_type": "RSA (2048 bit)", - "common_name": "self_ca_signed", - "authority_key_identifier": "3A:79:E0:3E:61:CD:94:29:1D:BB:45:37:0B:E9:78:E9:2F:40:67:CA", - "subject_key_identifier": "93:35:2B:75:09:B9:FF:01:1B:63:F1:0E:50:71:9C:4E:B4:E2:02:BA", - "thumbprint_algorithm": "SHA-256", - "thumbprint": "C1:EB:E8:CE:35:77:63:75:D3:C0:E7:97:5F:02:8C:D3:D8:C4:12:34:40:45:D3:98:67:39:BE:8A:33:CE:1F:B2" - } - }, - "PrivateKeyMetadata": { - "type": "object", - "description": "Metadata for a private key.", - "properties": { - "key_size": { - "description": "Size of the private key in bits.", - "type": "integer", - "format": "int64" - }, - "encryption_algorithm": { - "description": "The encryption algorithm used for the private key.", - "type": "string" + "description": "The list of files in the directory.", + "items": { + "$ref": "#/components/schemas/FileDataRequest" + } } - }, - "example": { - "key_size": 512, - "encryption_algorithm": "RSA" } }, - "CertificateResponse": { + "NginxConfigObjectRequest": { "type": "object", - "description": "Response structure containing details of the created, updated or retrieved SSL certificate. In general, \nthe response should contain:\n * an overview of all the public certificates\n * `warnings` whether any issue is found after parsing the certificates and key\n * `certs`\n * `key_metadata` if key provided in the request body\n * timestamps that represent when this cert object was created or modified\n", - "allOf": [ - { - "$ref": "#/components/schemas/CertificateOverviewMetadata" - }, - { - "type": "object", - "properties": { - "warnings": { - "type": "string", - "description": "Warnings indicate whether there are any issues with the stored cert object. Empty when no issues were found.\n" - }, - "certs": { - "description": "An array of metadata for all the public certificates under the cert object.", - "type": "array", - "items": { - "$ref": "#/components/schemas/CertificateMetadata" - } - }, - "key": { - "$ref": "#/components/schemas/PrivateKeyMetadata" - }, - "created_at": { - "type": "string", - "format": "date-time", - "description": "The date and time when the SSL certificate was created." - }, - "modified_at": { - "type": "string", - "format": "date-time", - "description": "The date and time when the SSL certificate was last modified." - } - } - } + "description": "Details of an NGINX configuration, the main configuration path, and the configuration directories.\n", + "required": [ + "configs" ], - "example": { - "name": "example-cert_key", - "object_id": "cert_Tet21AeYTHCj7taOwVfzyw", - "management": "managed", - "type": "cert_key", - "status": "valid", - "subject_name": "www.example.com", - "not_before": "2023-08-10T16:59:15Z", - "not_after": "2024-08-14T16:59:15Z", - "warnings": "The provided private key does not match the certificate's signing key.", - "certs_count": 1, - "certs": [ - { - "status": "valid", - "version": 3, - "serial_number": "71283929", - "signature_algorithm": "SHA256-RSA", - "issuer": "C=US, ST=WA, L=Seattle, O=F5 Networks, OU=nginx.test, CN=eg3bsriq_cert_A", - "not_before": "2023-02-10T16:59:15Z", - "not_after": "2024-08-14T16:59:15Z", - "subject": "C=US, ST=WA, L=Seattle, O=F5 Networks, OU=nginx.test, CN=eg3bsriq_cert_B", - "subject_alternative_name": [], - "public_key_type": "RSA (2048 bit)", - "common_name": "eg3bsriq_cert_B", - "authority_key_identifier": "3A:79:E0:3E:61:CD:94:29:1D:BB:45:37:0B:E9:78:E9:2F:40:67:CA", - "subject_key_identifier": "93:35:2B:75:09:B9:FF:01:1B:63:F1:0E:50:71:9C:4E:B4:E2:02:BA", - "thumbprint_algorithm": "SHA-256", - "thumbprint": "C1:EB:E8:CE:35:77:63:75:D3:C0:E7:97:5F:02:8C:D3:D8:C4:12:34:40:45:D3:98:67:39:BE:8A:33:CE:1F:B2" + "properties": { + "config_version": { + "type": "string", + "description": "A hash that uniquely identifies the contents of the config object. Can be used to detect change when updating the NginxConfig.\n" + }, + "conf_path": { + "$ref": "#/components/schemas/ConfigPath" + }, + "configs": { + "type": "array", + "description": "An array of directories containing NGINX configuration files.", + "items": { + "$ref": "#/components/schemas/DirectoryRequestWithFileContent" } - ], - "key": { - "key_size": 512, - "encryption_algorithm": "RSA" }, - "modified_at": "2023-11-01T00:00:00Z", - "created_at": "2023-10-01T00:00:00Z" + "aux": { + "type": "array", + "description": "An array of auxiliary directory contents related to the NGINX configuration. When auxiliary contents are\nprovided, they become the authoritative source of non-NGINX configuration content. Please ensure the\nprovided contents are complete, missing files that are referenced in the NGINX configuration can cause\nNGINX reload failure. When not provided, the previous known auxiliary contents will be used as part of\npublish.\n", + "items": { + "$ref": "#/components/schemas/DirectoryRequestWithFileContent" + } + } } }, - "CertificateBulkRequestData": { + "NginxConfigPayloadContents": { + "type": "string", + "format": "base64", + "description": "The base64-encoded contents of the file.", + "maxLength": 3145728 + }, + "PayloadObjectID": { + "description": "A globally unique identifier for the valid payload object reference.", + "type": "string", + "format": "object_id", + "pattern": "^(cert|pv|lp)_.*", + "x-go-type": "objects.ID", + "x-go-type-import": { + "name": "objects", + "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" + } + }, + "NginxConfigPayloadPaths": { + "type": "array", + "items": { + "type": "string" + } + }, + "NginxConfigPayload": { "type": "object", - "description": "Part of bulk operation on a certificate, only `delete` is supported.", + "description": "Details of Aux File Payload that goes with an NGINX configuration. Provide hints for the backend system on \nadditional file contents that should be part of the NGINX Config Publication.\nCan be used to deploy files related to SSL certificates, WAF policies and WAF log profiles to a data plane instance.\n", "required": [ - "action", - "object_id" + "type", + "paths" ], "properties": { + "type": { + "type": "string", + "description": "Types of Aux File Payload:\n - inline_secret - indicates the provided content for the payload should be stored in a secret location, and removed after the publication is done.\n - inline_content - indicates the provided content for the payload should be stored, and removed after the publication is done. Note, the contents may end up in the `aux` content if used in this NGINX configuration.\n - unmanaged_certificate - indicates certificate content for an unmanaged certificate detected from a data plane instance through NGINX configurations. Will be filtered and ignored in the payload deployment.\n - managed_certificate - indicates public certificates managed by NGINX One Console.\n - managed_key - indicates a private key managed by NGINX One Console.\n - nap_policy_version - indicates a version of WAF policy managed by NGINX One Console.\n - nap_log_profile - indicates a WAF log profile managed by NGINX One Console.\n", + "enum": [ + "inline_secret", + "inline_content", + "unmanaged_certificate", + "managed_certificate", + "managed_key", + "nap_policy_version", + "nap_log_profile" + ], + "x-enum-varnames": [ + "nginx_config_payload_inline_secret", + "nginx_config_payload_inline_content", + "nginx_config_payload_unmanaged_certificate", + "nginx_config_payload_managed_certificate", + "nginx_config_payload_managed_key", + "nginx_config_payload_nap_policy_version", + "nginx_config_payload_nap_log_profile" + ] + }, + "contents": { + "$ref": "#/components/schemas/NginxConfigPayloadContents" + }, "object_id": { - "$ref": "#/components/schemas/CertificateObjectID" + "$ref": "#/components/schemas/PayloadObjectID" }, - "action": { - "$ref": "#/components/schemas/BulkRequestAction" + "paths": { + "$ref": "#/components/schemas/NginxConfigPayloadPaths" } }, "example": { - "object_id": "cert_-uvR3F2TQGm18jnl7bpaGw", - "action": "delete" + "type": "inline_content", + "contents": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURUVENDQWpXZ0F3SUJBZ0lVVkcycitidUwwRk83U1FVeUtoVkNTN3YyRHZZd0RRWUpLb1pJaHZjTkFRRUwKQlFBd05qRVNNQkFHQTFVRUF3d0piRzlqWVd4b2IzTjBNUk13RVFZRFZRUUtEQXBPUjBsT1dDQkpibU11TVFzdwpDUVlEVlFRR0V3SlZVekFlRncweU5EQTBNall5TURVeE5ERmFGdzB5TkRBME1qY3lNRFV4TkRGYU1EWXhFakFRCkJnTlZCQU1NQ1d4dlkyRnNhRzl6ZERFVE1CRUdBMVVFQ2d3S1RrZEpUbGdnU1c1akxqRUxNQWtHQTFVRUJoTUMKVlZNd2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUUMyb0FJVU9HMkxGMFVGclpMeQp5aWhZRjBZWjdYTWFYZnZ4dWJMYVZZdUdJNjlYN1FQRUJtUXp2OXdod25aUktDUExDZHVCNG04Y0o3Q3BGenRHCldPYVFMbmNxVVA4RFU1aHlQeFBSbmZUdFFBcUdiMDJRZ1RVQXY1QkpJMFZheGhCcnNaemd0KzgyM3ZoTTZTUHcKMGdSc1NZRlFpKzVDWW9MMWZNSWdhS0N2Ri9zZGl5cHZFQ0JDZVZyTWZFZ0pGSVJBQ1kvdFBzdEsvTkxwKzlmawppZ3hFMlYxcldoSGdvRmhZRm5YYnVqM2RIMHJLai9DVlM5anZMMk9vRTlvenM5MkRVLytySGJ6eFR3QndVQjBzCmVPS2hPY2d2cENyTVlSUWxUUlhmWVJmV0NLN2Q2Mk1JR3kvajcvV1VieDFOYzl4MjJzUitydVRlZkxnRTA2NWgKMldDZkFnTUJBQUdqVXpCUk1CMEdBMVVkRGdRV0JCUnZnamkxWlByZlVBMnRlWlRMUGE0djlzdHFXakFmQmdOVgpIU01FR0RBV2dCUnZnamkxWlByZlVBMnRlWlRMUGE0djlzdHFXakFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTBHCkNTcUdTSWIzRFFFQkN3VUFBNElCQVFCNC9VM3lrMFYzMTFNRFQvaEttbFJ4MWRqalRyMlhIQnVEcXZYY3BIRTQKVDJwZ0xnWURwN2tmUTQrdnlHWUt1cndEc0F1VDhEZCtUUUZLZEIraEFGRzMyazlxS1RyY1ZCZ2tNSjIwQitvWQp4T2diWW5zVnpiTDhXL0hOR3BlbDkrbThwYURtMGRXNzhMUit5UnJleDVlY2pjYWlZMDg3b0dHNlJDeWhyUVd4CkpkdkFvNlU1ejl3TnVhNmMyNlY2cy84Yit6SkJWektGZ0tQNVVGL2lIcGJVNW1QcVMwWlk4ckhRLzZPTHRGRjgKZ1J2UUlRZjZLSjRmOXlUOFBYSHBIdGJCMzEzaWh2Z09wWW9la3lIWTZaSmllTWhkd0J4MzB1N3d2Uy9POEluYwpsZWZzTkxUcWFTM2JWdldLeUFaVlZyenFtU043aGh4QWZrc0RZelBFbkF3OAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0t", + "paths": [ + "/etc/nginx/ssl/server.crt" + ] } }, - "CertificateBulkRequest": { + "NginxConfigPayloads": { "type": "array", + "description": "An array of payloads that define which objects should be deployed and the file paths where each object will be placed on the data plane instance.\n* When the type is `managed_certificate`, `managed_key`, `nap_policy_version`, or `nap_log_profile`, you must specify an `object_id`. \nThe `object_id` must refer to a managed object.\n* The NGINX One Console manages deployed file paths only for managed certificates and keys. If you don't want \nthem to be managed by NGINX One Console, `inline_content` and `inline_secret` can be used for certificates or \nkeys respectively, with `contents`. When you retrieve certificate deployment details, \nonly the file paths of managed certificates and keys will be shown.\n* If you use `inline_content` and `inline_secret` in your NGINX configuration, the NGINX One Console \nwill detect them. When they are used as SSL directives of the NGINX configuration \nfor certificates and keys, the certificates will be listed as `unmanaged_certificate` in the certificate \ndeployment details.\n", "items": { - "$ref": "#/components/schemas/CertificateBulkRequestData" + "$ref": "#/components/schemas/NginxConfigPayload" }, - "minItems": 1, - "maxItems": 50, "example": [ { - "object_id": "cert_-uvR3F2TQGm18jnl7bpaGw", - "action": "delete" + "type": "managed_certificate", + "object_id": "cert_rto8NYiCQputrIasNx2NOA", + "paths": [ + "/etc/nginx/cert.pem" + ] }, { - "object_id": "cert_PL0c1XodRemmzVEjiXSsTg", - "action": "delete" + "type": "managed_key", + "object_id": "cert_rto8NYiCQputrIasNx2NOA", + "paths": [ + "/etc/nginx/key.pem" + ] + }, + { + "type": "inline_content", + "contents": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURUVENDQWpXZ0F3SUJBZ0lVVkcycitidUwwRk83U1FVeUtoVkNTN3YyRHZZd0RRWUpLb1pJaHZjTkFRRUwKQlFBd05qRVNNQkFHQTFVRUF3d0piRzlqWVd4b2IzTjBNUk13RVFZRFZRUUtEQXBPUjBsT1dDQkpibU11TVFzdwpDUVlEVlFRR0V3SlZVekFlRncweU5EQTBNall5TURVeE5ERmFGdzB5TkRBME1qY3lNRFV4TkRGYU1EWXhFakFRCkJnTlZCQU1NQ1d4dlkyRnNhRzl6ZERFVE1CRUdBMVVFQ2d3S1RrZEpUbGdnU1c1akxqRUxNQWtHQTFVRUJoTUMKVlZNd2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUUMyb0FJVU9HMkxGMFVGclpMeQp5aWhZRjBZWjdYTWFYZnZ4dWJMYVZZdUdJNjlYN1FQRUJtUXp2OXdod25aUktDUExDZHVCNG04Y0o3Q3BGenRHCldPYVFMbmNxVVA4RFU1aHlQeFBSbmZUdFFBcUdiMDJRZ1RVQXY1QkpJMFZheGhCcnNaemd0KzgyM3ZoTTZTUHcKMGdSc1NZRlFpKzVDWW9MMWZNSWdhS0N2Ri9zZGl5cHZFQ0JDZVZyTWZFZ0pGSVJBQ1kvdFBzdEsvTkxwKzlmawppZ3hFMlYxcldoSGdvRmhZRm5YYnVqM2RIMHJLai9DVlM5anZMMk9vRTlvenM5MkRVLytySGJ6eFR3QndVQjBzCmVPS2hPY2d2cENyTVlSUWxUUlhmWVJmV0NLN2Q2Mk1JR3kvajcvV1VieDFOYzl4MjJzUitydVRlZkxnRTA2NWgKMldDZkFnTUJBQUdqVXpCUk1CMEdBMVVkRGdRV0JCUnZnamkxWlByZlVBMnRlWlRMUGE0djlzdHFXakFmQmdOVgpIU01FR0RBV2dCUnZnamkxWlByZlVBMnRlWlRMUGE0djlzdHFXakFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTBHCkNTcUdTSWIzRFFFQkN3VUFBNElCQVFCNC9VM3lrMFYzMTFNRFQvaEttbFJ4MWRqalRyMlhIQnVEcXZYY3BIRTQKVDJwZ0xnWURwN2tmUTQrdnlHWUt1cndEc0F1VDhEZCtUUUZLZEIraEFGRzMyazlxS1RyY1ZCZ2tNSjIwQitvWQp4T2diWW5zVnpiTDhXL0hOR3BlbDkrbThwYURtMGRXNzhMUit5UnJleDVlY2pjYWlZMDg3b0dHNlJDeWhyUVd4CkpkdkFvNlU1ejl3TnVhNmMyNlY2cy84Yit6SkJWektGZ0tQNVVGL2lIcGJVNW1QcVMwWlk4ckhRLzZPTHRGRjgKZ1J2UUlRZjZLSjRmOXlUOFBYSHBIdGJCMzEzaWh2Z09wWW9la3lIWTZaSmllTWhkd0J4MzB1N3d2Uy9POEluYwpsZWZzTkxUcWFTM2JWdldLeUFaVlZyenFtU043aGh4QWZrc0RZelBFbkF3OAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0t", + "paths": [ + "/etc/nginx/inline_cert.crt" + ] + }, + { + "type": "nap_policy_version", + "object_id": "pv_dM68MUcVTe6pfDaCNsM9Qw", + "paths": [ + "/etc/nginx/strict_policy.tgz" + ] + }, + { + "type": "nap_log_profile", + "object_id": "lp_dM68MUcVTe6pfDaCNsM9Qw", + "paths": [ + "/etc/nginx/log_all.tgz" + ] } ] }, - "CertificateBulkResponse": { - "description": "The certificate bulk operation outcome.", - "type": "array", - "items": { - "$ref": "#/components/schemas/BulkRequestObjectStatus" - } - }, - "PublicationBulkResponse": { - "description": "The publication bulk operation outcome.\n", - "type": "array", - "items": { - "$ref": "#/components/schemas/BulkRequestObjectStatus" - } + "NginxConfigRequest": { + "allOf": [ + { + "$ref": "#/components/schemas/NginxConfigObjectRequest" + }, + { + "type": "object", + "properties": { + "payloads": { + "$ref": "#/components/schemas/NginxConfigPayloads" + } + } + } + ] }, - "CertificateUpdateContent": { + "NginxConfigProblem": { "type": "object", - "description": "Defines the PEM-formatted certificate content which includes the certificates and corresponding private key, all encoded in base64.\n", + "description": "Representation of a problem found during NGINX configuration analysis.", "properties": { - "public_certs": { - "type": "string", - "format": "base64", - "maxLength": 3145728, - "description": "Base64-encoded PEM-formatted certificate information. \nThis is used for updating an existing certificate object. The schema is the same as `CertificateContent`,\nthe only difference is that both `public_certs` and `private_key` fields are optional. There are three use\ncases for this schema:\n* the below update can be done on either a Cert Key Pair or a CA Bundle:\n * when only `public_certs` is populated, update the public certificates on a certificate object. \n The updated public certificates will be validated against the existing private key.\n* the below update can be done only on a Cert Key Pair:\n * when only `private_key` is populated, update only the private key on a certificate object. \n The updated private key will be validated against the existing public certificates.\n * when both `public_certs` and `private_key` fields are populated, update both of them on a certificate \n object.\n" + "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" }, - "private_key": { - "type": "string", - "format": "base64", - "maxLength": 3145728, - "description": "Base64-encoded private key string for the leaf certificate, required only for certificate-key pairs to \nverify the certificate's authenticity.\n" + "message": { + "description": "Details about the identified issue.", + "type": "string" } - }, - "example": { - "private_key": "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFM295ZHVlT0FOSkhodkwzeXZKZFRwaG9ldjVHTzdnbytCeVlPTy9sNTR1NU8yUHhNZVgrQWpBYjZBeG1xCmxpdkl1aHc9Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0t" } }, - "CertificateUpdateRequest": { + "NginxConfigReport": { "type": "object", - "description": "Request structure for updating a certificate object. If key provided, it will be validated against the \nexisting leaf certificate stored under the certificate object.\n* Update for an unmanaged certificate object:\n * This converts the unmanaged certificate object to managed.\n * `public_certs` should always be provided during the conversion.\n * When key is provided, this certificate object is converted to a managed Cert Key Pair. Otherwise, it is\n converted to a managed CA Bundle.\n", + "description": "An analysis of the NGINX configuration, highlighting issues and their severity, and offering recommendations.", "properties": { - "name": { - "description": "A name for the certificate, making it identifiable among others.", - "type": "string", - "minLength": 1, - "maxLength": 128 + "rule": { + "description": "The name of the configuration rule that was violated.", + "type": "string" }, - "content": { - "$ref": "#/components/schemas/CertificateUpdateContent" - } - }, - "example": { - "name": "example-cert-object", - "content": { - "public_certs": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUUzb3lkdWVPQU5KSGh2TDN5dkpkVHBob2V2NUdPN2dvK0J5WU9PL2w1NHU1TzJQeE1lWCtBakFiNkF4bXEKbGl2SXVodz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQ==" + "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" + } } } }, - "FilterNameCertificateDeployments": { - "type": "string", - "description": "Keywords for certificate deployment filters.\nWhen filtering on `association_type`, only the following `filter_values` are supported:\n * instance\n * config_sync_group\nWhen filtering on `deployment_status`, only the following `filter_values` are supported:\n * latest\n * stale\n", - "enum": [ - "name", - "association_type", - "deployment_status" - ], - "x-enum-varnames": [ - "filter_name_certificate_deployments_name", - "filter_name_certificate_deployments_association_type", - "filter_name_certificate_deployments_deployment_status" - ] + "NginxConfigReports": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NginxConfigReport" + } }, - "DeploymentAssociatedType": { + "FilterNameConfigSyncGroups": { "type": "string", - "description": "The type of the deployment association, with the following values:\n * `instance`\n * `config_sync_group`\n", + "description": "Keywords for config sync groups filters.\nWhen filtering on `config_status`, only the following `filter_values` are supported:\n * in_sync\n * out_of_sync\n * sync_in_progress\n * unknown\n", "enum": [ - "instance", - "config_sync_group" + "name", + "config_status", + "object_id" ], "x-enum-varnames": [ - "deployment_associated_type_instance", - "deployment_associated_type_config_sync_group" + "filter_name_config_sync_group_name", + "filter_name_config_sync_group_config_status", + "filter_name_config_sync_group_object_id" ] }, - "DeploymentAssociatedName": { + "ConfigSyncGroupObjectID": { + "description": "A globally unique identifier for the NGINX config sync group.", "type": "string", - "description": "Based on deployment type:\n * `instance`\n * `config_sync_group`\n" + "format": "object_id", + "pattern": "^csg_.*", + "x-go-type": "objects.ID", + "x-go-type-import": { + "name": "objects", + "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" + } }, - "CertificateDeploymentStatus": { + "ConfigSyncStatus": { "type": "string", - "description": "Certificate deployment status:\n * `latest` - This certificate deployment is up to date with the latest certificates and key.\n * `stale` - This certificate deployment is outdated and needs to deploy the latest certificates and key.\n * `unmanaged` - This certificate deployment is unmanaged by NGINX One Console.\n", + "description": "The current config sync status of the NGINX config sync group, with the following possible values:\n* `unknown` - The status cannot be determined at this moment.\n* `in_sync` - All NGINX instances in config sync group have same config as indicated by config_version.\n* `out_of_sync` - Some NGINX instances in config sync group have config different than indicated by config_version.\n* `sync_in_progress` - The operation of applying config_version to all NGINX instances in config sync group is in progress.\n", "enum": [ - "latest", - "stale", - "unmanaged" + "unknown", + "in_sync", + "out_of_sync", + "sync_in_progress" ], "x-enum-varnames": [ - "certificate_deployment_status_latest", - "certificate_deployment_status_stale", - "certificate_deployment_status_unmanaged" + "nginx_config_sync_group_config_status_unknown", + "nginx_config_sync_group_config_status_in_sync", + "nginx_config_sync_group_config_status_out_of_sync", + "nginx_config_sync_group_config_status_in_progress" ] }, - "CertificateDeployment": { + "CertificateInstanceSummary": { + "description": "A breakdown and tally of certificates, detailing the total count, number of expired certificates, certificates nearing expiration, and those that are valid.", "type": "object", - "description": "Response structure containing certificate deployment details for an SSL certificate, which include\n * `association_type` represents type of the object affected by this certificate deployment, which is either\n an instance or config sync group\n * `object_id` represents the object ID for the associated instance or config sync group\n * `name` for either the host name of an instance or the name of a config sync group\n * `deployment_status`:\n * `latest`: deployment is up to date with the latest updated certificate and key contents\n * `stale`: deployment for either certificates or key is outdated, requires a redeployment with the latest contents\n * `cert_paths` represents the file paths used for deploying public certificates of this certificate object\n * `key_paths` represents the file paths used for deploying the private key of this certificate object, if a\n private key is present\n", "required": [ - "association_type", + "total", + "expired", + "expiring", + "valid", + "not_ready" + ], + "properties": { + "total": { + "description": "Total count of certificates across the NGINX data plane.", + "type": "integer" + }, + "expired": { + "description": "The number of certificates that have expired and are no longer valid.", + "type": "integer" + }, + "expiring": { + "description": "The number of certificates due to expire in the next 30 days.", + "type": "integer" + }, + "valid": { + "description": "The number of certificates that are valid and in good standing.", + "type": "integer" + }, + "not_ready": { + "description": "The number of certificates that are not ready to be used.", + "type": "integer" + } + } + }, + "ListConfigSyncGroupObject": { + "type": "object", + "description": "Summary information of the NGINX config sync group.", + "required": [ "object_id", "name", - "deployment_status" + "created_at", + "instances_count", + "config_status" ], "properties": { - "association_type": { - "$ref": "#/components/schemas/DeploymentAssociatedType" - }, "object_id": { - "$ref": "#/components/schemas/ObjectID" + "$ref": "#/components/schemas/ConfigSyncGroupObjectID" }, "name": { - "$ref": "#/components/schemas/DeploymentAssociatedName" + "description": "Name of the NGINX config sync group.", + "type": "string" }, - "deployment_status": { - "$ref": "#/components/schemas/CertificateDeploymentStatus" + "created_at": { + "description": "The date and time when the config sync group was created.", + "type": "string", + "format": "date-time" }, - "cert_paths": { - "description": "Deployment file paths for public certificates.", - "type": "array", - "items": { - "type": "string" - } + "instances_count": { + "description": "Number of instances in the NGINX config sync group.", + "type": "integer" }, - "key_paths": { - "description": "Deployment file paths for the private key.", - "type": "array", - "items": { - "type": "string" - } + "config_status": { + "$ref": "#/components/schemas/ConfigSyncStatus" + }, + "cert_summary": { + "$ref": "#/components/schemas/CertificateInstanceSummary" } - }, - "example": { - "association_type": "instance", - "name": "instance-host-name", - "object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", - "deployment_status": "latest", - "cert_paths": [ - "/etc/nginx/example.crt", - "/etc/nginx/certs/cert.crt" - ], - "key_paths": [ - "/etc/nginx/example.key" - ] } }, - "CertificateDeploymentListResponse": { + "ConfigSyncGroupListResponse": { "allOf": [ { "$ref": "#/components/schemas/PaginationResponse" }, { "type": "object", - "description": "List of certificate deployments for a SSL certificate.", + "description": "List of NGINX config sync groups.", "required": [ "items" ], "properties": { "items": { - "description": "An array of certificate deployments for an SSL certificate. If this certificate object represents a \nCA bundle, there will be only public certificate file paths in the certificate deployment details.\n", + "description": "An array of Config Sync Group objects.", "type": "array", "items": { - "$ref": "#/components/schemas/CertificateDeployment" + "$ref": "#/components/schemas/ListConfigSyncGroupObject" } } } @@ -8185,2413 +10247,2527 @@ ], "example": { "total": 10, - "count": 2, + "count": 1, "start_index": 1, "items_per_page": 100, "items": [ { - "association_type": "instance", - "name": "instance-host-name", - "object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", - "deployment_status": "latest", - "cert_paths": [ - "/etc/nginx/example.crt", - "/etc/nginx/certs/cert.crt" - ], - "key_paths": [ - "/etc/nginx/example.key" - ] - }, - { - "association_type": "config_sync_group", - "name": "group1", - "object_id": "csg_vfr5Oqv-AhxGzyqTXW-Ubw", - "deployment_status": "stale", - "cert_paths": [ - "/etc/nginx/cert.crt" - ], - "key_paths": [ - "/etc/nginx/server.key" - ] + "object_id": "csg_-uvR3F2TQGm18jnl7bpaGw", + "name": "test-config-sync-group", + "created_at": "2023-12-05T22:30:20.220114Z", + "config_status": "in_sync", + "instances_count": 1 } ] } }, - "ConfigPath": { - "type": "string", - "minLength": 1, - "maxLength": 4096, - "description": "The full path to the main NGINX configuration file. This corresponds to the `--conf-path` parameter used in the NGINX binary.\n", - "example": "/etc/nginx/nginx.conf" - }, - "FileDataRequest": { - "type": "object", - "description": "Details about a file, name, and content.", + "ConfigSyncGroupCreateRequest": { + "description": "Body to create a NGINX config sync group.", "required": [ "name" ], "properties": { "name": { "type": "string", - "description": "The file's relative path to the parent directory, absolute path also accepted.", + "description": "A name to uniquely identify the NGINX config sync group in a given tenant namespace.", "minLength": 1, - "maxLength": 4096 - }, - "contents": { - "type": "string", - "format": "byte", - "description": "The base64-encoded contents of the file.", - "maxLength": 3145728 + "maxLength": 256, + "pattern": "^[a-zA-Z0-9]([a-zA-Z0-9-_]{0,254}[a-zA-Z0-9])?$" } + }, + "example": { + "name": "my-nginx-config-sync-group" } }, - "DirectoryRequestWithFileContent": { - "type": "object", - "description": "Represents a directory and its contents, detailing the directory's full path, and the files within it.", + "ConfigSyncGroupCreateResponse": { + "description": "Response to a create NGINX config sync group request.", "required": [ - "name", - "files" + "object_id", + "name" ], "properties": { - "name": { - "type": "string", - "minLength": 1, - "description": "The complete path of the directory." + "object_id": { + "$ref": "#/components/schemas/ConfigSyncGroupObjectID" }, - "files": { - "type": "array", - "description": "The list of files in the directory.", - "items": { - "$ref": "#/components/schemas/FileDataRequest" - } + "name": { + "description": "Name of the NGINX config sync group.", + "type": "string" } + }, + "example": { + "name": "my-nginx-config-sync-group", + "object_id": "csg_Tet21AeYTHCj7taOwVfzyw" } }, - "NginxConfigObjectRequest": { + "ConfigSyncGroupBulkRequestData": { "type": "object", - "description": "Details of an NGINX configuration, the main configuration path, and the configuration directories.\n", + "description": "Part of bulk operation on a config sync group, only `delete` is supported.", "required": [ - "configs" + "action", + "object_id" ], "properties": { - "config_version": { - "type": "string", - "description": "A hash that uniquely identifies the contents of the config object. Can be used to detect change when updating the NginxConfig.\n" - }, - "conf_path": { - "$ref": "#/components/schemas/ConfigPath" - }, - "configs": { - "type": "array", - "description": "An array of directories containing NGINX configuration files.", - "items": { - "$ref": "#/components/schemas/DirectoryRequestWithFileContent" - } + "object_id": { + "$ref": "#/components/schemas/ConfigSyncGroupObjectID" }, - "aux": { - "type": "array", - "description": "An array of auxiliary directory contents related to the NGINX configuration. When auxiliary contents are\nprovided, they become the authoritative source of non-NGINX configuration content. Please ensure the\nprovided contents are complete, missing files that are referenced in the NGINX configuration can cause\nNGINX reload failure. When not provided, the previous known auxiliary contents will be used as part of\npublish.\n", - "items": { - "$ref": "#/components/schemas/DirectoryRequestWithFileContent" - } + "action": { + "$ref": "#/components/schemas/BulkRequestAction" } + }, + "example": { + "object_id": "csg_-uvR3F2TQGm18jnl7bpaGw", + "action": "delete" } }, - "NginxConfigPayloadContents": { - "type": "string", - "format": "base64", - "description": "The base64-encoded contents of the file.", - "maxLength": 3145728 - }, - "PayloadObjectID": { - "description": "A globally unique identifier for the valid payload object reference.", - "type": "string", - "format": "object_id", - "pattern": "^(cert|pv|lp)_.*", - "x-go-type": "objects.ID", - "x-go-type-import": { - "name": "objects", - "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" - } + "ConfigSyncGroupBulkRequest": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigSyncGroupBulkRequestData" + }, + "minItems": 1, + "maxItems": 50, + "example": [ + { + "object_id": "csg_-uvR3F2TQGm18jnl7bpaGw", + "action": "delete" + }, + { + "object_id": "csg_PL0c1XodRemmzVEjiXSsTg", + "action": "delete" + } + ] }, - "NginxConfigPayloadPaths": { + "ConfigSyncGroupBulkResponse": { + "description": "The config sync group bulk outcome.", "type": "array", "items": { - "type": "string" + "$ref": "#/components/schemas/BulkRequestObjectStatus" } }, - "NginxConfigPayload": { + "ConfigSyncGroupMeta": { "type": "object", - "description": "Details of Aux File Payload that goes with an NGINX configuration. Provide hints for the backend system on \nadditional file contents that should be part of the NGINX Config Publication.\nCan be used to deploy files related to SSL certificates, WAF policies and WAF log profiles to a data plane instance.\n", + "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": [ - "type", - "paths" + "object_id", + "name", + "created_at" ], "properties": { - "type": { - "type": "string", - "description": "Types of Aux File Payload:\n - inline_secret - indicates the provided content for the payload should be stored in a secret location, and removed after the publication is done.\n - inline_content - indicates the provided content for the payload should be stored, and removed after the publication is done. Note, the contents may end up in the `aux` content if used in this NGINX configuration.\n - unmanaged_certificate - indicates certificate content for an unmanaged certificate detected from a data plane instance through NGINX configurations. Will be filtered and ignored in the payload deployment.\n - managed_certificate - indicates public certificates managed by NGINX One Console.\n - managed_key - indicates a private key managed by NGINX One Console.\n - nap_policy_version - indicates a version of WAF policy managed by NGINX One Console.\n - nap_log_profile - indicates a WAF log profile managed by NGINX One Console.\n", - "enum": [ - "inline_secret", - "inline_content", - "unmanaged_certificate", - "managed_certificate", - "managed_key", - "nap_policy_version", - "nap_log_profile" - ], - "x-enum-varnames": [ - "nginx_config_payload_inline_secret", - "nginx_config_payload_inline_content", - "nginx_config_payload_unmanaged_certificate", - "nginx_config_payload_managed_certificate", - "nginx_config_payload_managed_key", - "nginx_config_payload_nap_policy_version", - "nginx_config_payload_nap_log_profile" - ] + "object_id": { + "$ref": "#/components/schemas/ConfigSyncGroupObjectID" }, - "contents": { - "$ref": "#/components/schemas/NginxConfigPayloadContents" + "name": { + "description": "Name of the NGINX config sync group.", + "type": "string" }, - "object_id": { - "$ref": "#/components/schemas/PayloadObjectID" + "last_publication": { + "description": "The date and time of the most recent config sync group publication.", + "type": "string", + "format": "date-time" }, - "paths": { - "$ref": "#/components/schemas/NginxConfigPayloadPaths" + "created_at": { + "description": "The date and time when the config sync group was created.", + "type": "string", + "format": "date-time" } }, "example": { - "type": "inline_content", - "contents": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURUVENDQWpXZ0F3SUJBZ0lVVkcycitidUwwRk83U1FVeUtoVkNTN3YyRHZZd0RRWUpLb1pJaHZjTkFRRUwKQlFBd05qRVNNQkFHQTFVRUF3d0piRzlqWVd4b2IzTjBNUk13RVFZRFZRUUtEQXBPUjBsT1dDQkpibU11TVFzdwpDUVlEVlFRR0V3SlZVekFlRncweU5EQTBNall5TURVeE5ERmFGdzB5TkRBME1qY3lNRFV4TkRGYU1EWXhFakFRCkJnTlZCQU1NQ1d4dlkyRnNhRzl6ZERFVE1CRUdBMVVFQ2d3S1RrZEpUbGdnU1c1akxqRUxNQWtHQTFVRUJoTUMKVlZNd2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUUMyb0FJVU9HMkxGMFVGclpMeQp5aWhZRjBZWjdYTWFYZnZ4dWJMYVZZdUdJNjlYN1FQRUJtUXp2OXdod25aUktDUExDZHVCNG04Y0o3Q3BGenRHCldPYVFMbmNxVVA4RFU1aHlQeFBSbmZUdFFBcUdiMDJRZ1RVQXY1QkpJMFZheGhCcnNaemd0KzgyM3ZoTTZTUHcKMGdSc1NZRlFpKzVDWW9MMWZNSWdhS0N2Ri9zZGl5cHZFQ0JDZVZyTWZFZ0pGSVJBQ1kvdFBzdEsvTkxwKzlmawppZ3hFMlYxcldoSGdvRmhZRm5YYnVqM2RIMHJLai9DVlM5anZMMk9vRTlvenM5MkRVLytySGJ6eFR3QndVQjBzCmVPS2hPY2d2cENyTVlSUWxUUlhmWVJmV0NLN2Q2Mk1JR3kvajcvV1VieDFOYzl4MjJzUitydVRlZkxnRTA2NWgKMldDZkFnTUJBQUdqVXpCUk1CMEdBMVVkRGdRV0JCUnZnamkxWlByZlVBMnRlWlRMUGE0djlzdHFXakFmQmdOVgpIU01FR0RBV2dCUnZnamkxWlByZlVBMnRlWlRMUGE0djlzdHFXakFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTBHCkNTcUdTSWIzRFFFQkN3VUFBNElCQVFCNC9VM3lrMFYzMTFNRFQvaEttbFJ4MWRqalRyMlhIQnVEcXZYY3BIRTQKVDJwZ0xnWURwN2tmUTQrdnlHWUt1cndEc0F1VDhEZCtUUUZLZEIraEFGRzMyazlxS1RyY1ZCZ2tNSjIwQitvWQp4T2diWW5zVnpiTDhXL0hOR3BlbDkrbThwYURtMGRXNzhMUit5UnJleDVlY2pjYWlZMDg3b0dHNlJDeWhyUVd4CkpkdkFvNlU1ejl3TnVhNmMyNlY2cy84Yit6SkJWektGZ0tQNVVGL2lIcGJVNW1QcVMwWlk4ckhRLzZPTHRGRjgKZ1J2UUlRZjZLSjRmOXlUOFBYSHBIdGJCMzEzaWh2Z09wWW9la3lIWTZaSmllTWhkd0J4MzB1N3d2Uy9POEluYwpsZWZzTkxUcWFTM2JWdldLeUFaVlZyenFtU043aGh4QWZrc0RZelBFbkF3OAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0t", - "paths": [ - "/etc/nginx/ssl/server.crt" - ] + "object_id": "csg_-uvR3F2TQGm18jnl7bpaGw", + "name": "test-config-sync-group", + "last_publication": "2023-12-06T22:37:24.120114Z", + "created_at": "2023-12-05T22:30:20.220114Z" } }, - "NginxConfigPayloads": { - "type": "array", - "description": "An array of payloads that define which objects should be deployed and the file paths where each object will be placed on the data plane instance.\n* When the type is `managed_certificate`, `managed_key`, `nap_policy_version`, or `nap_log_profile`, you must specify an `object_id`. \nThe `object_id` must refer to a managed object.\n* The NGINX One Console manages deployed file paths only for managed certificates and keys. If you don't want \nthem to be managed by NGINX One Console, `inline_content` and `inline_secret` can be used for certificates or \nkeys respectively, with `contents`. When you retrieve certificate deployment details, \nonly the file paths of managed certificates and keys will be shown.\n* If you use `inline_content` and `inline_secret` in your NGINX configuration, the NGINX One Console \nwill detect them. When they are used as SSL directives of the NGINX configuration \nfor certificates and keys, the certificates will be listed as `unmanaged_certificate` in the certificate \ndeployment details.\n", - "items": { - "$ref": "#/components/schemas/NginxConfigPayload" - }, - "example": [ - { - "type": "managed_certificate", - "object_id": "cert_rto8NYiCQputrIasNx2NOA", - "paths": [ - "/etc/nginx/cert.pem" - ] - }, - { - "type": "managed_key", - "object_id": "cert_rto8NYiCQputrIasNx2NOA", - "paths": [ - "/etc/nginx/key.pem" - ] - }, - { - "type": "inline_content", - "contents": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURUVENDQWpXZ0F3SUJBZ0lVVkcycitidUwwRk83U1FVeUtoVkNTN3YyRHZZd0RRWUpLb1pJaHZjTkFRRUwKQlFBd05qRVNNQkFHQTFVRUF3d0piRzlqWVd4b2IzTjBNUk13RVFZRFZRUUtEQXBPUjBsT1dDQkpibU11TVFzdwpDUVlEVlFRR0V3SlZVekFlRncweU5EQTBNall5TURVeE5ERmFGdzB5TkRBME1qY3lNRFV4TkRGYU1EWXhFakFRCkJnTlZCQU1NQ1d4dlkyRnNhRzl6ZERFVE1CRUdBMVVFQ2d3S1RrZEpUbGdnU1c1akxqRUxNQWtHQTFVRUJoTUMKVlZNd2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUUMyb0FJVU9HMkxGMFVGclpMeQp5aWhZRjBZWjdYTWFYZnZ4dWJMYVZZdUdJNjlYN1FQRUJtUXp2OXdod25aUktDUExDZHVCNG04Y0o3Q3BGenRHCldPYVFMbmNxVVA4RFU1aHlQeFBSbmZUdFFBcUdiMDJRZ1RVQXY1QkpJMFZheGhCcnNaemd0KzgyM3ZoTTZTUHcKMGdSc1NZRlFpKzVDWW9MMWZNSWdhS0N2Ri9zZGl5cHZFQ0JDZVZyTWZFZ0pGSVJBQ1kvdFBzdEsvTkxwKzlmawppZ3hFMlYxcldoSGdvRmhZRm5YYnVqM2RIMHJLai9DVlM5anZMMk9vRTlvenM5MkRVLytySGJ6eFR3QndVQjBzCmVPS2hPY2d2cENyTVlSUWxUUlhmWVJmV0NLN2Q2Mk1JR3kvajcvV1VieDFOYzl4MjJzUitydVRlZkxnRTA2NWgKMldDZkFnTUJBQUdqVXpCUk1CMEdBMVVkRGdRV0JCUnZnamkxWlByZlVBMnRlWlRMUGE0djlzdHFXakFmQmdOVgpIU01FR0RBV2dCUnZnamkxWlByZlVBMnRlWlRMUGE0djlzdHFXakFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTBHCkNTcUdTSWIzRFFFQkN3VUFBNElCQVFCNC9VM3lrMFYzMTFNRFQvaEttbFJ4MWRqalRyMlhIQnVEcXZYY3BIRTQKVDJwZ0xnWURwN2tmUTQrdnlHWUt1cndEc0F1VDhEZCtUUUZLZEIraEFGRzMyazlxS1RyY1ZCZ2tNSjIwQitvWQp4T2diWW5zVnpiTDhXL0hOR3BlbDkrbThwYURtMGRXNzhMUit5UnJleDVlY2pjYWlZMDg3b0dHNlJDeWhyUVd4CkpkdkFvNlU1ejl3TnVhNmMyNlY2cy84Yit6SkJWektGZ0tQNVVGL2lIcGJVNW1QcVMwWlk4ckhRLzZPTHRGRjgKZ1J2UUlRZjZLSjRmOXlUOFBYSHBIdGJCMzEzaWh2Z09wWW9la3lIWTZaSmllTWhkd0J4MzB1N3d2Uy9POEluYwpsZWZzTkxUcWFTM2JWdldLeUFaVlZyenFtU043aGh4QWZrc0RZelBFbkF3OAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0t", - "paths": [ - "/etc/nginx/inline_cert.crt" - ] - }, - { - "type": "nap_policy_version", - "object_id": "pv_dM68MUcVTe6pfDaCNsM9Qw", - "paths": [ - "/etc/nginx/strict_policy.tgz" - ] - }, - { - "type": "nap_log_profile", - "object_id": "lp_dM68MUcVTe6pfDaCNsM9Qw", - "paths": [ - "/etc/nginx/log_all.tgz" - ] - } - ] - }, - "NginxConfigRequest": { - "allOf": [ - { - "$ref": "#/components/schemas/NginxConfigObjectRequest" - }, - { - "type": "object", - "properties": { - "payloads": { - "$ref": "#/components/schemas/NginxConfigPayloads" - } - } - } - ] + "InstanceObjectID": { + "description": "A globally unique identifier for the NGINX instance.", + "type": "string", + "format": "object_id", + "pattern": "^inst_.*", + "x-go-type": "objects.ID", + "x-go-type-import": { + "name": "objects", + "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" + } }, - "NginxConfigProblem": { + "NginxBuild": { + "description": "The build details for the NGINX binary, including its configuration parameters.\n", "type": "object", - "description": "Representation of a problem found during NGINX configuration analysis.", + "required": [ + "version" + ], "properties": { - "directive": { - "description": "Directive in the NGINX configuration where the issue is identified.", + "version": { + "description": "The version number of the base open-source NGINX.", "type": "string" }, - "file": { - "description": "File where the issue is detected.", + "plus_release": { + "description": "The NGINX Plus release version, if applicable.", "type": "string" }, - "line": { - "description": "Line number in the configuration where the issue is found.", - "type": "integer" - }, - "message": { - "description": "Details about the identified issue.", + "conf_path": { + "description": "The absolute path to the NGINX configuration, as set by the `--conf-path` option during build time.", "type": "string" } } }, - "NginxConfigReport": { + "NginxAppProtectVersions": { + "description": "Version information regarding NGINX App Protect.\n", "type": "object", - "description": "An analysis of the NGINX configuration, highlighting issues and their severity, and offering recommendations.", + "required": [ + "engine_version" + ], "properties": { - "rule": { - "description": "The name of the configuration rule that was violated.", - "type": "string" - }, - "info": { - "description": "A detailed description of the issue.", + "release_version": { + "description": "The release version of NGINX App Protect.", "type": "string" }, - "severity": { - "description": "The severity level of the issue.", + "engine_version": { + "description": "The version of the App Protect enforcement engine.", "type": "string" + } + } + }, + "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" }, - "category": { - "description": "Classification category of the issue.", - "type": "string" + "deployed": { + "description": "The number of NAP policy versions that have deployed.", + "type": "integer" }, - "documentation": { - "description": "Links to documentation that can assist in resolving the identified issue.", - "type": "array", - "items": { - "type": "string" - } + "deploying": { + "description": "The number of NAP policy versions that are deploying.", + "type": "integer" }, - "where": { - "description": "Specific locations in the configuration where issues were detected.", - "type": "array", - "items": { - "$ref": "#/components/schemas/NginxConfigProblem" - } + "failed": { + "description": "The number of NAP policy versions that have failed deployment.", + "type": "integer" } } }, - "NginxConfigReports": { - "type": "array", - "items": { - "$ref": "#/components/schemas/NginxConfigReport" - } + "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" + } + } + } + ] }, - "FilterNameConfigSyncGroups": { + "CveSeverityType": { "type": "string", - "description": "Keywords for config sync groups filters.\nWhen filtering on `config_status`, only the following `filter_values` are supported:\n * in_sync\n * out_of_sync\n * sync_in_progress\n * unknown\n", + "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", "enum": [ - "name", - "config_status", - "object_id" + "high", + "medium", + "low", + "none", + "other" ], "x-enum-varnames": [ - "filter_name_config_sync_group_name", - "filter_name_config_sync_group_config_status", - "filter_name_config_sync_group_object_id" + "cve_severity_type_high", + "cve_severity_type_medium", + "cve_severity_type_low", + "cve_severity_type_none", + "cve_severity_type_other" ] }, - "ConfigSyncGroupObjectID": { - "description": "A globally unique identifier for the NGINX config sync group.", - "type": "string", - "format": "object_id", - "pattern": "^csg_.*", - "x-go-type": "objects.ID", - "x-go-type-import": { - "name": "objects", - "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" + "CveDetails": { + "description": "CVEs details, including the type and count.\n", + "type": "object", + "required": [ + "type", + "count" + ], + "properties": { + "type": { + "$ref": "#/components/schemas/CveSeverityType" + }, + "count": { + "description": "The total number of each CVE type.", + "type": "integer" + } } }, - "ConfigSyncStatus": { + "RecommendationType": { "type": "string", - "description": "The current config sync status of the NGINX config sync group, with the following possible values:\n* `unknown` - The status cannot be determined at this moment.\n* `in_sync` - All NGINX instances in config sync group have same config as indicated by config_version.\n* `out_of_sync` - Some NGINX instances in config sync group have config different than indicated by config_version.\n* `sync_in_progress` - The operation of applying config_version to all NGINX instances in config sync group is in progress.\n", + "description": "Types of configuration recommendations:\n * `best_practice` - Suggestions based on established best practices.\n * `security` - Recommendations related to security.\n * `optimization` - Advice for optimizing performance.\n * `other` - Recommendations that do not fit the above categories.\n", "enum": [ - "unknown", - "in_sync", - "out_of_sync", - "sync_in_progress" + "best_practice", + "security", + "optimization", + "other" ], "x-enum-varnames": [ - "nginx_config_sync_group_config_status_unknown", - "nginx_config_sync_group_config_status_in_sync", - "nginx_config_sync_group_config_status_out_of_sync", - "nginx_config_sync_group_config_status_in_progress" + "recommendation_type_best_practice", + "recommendation_type_security", + "recommendation_type_optimization", + "recommendation_type_other" ] }, - "CertificateInstanceSummary": { - "description": "A breakdown and tally of certificates, detailing the total count, number of expired certificates, certificates nearing expiration, and those that are valid.", + "IssueDetails": { + "description": "Issue details, including the type and count.\n", "type": "object", "required": [ - "total", - "expired", - "expiring", - "valid", - "not_ready" + "type", + "count" ], "properties": { - "total": { - "description": "Total count of certificates across the NGINX data plane.", - "type": "integer" + "type": { + "$ref": "#/components/schemas/RecommendationType" }, - "expired": { - "description": "The number of certificates that have expired and are no longer valid.", + "count": { + "description": "The total number of issues identified for the specific recommendation type.", "type": "integer" + } + } + }, + "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" }, - "expiring": { - "description": "The number of certificates due to expire in the next 30 days.", - "type": "integer" + "name": { + "description": "Control plane name.", + "type": "string" }, - "valid": { - "description": "The number of certificates that are valid and in good standing.", - "type": "integer" + "product_version": { + "description": "Control plane product name and version.", + "type": "string" }, - "not_ready": { - "description": "The number of certificates that are not ready to be used.", - "type": "integer" + "created_at": { + "type": "string", + "format": "date-time", + "description": "The date and time when the control plane was created." } } }, - "ListConfigSyncGroupObject": { + "Instance": { "type": "object", - "description": "Summary information of the NGINX config sync group.", + "description": "Summary information about a NGINX instance.", "required": [ "object_id", - "name", - "created_at", - "instances_count", - "config_status" + "hostname", + "system_id", + "agent_version", + "registered_at", + "last_reported", + "status", + "has_container_host" ], "properties": { "object_id": { - "$ref": "#/components/schemas/ConfigSyncGroupObjectID" + "$ref": "#/components/schemas/InstanceObjectID" + }, + "hostname": { + "description": "The name of the host system where the NGINX instance is running.", + "type": "string" + }, + "system_id": { + "description": "The unique identifier assigned to the host system by the NGINX Agent.", + "type": "string" + }, + "nginx_id": { + "description": "The unique identifier for the NGINX process on the host system, assigned by the NGINX Agent.", + "type": "string" + }, + "agent_version": { + "description": "The version of the NGINX Agent.", + "type": "string" + }, + "key_object_id": { + "$ref": "#/components/schemas/DataPlaneKeyObjectID" + }, + "nginx_build": { + "$ref": "#/components/schemas/NginxBuild" + }, + "os_version": { + "description": "The operating system's name and its and version or codename.\n", + "type": "string", + "example": "ubuntu_jammy" }, - "name": { - "description": "Name of the NGINX config sync group.", - "type": "string" + "nginx_app_protect": { + "$ref": "#/components/schemas/NginxAppProtectSummary" }, - "created_at": { - "description": "The date and time when the config sync group was created.", + "registered_at": { + "description": "The date and time when the NGINX instance first registered with NGINX One.", "type": "string", "format": "date-time" }, - "instances_count": { - "description": "Number of instances in the NGINX config sync group.", - "type": "integer" + "last_reported": { + "description": "The date and time of the most recent report received from the NGINX Agent.", + "type": "string", + "format": "date-time" }, - "config_status": { - "$ref": "#/components/schemas/ConfigSyncStatus" + "status": { + "type": "string", + "description": "The current operational status of the NGINX instance, with the following possible values:\n* `unknown` - The status of the NGINX instance cannot be determined at this moment.\n* `unavailable` - The NGINX Agent has lost connection to NGINX One, rendering the NGINX instance unavailable.\n* `offline` - The NGINX Agent is connected to NGINX One, but the NGINX instance is offline.\n* `online` - The NGINX Agent is connected to NGINX One, and the NGINX instance is online.\n", + "enum": [ + "unknown", + "unavailable", + "offline", + "online" + ] }, "cert_summary": { "$ref": "#/components/schemas/CertificateInstanceSummary" + }, + "cve_severity": { + "type": "array", + "description": "An array summarizing identified Common Vulnerabilities and Exposures (CVEs) across the NGINX data plane.", + "items": { + "$ref": "#/components/schemas/CveDetails" + } + }, + "recommendations": { + "type": "array", + "description": "An array summarizing the suggestions from the configuration analysis report.", + "items": { + "$ref": "#/components/schemas/IssueDetails" + } + }, + "control_plane": { + "$ref": "#/components/schemas/ControlPlaneBaseInfo" + }, + "has_container_host": { + "type": "boolean", + "description": "Indicates whether the instance is running in a containerized environment." } } }, - "ConfigSyncGroupListResponse": { + "ConfigSyncGroupInstance": { "allOf": [ { - "$ref": "#/components/schemas/PaginationResponse" + "$ref": "#/components/schemas/Instance" }, { "type": "object", - "description": "List of NGINX config sync groups.", "required": [ - "items" + "config_status", + "config_version" ], "properties": { - "items": { - "description": "An array of Config Sync Group objects.", - "type": "array", - "items": { - "$ref": "#/components/schemas/ListConfigSyncGroupObject" - } + "config_status": { + "$ref": "#/components/schemas/ConfigSyncStatus" + }, + "config_version": { + "description": "A computed hash of current config on the config sync group.", + "type": "string" } } } - ], - "example": { - "total": 10, - "count": 1, - "start_index": 1, - "items_per_page": 100, - "items": [ - { - "object_id": "csg_-uvR3F2TQGm18jnl7bpaGw", - "name": "test-config-sync-group", - "created_at": "2023-12-05T22:30:20.220114Z", - "config_status": "in_sync", - "instances_count": 1 - } - ] - } + ] }, - "ConfigSyncGroupCreateRequest": { - "description": "Body to create a NGINX config sync group.", - "required": [ - "name" + "ConfigSyncGroupPublicationStatus": { + "type": "string", + "description": "The status on the last publication issued on this config sync group:\n* `pending` - The publication request has been accepted and is currently processing.\n* `failed` - The publication attempt failed.\n* `succeeded` - The publication was successful.\n* `partially_succeeded` - The publication attempt had one or more failures.\n", + "enum": [ + "pending", + "failed", + "succeeded", + "partially_succeeded" ], - "properties": { - "name": { - "type": "string", - "description": "A name to uniquely identify the NGINX config sync group in a given tenant namespace.", - "minLength": 1, - "maxLength": 256, - "pattern": "^[a-zA-Z0-9]([a-zA-Z0-9-_]{0,254}[a-zA-Z0-9])?$" - } - }, - "example": { - "name": "my-nginx-config-sync-group" - } + "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" + ] }, - "ConfigSyncGroupCreateResponse": { - "description": "Response to a create NGINX config sync group request.", + "CertAssociation": { + "type": "object", + "description": "Details for a certificate that's associated with an instance or a config sync group.", "required": [ + "name", "object_id", - "name" + "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/ConfigSyncGroupObjectID" + "$ref": "#/components/schemas/CertificateObjectID" }, - "name": { - "description": "Name of the NGINX config sync group.", - "type": "string" + "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." } - }, - "example": { - "name": "my-nginx-config-sync-group", - "object_id": "csg_Tet21AeYTHCj7taOwVfzyw" } }, - "ConfigSyncGroupBulkRequestData": { - "type": "object", - "description": "Part of bulk operation on a config sync group, only `delete` is supported.", - "required": [ - "action", - "object_id" - ], - "properties": { - "object_id": { - "$ref": "#/components/schemas/ConfigSyncGroupObjectID" - }, - "action": { - "$ref": "#/components/schemas/BulkRequestAction" - } - }, - "example": { - "object_id": "csg_-uvR3F2TQGm18jnl7bpaGw", - "action": "delete" + "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" } }, - "ConfigSyncGroupBulkRequest": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ConfigSyncGroupBulkRequestData" - }, - "minItems": 1, - "maxItems": 50, - "example": [ - { - "object_id": "csg_-uvR3F2TQGm18jnl7bpaGw", - "action": "delete" - }, - { - "object_id": "csg_PL0c1XodRemmzVEjiXSsTg", - "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" + } + }, + "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" ] }, - "ConfigSyncGroupBulkResponse": { - "description": "The config sync group bulk outcome.", - "type": "array", - "items": { - "$ref": "#/components/schemas/BulkRequestObjectStatus" - } + "NapDeploymentStatus": { + "description": "The current deployment status of the NGINX App Protect policy or log profile, with the following possible values:\n* `deployed` - The NGINX App Protect policy or log profile has been deployed.\n* `not_deployed` - The NGINX App Protect policy or log profile has not been deployed.\n* `deploying` - The NGINX App Protect policy or log profile is currently being deployed.\n* `failed` - The NGINX App Protect policy or log profile 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" + ] }, - "ConfigSyncGroupMeta": { - "type": "object", - "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", + "NapAssociation": { + "description": "Details for a NGINX App Protect policy version that's associated with an instance or a config sync group.", "required": [ - "object_id", "name", - "created_at" + "version", + "policy_object_id", + "policy_version_object_id", + "paths", + "deployment_status", + "publication_object_id", + "deployed_on", + "enforcement_mode" ], "properties": { - "object_id": { - "$ref": "#/components/schemas/ConfigSyncGroupObjectID" - }, "name": { - "description": "Name of the NGINX config sync group.", - "type": "string" + "type": "string", + "description": "Name of the policy at the time of the deployment." }, - "last_publication": { - "description": "The date and time of the most recent config sync group publication.", + "version": { "type": "string", - "format": "date-time" + "description": "Version of the policy at the time of the deployment." }, - "created_at": { - "description": "The date and time when the config sync group was created.", + "policy_object_id": { + "$ref": "#/components/schemas/NapPolicyObjectID" + }, + "policy_version_object_id": { + "$ref": "#/components/schemas/NapPolicyVersionObjectID" + }, + "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 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/default_policy.tgz", + "/etc/nginx/default_policy_server_2.tgz" + ], + "items": { + "type": "string" + } + }, + "deployment_status": { + "$ref": "#/components/schemas/NapDeploymentStatus" + }, + "deployed_on": { + "description": "Date and time of the deployment.", "type": "string", "format": "date-time" } }, "example": { - "object_id": "csg_-uvR3F2TQGm18jnl7bpaGw", - "name": "test-config-sync-group", - "last_publication": "2023-12-06T22:37:24.120114Z", - "created_at": "2023-12-05T22:30:20.220114Z" + "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" } }, - "InstanceObjectID": { - "description": "A globally unique identifier for the NGINX instance.", + "NapLatestDeployed": { + "description": "Whether the latest F5 WAF object (i.e., log profile) was deployed, with the following possible values:\n* `yes` - The latest NAP object has been deployed.\n* `no` - The latest NAP object has not been deployed.\n", + "type": "string", + "enum": [ + "yes", + "no" + ], + "x-enum-varnames": [ + "nap_latest_deployed_yes", + "nap_latest_deployed_no" + ] + }, + "NapLogProfileObjectID": { + "description": "A globally unique identifier for the App Protect log profile.", "type": "string", "format": "object_id", - "pattern": "^inst_.*", + "pattern": "^lp_.*", "x-go-type": "objects.ID", "x-go-type-import": { "name": "objects", "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" } }, - "NginxBuild": { - "description": "The build details for the NGINX binary, including its configuration parameters.\n", - "type": "object", + "LogProfileAssociation": { + "description": "Details for a F5 WAF log profile that's associated with an instance or a config sync group.", "required": [ - "version" + "name", + "nap_release", + "latest_deployed", + "log_profile_object_id", + "publication_object_id", + "paths", + "deployment_status", + "deployed_on" ], "properties": { - "version": { - "description": "The version number of the base open-source NGINX.", - "type": "string" + "name": { + "type": "string", + "description": "Name of the log profile at the time of the deployment." }, - "plus_release": { - "description": "The NGINX Plus release version, if applicable.", - "type": "string" + "nap_release": { + "type": "string", + "description": "The release version of the compiler used for the log profile." }, - "conf_path": { - "description": "The absolute path to the NGINX configuration, as set by the `--conf-path` option during build time.", - "type": "string" + "latest_deployed": { + "$ref": "#/components/schemas/NapLatestDeployed" + }, + "log_profile_object_id": { + "$ref": "#/components/schemas/NapLogProfileObjectID" + }, + "publication_object_id": { + "$ref": "#/components/schemas/PublicationObjectID" + }, + "paths": { + "type": "array", + "description": "The list of file system paths where the compiled log profile bundle file is installed. \nSince a single compiled log profile bundle file may be applied in multiple contexts, all relevant paths are included.\n", + "example": [ + "/etc/nginx/default_log_profile.tgz", + "/etc/nginx/default_log_profile_2.tgz" + ], + "items": { + "type": "string" + } + }, + "deployment_status": { + "$ref": "#/components/schemas/NapDeploymentStatus" + }, + "deployed_on": { + "description": "Date and time of the deployment.", + "type": "string", + "format": "date-time" } + }, + "example": { + "name": "default_log_profile", + "nap_release": "5.10.0", + "latest_deployed": "yes", + "log_profile_object_id": "lp_panEdeY-Sh2rWm365y7wsw", + "publication_object_id": "pub_72pGHoGsSICL_THZrs964g", + "paths": [ + "/etc/nginx/default_log_profile.tgz" + ], + "deployment_status": "deployed", + "deployed_on": "2023-12-06T22:37:24.120114Z" } }, - "NginxAppProtectVersions": { - "description": "Version information regarding NGINX App Protect.\n", - "type": "object", - "required": [ - "engine_version" - ], - "properties": { - "release_version": { - "description": "The release version of NGINX App Protect.", - "type": "string" + "ConfigSyncGroup": { + "allOf": [ + { + "$ref": "#/components/schemas/ConfigSyncGroupMeta" }, - "engine_version": { - "description": "The version of the App Protect enforcement engine.", - "type": "string" + { + "type": "object", + "description": "Additional information of the NGINX config sync group including:\n* config sync status\n* config checksum\n* instances\n* last known publication status\n* certs associated with this config sync group\n", + "properties": { + "config_status": { + "$ref": "#/components/schemas/ConfigSyncStatus" + }, + "config_version": { + "description": "A computed hash of current config on the config sync group.", + "type": "string" + }, + "instances": { + "description": "An array of Instance objects.", + "type": "array", + "items": { + "$ref": "#/components/schemas/ConfigSyncGroupInstance" + } + }, + "last_publication_status": { + "$ref": "#/components/schemas/ConfigSyncGroupPublicationStatus" + }, + "certs": { + "description": "An array detailing each certificate's information, including its friendly name, unique identifier, applicable file system paths, subject name, and validity dates. \nIt provides insights into the operational status of each certificate, such as whether it's currently valid, nearing expiration, is not ready to be used, or has already expired.\nThe deployment status indicates whether the latest certs and key managed by NGINX One Console are deployed onto the data plane instances that are part of this config sync group.\n", + "type": "array", + "items": { + "$ref": "#/components/schemas/CertAssociation" + } + }, + "nginx_app_protect": { + "type": "object", + "required": [ + "deployments" + ], + "properties": { + "deployments": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NapAssociation" + } + } + } + }, + "log_profile": { + "type": "object", + "required": [ + "deployments" + ], + "properties": { + "deployments": { + "type": "array", + "items": { + "$ref": "#/components/schemas/LogProfileAssociation" + } + } + } + } + } } - } - }, - "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" - } + "example": { + "object_id": "csg_-uvR3F2TQGm18jnl7bpaGw", + "name": "test-config-sync-group", + "created_at": "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", + "has_container_host": false + } + ], + "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" + } + ] } }, - "NginxAppProtectSummary": { - "description": "Summary information regarding NGINX App Protect.\n", + "ConfigSyncGroupDetails": { "type": "object", + "description": "Detailed information of the NGINX config sync group.", "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", - "enum": [ - "high", - "medium", - "low", - "none", - "other" - ], - "x-enum-varnames": [ - "cve_severity_type_high", - "cve_severity_type_medium", - "cve_severity_type_low", - "cve_severity_type_none", - "cve_severity_type_other" - ] - }, - "CveDetails": { - "description": "CVEs details, including the type and count.\n", - "type": "object", - "required": [ - "type", - "count" - ], - "properties": { - "type": { - "$ref": "#/components/schemas/CveSeverityType" - }, - "count": { - "description": "The total number of each CVE type.", - "type": "integer" + "$ref": "#/components/schemas/ConfigSyncGroup" } - } - }, - "RecommendationType": { - "type": "string", - "description": "Types of configuration recommendations:\n * `best_practice` - Suggestions based on established best practices.\n * `security` - Recommendations related to security.\n * `optimization` - Advice for optimizing performance.\n * `other` - Recommendations that do not fit the above categories.\n", - "enum": [ - "best_practice", - "security", - "optimization", - "other" - ], - "x-enum-varnames": [ - "recommendation_type_best_practice", - "recommendation_type_security", - "recommendation_type_optimization", - "recommendation_type_other" ] }, - "IssueDetails": { - "description": "Issue details, including the type and count.\n", - "type": "object", - "required": [ - "type", - "count" - ], - "properties": { - "type": { - "$ref": "#/components/schemas/RecommendationType" - }, - "count": { - "description": "The total number of issues identified for the specific recommendation type.", - "type": "integer" - } - } - }, - "ControlPlaneObjectID": { - "description": "A globally unique identifier for the control plane.", - "type": "string", - "format": "object_id", - "pattern": "^ecp_.*", - "x-go-type": "objects.ID" - }, - "ControlPlaneBaseInfo": { + "FileData": { "type": "object", - "description": "Base information of a control plane, which includes name, product version and optionally an object ID.", + "description": "Details about a file, including its path, content, size, and last modified time.", "required": [ "name", - "product_version", - "created_at" + "contents", + "size", + "mtime" ], "properties": { - "object_id": { - "$ref": "#/components/schemas/ControlPlaneObjectID" - }, "name": { - "description": "Control plane name.", - "type": "string" + "type": "string", + "description": "The file's relative path to the parent directory.", + "minLength": 1, + "maxLength": 4096 }, - "product_version": { - "description": "Control plane product name and version.", - "type": "string" + "contents": { + "type": "string", + "format": "byte", + "description": "The base64-encoded contents of the file.", + "maxLength": 3145728 }, - "created_at": { + "size": { + "type": "integer", + "description": "The size of the file, in bytes." + }, + "mtime": { "type": "string", "format": "date-time", - "description": "The date and time when the control plane was created." + "description": "Timestamp of the last modification made to the file." } } }, - "Instance": { + "DirectoryWithFileContent": { "type": "object", - "description": "Summary information about a NGINX instance.", + "description": "Represents a directory and its contents, detailing the directory's full path, assigned permissions, last modified time, and the files within it.", "required": [ - "object_id", - "hostname", - "system_id", - "agent_version", - "registered_at", - "last_reported", - "status", - "has_container_host" + "name", + "files" ], "properties": { - "object_id": { - "$ref": "#/components/schemas/InstanceObjectID" - }, - "hostname": { - "description": "The name of the host system where the NGINX instance is running.", - "type": "string" - }, - "system_id": { - "description": "The unique identifier assigned to the host system by the NGINX Agent.", - "type": "string" - }, - "nginx_id": { - "description": "The unique identifier for the NGINX process on the host system, assigned by the NGINX Agent.", - "type": "string" - }, - "agent_version": { - "description": "The version of the NGINX Agent.", - "type": "string" - }, - "key_object_id": { - "$ref": "#/components/schemas/DataPlaneKeyObjectID" - }, - "nginx_build": { - "$ref": "#/components/schemas/NginxBuild" - }, - "os_version": { - "description": "The operating system's name and its and version or codename.\n", + "name": { "type": "string", - "example": "ubuntu_jammy" - }, - "nginx_app_protect": { - "$ref": "#/components/schemas/NginxAppProtectSummary" + "description": "The complete path of the directory." }, - "registered_at": { - "description": "The date and time when the NGINX instance first registered with NGINX One.", + "permissions": { "type": "string", - "format": "date-time" - }, - "last_reported": { - "description": "The date and time of the most recent report received from the NGINX Agent.", + "description": "The permissions for the directory." + }, + "mtime": { "type": "string", + "description": "The date and time when the directory was last modified.", "format": "date-time" }, - "status": { + "files": { + "type": "array", + "description": "The list of files in the directory.", + "items": { + "$ref": "#/components/schemas/FileData" + } + } + } + }, + "NginxConfigObject": { + "type": "object", + "description": "Details of an NGINX configuration, the main configuration path, and the configuration directories.\n", + "required": [ + "conf_path", + "configs" + ], + "properties": { + "config_version": { "type": "string", - "description": "The current operational status of the NGINX instance, with the following possible values:\n* `unknown` - The status of the NGINX instance cannot be determined at this moment.\n* `unavailable` - The NGINX Agent has lost connection to NGINX One, rendering the NGINX instance unavailable.\n* `offline` - The NGINX Agent is connected to NGINX One, but the NGINX instance is offline.\n* `online` - The NGINX Agent is connected to NGINX One, and the NGINX instance is online.\n", - "enum": [ - "unknown", - "unavailable", - "offline", - "online" - ] + "description": "A hash that uniquely identifies the contents of the config object. Can be used to detect change when updating the NginxConfig.\n" }, - "cert_summary": { - "$ref": "#/components/schemas/CertificateInstanceSummary" + "conf_path": { + "$ref": "#/components/schemas/ConfigPath" }, - "cve_severity": { + "configs": { "type": "array", - "description": "An array summarizing identified Common Vulnerabilities and Exposures (CVEs) across the NGINX data plane.", + "description": "An array of directories containing NGINX configuration files.", "items": { - "$ref": "#/components/schemas/CveDetails" + "$ref": "#/components/schemas/DirectoryWithFileContent" } }, - "recommendations": { + "aux": { "type": "array", - "description": "An array summarizing the suggestions from the configuration analysis report.", + "description": "An array of auxiliary directory contents related to the NGINX configuration.", "items": { - "$ref": "#/components/schemas/IssueDetails" + "$ref": "#/components/schemas/DirectoryWithFileContent" } - }, - "control_plane": { - "$ref": "#/components/schemas/ControlPlaneBaseInfo" - }, - "has_container_host": { - "type": "boolean", - "description": "Indicates whether the instance is running in a containerized environment." } + }, + "example": { + "aux": [], + "conf_path": "/etc/nginx/nginx.conf", + "configs": [ + { + "files": [ + { + "contents": "Cm1hcCAkdXJpICRtYXBwZWRfc2VydmljZSB7CiAgICBkZWZhdWx0IFVOTUFUQ0hFRDsKICAgICJ+Xi9hcGkvdjEvbmFtZXNwYWNlcy9cdysvaW5zdGFuY2VzIiAgICAgICAgaW5zdGFuY2VzLXN2YzsKICAgICJ+Xi9hcGkvdjEvbmFtZXNwYWNlcy9cdysvZGF0YS1wbGFuZS1rZXlzIiAga2V5cy1zdmM7CiAgICAifl4vYXBpL3YxL25hbWVzcGFjZXMvXHcrL21vbml0b3IiICAgICAgICAgIG1vbml0b3Itc3ZjOwp9Cgp1cHN0cmVhbSBpbnN0YW5jZXMtc3ZjIHsKICAgIHNlcnZlciBpbnN0YW5jZXMtc3ZjOjgwODA7Cn0KCnVwc3RyZWFtIGtleXMtc3ZjIHsKICAgIHNlcnZlciBrZXlzLXN2Yzo4MDkwOwp9Cgp1cHN0cmVhbSBkYXRhcGxhbmUtY3RybCB7CiAgICBzZXJ2ZXIgZGF0YXBsYW5lLWN0cmw6ODA4MDsKfQoKdXBzdHJlYW0gbW9uaXRvci1zdmMgewogICAgc2VydmVyIG1vbml0b3Itc3ZjOjgwODA7Cn0KCnVwc3RyZWFtIG1ldHJpY3MtaW5nZXN0IHsKICAgIHNlcnZlciBtZXRyaWNzLWluZ2VzdDo4MDgwOwp9CgpzZXJ2ZXIgewogICAgbGlzdGVuIDg4ODg7CiAgICBzZXJ2ZXJfbmFtZSBfOwogICAgaHR0cDIgb247CgogICAgcHJveHlfcGFzc19yZXF1ZXN0X2hlYWRlcnMgb247CiAgICByZXdyaXRlICJeL2FwaS8obmdpbngvb25lfHYxKS8oLiopJCIgIi9hcGkvdjEvJDIiIGJyZWFrOwogICAgbG9jYXRpb24gL2FwaS92MS8gewogICAgICAgIGlmICgkbWFwcGVkX3NlcnZpY2UgPSAiVU5NQVRDSEVEIikgewogICAgICAgICAgICByZXR1cm4gNDA0ICd7ImVycm9yOiAiTm90IGZvdW5kIn0nOwogICAgICAgIH0KICAgICAgICBwcm94eV9wYXNzX2hlYWRlciBYLVZvbHRlcnJhLUFwaWd3LVRlbmFudDsKICAgICAgICBwcm94eV9wYXNzIGh0dHA6Ly8kbWFwcGVkX3NlcnZpY2U7CiAgICB9CgogICAgIyBnUlBDIHNlcnZpY2UgZm9yIGRhdGFwbGFuZS1jdHJsCiAgICBsb2NhdGlvbiAvZjUubmdpbnguYWdlbnQuc2RrLkNvbW1hbmRlciB7CiAgICAgICAgZ3JwY19zb2NrZXRfa2VlcGFsaXZlIG9uOwogICAgICAgIGdycGNfcmVhZF90aW1lb3V0IDVtOwogICAgICAgIGdycGNfc2VuZF90aW1lb3V0IDVtOwogICAgICAgIGNsaWVudF9ib2R5X3RpbWVvdXQgMTBtOwogICAgICAgIGdycGNfcGFzcyBncnBjOi8vZGF0YXBsYW5lLWN0cmw7CiAgICB9CgogICAgIyBnUlBDIHNlcnZpY2UgZm9yIG1ldHJpY3MgaW5nZXN0aW9uCiAgICBsb2NhdGlvbiAvZjUubmdpbnguYWdlbnQuc2RrLk1ldHJpY3NTZXJ2aWNlIHsKICAgICAgICBncnBjX3NvY2tldF9rZWVwYWxpdmUgb247CiAgICAgICAgZ3JwY19yZWFkX3RpbWVvdXQgNW07CiAgICAgICAgZ3JwY19zZW5kX3RpbWVvdXQgNW07CiAgICAgICAgY2xpZW50X2JvZHlfdGltZW91dCAxMG07CiAgICAgICAgY2xpZW50X21heF9ib2R5X3NpemUgMDsKICAgICAgICBncnBjX3Bhc3MgZ3JwYzovL21ldHJpY3MtaW5nZXN0OwogICAgfQp9CgojIHByb3h5IHRvIHRoZSBtYW5hZ2VtZW50IHNlcnZlcnMKc2VydmVyIHsKICAgIGxpc3RlbiAxNTAwMDsKICAgIHNlcnZlcl9uYW1lIF87CiAgICAjIHVzZSBkb2NrZXIgRE5TCiAgICByZXNvbHZlciAxMjcuMC4wLjExIHZhbGlkPTMwczsKCiAgICAjIG1hdGNoIC88c2VydmljZT4vPG1nbXQgZW5kcG9pbnQ+CiAgICBsb2NhdGlvbiB+Xi8oW14vXSspLyguKykkIHsKICAgICAgICBwcm94eV9wYXNzIGh0dHA6Ly8kMToxNTAwMC8kMjsKICAgIH0KCiAgICBsb2NhdGlvbiAvIHsKICAgICAgICBhZGRfaGVhZGVyICJDb250ZW50LVR5cGUiICJ0ZXh0L2h0bWwiOwogICAgICAgIHJldHVybiAyMDAgIjxwPkFjY2VzcyB0aGUgbWFuYWdlbWVudCBzZXJ2ZXIgb2YgYW55IHNlcnZpY2Ugd2l0aCBVUkxzIGxpa2UgPGNvZGU+aHR0cDovL2xvY2FsaG9zdDoxNTAwMC8mbHQ7U0VSVklDRV9OQU1FJmd0Oy9tZXRyaWNzPC9jb2RlPjwvcD4iOwogICAgfQp9Cg==", + "mtime": "1970-01-01T00:00:00Z", + "name": "default.conf", + "size": 1942 + } + ], + "name": "/etc/nginx/conf.d" + }, + { + "files": [ + { + "contents": "CnVzZXIgIG5naW54Owp3b3JrZXJfcHJvY2Vzc2VzICBhdXRvOwoKZXJyb3JfbG9nICAvdmFyL2xvZy9uZ2lueC9lcnJvci5sb2cgbm90aWNlOwpwaWQgICAgICAgIC92YXIvcnVuL25naW54LnBpZDsKCgpldmVudHMgewogICAgd29ya2VyX2Nvbm5lY3Rpb25zICAxMDI0Owp9CgoKaHR0cCB7CiAgICBpbmNsdWRlICAgICAgIC9ldGMvbmdpbngvbWltZS50eXBlczsKICAgIGRlZmF1bHRfdHlwZSAgYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtOwoKICAgIGxvZ19mb3JtYXQgIG1haW4gICckcmVtb3RlX2FkZHIgLSAkcmVtb3RlX3VzZXIgWyR0aW1lX2xvY2FsXSAiJHJlcXVlc3QiICcKICAgICAgICAgICAgICAgICAgICAgICckc3RhdHVzICRib2R5X2J5dGVzX3NlbnQgIiRodHRwX3JlZmVyZXIiICcKICAgICAgICAgICAgICAgICAgICAgICciJGh0dHBfdXNlcl9hZ2VudCIgIiRodHRwX3hfZm9yd2FyZGVkX2ZvciInOwoKICAgIGFjY2Vzc19sb2cgIC92YXIvbG9nL25naW54L2FjY2Vzcy5sb2cgIG1haW47CgogICAgc2VuZGZpbGUgICAgICAgIG9uOwogICAgI3RjcF9ub3B1c2ggICAgIG9uOwoKICAgIGtlZXBhbGl2ZV90aW1lb3V0ICA2NTsKCiAgICAjZ3ppcCAgb247CgogICAgaW5jbHVkZSAvZXRjL25naW54L2NvbmYuZC8qLmNvbmY7Cn0K", + "mtime": "1970-01-01T00:00:00Z", + "name": "nginx.conf", + "size": 648 + }, + { + "contents": "CnR5cGVzIHsKICAgIHRleHQvaHRtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBodG1sIGh0bSBzaHRtbDsKICAgIHRleHQvY3NzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3M7CiAgICB0ZXh0L3htbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sOwogICAgaW1hZ2UvZ2lmICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdpZjsKICAgIGltYWdlL2pwZWcgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqcGVnIGpwZzsKICAgIGFwcGxpY2F0aW9uL2phdmFzY3JpcHQgICAgICAgICAgICAgICAgICAgICAgICAgICBqczsKICAgIGFwcGxpY2F0aW9uL2F0b20reG1sICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdG9tOwogICAgYXBwbGljYXRpb24vcnNzK3htbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJzczsKCiAgICB0ZXh0L21hdGhtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW1sOwogICAgdGV4dC9wbGFpbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR4dDsKICAgIHRleHQvdm5kLnN1bi5qMm1lLmFwcC1kZXNjcmlwdG9yICAgICAgICAgICAgICAgICBqYWQ7CiAgICB0ZXh0L3ZuZC53YXAud21sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd21sOwogICAgdGV4dC94LWNvbXBvbmVudCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGh0YzsKCiAgICBpbWFnZS9hdmlmICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXZpZjsKICAgIGltYWdlL3BuZyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbmc7CiAgICBpbWFnZS9zdmcreG1sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ZnIHN2Z3o7CiAgICBpbWFnZS90aWZmICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGlmIHRpZmY7CiAgICBpbWFnZS92bmQud2FwLndibXAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2JtcDsKICAgIGltYWdlL3dlYnAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3ZWJwOwogICAgaW1hZ2UveC1pY29uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGljbzsKICAgIGltYWdlL3gtam5nICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqbmc7CiAgICBpbWFnZS94LW1zLWJtcCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm1wOwoKICAgIGZvbnQvd29mZiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3b2ZmOwogICAgZm9udC93b2ZmMiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdvZmYyOwoKICAgIGFwcGxpY2F0aW9uL2phdmEtYXJjaGl2ZSAgICAgICAgICAgICAgICAgICAgICAgICBqYXIgd2FyIGVhcjsKICAgIGFwcGxpY2F0aW9uL2pzb24gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uOwogICAgYXBwbGljYXRpb24vbWFjLWJpbmhleDQwICAgICAgICAgICAgICAgICAgICAgICAgIGhxeDsKICAgIGFwcGxpY2F0aW9uL21zd29yZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2M7CiAgICBhcHBsaWNhdGlvbi9wZGYgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGRmOwogICAgYXBwbGljYXRpb24vcG9zdHNjcmlwdCAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzIGVwcyBhaTsKICAgIGFwcGxpY2F0aW9uL3J0ZiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBydGY7CiAgICBhcHBsaWNhdGlvbi92bmQuYXBwbGUubXBlZ3VybCAgICAgICAgICAgICAgICAgICAgbTN1ODsKICAgIGFwcGxpY2F0aW9uL3ZuZC5nb29nbGUtZWFydGgua21sK3htbCAgICAgICAgICAgICBrbWw7CiAgICBhcHBsaWNhdGlvbi92bmQuZ29vZ2xlLWVhcnRoLmtteiAgICAgICAgICAgICAgICAga216OwogICAgYXBwbGljYXRpb24vdm5kLm1zLWV4Y2VsICAgICAgICAgICAgICAgICAgICAgICAgIHhsczsKICAgIGFwcGxpY2F0aW9uL3ZuZC5tcy1mb250b2JqZWN0ICAgICAgICAgICAgICAgICAgICBlb3Q7CiAgICBhcHBsaWNhdGlvbi92bmQubXMtcG93ZXJwb2ludCAgICAgICAgICAgICAgICAgICAgcHB0OwogICAgYXBwbGljYXRpb24vdm5kLm9hc2lzLm9wZW5kb2N1bWVudC5ncmFwaGljcyAgICAgIG9kZzsKICAgIGFwcGxpY2F0aW9uL3ZuZC5vYXNpcy5vcGVuZG9jdW1lbnQucHJlc2VudGF0aW9uICBvZHA7CiAgICBhcHBsaWNhdGlvbi92bmQub2FzaXMub3BlbmRvY3VtZW50LnNwcmVhZHNoZWV0ICAgb2RzOwogICAgYXBwbGljYXRpb24vdm5kLm9hc2lzLm9wZW5kb2N1bWVudC50ZXh0ICAgICAgICAgIG9kdDsKICAgIGFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5wcmVzZW50YXRpb25tbC5wcmVzZW50YXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcHR4OwogICAgYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwuc2hlZXQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bHN4OwogICAgYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LndvcmRwcm9jZXNzaW5nbWwuZG9jdW1lbnQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N4OwogICAgYXBwbGljYXRpb24vdm5kLndhcC53bWxjICAgICAgICAgICAgICAgICAgICAgICAgIHdtbGM7CiAgICBhcHBsaWNhdGlvbi93YXNtICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2FzbTsKICAgIGFwcGxpY2F0aW9uL3gtN3otY29tcHJlc3NlZCAgICAgICAgICAgICAgICAgICAgICA3ejsKICAgIGFwcGxpY2F0aW9uL3gtY29jb2EgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjY287CiAgICBhcHBsaWNhdGlvbi94LWphdmEtYXJjaGl2ZS1kaWZmICAgICAgICAgICAgICAgICAgamFyZGlmZjsKICAgIGFwcGxpY2F0aW9uL3gtamF2YS1qbmxwLWZpbGUgICAgICAgICAgICAgICAgICAgICBqbmxwOwogICAgYXBwbGljYXRpb24veC1tYWtlc2VsZiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ1bjsKICAgIGFwcGxpY2F0aW9uL3gtcGVybCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbCBwbTsKICAgIGFwcGxpY2F0aW9uL3gtcGlsb3QgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmMgcGRiOwogICAgYXBwbGljYXRpb24veC1yYXItY29tcHJlc3NlZCAgICAgICAgICAgICAgICAgICAgIHJhcjsKICAgIGFwcGxpY2F0aW9uL3gtcmVkaGF0LXBhY2thZ2UtbWFuYWdlciAgICAgICAgICAgICBycG07CiAgICBhcHBsaWNhdGlvbi94LXNlYSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VhOwogICAgYXBwbGljYXRpb24veC1zaG9ja3dhdmUtZmxhc2ggICAgICAgICAgICAgICAgICAgIHN3ZjsKICAgIGFwcGxpY2F0aW9uL3gtc3R1ZmZpdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXQ7CiAgICBhcHBsaWNhdGlvbi94LXRjbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGNsIHRrOwogICAgYXBwbGljYXRpb24veC14NTA5LWNhLWNlcnQgICAgICAgICAgICAgICAgICAgICAgIGRlciBwZW0gY3J0OwogICAgYXBwbGljYXRpb24veC14cGluc3RhbGwgICAgICAgICAgICAgICAgICAgICAgICAgIHhwaTsKICAgIGFwcGxpY2F0aW9uL3hodG1sK3htbCAgICAgICAgICAgICAgICAgICAgICAgICAgICB4aHRtbDsKICAgIGFwcGxpY2F0aW9uL3hzcGYreG1sICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4c3BmOwogICAgYXBwbGljYXRpb24vemlwICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHppcDsKCiAgICBhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0gICAgICAgICAgICAgICAgICAgICAgICAgYmluIGV4ZSBkbGw7CiAgICBhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0gICAgICAgICAgICAgICAgICAgICAgICAgZGViOwogICAgYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtICAgICAgICAgICAgICAgICAgICAgICAgIGRtZzsKICAgIGFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSAgICAgICAgICAgICAgICAgICAgICAgICBpc28gaW1nOwogICAgYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtICAgICAgICAgICAgICAgICAgICAgICAgIG1zaSBtc3AgbXNtOwoKICAgIGF1ZGlvL21pZGkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaWQgbWlkaSBrYXI7CiAgICBhdWRpby9tcGVnICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXAzOwogICAgYXVkaW8vb2dnICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9nZzsKICAgIGF1ZGlvL3gtbTRhICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtNGE7CiAgICBhdWRpby94LXJlYWxhdWRpbyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmE7CgogICAgdmlkZW8vM2dwcCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDNncHAgM2dwOwogICAgdmlkZW8vbXAydCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRzOwogICAgdmlkZW8vbXA0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1wNDsKICAgIHZpZGVvL21wZWcgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtcGVnIG1wZzsKICAgIHZpZGVvL3F1aWNrdGltZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb3Y7CiAgICB2aWRlby93ZWJtICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2VibTsKICAgIHZpZGVvL3gtZmx2ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbHY7CiAgICB2aWRlby94LW00diAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbTR2OwogICAgdmlkZW8veC1tbmcgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1uZzsKICAgIHZpZGVvL3gtbXMtYXNmICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3ggYXNmOwogICAgdmlkZW8veC1tcy13bXYgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdtdjsKICAgIHZpZGVvL3gtbXN2aWRlbyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdmk7Cn0K", + "mtime": "1970-01-01T00:00:00Z", + "name": "mime.types", + "size": 5349 + } + ], + "name": "/etc/nginx" + } + ] } }, - "ConfigSyncGroupInstance": { + "NginxConfigObjectID": { + "description": "A globally unique identifier for the NGINX Config object.", + "type": "string", + "format": "object_id", + "pattern": "^nc_.*", + "x-go-type": "objects.ID", + "x-go-type-import": { + "name": "objects", + "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" + } + }, + "NginxConfig": { + "description": "Details of an NGINX configuration, including its unique identifier, the main configuration path, the \nconfiguration directories, and the NGINX configuration payloads that indicate where managed SSL certificates\nand keys were deployed to on the data plane instance.\n", "allOf": [ { - "$ref": "#/components/schemas/Instance" + "$ref": "#/components/schemas/NginxConfigObject" }, { "type": "object", "required": [ - "config_status", - "config_version" + "object_id" ], "properties": { - "config_status": { - "$ref": "#/components/schemas/ConfigSyncStatus" + "object_id": { + "$ref": "#/components/schemas/NginxConfigObjectID" }, - "config_version": { - "description": "A computed hash of current config on the config sync group.", - "type": "string" + "payloads": { + "$ref": "#/components/schemas/NginxConfigPayloads" } } } ] }, - "ConfigSyncGroupPublicationStatus": { - "type": "string", - "description": "The status on the last publication issued on this config sync group:\n* `pending` - The publication request has been accepted and is currently processing.\n* `failed` - The publication attempt failed.\n* `succeeded` - The publication was successful.\n* `partially_succeeded` - The publication attempt had one or more failures.\n", - "enum": [ - "pending", - "failed", - "succeeded", - "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" - ] - }, - "CertAssociation": { + "PublicationStatusCause": { + "description": "Cause of the failure, provided only if the status is `failed`.", "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": { + "cause": { + "description": "Cause of the failure, detailed as follows:\n* `unknown` - The reason for the failure is not known.\n* `timeout` - The publication request reached its time limit without receiving a response from the NGINX Agent.\n* `remote` - The NGINX Agent reported a failure when trying to apply the configuration. See the message for more details.\n* `payload` - The publication was successful, but there were warnings reported by attached payloads, see message for more details.\n", "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" + "enum": [ + "unknown", + "timeout", + "remote", + "payload" ], - "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." + "x-enum-varnames": [ + "publication_instance_status_cause_unknown", + "publication_instance_status_cause_timeout", + "publication_instance_status_cause_remote", + "publication_instance_status_cause_payload" + ] }, - "not_after": { + "message": { "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" - ] + "description": "more specific failure message from the agent." + } + } }, - "NapDeploymentStatus": { - "description": "The current deployment status of the NGINX App Protect policy or log profile, with the following possible values:\n* `deployed` - The NGINX App Protect policy or log profile has been deployed.\n* `not_deployed` - The NGINX App Protect policy or log profile has not been deployed.\n* `deploying` - The NGINX App Protect policy or log profile is currently being deployed.\n* `failed` - The NGINX App Protect policy or log profile 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" + "ConfigSyncGroupPublicationStatusReason": { + "allOf": [ + { + "$ref": "#/components/schemas/PublicationStatusCause" + }, + { + "type": "object", + "required": [ + "object_id" + ], + "properties": { + "object_id": { + "$ref": "#/components/schemas/InstanceObjectID" + } + } + } ] }, - "NapAssociation": { - "description": "Details for a NGINX App Protect policy version that's associated with an instance or a config sync group.", + "ConfigSyncGroupPublication": { + "description": "Details of a publication request for the NGINX config sync group.", "required": [ - "name", - "version", - "policy_object_id", - "policy_version_object_id", - "paths", - "deployment_status", - "publication_object_id", - "deployed_on", - "enforcement_mode" + "status", + "created_at", + "modified_at" ], "properties": { - "name": { - "type": "string", - "description": "Name of the policy at the time of the deployment." - }, - "version": { - "type": "string", - "description": "Version of the policy at the time of the deployment." - }, - "policy_object_id": { - "$ref": "#/components/schemas/NapPolicyObjectID" + "object_id": { + "$ref": "#/components/schemas/PublicationObjectID" }, - "policy_version_object_id": { - "$ref": "#/components/schemas/NapPolicyVersionObjectID" + "status": { + "$ref": "#/components/schemas/ConfigSyncGroupPublicationStatus" }, - "publication_object_id": { - "$ref": "#/components/schemas/PublicationObjectID" + "created_at": { + "type": "string", + "format": "date-time", + "description": "The date and time when the publication was created for the instance." }, - "enforcement_mode": { - "$ref": "#/components/schemas/NapPolicyEnforcementMode" + "modified_at": { + "type": "string", + "format": "date-time", + "description": "The date and time when the publication was last modified for the instance." }, - "paths": { + "status_reasons": { + "description": "Detailed failure reasons on each instance's publication, when 'status' is in 'failed' or 'partially_succeeded'", "type": "array", - "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/default_policy.tgz", - "/etc/nginx/default_policy_server_2.tgz" - ], "items": { - "type": "string" + "$ref": "#/components/schemas/ConfigSyncGroupPublicationStatusReason" } }, - "deployment_status": { - "$ref": "#/components/schemas/NapDeploymentStatus" - }, - "deployed_on": { - "description": "Date and time of the deployment.", + "config_version": { "type": "string", - "format": "date-time" + "description": "A hash that uniquely identifies the contents of the config object in the publication.\n" } }, "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" - } - }, - "NapLatestDeployed": { - "description": "Whether the latest F5 WAF object (i.e., log profile) was deployed, with the following possible values:\n* `yes` - The latest NAP object has been deployed.\n* `no` - The latest NAP object has not been deployed.\n", - "type": "string", - "enum": [ - "yes", - "no" - ], - "x-enum-varnames": [ - "nap_latest_deployed_yes", - "nap_latest_deployed_no" - ] - }, - "NapLogProfileObjectID": { - "description": "A globally unique identifier for the App Protect log profile.", - "type": "string", - "format": "object_id", - "pattern": "^lp_.*", - "x-go-type": "objects.ID", - "x-go-type-import": { - "name": "objects", - "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" + "config_version": "fc3bb4b50c145b3ca5c5d1342be5ec0718eeb9bb84f8d53c5734b6b8", + "created_at": "2024-05-23T21:57:13.048285Z", + "modified_at": "2024-05-23T21:57:13.048285Z", + "object_id": "pub_UPV8jXFwSgm1vHQJCvLD1w", + "status": "failed", + "status_reasons": [ + { + "cause": "remote", + "message": "Config apply failed (write): error running nginx -t -c /etc/nginx/nginx.conf:\n error running nginx -t -c /etc/nginx/nginx.conf:\nnginx: [emerg] invalid number of arguments in \"worker_processes\" directive in /etc/nginx/nginx.conf:7\nnginx: configuration file /etc/nginx/nginx.conf test failed\n", + "object_id": "inst_QBBobKIAQ_21grAwV83VYw" + } + ] } }, - "LogProfileAssociation": { - "description": "Details for a F5 WAF log profile that's associated with an instance or a config sync group.", + "PublicationInstance": { + "description": "Details of a publication request for an NGINX instance.", "required": [ - "name", - "nap_release", - "latest_deployed", - "log_profile_object_id", - "publication_object_id", - "paths", - "deployment_status", - "deployed_on" + "status", + "created_at", + "modified_at" ], "properties": { - "name": { + "object_id": { + "$ref": "#/components/schemas/PublicationObjectID" + }, + "config_version": { "type": "string", - "description": "Name of the log profile at the time of the deployment." + "description": "A hash that uniquely identifies the contents of the config object in the publication.\n" }, - "nap_release": { + "status": { + "description": "Publication status for the NGINX instance:\n* `pending` - The publication request has been accepted and is currently processing.\n* `failed` - The publication attempt failed.\n* `succeeded` - The publication was successful.\n* `succeeded_with_warnings` - The publication was successful, but there were warnings.\n", "type": "string", - "description": "The release version of the compiler used for the log profile." + "enum": [ + "pending", + "failed", + "succeeded", + "succeeded_with_warnings" + ], + "x-enum-varnames": [ + "publication_instance_status_pending", + "publication_instance_status_failed", + "publication_instance_status_succeeded", + "publication_instance_status_succeeded_with_warnings" + ] }, - "latest_deployed": { - "$ref": "#/components/schemas/NapLatestDeployed" + "status_cause": { + "$ref": "#/components/schemas/PublicationStatusCause" }, - "log_profile_object_id": { - "$ref": "#/components/schemas/NapLogProfileObjectID" + "created_at": { + "type": "string", + "format": "date-time", + "description": "The date and time when the publication was created for the instance." }, - "publication_object_id": { - "$ref": "#/components/schemas/PublicationObjectID" + "modified_at": { + "type": "string", + "format": "date-time", + "description": "The date and time when the publication was last modified for the instance." + } + }, + "example": { + "config_version": "c039fbbd5d7f73d894390fb446bd3690da099ed8862b2527299bc2ba", + "created_at": "2024-05-14T20:36:06.272704Z", + "modified_at": "2024-05-14T20:36:06.272704Z", + "object_id": "pub_vfr5Oqv-AhxGzyqTXW-Ubw", + "status": "pending" + } + }, + "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" }, - "paths": { - "type": "array", - "description": "The list of file system paths where the compiled log profile bundle file is installed. \nSince a single compiled log profile bundle file may be applied in multiple contexts, all relevant paths are included.\n", - "example": [ - "/etc/nginx/default_log_profile.tgz", - "/etc/nginx/default_log_profile_2.tgz" - ], - "items": { - "type": "string" - } + "config_version": { + "type": "string", + "description": "A hash that uniquely identifies the contents of the config object.\n" }, - "deployment_status": { - "$ref": "#/components/schemas/NapDeploymentStatus" + "created_at": { + "type": "string", + "format": "date-time", + "description": "The date and time when the NGINX configuration object was created for the instance." }, - "deployed_on": { - "description": "Date and time of the deployment.", + "modified_at": { "type": "string", - "format": "date-time" + "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": { - "name": "default_log_profile", - "nap_release": "5.10.0", - "latest_deployed": "yes", - "log_profile_object_id": "lp_panEdeY-Sh2rWm365y7wsw", - "publication_object_id": "pub_72pGHoGsSICL_THZrs964g", - "paths": [ - "/etc/nginx/default_log_profile.tgz" - ], - "deployment_status": "deployed", - "deployed_on": "2023-12-06T22:37:24.120114Z" + "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" } }, - "ConfigSyncGroup": { + "FilterNameControlPlanes": { + "type": "string", + "description": "Keywords for control plane filters.\n", + "enum": [ + "name", + "product_version", + "object_id", + "cve_severity" + ], + "x-enum-varnames": [ + "filter_name_control_plane_name", + "filter_name_control_plane_product_version", + "filter_name_control_plane_object_id", + "filter_name_control_plane_cve_severity" + ] + }, + "ListControlPlaneObject": { "allOf": [ { - "$ref": "#/components/schemas/ConfigSyncGroupMeta" + "$ref": "#/components/schemas/ControlPlaneBaseInfo" }, { "type": "object", - "description": "Additional information of the NGINX config sync group including:\n* config sync status\n* config checksum\n* instances\n* last known publication status\n* certs associated with this config sync group\n", + "description": "Summary information about a control plane.", + "required": [ + "object_id", + "instances_count", + "online_instances_count" + ], "properties": { - "config_status": { - "$ref": "#/components/schemas/ConfigSyncStatus" + "object_id": { + "$ref": "#/components/schemas/ControlPlaneObjectID" }, - "config_version": { - "description": "A computed hash of current config on the config sync group.", - "type": "string" + "instances_count": { + "description": "Total number of instances in the control plane.", + "type": "integer" }, - "instances": { - "description": "An array of Instance objects.", + "online_instances_count": { + "description": "Total number of online instances in the control plane.", + "type": "integer" + }, + "cve_severity": { "type": "array", + "description": "An array summarizing identified Common Vulnerabilities and Exposures (CVEs) across the NGINX control plane.", "items": { - "$ref": "#/components/schemas/ConfigSyncGroupInstance" + "$ref": "#/components/schemas/CveDetails" } - }, - "last_publication_status": { - "$ref": "#/components/schemas/ConfigSyncGroupPublicationStatus" - }, - "certs": { - "description": "An array detailing each certificate's information, including its friendly name, unique identifier, applicable file system paths, subject name, and validity dates. \nIt provides insights into the operational status of each certificate, such as whether it's currently valid, nearing expiration, is not ready to be used, or has already expired.\nThe deployment status indicates whether the latest certs and key managed by NGINX One Console are deployed onto the data plane instances that are part of this config sync group.\n", + } + } + } + ] + }, + "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/CertAssociation" + "$ref": "#/components/schemas/ListControlPlaneObject" } - }, - "nginx_app_protect": { - "type": "object", - "required": [ - "deployments" - ], - "properties": { - "deployments": { - "type": "array", - "items": { - "$ref": "#/components/schemas/NapAssociation" - } - } + } + } + } + ], + "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", + "created_at": "2023-12-06T22:37:24.120114Z", + "instances_count": 5, + "online_instances_count": 3, + "cve_severity": [ + { + "count": 6, + "type": "medium" + }, + { + "count": 1, + "type": "high" } - }, - "log_profile": { - "type": "object", - "required": [ - "deployments" - ], - "properties": { - "deployments": { - "type": "array", - "items": { - "$ref": "#/components/schemas/LogProfileAssociation" - } - } + ] + }, + { + "object_id": "ecp_-bRQlhscTKmbUIdJaYhGJA", + "name": "ngf-deployment", + "created_at": "2023-12-06T22:37:24.120114Z", + "product_version": "nginx-gateway-fabric-2.0.1", + "instances_count": 3, + "online_instances_count": 1, + "cve_severity": [ + { + "count": 2, + "type": "medium" + }, + { + "count": 3, + "type": "high" } - } + ] } + ] + } + }, + "ControlPlaneBulkRequestData": { + "type": "object", + "description": "Part of bulk operation on a control plane, only `delete` is supported.", + "required": [ + "action", + "object_id" + ], + "properties": { + "object_id": { + "$ref": "#/components/schemas/ControlPlaneObjectID" + }, + "action": { + "$ref": "#/components/schemas/BulkRequestAction" + } + }, + "example": { + "object_id": "ecp_-uvR3F2TQGm18jnl7bpaGw", + "action": "delete" + } + }, + "ControlPlaneBulkRequest": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ControlPlaneBulkRequestData" + }, + "minItems": 1, + "maxItems": 50, + "example": [ + { + "object_id": "ecp_-uvR3F2TQGm18jnl7bpaGw", + "action": "delete" + }, + { + "object_id": "ecp_PL0c1XodRemmzVEjiXSsTg", + "action": "delete" + } + ] + }, + "ControlPlaneBulkResponse": { + "description": "The control plane bulk outcome.", + "type": "array", + "items": { + "$ref": "#/components/schemas/BulkRequestObjectStatus" + } + }, + "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" + }, + "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" + }, + "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" + } + } + }, + "ControlPlane": { + "type": "object", + "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": { + "object_id": { + "$ref": "#/components/schemas/ControlPlaneObjectID" + }, + "cluster_uuid": { + "description": "The Kubernetes UID assigned to the cluster that the product is running in.", + "type": "string" + }, + "deployment_uuid": { + "description": "The Kubernetes UID assigned to the control plane.", + "type": "string" + }, + "key_object_id": { + "$ref": "#/components/schemas/DataPlaneKeyObjectID" + }, + "kubernetes_namespace": { + "description": "The kubernetes namespace that the product is running in.", + "type": "string" + }, + "cert_summary": { + "$ref": "#/components/schemas/CertificateInstanceSummary" + }, + "statuses": { + "$ref": "#/components/schemas/StatusSummary" } - ], - "example": { - "object_id": "csg_-uvR3F2TQGm18jnl7bpaGw", - "name": "test-config-sync-group", - "created_at": "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", - "has_container_host": false - } - ], - "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" - } - ] } }, - "ConfigSyncGroupDetails": { + "ControlPlaneDetails": { "type": "object", - "description": "Detailed information of the NGINX config sync group.", + "description": "Detailed information of control plane.", "allOf": [ { - "$ref": "#/components/schemas/ConfigSyncGroup" + "$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", + "created_at": "2023-12-06T22:37:24.120114Z", + "cert_summary": { + "total": 9, + "valid": 1, + "expired": 5, + "expiring": 3, + "not_ready": 0 + }, + "statuses": { + "offline": 0, + "online": 3, + "unavailable": 0 + } + } }, - "FileData": { + "SummaryDisplayCount": { + "description": "The name, the total count, and an optional user-friendly display name of the resource being summarized.", "type": "object", - "description": "Details about a file, including its path, content, size, and last modified time.", "required": [ "name", - "contents", - "size", - "mtime" + "count" ], "properties": { "name": { - "type": "string", - "description": "The file's relative path to the parent directory.", - "minLength": 1, - "maxLength": 4096 - }, - "contents": { - "type": "string", - "format": "byte", - "description": "The base64-encoded contents of the file.", - "maxLength": 3145728 + "description": "Identifies the category of data being reported, such as an operating system, NGINX version, or another type.", + "type": "string" }, - "size": { - "type": "integer", - "description": "The size of the file, in bytes." + "count": { + "description": "The number of resources matching the given type.", + "type": "integer" }, - "mtime": { - "type": "string", - "format": "date-time", - "description": "Timestamp of the last modification made to the file." + "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" } } }, - "DirectoryWithFileContent": { + "ControlPlaneProductVersionSummary": { + "description": "An array of control plane product names/versions.", + "type": "array", + "items": { + "$ref": "#/components/schemas/SummaryDisplayCount" + } + }, + "CveControlPlaneSummary": { + "description": "A summary of Common Vulnerabilities and Exposures (CVEs) across the NGINX control plane.", "type": "object", - "description": "Represents a directory and its contents, detailing the directory's full path, assigned permissions, last modified time, and the files within it.", "required": [ - "name", - "files" + "severity", + "count", + "affected_control_planes" ], "properties": { - "name": { - "type": "string", - "description": "The complete path of the directory." - }, - "permissions": { - "type": "string", - "description": "The permissions for the directory." + "severity": { + "$ref": "#/components/schemas/CveSeverityType" }, - "mtime": { - "type": "string", - "description": "The date and time when the directory was last modified.", - "format": "date-time" + "count": { + "description": "The number of CVEs at each severity level.", + "type": "integer" }, - "files": { - "type": "array", - "description": "The list of files in the directory.", - "items": { - "$ref": "#/components/schemas/FileData" - } + "affected_control_planes": { + "description": "The number of control planes affected by each CVE.", + "type": "integer" } } }, - "NginxConfigObject": { + "ControlPlaneSummary": { + "description": "A summary of control planes including their product names/version details.", "type": "object", - "description": "Details of an NGINX configuration, the main configuration path, and the configuration directories.\n", - "required": [ - "conf_path", - "configs" - ], "properties": { - "config_version": { - "type": "string", - "description": "A hash that uniquely identifies the contents of the config object. Can be used to detect change when updating the NginxConfig.\n" - }, - "conf_path": { - "$ref": "#/components/schemas/ConfigPath" - }, - "configs": { - "type": "array", - "description": "An array of directories containing NGINX configuration files.", - "items": { - "$ref": "#/components/schemas/DirectoryWithFileContent" - } + "product_versions": { + "$ref": "#/components/schemas/ControlPlaneProductVersionSummary" }, - "aux": { + "cves": { + "description": "An array summarizing identified Common Vulnerabilities and Exposures (CVEs) across the NGINX control plane.", "type": "array", - "description": "An array of auxiliary directory contents related to the NGINX configuration.", "items": { - "$ref": "#/components/schemas/DirectoryWithFileContent" + "$ref": "#/components/schemas/CveControlPlaneSummary" } } }, "example": { - "aux": [], - "conf_path": "/etc/nginx/nginx.conf", - "configs": [ + "product_versions": [ { - "files": [ - { - "contents": "Cm1hcCAkdXJpICRtYXBwZWRfc2VydmljZSB7CiAgICBkZWZhdWx0IFVOTUFUQ0hFRDsKICAgICJ+Xi9hcGkvdjEvbmFtZXNwYWNlcy9cdysvaW5zdGFuY2VzIiAgICAgICAgaW5zdGFuY2VzLXN2YzsKICAgICJ+Xi9hcGkvdjEvbmFtZXNwYWNlcy9cdysvZGF0YS1wbGFuZS1rZXlzIiAga2V5cy1zdmM7CiAgICAifl4vYXBpL3YxL25hbWVzcGFjZXMvXHcrL21vbml0b3IiICAgICAgICAgIG1vbml0b3Itc3ZjOwp9Cgp1cHN0cmVhbSBpbnN0YW5jZXMtc3ZjIHsKICAgIHNlcnZlciBpbnN0YW5jZXMtc3ZjOjgwODA7Cn0KCnVwc3RyZWFtIGtleXMtc3ZjIHsKICAgIHNlcnZlciBrZXlzLXN2Yzo4MDkwOwp9Cgp1cHN0cmVhbSBkYXRhcGxhbmUtY3RybCB7CiAgICBzZXJ2ZXIgZGF0YXBsYW5lLWN0cmw6ODA4MDsKfQoKdXBzdHJlYW0gbW9uaXRvci1zdmMgewogICAgc2VydmVyIG1vbml0b3Itc3ZjOjgwODA7Cn0KCnVwc3RyZWFtIG1ldHJpY3MtaW5nZXN0IHsKICAgIHNlcnZlciBtZXRyaWNzLWluZ2VzdDo4MDgwOwp9CgpzZXJ2ZXIgewogICAgbGlzdGVuIDg4ODg7CiAgICBzZXJ2ZXJfbmFtZSBfOwogICAgaHR0cDIgb247CgogICAgcHJveHlfcGFzc19yZXF1ZXN0X2hlYWRlcnMgb247CiAgICByZXdyaXRlICJeL2FwaS8obmdpbngvb25lfHYxKS8oLiopJCIgIi9hcGkvdjEvJDIiIGJyZWFrOwogICAgbG9jYXRpb24gL2FwaS92MS8gewogICAgICAgIGlmICgkbWFwcGVkX3NlcnZpY2UgPSAiVU5NQVRDSEVEIikgewogICAgICAgICAgICByZXR1cm4gNDA0ICd7ImVycm9yOiAiTm90IGZvdW5kIn0nOwogICAgICAgIH0KICAgICAgICBwcm94eV9wYXNzX2hlYWRlciBYLVZvbHRlcnJhLUFwaWd3LVRlbmFudDsKICAgICAgICBwcm94eV9wYXNzIGh0dHA6Ly8kbWFwcGVkX3NlcnZpY2U7CiAgICB9CgogICAgIyBnUlBDIHNlcnZpY2UgZm9yIGRhdGFwbGFuZS1jdHJsCiAgICBsb2NhdGlvbiAvZjUubmdpbnguYWdlbnQuc2RrLkNvbW1hbmRlciB7CiAgICAgICAgZ3JwY19zb2NrZXRfa2VlcGFsaXZlIG9uOwogICAgICAgIGdycGNfcmVhZF90aW1lb3V0IDVtOwogICAgICAgIGdycGNfc2VuZF90aW1lb3V0IDVtOwogICAgICAgIGNsaWVudF9ib2R5X3RpbWVvdXQgMTBtOwogICAgICAgIGdycGNfcGFzcyBncnBjOi8vZGF0YXBsYW5lLWN0cmw7CiAgICB9CgogICAgIyBnUlBDIHNlcnZpY2UgZm9yIG1ldHJpY3MgaW5nZXN0aW9uCiAgICBsb2NhdGlvbiAvZjUubmdpbnguYWdlbnQuc2RrLk1ldHJpY3NTZXJ2aWNlIHsKICAgICAgICBncnBjX3NvY2tldF9rZWVwYWxpdmUgb247CiAgICAgICAgZ3JwY19yZWFkX3RpbWVvdXQgNW07CiAgICAgICAgZ3JwY19zZW5kX3RpbWVvdXQgNW07CiAgICAgICAgY2xpZW50X2JvZHlfdGltZW91dCAxMG07CiAgICAgICAgY2xpZW50X21heF9ib2R5X3NpemUgMDsKICAgICAgICBncnBjX3Bhc3MgZ3JwYzovL21ldHJpY3MtaW5nZXN0OwogICAgfQp9CgojIHByb3h5IHRvIHRoZSBtYW5hZ2VtZW50IHNlcnZlcnMKc2VydmVyIHsKICAgIGxpc3RlbiAxNTAwMDsKICAgIHNlcnZlcl9uYW1lIF87CiAgICAjIHVzZSBkb2NrZXIgRE5TCiAgICByZXNvbHZlciAxMjcuMC4wLjExIHZhbGlkPTMwczsKCiAgICAjIG1hdGNoIC88c2VydmljZT4vPG1nbXQgZW5kcG9pbnQ+CiAgICBsb2NhdGlvbiB+Xi8oW14vXSspLyguKykkIHsKICAgICAgICBwcm94eV9wYXNzIGh0dHA6Ly8kMToxNTAwMC8kMjsKICAgIH0KCiAgICBsb2NhdGlvbiAvIHsKICAgICAgICBhZGRfaGVhZGVyICJDb250ZW50LVR5cGUiICJ0ZXh0L2h0bWwiOwogICAgICAgIHJldHVybiAyMDAgIjxwPkFjY2VzcyB0aGUgbWFuYWdlbWVudCBzZXJ2ZXIgb2YgYW55IHNlcnZpY2Ugd2l0aCBVUkxzIGxpa2UgPGNvZGU+aHR0cDovL2xvY2FsaG9zdDoxNTAwMC8mbHQ7U0VSVklDRV9OQU1FJmd0Oy9tZXRyaWNzPC9jb2RlPjwvcD4iOwogICAgfQp9Cg==", - "mtime": "1970-01-01T00:00:00Z", - "name": "default.conf", - "size": 1942 - } - ], - "name": "/etc/nginx/conf.d" + "count": 10, + "name": "nginx-ingress-controller-1.0.0" + } + ], + "cves": [ + { + "affected_control_planes": 3, + "count": 13, + "severity": "medium" }, { - "files": [ - { - "contents": "CnVzZXIgIG5naW54Owp3b3JrZXJfcHJvY2Vzc2VzICBhdXRvOwoKZXJyb3JfbG9nICAvdmFyL2xvZy9uZ2lueC9lcnJvci5sb2cgbm90aWNlOwpwaWQgICAgICAgIC92YXIvcnVuL25naW54LnBpZDsKCgpldmVudHMgewogICAgd29ya2VyX2Nvbm5lY3Rpb25zICAxMDI0Owp9CgoKaHR0cCB7CiAgICBpbmNsdWRlICAgICAgIC9ldGMvbmdpbngvbWltZS50eXBlczsKICAgIGRlZmF1bHRfdHlwZSAgYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtOwoKICAgIGxvZ19mb3JtYXQgIG1haW4gICckcmVtb3RlX2FkZHIgLSAkcmVtb3RlX3VzZXIgWyR0aW1lX2xvY2FsXSAiJHJlcXVlc3QiICcKICAgICAgICAgICAgICAgICAgICAgICckc3RhdHVzICRib2R5X2J5dGVzX3NlbnQgIiRodHRwX3JlZmVyZXIiICcKICAgICAgICAgICAgICAgICAgICAgICciJGh0dHBfdXNlcl9hZ2VudCIgIiRodHRwX3hfZm9yd2FyZGVkX2ZvciInOwoKICAgIGFjY2Vzc19sb2cgIC92YXIvbG9nL25naW54L2FjY2Vzcy5sb2cgIG1haW47CgogICAgc2VuZGZpbGUgICAgICAgIG9uOwogICAgI3RjcF9ub3B1c2ggICAgIG9uOwoKICAgIGtlZXBhbGl2ZV90aW1lb3V0ICA2NTsKCiAgICAjZ3ppcCAgb247CgogICAgaW5jbHVkZSAvZXRjL25naW54L2NvbmYuZC8qLmNvbmY7Cn0K", - "mtime": "1970-01-01T00:00:00Z", - "name": "nginx.conf", - "size": 648 - }, - { - "contents": "CnR5cGVzIHsKICAgIHRleHQvaHRtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBodG1sIGh0bSBzaHRtbDsKICAgIHRleHQvY3NzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3M7CiAgICB0ZXh0L3htbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sOwogICAgaW1hZ2UvZ2lmICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdpZjsKICAgIGltYWdlL2pwZWcgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqcGVnIGpwZzsKICAgIGFwcGxpY2F0aW9uL2phdmFzY3JpcHQgICAgICAgICAgICAgICAgICAgICAgICAgICBqczsKICAgIGFwcGxpY2F0aW9uL2F0b20reG1sICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdG9tOwogICAgYXBwbGljYXRpb24vcnNzK3htbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJzczsKCiAgICB0ZXh0L21hdGhtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW1sOwogICAgdGV4dC9wbGFpbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR4dDsKICAgIHRleHQvdm5kLnN1bi5qMm1lLmFwcC1kZXNjcmlwdG9yICAgICAgICAgICAgICAgICBqYWQ7CiAgICB0ZXh0L3ZuZC53YXAud21sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd21sOwogICAgdGV4dC94LWNvbXBvbmVudCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGh0YzsKCiAgICBpbWFnZS9hdmlmICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXZpZjsKICAgIGltYWdlL3BuZyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbmc7CiAgICBpbWFnZS9zdmcreG1sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ZnIHN2Z3o7CiAgICBpbWFnZS90aWZmICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGlmIHRpZmY7CiAgICBpbWFnZS92bmQud2FwLndibXAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2JtcDsKICAgIGltYWdlL3dlYnAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3ZWJwOwogICAgaW1hZ2UveC1pY29uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGljbzsKICAgIGltYWdlL3gtam5nICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqbmc7CiAgICBpbWFnZS94LW1zLWJtcCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm1wOwoKICAgIGZvbnQvd29mZiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3b2ZmOwogICAgZm9udC93b2ZmMiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdvZmYyOwoKICAgIGFwcGxpY2F0aW9uL2phdmEtYXJjaGl2ZSAgICAgICAgICAgICAgICAgICAgICAgICBqYXIgd2FyIGVhcjsKICAgIGFwcGxpY2F0aW9uL2pzb24gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqc29uOwogICAgYXBwbGljYXRpb24vbWFjLWJpbmhleDQwICAgICAgICAgICAgICAgICAgICAgICAgIGhxeDsKICAgIGFwcGxpY2F0aW9uL21zd29yZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2M7CiAgICBhcHBsaWNhdGlvbi9wZGYgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGRmOwogICAgYXBwbGljYXRpb24vcG9zdHNjcmlwdCAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzIGVwcyBhaTsKICAgIGFwcGxpY2F0aW9uL3J0ZiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBydGY7CiAgICBhcHBsaWNhdGlvbi92bmQuYXBwbGUubXBlZ3VybCAgICAgICAgICAgICAgICAgICAgbTN1ODsKICAgIGFwcGxpY2F0aW9uL3ZuZC5nb29nbGUtZWFydGgua21sK3htbCAgICAgICAgICAgICBrbWw7CiAgICBhcHBsaWNhdGlvbi92bmQuZ29vZ2xlLWVhcnRoLmtteiAgICAgICAgICAgICAgICAga216OwogICAgYXBwbGljYXRpb24vdm5kLm1zLWV4Y2VsICAgICAgICAgICAgICAgICAgICAgICAgIHhsczsKICAgIGFwcGxpY2F0aW9uL3ZuZC5tcy1mb250b2JqZWN0ICAgICAgICAgICAgICAgICAgICBlb3Q7CiAgICBhcHBsaWNhdGlvbi92bmQubXMtcG93ZXJwb2ludCAgICAgICAgICAgICAgICAgICAgcHB0OwogICAgYXBwbGljYXRpb24vdm5kLm9hc2lzLm9wZW5kb2N1bWVudC5ncmFwaGljcyAgICAgIG9kZzsKICAgIGFwcGxpY2F0aW9uL3ZuZC5vYXNpcy5vcGVuZG9jdW1lbnQucHJlc2VudGF0aW9uICBvZHA7CiAgICBhcHBsaWNhdGlvbi92bmQub2FzaXMub3BlbmRvY3VtZW50LnNwcmVhZHNoZWV0ICAgb2RzOwogICAgYXBwbGljYXRpb24vdm5kLm9hc2lzLm9wZW5kb2N1bWVudC50ZXh0ICAgICAgICAgIG9kdDsKICAgIGFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5wcmVzZW50YXRpb25tbC5wcmVzZW50YXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcHR4OwogICAgYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwuc2hlZXQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bHN4OwogICAgYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LndvcmRwcm9jZXNzaW5nbWwuZG9jdW1lbnQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N4OwogICAgYXBwbGljYXRpb24vdm5kLndhcC53bWxjICAgICAgICAgICAgICAgICAgICAgICAgIHdtbGM7CiAgICBhcHBsaWNhdGlvbi93YXNtICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2FzbTsKICAgIGFwcGxpY2F0aW9uL3gtN3otY29tcHJlc3NlZCAgICAgICAgICAgICAgICAgICAgICA3ejsKICAgIGFwcGxpY2F0aW9uL3gtY29jb2EgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjY287CiAgICBhcHBsaWNhdGlvbi94LWphdmEtYXJjaGl2ZS1kaWZmICAgICAgICAgICAgICAgICAgamFyZGlmZjsKICAgIGFwcGxpY2F0aW9uL3gtamF2YS1qbmxwLWZpbGUgICAgICAgICAgICAgICAgICAgICBqbmxwOwogICAgYXBwbGljYXRpb24veC1tYWtlc2VsZiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ1bjsKICAgIGFwcGxpY2F0aW9uL3gtcGVybCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbCBwbTsKICAgIGFwcGxpY2F0aW9uL3gtcGlsb3QgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmMgcGRiOwogICAgYXBwbGljYXRpb24veC1yYXItY29tcHJlc3NlZCAgICAgICAgICAgICAgICAgICAgIHJhcjsKICAgIGFwcGxpY2F0aW9uL3gtcmVkaGF0LXBhY2thZ2UtbWFuYWdlciAgICAgICAgICAgICBycG07CiAgICBhcHBsaWNhdGlvbi94LXNlYSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VhOwogICAgYXBwbGljYXRpb24veC1zaG9ja3dhdmUtZmxhc2ggICAgICAgICAgICAgICAgICAgIHN3ZjsKICAgIGFwcGxpY2F0aW9uL3gtc3R1ZmZpdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXQ7CiAgICBhcHBsaWNhdGlvbi94LXRjbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGNsIHRrOwogICAgYXBwbGljYXRpb24veC14NTA5LWNhLWNlcnQgICAgICAgICAgICAgICAgICAgICAgIGRlciBwZW0gY3J0OwogICAgYXBwbGljYXRpb24veC14cGluc3RhbGwgICAgICAgICAgICAgICAgICAgICAgICAgIHhwaTsKICAgIGFwcGxpY2F0aW9uL3hodG1sK3htbCAgICAgICAgICAgICAgICAgICAgICAgICAgICB4aHRtbDsKICAgIGFwcGxpY2F0aW9uL3hzcGYreG1sICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4c3BmOwogICAgYXBwbGljYXRpb24vemlwICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHppcDsKCiAgICBhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0gICAgICAgICAgICAgICAgICAgICAgICAgYmluIGV4ZSBkbGw7CiAgICBhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0gICAgICAgICAgICAgICAgICAgICAgICAgZGViOwogICAgYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtICAgICAgICAgICAgICAgICAgICAgICAgIGRtZzsKICAgIGFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSAgICAgICAgICAgICAgICAgICAgICAgICBpc28gaW1nOwogICAgYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtICAgICAgICAgICAgICAgICAgICAgICAgIG1zaSBtc3AgbXNtOwoKICAgIGF1ZGlvL21pZGkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaWQgbWlkaSBrYXI7CiAgICBhdWRpby9tcGVnICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXAzOwogICAgYXVkaW8vb2dnICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9nZzsKICAgIGF1ZGlvL3gtbTRhICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtNGE7CiAgICBhdWRpby94LXJlYWxhdWRpbyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmE7CgogICAgdmlkZW8vM2dwcCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDNncHAgM2dwOwogICAgdmlkZW8vbXAydCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRzOwogICAgdmlkZW8vbXA0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1wNDsKICAgIHZpZGVvL21wZWcgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtcGVnIG1wZzsKICAgIHZpZGVvL3F1aWNrdGltZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb3Y7CiAgICB2aWRlby93ZWJtICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2VibTsKICAgIHZpZGVvL3gtZmx2ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbHY7CiAgICB2aWRlby94LW00diAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbTR2OwogICAgdmlkZW8veC1tbmcgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1uZzsKICAgIHZpZGVvL3gtbXMtYXNmICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3ggYXNmOwogICAgdmlkZW8veC1tcy13bXYgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdtdjsKICAgIHZpZGVvL3gtbXN2aWRlbyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdmk7Cn0K", - "mtime": "1970-01-01T00:00:00Z", - "name": "mime.types", - "size": 5349 - } - ], - "name": "/etc/nginx" + "affected_control_planes": 2, + "count": 2, + "severity": "high" } ] } }, - "NginxConfigObjectID": { - "description": "A globally unique identifier for the NGINX Config object.", - "type": "string", - "format": "object_id", - "pattern": "^nc_.*", - "x-go-type": "objects.ID", - "x-go-type-import": { - "name": "objects", - "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" + "NginxCVEObject": { + "type": "object", + "required": [ + "id", + "severity", + "info", + "published_at" + ], + "description": "Details about a specific NGINX security advisory, including the number of instances impacted by it, its severity, and a brief description.", + "properties": { + "id": { + "description": "The security advisory's unique identifier.", + "type": "string" + }, + "severity": { + "$ref": "#/components/schemas/CveSeverityType" + }, + "info": { + "description": "A brief description of security advisory.", + "type": "string" + }, + "instances_impacted": { + "description": "Number of instances impacted by the security advisory", + "type": "integer" + }, + "control_planes_impacted": { + "description": "Number of control planes impacted by the security advisory", + "type": "integer" + }, + "published_at": { + "description": "The date and time when the cve was published", + "type": "string", + "format": "date-time" + } } }, - "NginxConfig": { - "description": "Details of an NGINX configuration, including its unique identifier, the main configuration path, the \nconfiguration directories, and the NGINX configuration payloads that indicate where managed SSL certificates\nand keys were deployed to on the data plane instance.\n", + "CVEListResponse": { "allOf": [ { - "$ref": "#/components/schemas/NginxConfigObject" + "$ref": "#/components/schemas/PaginationResponse" }, { "type": "object", + "description": "List of all CVEs.", "required": [ - "object_id" + "items" ], "properties": { - "object_id": { - "$ref": "#/components/schemas/NginxConfigObjectID" - }, - "payloads": { - "$ref": "#/components/schemas/NginxConfigPayloads" + "items": { + "description": "An array of CVE objects.", + "type": "array", + "items": { + "$ref": "#/components/schemas/NginxCVEObject" + } } } } ] }, - "PublicationStatusCause": { - "description": "Cause of the failure, provided only if the status is `failed`.", + "NginxProduct": { + "type": "string", + "description": "NGINX product :\n * `noss` - NGINX Open Source.\n * `nplus` - NGINX PLUS.\n * `nic` - NGINX Ingress Controller.\n * `ngf` - NGINX Gateway Fabric.\n", + "enum": [ + "noss", + "nplus", + "nic", + "ngf", + "unknown" + ], + "x-enum-varnames": [ + "nginx_product_noss", + "nginx_product_nplus", + "nginx_product_nic", + "nginx_product_ngf", + "nginx_product_unknown" + ] + }, + "CveImpactedNginxProduct": { "type": "object", + "required": [ + "versions", + "name" + ], + "description": "security advisory impacted NGINX product and its version.", "properties": { - "cause": { - "description": "Cause of the failure, detailed as follows:\n* `unknown` - The reason for the failure is not known.\n* `timeout` - The publication request reached its time limit without receiving a response from the NGINX Agent.\n* `remote` - The NGINX Agent reported a failure when trying to apply the configuration. See the message for more details.\n* `payload` - The publication was successful, but there were warnings reported by attached payloads, see message for more details.\n", - "type": "string", - "enum": [ - "unknown", - "timeout", - "remote", - "payload" - ], - "x-enum-varnames": [ - "publication_instance_status_cause_unknown", - "publication_instance_status_cause_timeout", - "publication_instance_status_cause_remote", - "publication_instance_status_cause_payload" - ] + "versions": { + "description": "List of impacted NGINX product versions.", + "type": "array", + "items": { + "type": "string" + } }, - "message": { - "type": "string", - "description": "more specific failure message from the agent." + "name": { + "$ref": "#/components/schemas/NginxProduct" } } }, - "ConfigSyncGroupPublicationStatusReason": { + "NginxCVEDetailsResponse": { "allOf": [ { - "$ref": "#/components/schemas/PublicationStatusCause" + "$ref": "#/components/schemas/NginxCVEObject" }, { "type": "object", "required": [ - "object_id" + "detail", + "impacted_products" ], + "description": "Details about a specific NGINX security advisory, including its severity, detail,\npublished date and time, description and impacted products.\n", "properties": { - "object_id": { - "$ref": "#/components/schemas/InstanceObjectID" + "impacted_products": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CveImpactedNginxProduct" + } + }, + "detail": { + "description": "the details about security advisory", + "type": "string" } + }, + "example": { + "detail": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-ID", + "id": "CVE-ID", + "impacted_products": [ + { + "name": "nplus", + "versions": [ + "r1", + "r2" + ] + }, + { + "name": "noss", + "versions": [ + "1.11.1", + "1.20.2", + "1.19.9" + ] + }, + { + "name": "nic", + "versions": [ + "1.0.0", + "2.1.0" + ] + }, + { + "name": "ngf", + "versions": [ + "1.6.2", + "2.0.1" + ] + } + ], + "info": "Memory disclosure in the ngx_http_mp4_module", + "published_at": "2022-10-19T00:00:00Z", + "severity": "medium" } } ] }, - "ConfigSyncGroupPublication": { - "description": "Details of a publication request for the NGINX config sync group.", + "NginxProductInfo": { + "type": "object", + "description": "Information about an NGINX product type and its version", "required": [ - "status", - "created_at", - "modified_at" + "name", + "version" ], "properties": { - "object_id": { - "$ref": "#/components/schemas/PublicationObjectID" - }, - "status": { - "$ref": "#/components/schemas/ConfigSyncGroupPublicationStatus" + "name": { + "$ref": "#/components/schemas/NginxProduct" }, - "created_at": { - "type": "string", - "format": "date-time", - "description": "The date and time when the publication was created for the instance." + "version": { + "description": "version of the NGINX product installed on the instance.", + "type": "string" + } + } + }, + "CVEImpactedInstance": { + "type": "object", + "description": "Summary information about a NGINX instance.", + "required": [ + "object_id", + "hostname", + "status" + ], + "properties": { + "object_id": { + "$ref": "#/components/schemas/InstanceObjectID" }, - "modified_at": { - "type": "string", - "format": "date-time", - "description": "The date and time when the publication was last modified for the instance." + "hostname": { + "description": "The name of the host system where the NGINX instance is running.", + "type": "string" }, - "status_reasons": { - "description": "Detailed failure reasons on each instance's publication, when 'status' is in 'failed' or 'partially_succeeded'", + "products": { + "description": "List of NGINX products in the instance", "type": "array", "items": { - "$ref": "#/components/schemas/ConfigSyncGroupPublicationStatusReason" + "$ref": "#/components/schemas/NginxProductInfo" } }, - "config_version": { + "status": { "type": "string", - "description": "A hash that uniquely identifies the contents of the config object in the publication.\n" + "description": "The current operational status of the NGINX instance, with the following possible values:\n* `unknown` - The status of the NGINX instance cannot be determined at this moment.\n* `unavailable` - The NGINX Agent has lost connection to NGINX One, rendering the NGINX instance unavailable.\n* `offline` - The NGINX Agent is connected to NGINX One, but the NGINX instance is offline.\n* `online` - The NGINX Agent is connected to NGINX One, and the NGINX instance is online.\n", + "enum": [ + "unknown", + "unavailable", + "offline", + "online" + ] } - }, - "example": { - "config_version": "fc3bb4b50c145b3ca5c5d1342be5ec0718eeb9bb84f8d53c5734b6b8", - "created_at": "2024-05-23T21:57:13.048285Z", - "modified_at": "2024-05-23T21:57:13.048285Z", - "object_id": "pub_UPV8jXFwSgm1vHQJCvLD1w", - "status": "failed", - "status_reasons": [ - { - "cause": "remote", - "message": "Config apply failed (write): error running nginx -t -c /etc/nginx/nginx.conf:\n error running nginx -t -c /etc/nginx/nginx.conf:\nnginx: [emerg] invalid number of arguments in \"worker_processes\" directive in /etc/nginx/nginx.conf:7\nnginx: configuration file /etc/nginx/nginx.conf test failed\n", - "object_id": "inst_QBBobKIAQ_21grAwV83VYw" + } + }, + "CVEImpactedInstancesListResponse": { + "allOf": [ + { + "$ref": "#/components/schemas/PaginationResponse" + }, + { + "type": "object", + "description": "List of instances affected by a CVE.", + "required": [ + "items" + ], + "properties": { + "items": { + "description": "An array of Instance objects.", + "type": "array", + "items": { + "$ref": "#/components/schemas/CVEImpactedInstance" + } + } + }, + "example": { + "total": 10, + "count": 1, + "start_index": 1, + "items_per_page": 100, + "items": [ + { + "object_id": "inst_8Iwn7dT7RF-PRLxkSt5EYQ", + "hostname": "4d116619f106", + "products": [ + { + "name": "noss", + "version": "1.18.0" + } + ], + "status": "unknown" + } + ] } - ] + } + ] + }, + "FilterNameEvents": { + "type": "string", + "description": "Keywords for events filters.\n", + "enum": [ + "object_id" + ], + "x-enum-varnames": [ + "filter_name_events_object_id" + ] + }, + "EventObjectID": { + "description": "A globally unique identifier for a NGINX One system event.", + "type": "string", + "format": "object_id", + "pattern": "^event_.*", + "x-go-type": "objects.ID", + "x-go-type-import": { + "name": "objects", + "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" } }, - "PublicationInstance": { - "description": "Details of a publication request for an NGINX instance.", + "Event": { + "type": "object", + "description": "An Event is a system message.", "required": [ - "status", - "created_at", - "modified_at" + "type", + "timestamp", + "object_id", + "message" ], "properties": { - "object_id": { - "$ref": "#/components/schemas/PublicationObjectID" - }, - "config_version": { + "timestamp": { + "description": "time of the event", "type": "string", - "description": "A hash that uniquely identifies the contents of the config object in the publication.\n" + "format": "date-time", + "example": "2019-08-07T09:57:36.088757764Z" }, - "status": { - "description": "Publication status for the NGINX instance:\n* `pending` - The publication request has been accepted and is currently processing.\n* `failed` - The publication attempt failed.\n* `succeeded` - The publication was successful.\n* `succeeded_with_warnings` - The publication was successful, but there were warnings.\n", + "type": { "type": "string", + "description": "type of event, indication for affected object type.", "enum": [ - "pending", - "failed", - "succeeded", - "succeeded_with_warnings" + "instance_cleanup", + "certificates", + "publications", + "nap_compilation_jobs" ], "x-enum-varnames": [ - "publication_instance_status_pending", - "publication_instance_status_failed", - "publication_instance_status_succeeded", - "publication_instance_status_succeeded_with_warnings" + "event_type_instance_cleanup", + "event_type_certificates", + "event_type_publications", + "event_type_nap_compilation_jobs" ] }, - "status_cause": { - "$ref": "#/components/schemas/PublicationStatusCause" - }, - "created_at": { - "type": "string", - "format": "date-time", - "description": "The date and time when the publication was created for the instance." - }, - "modified_at": { - "type": "string", - "format": "date-time", - "description": "The date and time when the publication was last modified for the instance." - } - }, - "example": { - "config_version": "c039fbbd5d7f73d894390fb446bd3690da099ed8862b2527299bc2ba", - "created_at": "2024-05-14T20:36:06.272704Z", - "modified_at": "2024-05-14T20:36:06.272704Z", - "object_id": "pub_vfr5Oqv-AhxGzyqTXW-Ubw", - "status": "pending" - } - }, - "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" + "$ref": "#/components/schemas/EventObjectID" }, - "created_at": { - "type": "string", - "format": "date-time", - "description": "The date and time when the NGINX configuration object was created for the instance." + "affected_object_id": { + "$ref": "#/components/schemas/ObjectID" }, - "modified_at": { + "hostname": { "type": "string", - "format": "date-time", - "description": "The date and time when the NGINX configuration object was last modified for the instance." + "description": "hostname of the affected instance, if any." }, - "config_source": { + "message": { "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" + "description": "Details regarding the event.", + "example": "Instance \"demo-1\" deleted by instance cleanup after \"unavailable\" for 25 hours." } }, "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" + "timestamp": "2024-02-04T09:57:36.088757764Z", + "type": "instance_cleanup", + "object_id": "event_-uvR3F2TQGm18jnl7bpaGw", + "affected_object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", + "message": "ip-170.0.1 deleted after age out period of 3 hours, last seen 2023-08-07T09:57:36.088757764Z" } }, - "FilterNameControlPlanes": { - "type": "string", - "description": "Keywords for control plane filters.\n", - "enum": [ - "name", - "product_version", - "object_id", - "cve_severity" - ], - "x-enum-varnames": [ - "filter_name_control_plane_name", - "filter_name_control_plane_product_version", - "filter_name_control_plane_object_id", - "filter_name_control_plane_cve_severity" - ] - }, - "ListControlPlaneObject": { + "EventsListResponse": { "allOf": [ { - "$ref": "#/components/schemas/ControlPlaneBaseInfo" + "$ref": "#/components/schemas/PaginationResponse" }, { "type": "object", - "description": "Summary information about a control plane.", + "description": "List of Events.", "required": [ - "object_id", - "instances_count", - "online_instances_count" + "items" ], "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" - }, - "cve_severity": { + "items": { + "description": "An array of Event objects.", "type": "array", - "description": "An array summarizing identified Common Vulnerabilities and Exposures (CVEs) across the NGINX control plane.", "items": { - "$ref": "#/components/schemas/CveDetails" + "$ref": "#/components/schemas/Event" } } } } ] }, - "ControlPlaneListResponse": { + "FilterNameInstances": { + "type": "string", + "description": "Keywords for instance filters.\n\nWhen filtering on `instance_status`, only the following `filter_values` are supported:\n * online\n * offline\n * unavailable\n * unknown\nWhen filtering base on `cert_status`, only the following `filter_values` are supported:\n * valid\n * expiring\n * expired\n * not_ready\n", + "enum": [ + "hostname", + "nginx_version", + "os_version", + "instance_status", + "cert_status", + "cve_severity", + "config_recommendation", + "key_object_id", + "system_id", + "object_id" + ], + "x-enum-varnames": [ + "filter_name_instances_hostname", + "filter_name_instances_nginx_version", + "filter_name_instances_os_version", + "filter_name_instances_instance_status", + "filter_name_instances_cert_status", + "filter_name_instances_cve_severity", + "filter_name_instances_config_recommendation", + "filter_name_instances_key_object_id", + "filter_name_instances_system_id", + "filter_name_instances_object_id" + ] + }, + "InstanceListResponse": { "allOf": [ { "$ref": "#/components/schemas/PaginationResponse" }, { "type": "object", - "description": "List of control planes.", + "description": "List of data plane instances.", "required": [ "items" ], "properties": { "items": { - "description": "An array of control plane objects.", + "description": "An array of Instance objects.", "type": "array", "items": { - "$ref": "#/components/schemas/ListControlPlaneObject" + "$ref": "#/components/schemas/Instance" } } } } ], - "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", - "created_at": "2023-12-06T22:37:24.120114Z", - "instances_count": 5, - "online_instances_count": 3, - "cve_severity": [ - { - "count": 6, - "type": "medium" - }, - { - "count": 1, - "type": "high" - } - ] - }, - { - "object_id": "ecp_-bRQlhscTKmbUIdJaYhGJA", - "name": "ngf-deployment", - "created_at": "2023-12-06T22:37:24.120114Z", - "product_version": "nginx-gateway-fabric-2.0.1", - "instances_count": 3, - "online_instances_count": 1, - "cve_severity": [ - { - "count": 2, - "type": "medium" - }, - { - "count": 3, - "type": "high" - } - ] + "example": { + "total": 10, + "count": 1, + "start_index": 1, + "items_per_page": 100, + "items": [ + { + "agent_version": "v2.30.3", + "hostname": "4d116619f106", + "key": "key_Tet21AeYTHCj7taOwVfzyw", + "last_reported": "2023-12-06T22:37:24.120114Z", + "nginx_build": { + "conf_path": "/etc/nginx/nginx.conf", + "version": "1.25.3" + }, + "nginx_id": "b636d4376dea15405589692d3c5d3869ff3a9b26b0e7bb4bb1aa7e658ace1437", + "registered_at": "2023-12-06T22:37:24.120114Z", + "status": "unknown", + "system_id": "b2c0b6a8-8b6a-3a8f-a541-17d8899c119a", + "object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", + "has_container_host": false } ] } }, - "ControlPlaneBulkRequestData": { + "InstanceBulkRequestData": { "type": "object", - "description": "Part of bulk operation on a control plane, only `delete` is supported.", + "description": "Part of bulk operation on a NGINX instance, only `delete` is supported.", "required": [ - "action", - "object_id" + "action" ], "properties": { "object_id": { - "$ref": "#/components/schemas/ControlPlaneObjectID" + "$ref": "#/components/schemas/InstanceObjectID" }, "action": { "$ref": "#/components/schemas/BulkRequestAction" } }, "example": { - "object_id": "ecp_-uvR3F2TQGm18jnl7bpaGw", + "object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", "action": "delete" } }, - "ControlPlaneBulkRequest": { + "InstanceBulkRequest": { "type": "array", "items": { - "$ref": "#/components/schemas/ControlPlaneBulkRequestData" + "$ref": "#/components/schemas/InstanceBulkRequestData" }, - "minItems": 1, "maxItems": 50, "example": [ { - "object_id": "ecp_-uvR3F2TQGm18jnl7bpaGw", + "object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", "action": "delete" }, { - "object_id": "ecp_PL0c1XodRemmzVEjiXSsTg", + "object_id": "inst_PL0c1XodRemmzVEjiXSsTg", "action": "delete" } ] }, - "ControlPlaneBulkResponse": { - "description": "The control plane bulk outcome.", + "InstanceBulkResponse": { + "description": "The NGINX instance bulk outcome.", "type": "array", "items": { "$ref": "#/components/schemas/BulkRequestObjectStatus" } }, - "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" - }, - "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" - }, - "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" - } - } - }, - "ControlPlane": { - "type": "object", - "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": { - "object_id": { - "$ref": "#/components/schemas/ControlPlaneObjectID" - }, - "cluster_uuid": { - "description": "The Kubernetes UID assigned to the cluster that the product is running in.", - "type": "string" - }, - "deployment_uuid": { - "description": "The Kubernetes UID assigned to the control plane.", - "type": "string" - }, - "key_object_id": { - "$ref": "#/components/schemas/DataPlaneKeyObjectID" - }, - "kubernetes_namespace": { - "description": "The kubernetes namespace that the product is running in.", - "type": "string" - }, - "cert_summary": { - "$ref": "#/components/schemas/CertificateInstanceSummary" - }, - "statuses": { - "$ref": "#/components/schemas/StatusSummary" - } - } - }, - "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", - "created_at": "2023-12-06T22:37:24.120114Z", - "cert_summary": { - "total": 9, - "valid": 1, - "expired": 5, - "expiring": 3, - "not_ready": 0 - }, - "statuses": { - "offline": 0, - "online": 3, - "unavailable": 0 - } - } - }, - "SummaryDisplayCount": { - "description": "The name, the total count, and an optional user-friendly display name of the resource being summarized.", + "OperatingSystem": { + "description": "Release details for the operating system.", "type": "object", "required": [ "name", - "count" + "id", + "codename", + "version", + "version_id" ], "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.", + "description": "The official name of the operating system release.", "type": "string" - } - } - }, - "ControlPlaneProductVersionSummary": { - "description": "An array of control plane product names/versions.", - "type": "array", - "items": { - "$ref": "#/components/schemas/SummaryDisplayCount" - } - }, - "CveControlPlaneSummary": { - "description": "A summary of Common Vulnerabilities and Exposures (CVEs) across the NGINX control plane.", - "type": "object", - "required": [ - "severity", - "count", - "affected_control_planes" - ], - "properties": { - "severity": { - "$ref": "#/components/schemas/CveSeverityType" - }, - "count": { - "description": "The number of CVEs at each severity level.", - "type": "integer" - }, - "affected_control_planes": { - "description": "The number of control planes affected by each CVE.", - "type": "integer" - } - } - }, - "ControlPlaneSummary": { - "description": "A summary of control planes including their product names/version details.", - "type": "object", - "properties": { - "product_versions": { - "$ref": "#/components/schemas/ControlPlaneProductVersionSummary" }, - "cves": { - "description": "An array summarizing identified Common Vulnerabilities and Exposures (CVEs) across the NGINX control plane.", - "type": "array", - "items": { - "$ref": "#/components/schemas/CveControlPlaneSummary" - } - } - }, - "example": { - "product_versions": [ - { - "count": 10, - "name": "nginx-ingress-controller-1.0.0" - } - ], - "cves": [ - { - "affected_control_planes": 3, - "count": 13, - "severity": "medium" - }, - { - "affected_control_planes": 2, - "count": 2, - "severity": "high" - } - ] - } - }, - "NginxCVEObject": { - "type": "object", - "required": [ - "id", - "severity", - "info", - "published_at" - ], - "description": "Details about a specific NGINX security advisory, including the number of instances impacted by it, its severity, and a brief description.", - "properties": { "id": { - "description": "The security advisory's unique identifier.", + "description": "The distinctive identifier for the operating system release.", "type": "string" }, - "severity": { - "$ref": "#/components/schemas/CveSeverityType" - }, - "info": { - "description": "A brief description of security advisory.", + "codename": { + "description": "The codename assigned to the operating system release.", "type": "string" }, - "instances_impacted": { - "description": "Number of instances impacted by the security advisory", - "type": "integer" - }, - "control_planes_impacted": { - "description": "Number of control planes impacted by the security advisory", - "type": "integer" - }, - "published_at": { - "description": "The date and time when the cve was published", - "type": "string", - "format": "date-time" + "version": { + "description": "The version label for the operating system, which may include the name and version number or codename.", + "type": "string" + }, + "version_id": { + "description": "The specific version number of the operating system release.", + "type": "string" } + }, + "example": { + "name": "Ubuntu", + "id": "ubuntu", + "codename": "bionic", + "version": "18.04.5 LTS (Bionic Beaver)", + "version_id": "18.04" } }, - "CVEListResponse": { + "ConfigSyncGroupInstanceMeta": { "allOf": [ { - "$ref": "#/components/schemas/PaginationResponse" + "$ref": "#/components/schemas/ConfigSyncGroupMeta" }, { "type": "object", - "description": "List of all CVEs.", - "required": [ - "items" - ], + "description": "Additional details on instance in the NGINX config sync group including:\n* config sync status\n", "properties": { - "items": { - "description": "An array of CVE objects.", - "type": "array", - "items": { - "$ref": "#/components/schemas/NginxCVEObject" - } + "instance_config_status": { + "$ref": "#/components/schemas/ConfigSyncStatus" } } } ] }, - "NginxProduct": { + "NapSignatureVersion": { + "description": "The version of the NGINX App Protect resource.", "type": "string", - "description": "NGINX product :\n * `noss` - NGINX Open Source.\n * `nplus` - NGINX PLUS.\n * `nic` - NGINX Ingress Controller.\n * `ngf` - NGINX Gateway Fabric.\n", - "enum": [ - "noss", - "nplus", - "nic", - "ngf", - "unknown" + "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" + } + } + } ], - "x-enum-varnames": [ - "nginx_product_noss", - "nginx_product_nplus", - "nginx_product_nic", - "nginx_product_ngf", - "nginx_product_unknown" - ] + "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" + } }, - "CveImpactedNginxProduct": { + "NginxAppProtectDetails": { + "description": "Information regarding NGINX App Protect. Includes version and deployments.\n", "type": "object", "required": [ - "versions", - "name" + "engine_version", + "deployments" ], - "description": "security advisory impacted NGINX product and its version.", "properties": { - "versions": { - "description": "List of impacted NGINX product versions.", + "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": { - "type": "string" + "$ref": "#/components/schemas/NapInstanceAssociation" } + } + } + }, + "LogProfileDetails": { + "description": "Information regarding deployed log profiles for F5 WAF.\n", + "type": "object", + "required": [ + "nap_release", + "deployments" + ], + "properties": { + "nap_release": { + "type": "string", + "description": "The release version of the compiler used for log profiles." }, - "name": { - "$ref": "#/components/schemas/NginxProduct" + "deployments": { + "type": "array", + "items": { + "$ref": "#/components/schemas/LogProfileAssociation" + } } } }, - "NginxCVEDetailsResponse": { + "InstanceDetails": { + "type": "object", + "description": "Detailed information about an NGINX instance.", "allOf": [ { - "$ref": "#/components/schemas/NginxCVEObject" + "$ref": "#/components/schemas/Instance" }, { "type": "object", - "required": [ - "detail", - "impacted_products" - ], - "description": "Details about a specific NGINX security advisory, including its severity, detail,\npublished date and time, description and impacted products.\n", "properties": { - "impacted_products": { + "certs": { + "description": "An array detailing each certificate's information, including its friendly name, unique identifier, applicable file system paths, subject name, and validity dates. \nIt provides insights into the operational status of each certificate, such as whether it's currently valid, nearing expiration, is not ready to be used, or has already expired.\nThe deployment status indicates whether the latest certs and key managed by NGINX One Console are deployed onto this data plane instance.\n", "type": "array", "items": { - "$ref": "#/components/schemas/CveImpactedNginxProduct" + "$ref": "#/components/schemas/CertAssociation" } }, - "detail": { - "description": "the details about security advisory", - "type": "string" + "os": { + "$ref": "#/components/schemas/OperatingSystem" + }, + "config_sync_group": { + "$ref": "#/components/schemas/ConfigSyncGroupInstanceMeta" + }, + "nginx_app_protect": { + "$ref": "#/components/schemas/NginxAppProtectDetails" + }, + "control_plane": { + "$ref": "#/components/schemas/ControlPlaneBaseInfo" + }, + "log_profile": { + "$ref": "#/components/schemas/LogProfileDetails" } - }, - "example": { - "detail": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-ID", - "id": "CVE-ID", - "impacted_products": [ - { - "name": "nplus", - "versions": [ - "r1", - "r2" - ] - }, - { - "name": "noss", - "versions": [ - "1.11.1", - "1.20.2", - "1.19.9" - ] - }, - { - "name": "nic", - "versions": [ - "1.0.0", - "2.1.0" - ] - }, - { - "name": "ngf", - "versions": [ - "1.6.2", - "2.0.1" - ] - } + } + } + ], + "example": { + "agent_version": "v2.30.3", + "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" ], - "info": "Memory disclosure in the ngx_http_mp4_module", - "published_at": "2022-10-19T00:00:00Z", - "severity": "medium" + "cert_status": "expiring", + "deployment_status": "latest", + "object_id": "cert_Tet21AeYTHCj7taOwVfzyw" } + ], + "hostname": "4d116619f106", + "key": "key_wN3IhLCmR3qmwybG_6ptEg", + "control_plane": { + "object_id": "ecp_CO1DdBxZToWmr3pTcaQ8QA", + "name": "nginx-ingress-001", + "product_version": "nginx-ingress-controller-4.0.1", + "created_at": "2023-12-06T22:37:24.120114Z" + }, + "last_reported": "2023-12-06T22:37:24.120114Z", + "nginx_build": { + "conf_path": "/etc/nginx/nginx.conf", + "version": "1.25.3" + }, + "nginx_id": "b636d4376dea15405589692d3c5d3869ff3a9b26b0e7bb4bb1aa7e658ace1437", + "os": { + "codename": "jammy", + "id": "ubuntu", + "name": "Ubuntu", + "version": "22.04.3 LTS (Jammy Jellyfish)", + "version_id": "22.04" + }, + "registered_at": "2023-12-06T22:37:24.120114Z", + "status": "unknown", + "system_id": "b2c0b6a8-8b6a-3a8f-a541-17d8899c119a", + "object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", + "has_container_host": false + } + }, + "NginxSecurityAdvisory": { + "type": "object", + "description": "Details about a specific NGINX security advisory, including its severity, a link to more information, and a brief description.", + "required": [ + "id", + "severity", + "advisory", + "info" + ], + "properties": { + "id": { + "description": "The security advisory's unique identifier.", + "type": "string" + }, + "severity": { + "$ref": "#/components/schemas/CveSeverityType" + }, + "advisory": { + "description": "The URL to detailed information about the security advisory.", + "type": "string" + }, + "info": { + "description": "A brief description of security advisory.", + "type": "string" } - ] + } }, - "NginxProductInfo": { + "CertificateSummaryItem": { + "description": "summary information for certificate with certain status.", "type": "object", - "description": "Information about an NGINX product type and its version", "required": [ - "name", - "version" + "status", + "count", + "affected_instances" ], "properties": { - "name": { - "$ref": "#/components/schemas/NginxProduct" + "status": { + "$ref": "#/components/schemas/CertificateStatus" }, - "version": { - "description": "version of the NGINX product installed on the instance.", - "type": "string" + "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" } } }, - "CVEImpactedInstance": { + "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", - "description": "Summary information about a NGINX instance.", "required": [ - "object_id", - "hostname", - "status" + "severity", + "count", + "affected_instances" ], "properties": { - "object_id": { - "$ref": "#/components/schemas/InstanceObjectID" + "severity": { + "$ref": "#/components/schemas/CveSeverityType" }, - "hostname": { - "description": "The name of the host system where the NGINX instance is running.", - "type": "string" + "count": { + "description": "The number of CVEs at each severity level.", + "type": "integer" }, - "products": { - "description": "List of NGINX products in the instance", - "type": "array", - "items": { - "$ref": "#/components/schemas/NginxProductInfo" - } + "affected_instances": { + "description": "The number of NGINX instances affected by each CVE.", + "type": "integer" + } + } + }, + "IssueSummary": { + "description": "A summary of issue details from the configuration analysis report.", + "type": "object", + "required": [ + "type", + "count", + "affected_instances" + ], + "properties": { + "type": { + "$ref": "#/components/schemas/RecommendationType" }, - "status": { - "type": "string", - "description": "The current operational status of the NGINX instance, with the following possible values:\n* `unknown` - The status of the NGINX instance cannot be determined at this moment.\n* `unavailable` - The NGINX Agent has lost connection to NGINX One, rendering the NGINX instance unavailable.\n* `offline` - The NGINX Agent is connected to NGINX One, but the NGINX instance is offline.\n* `online` - The NGINX Agent is connected to NGINX One, and the NGINX instance is online.\n", - "enum": [ - "unknown", - "unavailable", - "offline", - "online" - ] + "count": { + "description": "The number of times this recommendation appears in the configuration analysis report.", + "type": "integer" + }, + "affected_instances": { + "description": "The number of instances affected by this issue.", + "type": "integer" } } }, - "CVEImpactedInstancesListResponse": { - "allOf": [ - { - "$ref": "#/components/schemas/PaginationResponse" + "InstanceSummary": { + "description": "A summary of NGINX instances, including certificates, OS versions, NGINX versions, and status details.", + "type": "object", + "properties": { + "certs": { + "description": "An array detailing each certificate's status across all NGINX instances.", + "type": "array", + "items": { + "$ref": "#/components/schemas/CertificateSummaryItem" + } }, - { - "type": "object", - "description": "List of instances affected by a CVE.", - "required": [ - "items" - ], - "properties": { - "items": { - "description": "An array of Instance objects.", - "type": "array", - "items": { - "$ref": "#/components/schemas/CVEImpactedInstance" - } - } - }, - "example": { - "total": 10, - "count": 1, - "start_index": 1, - "items_per_page": 100, - "items": [ - { - "object_id": "inst_8Iwn7dT7RF-PRLxkSt5EYQ", - "hostname": "4d116619f106", - "products": [ - { - "name": "noss", - "version": "1.18.0" - } - ], - "status": "unknown" - } - ] + "os": { + "$ref": "#/components/schemas/OperatingSystemVersionSummary" + }, + "nginx_versions": { + "$ref": "#/components/schemas/NGINXVersionSummary" + }, + "statuses": { + "$ref": "#/components/schemas/StatusSummary" + }, + "cves": { + "description": "An array summarizing identified Common Vulnerabilities and Exposures (CVEs) across the NGINX data plane.", + "type": "array", + "items": { + "$ref": "#/components/schemas/CveSummary" + } + }, + "recommendations": { + "description": "An array summarizing the suggestions from the configuration analysis report.", + "type": "array", + "items": { + "$ref": "#/components/schemas/IssueSummary" } } - ] + } }, - "FilterNameEvents": { + "FilterStagedConfigs": { "type": "string", - "description": "Keywords for events filters.\n", + "description": "Keywords for staged configs filters.\n", "enum": [ + "name", "object_id" ], "x-enum-varnames": [ - "filter_name_events_object_id" + "filter_name_staged_config_name", + "filter_name_staged_config_object_id" ] }, - "EventObjectID": { - "description": "A globally unique identifier for a NGINX One system event.", + "StagedConfigObjectID": { + "description": "A globally unique identifier for the NGINX staged config.", "type": "string", "format": "object_id", - "pattern": "^event_.*", + "pattern": "^sc_.*", "x-go-type": "objects.ID", "x-go-type-import": { "name": "objects", "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" } }, - "Event": { + "StagedConfigCertificateSummary": { "type": "object", - "description": "An Event is a system message.", + "description": "Provides a summary of the current status of certificates used in NGINX configurations. It includes the total number of certificates, as well as the counts of expired certificates, those nearing expiration, valid certificates, certificates that are not found, and those that are not ready for use.", "required": [ - "type", - "timestamp", - "object_id", - "message" + "total", + "expired", + "expiring", + "valid", + "not_found", + "not_ready" ], "properties": { - "timestamp": { - "description": "time of the event", - "type": "string", - "format": "date-time", - "example": "2019-08-07T09:57:36.088757764Z" + "total": { + "description": "Total count of certificates used as `payloads` in NGINX config.", + "type": "integer" }, - "type": { - "type": "string", - "description": "type of event, indication for affected object type.", - "enum": [ - "instance_cleanup", - "certificates", - "publications", - "nap_compilation_jobs" - ], - "x-enum-varnames": [ - "event_type_instance_cleanup", - "event_type_certificates", - "event_type_publications", - "event_type_nap_compilation_jobs" - ] + "expired": { + "description": "The number of certificates that have expired and are no longer valid.", + "type": "integer" + }, + "expiring": { + "description": "The number of certificates due to expire in the next 30 days.", + "type": "integer" + }, + "valid": { + "description": "The number of certificates that are valid and in good standing.", + "type": "integer" + }, + "not_found": { + "description": "The number of certificates that are not found on NGINX One Console.", + "type": "integer" }, + "not_ready": { + "description": "The number of certificates that are not ready to be used.", + "type": "integer" + } + } + }, + "StagedConfigMeta": { + "type": "object", + "description": "Summary information of the NGINX staged config.", + "required": [ + "object_id", + "name", + "created_at", + "modified_at" + ], + "properties": { "object_id": { - "$ref": "#/components/schemas/EventObjectID" + "$ref": "#/components/schemas/StagedConfigObjectID" }, - "affected_object_id": { - "$ref": "#/components/schemas/ObjectID" + "name": { + "description": "Name of the NGINX staged config", + "type": "string" }, - "hostname": { + "created_at": { "type": "string", - "description": "hostname of the affected instance, if any." + "format": "date-time", + "description": "The date and time when the NGINX configuration object was created for the instance." }, - "message": { + "modified_at": { "type": "string", - "description": "Details regarding the event.", - "example": "Instance \"demo-1\" deleted by instance cleanup after \"unavailable\" for 25 hours." - } - }, - "example": { - "timestamp": "2024-02-04T09:57:36.088757764Z", - "type": "instance_cleanup", - "object_id": "event_-uvR3F2TQGm18jnl7bpaGw", - "affected_object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", - "message": "ip-170.0.1 deleted after age out period of 3 hours, last seen 2023-08-07T09:57:36.088757764Z" - } - }, - "EventsListResponse": { - "allOf": [ - { - "$ref": "#/components/schemas/PaginationResponse" + "format": "date-time", + "description": "The date and time when the NGINX configuration object was last modified for the instance." }, - { - "type": "object", - "description": "List of Events.", - "required": [ - "items" - ], - "properties": { - "items": { - "description": "An array of Event objects.", - "type": "array", - "items": { - "$ref": "#/components/schemas/Event" - } - } - } + "cert_summary": { + "$ref": "#/components/schemas/StagedConfigCertificateSummary" } - ] - }, - "FilterNameInstances": { - "type": "string", - "description": "Keywords for instance filters.\n\nWhen filtering on `instance_status`, only the following `filter_values` are supported:\n * online\n * offline\n * unavailable\n * unknown\nWhen filtering base on `cert_status`, only the following `filter_values` are supported:\n * valid\n * expiring\n * expired\n * not_ready\n", - "enum": [ - "hostname", - "nginx_version", - "os_version", - "instance_status", - "cert_status", - "cve_severity", - "config_recommendation", - "key_object_id", - "system_id", - "object_id" - ], - "x-enum-varnames": [ - "filter_name_instances_hostname", - "filter_name_instances_nginx_version", - "filter_name_instances_os_version", - "filter_name_instances_instance_status", - "filter_name_instances_cert_status", - "filter_name_instances_cve_severity", - "filter_name_instances_config_recommendation", - "filter_name_instances_key_object_id", - "filter_name_instances_system_id", - "filter_name_instances_object_id" - ] + } }, - "InstanceListResponse": { + "StagedConfigListResponse": { "allOf": [ { "$ref": "#/components/schemas/PaginationResponse" }, { "type": "object", - "description": "List of data plane instances.", + "description": "List of NGINX staged configs.", "required": [ "items" ], "properties": { "items": { - "description": "An array of Instance objects.", + "description": "An array of Staged Config objects.", "type": "array", "items": { - "$ref": "#/components/schemas/Instance" + "$ref": "#/components/schemas/StagedConfigMeta" } } } @@ -10604,2297 +12780,3068 @@ "items_per_page": 100, "items": [ { - "agent_version": "v2.30.3", - "hostname": "4d116619f106", - "key": "key_Tet21AeYTHCj7taOwVfzyw", - "last_reported": "2023-12-06T22:37:24.120114Z", - "nginx_build": { - "conf_path": "/etc/nginx/nginx.conf", - "version": "1.25.3" - }, - "nginx_id": "b636d4376dea15405589692d3c5d3869ff3a9b26b0e7bb4bb1aa7e658ace1437", - "registered_at": "2023-12-06T22:37:24.120114Z", - "status": "unknown", - "system_id": "b2c0b6a8-8b6a-3a8f-a541-17d8899c119a", - "object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", - "has_container_host": false + "object_id": "sc_Tet21AeYTHCj7taOwVfzyw", + "name": "my-nginx-staged-config", + "created_at": "2023-08-10T16:59:15Z", + "modified_at": "2023-08-10T16:59:15Z" } ] } }, - "InstanceBulkRequestData": { - "type": "object", - "description": "Part of bulk operation on a NGINX instance, only `delete` is supported.", - "required": [ - "action" - ], - "properties": { - "object_id": { - "$ref": "#/components/schemas/InstanceObjectID" - }, - "action": { - "$ref": "#/components/schemas/BulkRequestAction" - } - }, - "example": { - "object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", - "action": "delete" - } - }, - "InstanceBulkRequest": { - "type": "array", - "items": { - "$ref": "#/components/schemas/InstanceBulkRequestData" - }, - "maxItems": 50, - "example": [ - { - "object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", - "action": "delete" - }, - { - "object_id": "inst_PL0c1XodRemmzVEjiXSsTg", - "action": "delete" - } - ] - }, - "InstanceBulkResponse": { - "description": "The NGINX instance bulk outcome.", - "type": "array", - "items": { - "$ref": "#/components/schemas/BulkRequestObjectStatus" - } + "StagedConfigName": { + "type": "string", + "description": "A name to identify the NGINX staged config.", + "minLength": 1, + "maxLength": 256, + "pattern": "^[^\\s]+$" }, - "OperatingSystem": { - "description": "Release details for the operating system.", - "type": "object", + "StagedConfigCreateRequest": { + "description": "Body to create a NGINX staged config. A staged config can be empty; config payload is optional.", "required": [ - "name", - "id", - "codename", - "version", - "version_id" + "name" ], "properties": { "name": { - "description": "The official name of the operating system release.", - "type": "string" - }, - "id": { - "description": "The distinctive identifier for the operating system release.", - "type": "string" - }, - "codename": { - "description": "The codename assigned to the operating system release.", - "type": "string" - }, - "version": { - "description": "The version label for the operating system, which may include the name and version number or codename.", - "type": "string" + "$ref": "#/components/schemas/StagedConfigName" }, - "version_id": { - "description": "The specific version number of the operating system release.", - "type": "string" + "config": { + "$ref": "#/components/schemas/NginxConfigRequest" } }, "example": { - "name": "Ubuntu", - "id": "ubuntu", - "codename": "bionic", - "version": "18.04.5 LTS (Bionic Beaver)", - "version_id": "18.04" - } - }, - "ConfigSyncGroupInstanceMeta": { - "allOf": [ - { - "$ref": "#/components/schemas/ConfigSyncGroupMeta" - }, - { - "type": "object", - "description": "Additional details on instance in the NGINX config sync group including:\n* config sync status\n", - "properties": { - "instance_config_status": { - "$ref": "#/components/schemas/ConfigSyncStatus" - } - } - } - ] - }, - "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" + "name": "my-nginx-staged-config", + "config": { + "aux": [], + "conf_path": "/etc/nginx/nginx.conf", + "configs": [ + { + "files": [ + { + "contents": "string", + "name": "default.conf" + } + ], + "name": "/etc/nginx/conf.d" } - } + ] } - ], - "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", + "StagedConfigCreateResponse": { + "description": "Response to a create NGINX staged config request.", "required": [ - "engine_version", - "deployments" + "object_id", + "name" ], "properties": { - "release_version": { - "description": "The release version of NGINX App Protect.", - "type": "string" + "object_id": { + "$ref": "#/components/schemas/StagedConfigObjectID" }, - "engine_version": { - "description": "The version of the App Protect enforcement engine.", + "name": { + "description": "Name of the NGINX staged config.", "type": "string" - }, - "deployments": { - "type": "array", - "items": { - "$ref": "#/components/schemas/NapInstanceAssociation" - } } + }, + "example": { + "name": "my-nginx-staged-config", + "object_id": "sc_Tet21AeYTHCj7taOwVfzyw" } }, - "LogProfileDetails": { - "description": "Information regarding deployed log profiles for F5 WAF.\n", + "StagedConfigBulkRequestData": { "type": "object", + "description": "Part of bulk operation on a staged config, only `delete` is supported.", "required": [ - "nap_release", - "deployments" + "action", + "object_id" ], "properties": { - "nap_release": { - "type": "string", - "description": "The release version of the compiler used for log profiles." + "object_id": { + "$ref": "#/components/schemas/StagedConfigObjectID" }, - "deployments": { - "type": "array", - "items": { - "$ref": "#/components/schemas/LogProfileAssociation" - } + "action": { + "$ref": "#/components/schemas/BulkRequestAction" } + }, + "example": { + "object_id": "sc_-uvR3F2TQGm18jnl7bpaGw", + "action": "delete" } }, - "InstanceDetails": { - "type": "object", - "description": "Detailed information about an NGINX instance.", - "allOf": [ + "StagedConfigBulkRequest": { + "type": "array", + "items": { + "$ref": "#/components/schemas/StagedConfigBulkRequestData" + }, + "minItems": 1, + "maxItems": 50, + "example": [ { - "$ref": "#/components/schemas/Instance" + "object_id": "sc_-uvR3F2TQGm18jnl7bpaGw", + "action": "delete" }, { - "type": "object", - "properties": { - "certs": { - "description": "An array detailing each certificate's information, including its friendly name, unique identifier, applicable file system paths, subject name, and validity dates. \nIt provides insights into the operational status of each certificate, such as whether it's currently valid, nearing expiration, is not ready to be used, or has already expired.\nThe deployment status indicates whether the latest certs and key managed by NGINX One Console are deployed onto this data plane instance.\n", - "type": "array", - "items": { - "$ref": "#/components/schemas/CertAssociation" - } - }, - "os": { - "$ref": "#/components/schemas/OperatingSystem" - }, - "config_sync_group": { - "$ref": "#/components/schemas/ConfigSyncGroupInstanceMeta" - }, - "nginx_app_protect": { - "$ref": "#/components/schemas/NginxAppProtectDetails" - }, - "control_plane": { - "$ref": "#/components/schemas/ControlPlaneBaseInfo" - }, - "log_profile": { - "$ref": "#/components/schemas/LogProfileDetails" - } - } + "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": [ + "name" ], - "example": { - "agent_version": "v2.30.3", - "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" - } - ], - "hostname": "4d116619f106", - "key": "key_wN3IhLCmR3qmwybG_6ptEg", - "control_plane": { - "object_id": "ecp_CO1DdBxZToWmr3pTcaQ8QA", - "name": "nginx-ingress-001", - "product_version": "nginx-ingress-controller-4.0.1", - "created_at": "2023-12-06T22:37:24.120114Z" + "properties": { + "name": { + "type": "string", + "description": "Name of the NGINX staged config." }, - "last_reported": "2023-12-06T22:37:24.120114Z", - "nginx_build": { - "conf_path": "/etc/nginx/nginx.conf", - "version": "1.25.3" + "config": { + "$ref": "#/components/schemas/NginxConfig" + } + } + }, + "StagedConfigUpdateRequest": { + "description": "Body to update a NGINX staged config name and config contents.", + "required": [ + "name", + "config" + ], + "properties": { + "name": { + "$ref": "#/components/schemas/StagedConfigName" }, - "nginx_id": "b636d4376dea15405589692d3c5d3869ff3a9b26b0e7bb4bb1aa7e658ace1437", - "os": { - "codename": "jammy", - "id": "ubuntu", - "name": "Ubuntu", - "version": "22.04.3 LTS (Jammy Jellyfish)", - "version_id": "22.04" + "config": { + "$ref": "#/components/schemas/NginxConfigRequest" + } + }, + "example": { + "name": "my-nginx-staged-config", + "config": { + "aux": [], + "conf_path": "/etc/nginx/nginx.conf", + "config_version": "c039fbbd5d7f73d894390fb446bd3690da099ed8862b2527299bc2ba", + "configs": [ + { + "files": [ + { + "contents": "string", + "name": "default.conf" + } + ], + "name": "/etc/nginx/conf.d" + } + ] + } + } + }, + "StagedConfigChangeRequest": { + "description": "Update an NGINX staged config.", + "properties": { + "name": { + "$ref": "#/components/schemas/StagedConfigName" }, - "registered_at": "2023-12-06T22:37:24.120114Z", - "status": "unknown", - "system_id": "b2c0b6a8-8b6a-3a8f-a541-17d8899c119a", - "object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", - "has_container_host": false + "config": { + "$ref": "#/components/schemas/NginxConfigRequest" + } + }, + "example": { + "config": { + "aux": [], + "conf_path": "/etc/nginx/nginx.conf", + "config_version": "c039fbbd5d7f73d894390fb446bd3690da099ed8862b2527299bc2ba", + "configs": [ + { + "files": [ + { + "contents": "string", + "name": "default.conf" + } + ], + "name": "/etc/nginx/conf.d" + } + ] + } } }, - "NginxSecurityAdvisory": { + "StagedConfigImportRequest": { "type": "object", - "description": "Details about a specific NGINX security advisory, including its severity, a link to more information, and a brief description.", + "description": "Body to import a NGINX staged config", "required": [ - "id", - "severity", - "advisory", - "info" + "name", + "file", + "conf_path" ], "properties": { - "id": { - "description": "The security advisory's unique identifier.", - "type": "string" - }, - "severity": { - "$ref": "#/components/schemas/CveSeverityType" + "name": { + "$ref": "#/components/schemas/StagedConfigName" }, - "advisory": { - "description": "The URL to detailed information about the security advisory.", - "type": "string" + "file": { + "type": "string", + "format": "binary", + "example": "my-staged-config.tar.gz", + "maxLength": 5242880 }, - "info": { - "description": "A brief description of security advisory.", - "type": "string" + "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 } }, - "CertificateSummaryItem": { - "description": "summary information for certificate with certain status.", + "MetricQueryResultEx": { "type": "object", "required": [ - "status", - "count", - "affected_instances" + "query_metadata", + "metrics" ], "properties": { - "status": { - "$ref": "#/components/schemas/CertificateStatus" - }, - "count": { - "description": "The total number of SSL certificates for each status category.", - "type": "integer" + "query_metadata": { + "$ref": "#/components/schemas/MetricQueryMetadata" }, - "affected_instances": { - "description": "Indicates the total number of SSL/TLS certificates corresponding to the status provided.", - "type": "integer" + "metrics": { + "description": "An array of Metric objects, each including the name of the metric resource, aggregate function, and series details.", + "type": "array", + "items": { + "$ref": "#/components/schemas/MetricEx" + } } } }, - "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.", + "MetricQueryMetadata": { + "description": "This object includes details about the time period and resolution (granularity) used in the metrics query.\n", "type": "object", - "required": [ - "severity", - "count", - "affected_instances" - ], "properties": { - "severity": { - "$ref": "#/components/schemas/CveSeverityType" + "start_time": { + "description": "The beginning of the time period for the metrics query (inclusive).", + "type": "string", + "format": "date-time", + "example": "2019-08-07T09:57:36.088757764Z" }, - "count": { - "description": "The number of CVEs at each severity level.", - "type": "integer" + "end_time": { + "description": "The end point for the time period for the metrics query (non-inclusive).", + "type": "string", + "format": "date-time", + "example": "2019-08-07T09:57:36.088757764Z" }, - "affected_instances": { - "description": "The number of NGINX instances affected by each CVE.", - "type": "integer" + "resolution": { + "description": "The level of granularity for the time series data.", + "type": "string", + "example": "30m" } } }, - "IssueSummary": { - "description": "A summary of issue details from the configuration analysis report.", + "MetricEx": { "type": "object", "required": [ - "type", - "count", - "affected_instances" + "metric", + "series" ], + "description": "This object represents a metric, including the name of the metric resource, aggregate function, and series details.\n", "properties": { - "type": { - "$ref": "#/components/schemas/RecommendationType" + "metric": { + "$ref": "#/components/schemas/MetricName" }, - "count": { - "description": "The number of times this recommendation appears in the configuration analysis report.", - "type": "integer" + "aggregate": { + "$ref": "#/components/schemas/MetricAggregation" }, - "affected_instances": { - "description": "The number of instances affected by this issue.", - "type": "integer" + "series": { + "description": "An array of data points aligned along one or more dimensions from the Dimensions Catalog.\n", + "type": "array", + "items": { + "$ref": "#/components/schemas/SeriesEx" + }, + "example": [ + { + "dimensions": { + "nginx_id": "some-instance-obj-1", + "parent_hostname": "hostname-for-instance-1" + }, + "data": [ + { + "timestamp": "2019-08-07T09:57:30Z", + "value": 10 + } + ] + }, + { + "dimensions": { + "nginx_id": "some-instance-obj-2", + "parent_hostname": "hostname-for-instance-2" + }, + "data": [ + { + "timestamp": "2019-08-07T09:58:30Z", + "value": 5 + } + ] + } + ] } } }, - "InstanceSummary": { - "description": "A summary of NGINX instances, including certificates, OS versions, NGINX versions, and status details.", + "SeriesEx": { + "description": "This object represents a set of data points aligned along one or more dimensions from the Dimensions Catalog.", "type": "object", + "required": [ + "dimensions", + "data" + ], "properties": { - "certs": { - "description": "An array detailing each certificate's status across all NGINX instances.", - "type": "array", - "items": { - "$ref": "#/components/schemas/CertificateSummaryItem" + "dimensions": { + "description": "This object represents a set of data points aligned along one or more dimensions.\n", + "type": "object", + "additionalProperties": { + "description": "The name(s) of the dimensions used in the metrics query.\n", + "type": "string" + }, + "example": { + "nginx_id": "some-instance-object-id", + "parent_hostname": "hostname-for-instance" } }, - "os": { - "$ref": "#/components/schemas/OperatingSystemVersionSummary" - }, - "nginx_versions": { - "$ref": "#/components/schemas/NGINXVersionSummary" - }, - "statuses": { - "$ref": "#/components/schemas/StatusSummary" - }, - "cves": { - "description": "An array summarizing identified Common Vulnerabilities and Exposures (CVEs) across the NGINX data plane.", + "data": { + "description": "Array of data points for a metric.\n", "type": "array", "items": { - "$ref": "#/components/schemas/CveSummary" - } + "$ref": "#/components/schemas/MetricData" + }, + "example": [ + { + "timestamp": "2019-08-07T09:57:30Z", + "value": 10 + } + ] + } + } + }, + "MetricData": { + "type": "object", + "required": [ + "timestamp", + "value" + ], + "properties": { + "timestamp": { + "type": "string", + "description": "A date-time string that represent when the data point in the series was recorded.\n", + "format": "date-time" }, - "recommendations": { - "description": "An array summarizing the suggestions from the configuration analysis report.", - "type": "array", - "items": { - "$ref": "#/components/schemas/IssueSummary" - } + "value": { + "type": "number", + "format": "double", + "nullable": true, + "description": "A value for the data, where `null` indicates a gap.\n" } } }, - "FilterStagedConfigs": { + "StartTime": { + "description": "Sets the beginning of the time period for your metrics query (inclusive).\n\nUsage:\n* `start_time` is required if `end_time` is specified.\n* If `start_time` isn't provided, the API returns the latest metrics.\n* `start_time` is required for aggregated metrics in order to calculate the `resolution` (granularity).\n\nTime can be specified in two ways:\n* Using ISO 8601 format. For example, \"2019-08-07T09:57:36.088757764Z\".\n* As an offset from the current time. For the offset, use `+` or `-`, followed by a number and the appropriate time unit. The time unit can can be `y` (years), `M` (months), `w` (weeks), `d` (days), `h` (hours), `m` (minutes), or `s` (seconds). \nExample of an offset: \"now-3h\" (3 hours before now).\n", + "type": "string", + "example": "2019-08-07T09:57:36.088757764Z" + }, + "EndTime": { + "description": "Sets the end point for the time period for your metrics query (non-inclusive).\n\nUsage:\n* Must be greater than `start_time`.\n* If `start_time` is specified and `end_time` is not, `end_time` defaults to the current time.\n\nTime can be specified in two ways:\n* Using ISO 8601 format. For example, \"2019-08-07T09:57:36.088757764Z\".\n* As an offset from the current time. For the offset, use `+` or `-`, followed by a number and the appropriate time unit. The time unit can can be `y` (years), `M` (months), `w` (weeks), `d` (days), `h` (hours), `m` (minutes), or `s` (seconds). \nExample of an offset: \"now-3h\" (3 hours before now).\n", + "type": "string", + "example": "2019-08-07T09:57:36.088757764Z" + }, + "MetricAggregation": { + "type": "string", + "description": "Static list of aggregation functions that can be applied to a compatible metric.\n * min\n * max\n * sum\n * avg\n * rate\n * accum_rate\n", + "enum": [ + "min", + "max", + "sum", + "avg", + "rate", + "accum_rate" + ], + "x-enum-varnames": [ + "metric_aggregation_min", + "metric_aggregation_max", + "metric_aggregation_sum", + "metric_aggregation_avg", + "metric_aggregation_rate", + "metric_aggregation_accum_rate" + ] + }, + "MetricDimensions": { + "type": "array", + "description": "List the dimensions to include in the response for each metric series.\n\nUsage:\n\n* Specify the list of dimensions. Dimensions not specified in this parameter will be hidden in the results.\n* If you specify dimensions in `group_by`, you don't need to list them again in `dimensions`. \nHowever, if you are using `group_by`, then any dimensions you list in `dimensions` must also be included in `group_by`.\n * To return a single series, specify the metric name with aggregation (for example, `{ \"name\": \"agent.cpu.system\", \"aggregate\": \"avg\" }`) and leave the `dimensions` parameter empty.\n", + "items": { + "$ref": "#/components/schemas/MetricDimension" + } + }, + "GroupByDimensions": { + "type": "array", + "description": "Group the query results by the specified dimension(s).\n\nUsage:\n* Specify the list of dimensions.\n* For `group_by` to work, all metrics in the `names` parameter must be aggregated.\n", + "items": { + "$ref": "#/components/schemas/MetricDimension" + } + }, + "TopXMetricDimensions": { + "type": "array", + "description": "List additional dimensions to include in the response for each metric series. The dimension specified by `group_series_by` will be included by default.\n", + "items": { + "$ref": "#/components/schemas/MetricDimension" + } + }, + "MetricDimension": { "type": "string", - "description": "Keywords for staged configs filters.\n", + "default": "display_name", + "description": "Static list of all metric dimensions:\n * `display_name` - Display name of the NGINX instance.\n * `file_path` - Path to the file.\n * `parent_hostname` - Hostname of the NGINX Plus instance.\n * `instance_object_id` - Unique ID of the instance registered with NGINX One Console.\n * `location_zone` - Name of an HTTP location zone.\n * `mount_point` - Filesystem mount point.\n * `namespace` - Namespace for the metric data.\n * `network_interface` - Server network interface.\n * `nginx_id` - Unique ID of the NGINX instance running on the data plane.\n * `server_zone` - Name of an HTTP or Stream server zone.\n * `system_id` - Unique ID of the operating system running nginx-agent.\n * `tenant` - Tenant for the metric data.\n * `csg_object_id` - Unique ID of the Config Sync Group registered with NGINX One Console.\n * `mode` - Variant value for metric `system.cpu.utilization`.\n * `state` - Variant value for metrics `system.filesystem.usage`, `system.memory.usage`.\n * `io_direction` - Variant value for metric `system.network.io`.\n * `status_range` - Variant value for metric `nginx.http.response.count`.\n * `logical_number` - Variant value for metrics that return a processor number.\n * `outcome` - Variant value for metrics that return an outcome.\n * `upstream_zone` - upstream zone for the metric data.\n * `upstream_name` - upstream name for the metric data.\n * `peer_state` - Variant value for metric peer state for the metric `nginx.http.upstream.peer.count`.\n * `peer_health_check` - Variant value for metric peer health check for the metric `nginx.http.upstream.peer.health_checks`.\n * `peer_address` - peer address for metric data.\n * `peer_name` - peer name for metric data.\n * `ecp_object_id` - Unique ID of the External Control Plane registered with NGINX One Console.\n", "enum": [ - "name", - "object_id" + "display_name", + "file_path", + "parent_hostname", + "instance_object_id", + "location_zone", + "mount_point", + "namespace", + "network_interface", + "nginx_id", + "server_zone", + "system_id", + "tenant", + "csg_object_id", + "mode", + "state", + "io_direction", + "status_range", + "logical_number", + "outcome", + "upstream_zone", + "upstream_name", + "peer_state", + "peer_health_check", + "peer_address", + "peer_name", + "ecp_object_id" ], "x-enum-varnames": [ - "filter_name_staged_config_name", - "filter_name_staged_config_object_id" + "metric_dimension_display_name", + "metric_dimension_file_path", + "metric_dimension_hostname", + "metric_dimension_instance_object_id", + "metric_dimension_location_zone", + "metric_dimension_mount_point", + "metric_dimension_namespace", + "metric_dimension_network_interface", + "metric_dimension_nginx_id", + "metric_dimension_server_zone", + "metric_dimension_system_id", + "metric_dimension_tenant", + "metric_dimension_csg_object_id", + "metric_dimension_mode", + "metric_dimension_state", + "metric_dimension_io_direction", + "metric_dimension_status_range", + "metric_dimension_logical_number", + "metric_dimension_outcome", + "metric_dimension_upstream_zone", + "metric_dimension_upstream_name", + "metric_dimension_peer_state", + "metric_dimension_peer_health_check", + "metric_dimension_peer_address", + "metric_dimension_peer_name", + "metric_dimension_ecp_object_id" ] }, - "StagedConfigObjectID": { - "description": "A globally unique identifier for the NGINX staged config.", - "type": "string", - "format": "object_id", - "pattern": "^sc_.*", - "x-go-type": "objects.ID", - "x-go-type-import": { - "name": "objects", - "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" - } - }, - "StagedConfigCertificateSummary": { + "BaseMetricQueryRequest": { "type": "object", - "description": "Provides a summary of the current status of certificates used in NGINX configurations. It includes the total number of certificates, as well as the counts of expired certificates, those nearing expiration, valid certificates, certificates that are not found, and those that are not ready for use.", "required": [ - "total", - "expired", - "expiring", - "valid", - "not_found", - "not_ready" + "metrics", + "start_time", + "resolution" ], "properties": { - "total": { - "description": "Total count of certificates used as `payloads` in NGINX config.", - "type": "integer" - }, - "expired": { - "description": "The number of certificates that have expired and are no longer valid.", - "type": "integer" - }, - "expiring": { - "description": "The number of certificates due to expire in the next 30 days.", - "type": "integer" - }, - "valid": { - "description": "The number of certificates that are valid and in good standing.", - "type": "integer" - }, - "not_found": { - "description": "The number of certificates that are not found on NGINX One Console.", - "type": "integer" + "metrics": { + "$ref": "#/components/schemas/MetricNames" }, - "not_ready": { - "description": "The number of certificates that are not ready to be used.", - "type": "integer" - } - } - }, - "StagedConfigMeta": { - "type": "object", - "description": "Summary information of the NGINX staged config.", - "required": [ - "object_id", - "name", - "created_at", - "modified_at" - ], - "properties": { - "object_id": { - "$ref": "#/components/schemas/StagedConfigObjectID" + "filter": { + "$ref": "#/components/schemas/MetricFilters" }, - "name": { - "description": "Name of the NGINX staged config", - "type": "string" + "start_time": { + "$ref": "#/components/schemas/StartTime" }, - "created_at": { - "type": "string", - "format": "date-time", - "description": "The date and time when the NGINX configuration object was created for the instance." + "end_time": { + "$ref": "#/components/schemas/EndTime" }, - "modified_at": { + "resolution": { "type": "string", - "format": "date-time", - "description": "The date and time when the NGINX configuration object was last modified for the instance." - }, - "cert_summary": { - "$ref": "#/components/schemas/StagedConfigCertificateSummary" + "description": "Specifies the level of granularity for time series data in your results. Applicable only for endpoints that return time series data.\n\nUsage: \n* Specify as a string with a number followed by a unit of time, such as `y` (years), `M` (months), `w` (weeks), `d` (days), `h` (hours), `m` (minutes) or `s` (seconds).\n* Metrics in `names` must be aggregated.\n* `start_time` is required.\n* If `resolution` is not set, the API returns the maximum resolution (`end_time` - `start_time`).\n", + "example": "30s" } } }, - "StagedConfigListResponse": { + "MetricQueryRequest": { + "type": "object", "allOf": [ { - "$ref": "#/components/schemas/PaginationResponse" + "$ref": "#/components/schemas/BaseMetricQueryRequest" }, { "type": "object", - "description": "List of NGINX staged configs.", - "required": [ - "items" - ], "properties": { - "items": { - "description": "An array of Staged Config objects.", + "dimensions": { + "$ref": "#/components/schemas/MetricDimensions" + }, + "group_by": { + "$ref": "#/components/schemas/GroupByDimensions" + }, + "order_by": { + "description": "List the order by for dimension(s).\n\nUsage:\n\n* Must be a dimension included by `dimensions` or `group_by`.\n", "type": "array", "items": { - "$ref": "#/components/schemas/StagedConfigMeta" + "$ref": "#/components/schemas/OrderBy" } } } } - ], - "example": { - "total": 10, - "count": 1, - "start_index": 1, - "items_per_page": 100, - "items": [ - { - "object_id": "sc_Tet21AeYTHCj7taOwVfzyw", - "name": "my-nginx-staged-config", - "created_at": "2023-08-10T16:59:15Z", - "modified_at": "2023-08-10T16:59:15Z" - } - ] - } - }, - "StagedConfigName": { - "type": "string", - "description": "A name to identify the NGINX staged config.", - "minLength": 1, - "maxLength": 256, - "pattern": "^[^\\s]+$" - }, - "StagedConfigCreateRequest": { - "description": "Body to create a NGINX staged config. A staged config can be empty; config payload is optional.", - "required": [ - "name" - ], - "properties": { - "name": { - "$ref": "#/components/schemas/StagedConfigName" - }, - "config": { - "$ref": "#/components/schemas/NginxConfigRequest" - } - }, - "example": { - "name": "my-nginx-staged-config", - "config": { - "aux": [], - "conf_path": "/etc/nginx/nginx.conf", - "configs": [ - { - "files": [ - { - "contents": "string", - "name": "default.conf" - } - ], - "name": "/etc/nginx/conf.d" - } - ] - } - } - }, - "StagedConfigCreateResponse": { - "description": "Response to a create NGINX staged config request.", - "required": [ - "object_id", - "name" - ], - "properties": { - "object_id": { - "$ref": "#/components/schemas/StagedConfigObjectID" - }, - "name": { - "description": "Name of the NGINX staged config.", - "type": "string" - } - }, - "example": { - "name": "my-nginx-staged-config", - "object_id": "sc_Tet21AeYTHCj7taOwVfzyw" - } + ] }, - "StagedConfigBulkRequestData": { + "MetricTopXQueryRequest": { "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" + "allOf": [ + { + "$ref": "#/components/schemas/BaseMetricQueryRequest" }, - "action": { - "$ref": "#/components/schemas/BulkRequestAction" + { + "type": "object", + "required": [ + "series_limit", + "group_series_by" + ], + "properties": { + "dimensions": { + "$ref": "#/components/schemas/TopXMetricDimensions" + }, + "series_limit": { + "type": "integer", + "example": 25, + "description": "Sets the maximum number of series that can be returned. \n\nNotes:\n* Always returns an additional series with a dimension named `all`, aggregating the values of all metrics included in the results.\n* A series with a dimension named `other` may be returned, aggregating the values of metrics not included in the results.\n" + }, + "group_series_by": { + "$ref": "#/components/schemas/MetricDimension" + }, + "order_series_by": { + "$ref": "#/components/schemas/OrderSeriesBy" + } + } } - }, - "example": { - "object_id": "sc_-uvR3F2TQGm18jnl7bpaGw", - "action": "delete" - } + ] }, - "StagedConfigBulkRequest": { + "MetricNames": { "type": "array", + "description": "Specify the metrics you want details for.\n\nUsage: \n* List multiple metrics as json objects.\n * You can aggregate metrics with `avg`, `sum`, `min`, `max`, `rate`.\n* Metrics with aggregates require a `start_time`.\n* If you combine aggregated and non-aggregated metrics in a single query, any `group_by` clause applies only to the aggregated metrics.\n", "items": { - "$ref": "#/components/schemas/StagedConfigBulkRequestData" + "$ref": "#/components/schemas/MetricQuery" }, - "minItems": 1, - "maxItems": 50, "example": [ { - "object_id": "sc_-uvR3F2TQGm18jnl7bpaGw", - "action": "delete" - }, - { - "object_id": "sc_PL0c1XodRemmzVEjiXSsTg", - "action": "delete" + "name": "system.cpu.utilization", + "aggregate": "avg", + "filter": [ + { + "filterSet": [ + { + "dimension": "mode", + "operator": "=", + "values": [ + "system" + ] + } + ] + } + ] } ] }, - "StagedConfigBulkResponse": { - "description": "The staged config bulk outcome.", - "type": "array", - "items": { - "$ref": "#/components/schemas/BulkRequestObjectStatus" - } - }, - "StagedConfigResponse": { - "description": "Get an NGINX staged config.", + "MetricQuery": { + "type": "object", "required": [ "name" ], "properties": { "name": { - "type": "string", - "description": "Name of the NGINX staged config." + "$ref": "#/components/schemas/MetricName" }, - "config": { - "$ref": "#/components/schemas/NginxConfig" + "aggregate": { + "$ref": "#/components/schemas/MetricAggregation" } } }, - "StagedConfigUpdateRequest": { - "description": "Body to update a NGINX staged config name and config contents.", - "required": [ - "name", - "config" + "MetricFilterPredicate": { + "type": "string", + "enum": [ + "AND", + "OR" ], - "properties": { - "name": { - "$ref": "#/components/schemas/StagedConfigName" - }, - "config": { - "$ref": "#/components/schemas/NginxConfigRequest" - } + "x-enum-varnames": [ + "metric_filter_predicate_and", + "metric_filter_predicate_or" + ] + }, + "MetricFilters": { + "type": "array", + "description": "Filter results based on dimension operations against one or more values.\n\nUsage:\n* Format as one or more predicates by providing all required elements.\n * `dimension`: The dimension name you want to filter on.\n * `operator`: The possible operators (`=`, `!=`, `<`, `<=`, `>`, `>=`, `in`, `not`) you can use for comparison or condition checking.\n * `value`: Case sensitive value of the dimension to filter against.\n\nFor more complex filtering:\n\n* Specify a `predicate` for logical expressions (`AND`,`OR`). \n* Use a wildcard `*` in the `value` for matching partial values.\n", + "items": { + "$ref": "#/components/schemas/MetricFilterSet" }, - "example": { - "name": "my-nginx-staged-config", - "config": { - "aux": [], - "conf_path": "/etc/nginx/nginx.conf", - "config_version": "c039fbbd5d7f73d894390fb446bd3690da099ed8862b2527299bc2ba", - "configs": [ + "example": [ + { + "filterSet": [ { - "files": [ - { - "contents": "string", - "name": "default.conf" - } - ], - "name": "/etc/nginx/conf.d" + "dimension": "server_zone", + "operator": "!=", + "values": [ + "server_zone_1" + ] + }, + { + "predicate": "OR", + "dimension": "server_zone", + "operator": "=", + "values": [ + "server_zone_2" + ] } ] - } - } - }, - "StagedConfigChangeRequest": { - "description": "Update an NGINX staged config.", - "properties": { - "name": { - "$ref": "#/components/schemas/StagedConfigName" }, - "config": { - "$ref": "#/components/schemas/NginxConfigRequest" - } - }, - "example": { - "config": { - "aux": [], - "conf_path": "/etc/nginx/nginx.conf", - "config_version": "c039fbbd5d7f73d894390fb446bd3690da099ed8862b2527299bc2ba", - "configs": [ + { + "predicate": "AND", + "filterSet": [ { - "files": [ - { - "contents": "string", - "name": "default.conf" - } - ], - "name": "/etc/nginx/conf.d" + "dimension": "nginx_id", + "operator": "in", + "values": [ + "id1", + "id2" + ] } ] } - } + ] }, - "StagedConfigImportRequest": { + "MetricFilterSet": { "type": "object", - "description": "Body to import a NGINX staged config", + "description": "Encapsulates one or more `MetricFilter` object(s) to be grouped together.\n", "required": [ - "name", - "file", - "conf_path" + "filterSet" ], "properties": { - "name": { - "$ref": "#/components/schemas/StagedConfigName" - }, - "file": { - "type": "string", - "format": "binary", - "example": "my-staged-config.tar.gz", - "maxLength": 5242880 + "predicate": { + "$ref": "#/components/schemas/MetricFilterPredicate" }, - "conf_path": { - "$ref": "#/components/schemas/ConfigPath" + "filterSet": { + "type": "array", + "items": { + "$ref": "#/components/schemas/MetricFilter" + } } - }, - "example": { - "name": "my-nginx-config", - "file": "my-staged-config.tar.gz", - "conf_path": "/etc/nginx/nginx.conf", - "parse_only": true } }, - "MetricQueryResultEx": { + "MetricFilter": { "type": "object", "required": [ - "query_metadata", - "metrics" + "dimension", + "operator", + "values" ], "properties": { - "query_metadata": { - "$ref": "#/components/schemas/MetricQueryMetadata" + "dimension": { + "$ref": "#/components/schemas/MetricDimension" }, - "metrics": { - "description": "An array of Metric objects, each including the name of the metric resource, aggregate function, and series details.", + "operator": { + "type": "string", + "description": "Static list of all operations supported by filtering\n\n* The `=`, `!=` only use the first element of the `values` array. Wildcards for partial matching is supported.\n* The `in` and `not` both use all elements in the `values` array. Wildcards for partial matching is NOT supported.\n", + "enum": [ + "=", + "!=", + "in", + "not" + ], + "x-enum-varnames": [ + "metric_filter_equal", + "metric_filter_not_equal", + "metric_filter_in", + "metric_filter_not" + ] + }, + "values": { "type": "array", + "description": "Single value used for all operators except `in` and `not`.", "items": { - "$ref": "#/components/schemas/MetricEx" + "type": "string" } + }, + "predicate": { + "$ref": "#/components/schemas/MetricFilterPredicate" } } }, - "MetricQueryMetadata": { - "description": "This object includes details about the time period and resolution (granularity) used in the metrics query.\n", + "OrderDirection": { + "type": "string", + "enum": [ + "asc", + "desc" + ], + "x-enum-varnames": [ + "order_by_asc", + "order_by_desc" + ], + "default": "desc" + }, + "OrderBy": { "type": "object", + "description": "Sort order of the metric series in your results.\n\nUsage:\n* Provide all required elements. \n * `direction`: The sorting direction either `desc` or `asc`.\n * `dimension`: The dimension for ordering.\n", + "required": [ + "direction", + "dimension" + ], "properties": { - "start_time": { - "description": "The beginning of the time period for the metrics query (inclusive).", - "type": "string", - "format": "date-time", - "example": "2019-08-07T09:57:36.088757764Z" - }, - "end_time": { - "description": "The end point for the time period for the metrics query (non-inclusive).", - "type": "string", - "format": "date-time", - "example": "2019-08-07T09:57:36.088757764Z" + "direction": { + "$ref": "#/components/schemas/OrderDirection" }, - "resolution": { - "description": "The level of granularity for the time series data.", - "type": "string", - "example": "30m" + "dimension": { + "$ref": "#/components/schemas/MetricDimension" } } }, - "MetricEx": { + "OrderSeriesBy": { "type": "object", + "description": "Sort order of the metric series in your results.\n\nUsage:\n* Provide all required elements. \n * `direction`: The sorting direction either `desc` or `asc`.\n * `aggregate`: The aggregating function.\n", "required": [ - "metric", - "series" + "direction", + "aggregate" ], - "description": "This object represents a metric, including the name of the metric resource, aggregate function, and series details.\n", "properties": { - "metric": { - "$ref": "#/components/schemas/MetricName" + "direction": { + "$ref": "#/components/schemas/OrderDirection" }, "aggregate": { - "$ref": "#/components/schemas/MetricAggregation" - }, - "series": { - "description": "An array of data points aligned along one or more dimensions from the Dimensions Catalog.\n", - "type": "array", - "items": { - "$ref": "#/components/schemas/SeriesEx" - }, - "example": [ - { - "dimensions": { - "nginx_id": "some-instance-obj-1", - "parent_hostname": "hostname-for-instance-1" - }, - "data": [ - { - "timestamp": "2019-08-07T09:57:30Z", - "value": 10 - } - ] - }, - { - "dimensions": { - "nginx_id": "some-instance-obj-2", - "parent_hostname": "hostname-for-instance-2" - }, - "data": [ - { - "timestamp": "2019-08-07T09:58:30Z", - "value": 5 - } - ] - } - ] + "$ref": "#/components/schemas/MetricAggregation", + "default": "sum" } } }, - "SeriesEx": { - "description": "This object represents a set of data points aligned along one or more dimensions from the Dimensions Catalog.", + "MetricName": { + "type": "string", + "description": "Metric names available for querying.\n", + "example": "nginx.http.request.count", + "oneOf": [ + { + "$ref": "#/components/schemas/MetricSystemCpuUtilization" + }, + { + "$ref": "#/components/schemas/MetricSystemFilesystemUsage" + }, + { + "$ref": "#/components/schemas/MetricSystemMemoryUsage" + }, + { + "$ref": "#/components/schemas/MetricSystemCpuLogicalCount" + }, + { + "$ref": "#/components/schemas/MetricSystemNetworkIo" + }, + { + "$ref": "#/components/schemas/MetricNginxHttpRequestCount" + }, + { + "$ref": "#/components/schemas/MetricNginxHttpResponseCount" + }, + { + "$ref": "#/components/schemas/MetricNginxHttpConnectionCount" + }, + { + "$ref": "#/components/schemas/MetricNginxHttpConnections" + }, + { + "$ref": "#/components/schemas/MetricNginxHttpUpstreamPeerCount" + }, + { + "$ref": "#/components/schemas/MetricNginxHttpUpstreamPeerHealthChecks" + }, + { + "$ref": "#/components/schemas/MetricNginxStreamUpstreamPeerHealthChecks" + }, + { + "$ref": "#/components/schemas/MetricNginxStreamUpstreamPeerCount" + }, + { + "$ref": "#/components/schemas/MetricNginxHttpRequestIo" + } + ] + }, + "MetricSystemCpuUtilization": { + "type": "string", + "description": "Total system CPU use for 'system' or 'user' (percent). A filter is required to specify the mode.\n\nReplaces deprecated variants:\n * system.cpu.system\n * system.cpu.user\n\nSupported aggregations:\n * min\n * max\n * sum\n * avg\n * rate\n\nCatalog dimension filter:\n * mode (valid values:: 'system', 'user')\n\nSupported catalog dimensions:\n * instance_object_id\n * csg_object_id\n * ecp_object_id\n * system_id\n * parent_hostname\n * display_name\n * nginx_id\n * logical_number\n", + "enum": [ + "system.cpu.utilization" + ] + }, + "MetricSystemFilesystemUsage": { + "type": "string", + "description": "System disk usage statistic, percentage. A filter differentiator is needed for specific state(s).\n\nReplacement for deprecated variant(s):\n * system.disk.in_use\n * system.disk.total\n * system.disk.used\n\nAggregation(s) supported:\n * min\n * max\n * sum\n * avg\n * rate\n\nCatalog dimension filter differentiator:\n * state (applicable filter values: 'used', 'free', 'in_use')\n\nCatalog dimension(s) supported:\n * instance_object_id\n * csg_object_id\n * ecp_object_id\n * system_id\n * parent_hostname\n * display_name\n * nginx_id\n * mount_point\n", + "enum": [ + "system.filesystem.usage" + ] + }, + "MetricSystemMemoryUsage": { + "type": "string", + "description": "Total available statistic about system memory usage, bytes. A filter differentiator is needed for specific state(s).\n\nReplacement for deprecated variant(s):\n * system.mem.pct_used\n * system.mem.total\n * system.mem.used\n\nAggregation(s) supported:\n * min\n * max\n * sum\n * avg\n * rate \n\nCatalog dimension filter differentiator:\n * state (applicable filter values: 'used', 'free', 'total', 'pct_used')\n\nCatalog dimension(s) supported:\n * instance_object_id\n * csg_object_id\n * ecp_object_id\n * system_id\n * parent_hostname\n * display_name\n * nginx_id\n", + "enum": [ + "system.memory.usage" + ] + }, + "MetricSystemCpuLogicalCount": { + "type": "string", + "description": "Number of logical (virtual) processor cores created by the operating system.\n\nAggregation(s) supported:\n * min\n * max\n * sum\n * avg\n * rate \n\nCatalog dimension(s) supported:\n * instance_object_id\n * csg_object_id\n * ecp_object_id\n * system_id\n * parent_hostname\n * display_name\n * nginx_id\n", + "enum": [ + "system.cpu.logical.count" + ] + }, + "MetricNginxHttpConnectionCount": { + "type": "string", + "description": "Number of connections grouped by outcome ('ACTIVE', 'IDLE', 'READING', 'WRITING', 'WAITING').\nSupported aggregations:\n * min\n * max\n * sum\n * avg\n * rate\n\nSupported catalog dimensions:\n * instance_object_id\n * csg_object_id\n * ecp_object_id\n * system_id\n * parent_hostname\n * display_name\n * nginx_id\n * outcome\n", + "enum": [ + "nginx.http.connection.count" + ] + }, + "MetricNginxHttpConnections": { + "type": "string", + "description": "Total connections grouped by outcome ('ACCEPTED', 'HANDLED', 'DROPPED').\nSupported aggregations:\n * min\n * max\n * sum\n * avg\n * rate\n\nSupported catalog dimensions:\n * instance_object_id\n * csg_object_id\n * ecp_object_id\n * system_id\n * parent_hostname\n * display_name\n * nginx_id\n * outcome\n", + "enum": [ + "nginx.http.connections" + ] + }, + "MetricNginxHttpUpstreamPeerCount": { + "type": "string", + "description": "Number of upstream peers grouped by state ('CHECKING', 'DOWN', 'DRAINING', 'UNAVAILABLE', 'UNHEALTHY', 'UP').\nSupported aggregations:\n * min\n * max\n * sum\n * avg\n * rate\nSupported catalog dimensions:\n * instance_object_id\n * csg_object_id\n * ecp_object_id\n * system_id\n * parent_hostname\n * display_name\n * nginx_id\n * upstream_zone\n * upstream_name\n * peer_state\n", + "enum": [ + "nginx.http.upstream.peer.count" + ] + }, + "MetricNginxStreamUpstreamPeerCount": { + "type": "string", + "description": "Number of upstream peers grouped by state ('CHECKING', 'DOWN', 'DRAINING', 'UNAVAILABLE', 'UNHEALTHY', 'UP').\nSupported aggregations:\n * min\n * max\n * sum\n * avg\n * rate\nSupported catalog dimensions:\n * instance_object_id\n * csg_object_id\n * ecp_object_id\n * system_id\n * parent_hostname\n * display_name\n * nginx_id\n * upstream_zone\n * upstream_name\n * peer_state\n", + "enum": [ + "nginx.stream.upstream.peer.count" + ] + }, + "MetricNginxHttpUpstreamPeerHealthChecks": { + "type": "string", + "description": "The total number of health check requests made to a HTTP upstream peer.\nSupported aggregations:\n * min\n * max\n * sum\n * avg\n * rate\nSupported catalog dimensions:\n * instance_object_id\n * csg_object_id\n * ecp_object_id\n * system_id\n * parent_hostname\n * display_name\n * nginx_id\n * upstream_zone\n * upstream_name\n * peer_health_check\n * peer_address\n * peer_name\n", + "enum": [ + "nginx.http.upstream.peer.health_checks" + ] + }, + "MetricNginxStreamUpstreamPeerHealthChecks": { + "type": "string", + "description": "The total number of health check requests made to a stream upstream peer.\nSupported aggregations:\n * min\n * max\n * sum\n * avg\n * rate\nSupported catalog dimensions:\n * instance_object_id\n * csg_object_id\n * ecp_object_id\n * system_id\n * parent_hostname\n * display_name\n * nginx_id\n * upstream_zone\n * upstream_name\n * peer_health_check\n * peer_address\n * peer_name\n", + "enum": [ + "nginx.stream.upstream.peer.health_checks" + ] + }, + "MetricSystemNetworkIo": { + "type": "string", + "description": "Network I/O statistics. Number of bytes sent or received per network interface. A filter differentiator is needed for specific I/O direction(s).\n\nReplacement for deprecated variant(s):\n * system.net.bytes_rcvd\n * system.net.bytes_sent\n\nAggregation(s) supported:\n * min\n * max\n * sum\n * avg\n * accum_rate\n\nCatalog dimension filter differentiator:\n * io_direction (applicable filter values: 'transmit', 'receive')\n\nCatalog dimension(s) supported:\n * instance_object_id\n * csg_object_id\n * ecp_object_id\n * system_id\n * parent_hostname\n * display_name\n * nginx_id\n * network_interface\n", + "enum": [ + "system.network.io" + ] + }, + "MetricNginxHttpRequestCount": { + "type": "string", + "description": "The current number of client requests received from clients.\n\nReplacement for deprecated variant(s):\n * nginx.http.request.count\n * plus.http.request.count\n\nAggregation(s) supported:\n * min\n * max\n * sum\n * avg\n * rate\n\nCatalog dimension(s) supported:\n * instance_object_id\n * csg_object_id\n * ecp_object_id\n * system_id\n * parent_hostname\n * display_name\n * nginx_id\n * server_zone\n * location_zone\n", + "enum": [ + "nginx.http.request.count" + ] + }, + "MetricNginxHttpResponseCount": { + "type": "string", + "description": "The current number of responses, grouped by status code range. A filter differentiator is needed for specific status range(s).\n\nReplacement for deprecated variant(s):\n * nginx.http.status.4xx\n * plus.http.status.4xx\n\nAggregation(s) supported:\n * min\n * max\n * sum\n * avg\n * rate\n\nCatalog dimension filter differentiator:\n * status_range (applicable filter values: '4xx', '5xx')\n\nCatalog dimension(s) supported:\n * instance_object_id\n * csg_object_id\n * ecp_object_id\n * system_id\n * parent_hostname\n * display_name\n * nginx_id \n * server_zone\n * location_zone\n", + "enum": [ + "nginx.http.response.count" + ] + }, + "MetricNginxHttpRequestIo": { + "type": "string", + "description": "The total number of bytes sent or received. A filter differentiator is needed for specific I/O direction(s).\n\nReplacement for deprecated variant(s):\n * nginx.http.request.bytes_rcvd\n * nginx.http.request.bytes_sent\n\nAggregation(s) supported:\n * min\n * max\n * sum\n * avg\n * accum_rate\n\nCatalog dimension filter differentiator:\n * io_direction (applicable filter values: 'transmit', 'receive')\n\nCatalog dimension(s) supported:\n * instance_object_id\n * csg_object_id\n * ecp_object_id\n * system_id\n * parent_hostname\n * display_name\n * nginx_id\n * server_zone\n * location_zone\n", + "enum": [ + "nginx.http.request.io" + ] + }, + "SettingsInstanceCleanup": { "type": "object", + "description": "Preferences for automatic cleanup of stale NGINX One Instances.", "required": [ - "dimensions", - "data" + "age_out_duration" ], "properties": { - "dimensions": { - "description": "This object represents a set of data points aligned along one or more dimensions.\n", - "type": "object", - "additionalProperties": { - "description": "The name(s) of the dimensions used in the metrics query.\n", - "type": "string" - }, - "example": { - "nginx_id": "some-instance-object-id", - "parent_hostname": "hostname-for-instance" - } - }, - "data": { - "description": "Array of data points for a metric.\n", - "type": "array", - "items": { - "$ref": "#/components/schemas/MetricData" - }, - "example": [ + "age_out_duration": { + "type": "integer", + "format": "int32", + "description": "Specify the age of `unavailable` NGINX instances for clean up. NGINX instances older than this value in hours will be deleted automatically. Events related to automatically deleted NGINX instances will show up in `/events` API. '0' value disables the automatic clean up of `unavailable` NGINX instances.", + "default": 3, + "minimum": 0, + "maximum": 720 + } + }, + "example": { + "age_out_duration": 3 + } + }, + "HttpUsage": { + "type": "object", + "properties": { + "client": { + "allOf": [ { - "timestamp": "2019-08-07T09:57:30Z", - "value": 10 + "$ref": "#/components/schemas/UsageMetrics" + }, + { + "type": "object", + "properties": { + "requests": { + "type": "integer", + "description": "Total requests handled by an NGINX Instance", + "minimum": 0 + } + } } ] + }, + "upstream": { + "$ref": "#/components/schemas/UsageMetrics" } } }, - "MetricData": { + "StreamUsage": { "type": "object", - "required": [ - "timestamp", - "value" - ], "properties": { - "timestamp": { - "type": "string", - "description": "A date-time string that represent when the data point in the series was recorded.\n", - "format": "date-time" + "client": { + "$ref": "#/components/schemas/UsageMetrics" }, - "value": { - "type": "number", - "format": "double", - "nullable": true, - "description": "A value for the data, where `null` indicates a gap.\n" + "upstream": { + "$ref": "#/components/schemas/UsageMetrics" } } }, - "StartTime": { - "description": "Sets the beginning of the time period for your metrics query (inclusive).\n\nUsage:\n* `start_time` is required if `end_time` is specified.\n* If `start_time` isn't provided, the API returns the latest metrics.\n* `start_time` is required for aggregated metrics in order to calculate the `resolution` (granularity).\n\nTime can be specified in two ways:\n* Using ISO 8601 format. For example, \"2019-08-07T09:57:36.088757764Z\".\n* As an offset from the current time. For the offset, use `+` or `-`, followed by a number and the appropriate time unit. The time unit can can be `y` (years), `M` (months), `w` (weeks), `d` (days), `h` (hours), `m` (minutes), or `s` (seconds). \nExample of an offset: \"now-3h\" (3 hours before now).\n", + "UsageMetrics": { + "type": "object", + "properties": { + "received": { + "type": "integer", + "description": "Total bytes received by an NGINX Instance from clients/upstreams", + "minimum": 0 + }, + "sent": { + "type": "integer", + "description": "Total bytes sent by the NGINX Instance to clients/upstreams", + "minimum": 0 + }, + "connections": { + "type": "integer", + "description": "Total connections of the NGINX Instance with clients/upstreams", + "minimum": 0 + } + } + }, + "NginxUsageHttp": { + "$ref": "#/components/schemas/HttpUsage" + }, + "NginxUsageStream": { + "$ref": "#/components/schemas/StreamUsage" + }, + "MetricStartTime": { + "description": "The start time of your metrics query.\n\nUsage:\n* `start_time` is required if `end_time` is specified.\n* If `start_time` and `end_time` isn't provided, the API returns metrics from the current time to the month before the current time.\n* The `start_time` cannot be older than 120 days before the current time.\n\nYou can set the `start_time` in these ways:\n* In ISO 8601 format. For example, \"2019-08-07T09:57:36.088757764Z\".\n* As an offset from the current time. For the offset, use `+` or `-`, followed by a number and unit [`y` (years), `M` (months), `w` (weeks), `d` (days), `h` (hours), `m` (minutes), or `s` (seconds)]. \n* Example of an offset: \"now-3h\" (3 hours before now).\n", "type": "string", "example": "2019-08-07T09:57:36.088757764Z" }, - "EndTime": { - "description": "Sets the end point for the time period for your metrics query (non-inclusive).\n\nUsage:\n* Must be greater than `start_time`.\n* If `start_time` is specified and `end_time` is not, `end_time` defaults to the current time.\n\nTime can be specified in two ways:\n* Using ISO 8601 format. For example, \"2019-08-07T09:57:36.088757764Z\".\n* As an offset from the current time. For the offset, use `+` or `-`, followed by a number and the appropriate time unit. The time unit can can be `y` (years), `M` (months), `w` (weeks), `d` (days), `h` (hours), `m` (minutes), or `s` (seconds). \nExample of an offset: \"now-3h\" (3 hours before now).\n", + "MetricEndTime": { + "description": "The end time of your metrics query.\n\nUsage:\n* Must be greater than `start_time`.\n* The time difference between `start_time` and `end_time` should be greater than an hour.\n* The default `end_time` is the current time.\n* The `end_time` cannot be older than 120 days before the current time.\n\nYou can set the `end_time` in these ways:\n* In ISO 8601 format. For example, \"2019-08-07T09:57:36.088757764Z\".\n* As an offset from the current time. For the offset, use `+` or `-`, followed by a number and unit [`y` (years), `M` (months), `w` (weeks), `d` (days), `h` (hours), `m` (minutes), or `s` (seconds)]. \n* Example of an offset: \"now-3h\" (3 hours before now).\n", "type": "string", "example": "2019-08-07T09:57:36.088757764Z" }, - "MetricAggregation": { + "InventoryMetricAggregation": { "type": "string", - "description": "Static list of aggregation functions that can be applied to a compatible metric.\n * min\n * max\n * sum\n * avg\n * rate\n * accum_rate\n", + "description": "Static list of aggregation functions that can be applied to a compatible metric.\n * count\n * sum\n * avg\n * min\n * max\n", "enum": [ - "min", - "max", + "count", "sum", "avg", - "rate", - "accum_rate" + "min", + "max" ], "x-enum-varnames": [ - "metric_aggregation_min", - "metric_aggregation_max", + "metric_aggregation_count", "metric_aggregation_sum", "metric_aggregation_avg", - "metric_aggregation_rate", - "metric_aggregation_accum_rate" + "metric_aggregation_min", + "metric_aggregation_max" ] }, - "MetricDimensions": { - "type": "array", - "description": "List the dimensions to include in the response for each metric series.\n\nUsage:\n\n* Specify the list of dimensions. Dimensions not specified in this parameter will be hidden in the results.\n* If you specify dimensions in `group_by`, you don't need to list them again in `dimensions`. \nHowever, if you are using `group_by`, then any dimensions you list in `dimensions` must also be included in `group_by`.\n * To return a single series, specify the metric name with aggregation (for example, `{ \"name\": \"agent.cpu.system\", \"aggregate\": \"avg\" }`) and leave the `dimensions` parameter empty.\n", - "items": { - "$ref": "#/components/schemas/MetricDimension" + "BaseInventoryQueryRequest": { + "type": "object", + "required": [ + "metrics" + ], + "properties": { + "metrics": { + "$ref": "#/components/schemas/InventoryMetricNames" + }, + "start_time": { + "$ref": "#/components/schemas/MetricStartTime" + }, + "end_time": { + "$ref": "#/components/schemas/MetricEndTime" + } } }, - "GroupByDimensions": { - "type": "array", - "description": "Group the query results by the specified dimension(s).\n\nUsage:\n* Specify the list of dimensions.\n* For `group_by` to work, all metrics in the `names` parameter must be aggregated.\n", - "items": { - "$ref": "#/components/schemas/MetricDimension" - } + "InventoryMetricQueryRequest": { + "type": "object", + "allOf": [ + { + "$ref": "#/components/schemas/BaseInventoryQueryRequest" + } + ] }, - "TopXMetricDimensions": { + "InventoryMetricNames": { "type": "array", - "description": "List additional dimensions to include in the response for each metric series. The dimension specified by `group_series_by` will be included by default.\n", + "description": "Specify the metrics to collect.\n\nUsage: \n* List multiple metrics as JSON objects.\n* You can aggregate metrics with `count`, `sum`, `avg`, `min`, `max`.\n", "items": { - "$ref": "#/components/schemas/MetricDimension" + "$ref": "#/components/schemas/InventoryMetricQuery" + }, + "example": [ + { + "name": "nginx.plus.instances", + "aggregate": [ + "count" + ] + } + ] + }, + "InventoryMetricQuery": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "$ref": "#/components/schemas/InventoryMetricName" + }, + "aggregate": { + "type": "array", + "items": { + "$ref": "#/components/schemas/InventoryMetricAggregation" + } + } } }, - "MetricDimension": { + "InventoryMetricName": { "type": "string", - "default": "display_name", - "description": "Static list of all metric dimensions:\n * `display_name` - Display name of the NGINX instance.\n * `file_path` - Path to the file.\n * `parent_hostname` - Hostname of the NGINX Plus instance.\n * `instance_object_id` - Unique ID of the instance registered with NGINX One Console.\n * `location_zone` - Name of an HTTP location zone.\n * `mount_point` - Filesystem mount point.\n * `namespace` - Namespace for the metric data.\n * `network_interface` - Server network interface.\n * `nginx_id` - Unique ID of the NGINX instance running on the data plane.\n * `server_zone` - Name of an HTTP or Stream server zone.\n * `system_id` - Unique ID of the operating system running nginx-agent.\n * `tenant` - Tenant for the metric data.\n * `csg_object_id` - Unique ID of the Config Sync Group registered with NGINX One Console.\n * `mode` - Variant value for metric `system.cpu.utilization`.\n * `state` - Variant value for metrics `system.filesystem.usage`, `system.memory.usage`.\n * `io_direction` - Variant value for metric `system.network.io`.\n * `status_range` - Variant value for metric `nginx.http.response.count`.\n * `logical_number` - Variant value for metrics that return a processor number.\n * `outcome` - Variant value for metrics that return an outcome.\n * `upstream_zone` - upstream zone for the metric data.\n * `upstream_name` - upstream name for the metric data.\n * `peer_state` - Variant value for metric peer state for the metric `nginx.http.upstream.peer.count`.\n * `peer_health_check` - Variant value for metric peer health check for the metric `nginx.http.upstream.peer.health_checks`.\n * `peer_address` - peer address for metric data.\n * `peer_name` - peer name for metric data.\n * `ecp_object_id` - Unique ID of the External Control Plane registered with NGINX One Console.\n", + "description": "Metric names available for querying.\n", + "example": "nginx.plus.instances", + "oneOf": [ + { + "$ref": "#/components/schemas/MetricNginxInstancesPlus" + }, + { + "$ref": "#/components/schemas/MetricK8sClusterNodes" + } + ] + }, + "MetricNginxInstancesPlus": { + "type": "string", + "description": "Total number of nginx plus instances.\n\nAggregation(s) supported:\n * count\n * sum\n * avg\n * min\n * max\n", "enum": [ - "display_name", - "file_path", - "parent_hostname", - "instance_object_id", - "location_zone", - "mount_point", - "namespace", - "network_interface", - "nginx_id", - "server_zone", - "system_id", - "tenant", - "csg_object_id", - "mode", - "state", - "io_direction", - "status_range", - "logical_number", - "outcome", - "upstream_zone", - "upstream_name", - "peer_state", - "peer_health_check", - "peer_address", - "peer_name", - "ecp_object_id" + "nginx.plus.instances" + ] + }, + "MetricK8sClusterNodes": { + "type": "string", + "description": "Sum of the Kubernetes worker nodes where nginx plus instances are deployed in a Kubernetes cluster.\n\nAggregation(s) supported:\n * count\n * sum\n * avg\n * min\n * max\n", + "enum": [ + "k8s.cluster.nodes" + ] + }, + "FilterNameNapSignatures": { + "type": "string", + "description": "Keywords for NGINX App Protect signature filters.\nWhen filtering on `accuracy`, only the following `filter_values` are supported:\n * high\n * medium\n * low\nWhen filtering on `risk`, only the following `filter_values` are supported:\n * high\n * medium\n * low\nWhen filtering on `signature_type`, only the following `filter_values` are supported:\n * request\n * response\n", + "enum": [ + "accuracy", + "risk", + "signature_type" ], "x-enum-varnames": [ - "metric_dimension_display_name", - "metric_dimension_file_path", - "metric_dimension_hostname", - "metric_dimension_instance_object_id", - "metric_dimension_location_zone", - "metric_dimension_mount_point", - "metric_dimension_namespace", - "metric_dimension_network_interface", - "metric_dimension_nginx_id", - "metric_dimension_server_zone", - "metric_dimension_system_id", - "metric_dimension_tenant", - "metric_dimension_csg_object_id", - "metric_dimension_mode", - "metric_dimension_state", - "metric_dimension_io_direction", - "metric_dimension_status_range", - "metric_dimension_logical_number", - "metric_dimension_outcome", - "metric_dimension_upstream_zone", - "metric_dimension_upstream_name", - "metric_dimension_peer_state", - "metric_dimension_peer_health_check", - "metric_dimension_peer_address", - "metric_dimension_peer_name", - "metric_dimension_ecp_object_id" + "filter_name_nap_signature_accuracy", + "filter_name_nap_signature_risk", + "filter_name_nap_signature_signature_type" + ] + }, + "FilterNameNapSignatureSets": { + "type": "string", + "description": "Keywords for NGINX App Protect signature set filters.\nWhen filtering on `type`, only the following `filter_values` are supported:\n * filter-based\n * manual\n", + "enum": [ + "type", + "name" + ], + "x-enum-varnames": [ + "filter_name_nap_signature_set_type", + "filter_name_nap_signature_set_name" ] }, - "BaseMetricQueryRequest": { - "type": "object", + "NapSignatureID": { + "description": "An unique identifier for the NGINX App Protect signature.", + "type": "integer", + "pattern": "^\\d{9}" + }, + "NapSignatureSetObjectID": { + "description": "A globally unique identifier for the NGINX App Protect signature set.", + "type": "string", + "format": "object_id", + "pattern": "^sigset_.*", + "x-go-type": "objects.ID", + "x-go-type-import": { + "name": "objects", + "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" + } + }, + "NapCompileStatus": { + "description": "Provide the status of the NGINX App Protect compilation request.", "required": [ - "metrics", - "start_time", - "resolution" + "status", + "nap_release", + "created_at", + "modified_at" ], "properties": { - "metrics": { - "$ref": "#/components/schemas/MetricNames" + "nap_release": { + "description": "The NGINX App Protect release version the NGINX App Protect log profile compilation was requested for.", + "type": "string" }, - "filter": { - "$ref": "#/components/schemas/MetricFilters" + "status": { + "description": "Status of the NGINX App Protect compilation request. * `pending` - The compilation request has been accepted and is currently processing. * `failed` - The compilation attempt failed. * `succeeded` - The compilation was successful.", + "type": "string", + "enum": [ + "pending", + "failed", + "succeeded" + ], + "x-enum-varnames": [ + "nap_compile_status_pending", + "nap_compile_status_failed", + "nap_compile_status_succeeded" + ] }, - "start_time": { - "$ref": "#/components/schemas/StartTime" + "failure_reason": { + "type": "string", + "description": "The failure reason populated when status is 'failed'." }, - "end_time": { - "$ref": "#/components/schemas/EndTime" + "created_at": { + "type": "string", + "format": "date-time", + "description": "The date and time when the compile request was created." }, - "resolution": { + "modified_at": { "type": "string", - "description": "Specifies the level of granularity for time series data in your results. Applicable only for endpoints that return time series data.\n\nUsage: \n* Specify as a string with a number followed by a unit of time, such as `y` (years), `M` (months), `w` (weeks), `d` (days), `h` (hours), `m` (minutes) or `s` (seconds).\n* Metrics in `names` must be aggregated.\n* `start_time` is required.\n* If `resolution` is not set, the API returns the maximum resolution (`end_time` - `start_time`).\n", - "example": "30s" + "format": "date-time", + "description": "The date and time when the compile request was last modified." + }, + "size": { + "type": "integer", + "description": "The size of the compiled bundle, only set when status is `succeeded`." + }, + "hash": { + "type": "string", + "description": "The sha256 hash value of the compiled bundle, only set when status is `succeeded`." } + }, + "example": { + "nap_release": "5.10.0", + "status": "succeeded", + "created_at": "2026-01-13T18:54:19.140336Z", + "modified_at": "2026-01-13T18:56:31.264956Z" } }, - "MetricQueryRequest": { + "VersionsList": { + "type": "object", + "required": [ + "items" + ], + "properties": { + "items": { + "description": "An array of versions.", + "type": "array", + "items": { + "$ref": "#/components/schemas/NapSignatureVersion" + } + } + } + }, + "ThreatCampaignVersionsListResponse": { + "$ref": "#/components/schemas/VersionsList" + }, + "AttackSignatureVersionsListResponse": { + "$ref": "#/components/schemas/VersionsList" + }, + "BotSignatureVersionsListResponse": { + "$ref": "#/components/schemas/VersionsList" + }, + "NapPolicy": { + "description": "The base64-encoded contents of the NGINX App Protect policy.", "type": "object", + "required": [ + "policy" + ], + "properties": { + "policy": { + "type": "string", + "format": "base64", + "maxLength": 3145728 + } + } + }, + "NapPolicyObject": { "allOf": [ { - "$ref": "#/components/schemas/BaseMetricQueryRequest" + "$ref": "#/components/schemas/NapPolicyMetadata" }, { - "type": "object", - "properties": { - "dimensions": { - "$ref": "#/components/schemas/MetricDimensions" - }, - "group_by": { - "$ref": "#/components/schemas/GroupByDimensions" - }, - "order_by": { - "description": "List the order by for dimension(s).\n\nUsage:\n\n* Must be a dimension included by `dimensions` or `group_by`.\n", - "type": "array", - "items": { - "$ref": "#/components/schemas/OrderBy" - } - } - } + "$ref": "#/components/schemas/NapPolicyDeployments" } ] }, - "MetricTopXQueryRequest": { + "NapPolicyMetadata": { + "description": "Summary information about NGINX App Protect policy.", "type": "object", + "required": [ + "object_id", + "name", + "latest" + ], + "properties": { + "object_id": { + "$ref": "#/components/schemas/NapPolicyObjectID" + }, + "name": { + "description": "The name of the NGINX App Protect policy.", + "type": "string" + }, + "description": { + "type": "string", + "description": "Some detail on the NGINX App Protect policy." + }, + "latest": { + "$ref": "#/components/schemas/NapPolicyVersionMetadata" + } + } + }, + "NapPolicyListResponse": { + "description": "List of all NGINX App Protect policies.", "allOf": [ { - "$ref": "#/components/schemas/BaseMetricQueryRequest" + "$ref": "#/components/schemas/PaginationResponse" }, { + "description": "List of NGINX App Protect policies.", "type": "object", "required": [ - "series_limit", - "group_series_by" + "items" ], "properties": { - "dimensions": { - "$ref": "#/components/schemas/TopXMetricDimensions" - }, - "series_limit": { - "type": "integer", - "example": 25, - "description": "Sets the maximum number of series that can be returned. \n\nNotes:\n* Always returns an additional series with a dimension named `all`, aggregating the values of all metrics included in the results.\n* A series with a dimension named `other` may be returned, aggregating the values of metrics not included in the results.\n" - }, - "group_series_by": { - "$ref": "#/components/schemas/MetricDimension" - }, - "order_series_by": { - "$ref": "#/components/schemas/OrderSeriesBy" + "items": { + "description": "An array of NGINX App Protect policy objects.", + "type": "array", + "items": { + "$ref": "#/components/schemas/NapPolicyObject" + } } + }, + "example": { + "items": [ + { + "object_id": "pol_-uvR3F2TQGm18jnl7bpaGw", + "name": "test-policy", + "description": "test policy", + "deployments": [ + { + "publication_object_id": "pub_-uvR3F2TQGm18jnl7bpaGw", + "associated_name": "test-instance", + "associated_type": "instance", + "associated_object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", + "status": "deployed", + "enforcement_mode": "blocking", + "policy_version": "2023-12-06 22:37:24", + "policy_version_object_id": "pv_-abc3F2TQGm18jnl7bpaGw", + "deployed_on": "2023-12-06T22:37:24.120114Z" + } + ], + "latest": { + "object_id": "pv_-uvR3F2TQGm18jnl7bpaGw", + "version": "2023-12-06 22:37:24", + "created_at": "2023-12-06T22:37:24.120114Z", + "deployment_status": "deployed", + "enforcement_mode": "blocking" + } + } + ] } } ] }, - "MetricNames": { - "type": "array", - "description": "Specify the metrics you want details for.\n\nUsage: \n* List multiple metrics as json objects.\n * You can aggregate metrics with `avg`, `sum`, `min`, `max`, `rate`.\n* Metrics with aggregates require a `start_time`.\n* If you combine aggregated and non-aggregated metrics in a single query, any `group_by` clause applies only to the aggregated metrics.\n", - "items": { - "$ref": "#/components/schemas/MetricQuery" - }, - "example": [ - { - "name": "system.cpu.utilization", - "aggregate": "avg", - "filter": [ - { - "filterSet": [ - { - "dimension": "mode", - "operator": "=", - "values": [ - "system" - ] - } - ] - } - ] + "NapPolicyVersionDeployments": { + "type": "object", + "properties": { + "deployments": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NapPolicyVersionDeployment" + } } - ] + } }, - "MetricQuery": { + "NapDeploymentAssociation": { "type": "object", "required": [ - "name" + "associated_type", + "associated_object_id", + "associated_name" ], "properties": { - "name": { - "$ref": "#/components/schemas/MetricName" + "associated_type": { + "$ref": "#/components/schemas/DeploymentAssociatedType" }, - "aggregate": { - "$ref": "#/components/schemas/MetricAggregation" + "associated_object_id": { + "$ref": "#/components/schemas/ObjectID" + }, + "associated_name": { + "$ref": "#/components/schemas/DeploymentAssociatedName" } } }, - "MetricFilterPredicate": { - "type": "string", - "enum": [ - "AND", - "OR" - ], - "x-enum-varnames": [ - "metric_filter_predicate_and", - "metric_filter_predicate_or" - ] - }, - "MetricFilters": { - "type": "array", - "description": "Filter results based on dimension operations against one or more values.\n\nUsage:\n* Format as one or more predicates by providing all required elements.\n * `dimension`: The dimension name you want to filter on.\n * `operator`: The possible operators (`=`, `!=`, `<`, `<=`, `>`, `>=`, `in`, `not`) you can use for comparison or condition checking.\n * `value`: Case sensitive value of the dimension to filter against.\n\nFor more complex filtering:\n\n* Specify a `predicate` for logical expressions (`AND`,`OR`). \n* Use a wildcard `*` in the `value` for matching partial values.\n", - "items": { - "$ref": "#/components/schemas/MetricFilterSet" - }, - "example": [ + "NapDeployment": { + "allOf": [ { - "filterSet": [ - { - "dimension": "server_zone", - "operator": "!=", - "values": [ - "server_zone_1" - ] + "$ref": "#/components/schemas/NapDeploymentAssociation" + }, + { + "type": "object", + "description": "Information about a NGINX App Protect policy deployment.\n", + "required": [ + "publication_object_id", + "status", + "deployed_on" + ], + "properties": { + "publication_object_id": { + "$ref": "#/components/schemas/PublicationObjectID" }, - { - "predicate": "OR", - "dimension": "server_zone", - "operator": "=", - "values": [ - "server_zone_2" - ] + "status": { + "$ref": "#/components/schemas/NapDeploymentStatus" + }, + "deployed_on": { + "description": "Date and time of the deployment.", + "type": "string", + "format": "date-time" } - ] + }, + "example": { + "publication_object_id": "pub_-uvR3F2TQGm18jnl7bpaGw", + "associated_name": "test-instance", + "associated_type": "instance", + "associated_object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", + "status": "deployed", + "deployed_on": "2023-12-06T22:37:24.120114Z" + } + } + ] + }, + "NapPolicyVersionDeployment": { + "allOf": [ + { + "$ref": "#/components/schemas/NapDeploymentAssociation" }, { - "predicate": "AND", - "filterSet": [ - { - "dimension": "nginx_id", - "operator": "in", - "values": [ - "id1", - "id2" - ] + "type": "object", + "description": "Information about a NGINX App Protect policy deployment.\n", + "required": [ + "publication_object_id", + "status", + "deployed_on" + ], + "properties": { + "publication_object_id": { + "$ref": "#/components/schemas/PublicationObjectID" + }, + "status": { + "$ref": "#/components/schemas/NapDeploymentStatus" + }, + "deployed_on": { + "description": "Date and time of the deployment.", + "type": "string", + "format": "date-time" } - ] + }, + "example": { + "publication_object_id": "pub_-uvR3F2TQGm18jnl7bpaGw", + "associated_name": "test-instance", + "associated_type": "instance", + "associated_object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", + "status": "deployed", + "deployed_on": "2023-12-06T22:37:24.120114Z" + } } ] }, - "MetricFilterSet": { + "NapPolicyDeployments": { "type": "object", - "description": "Encapsulates one or more `MetricFilter` object(s) to be grouped together.\n", "required": [ - "filterSet" + "deployments" ], "properties": { - "predicate": { - "$ref": "#/components/schemas/MetricFilterPredicate" - }, - "filterSet": { + "deployments": { "type": "array", "items": { - "$ref": "#/components/schemas/MetricFilter" + "$ref": "#/components/schemas/NapPolicyDeployment" } } } }, - "MetricFilter": { + "NapLogProfileDeployments": { "type": "object", - "required": [ - "dimension", - "operator", - "values" - ], "properties": { - "dimension": { - "$ref": "#/components/schemas/MetricDimension" - }, - "operator": { - "type": "string", - "description": "Static list of all operations supported by filtering\n\n* The `=`, `!=` only use the first element of the `values` array. Wildcards for partial matching is supported.\n* The `in` and `not` both use all elements in the `values` array. Wildcards for partial matching is NOT supported.\n", - "enum": [ - "=", - "!=", - "in", - "not" - ], - "x-enum-varnames": [ - "metric_filter_equal", - "metric_filter_not_equal", - "metric_filter_in", - "metric_filter_not" - ] - }, - "values": { + "deployments": { "type": "array", - "description": "Single value used for all operators except `in` and `not`.", "items": { - "type": "string" + "$ref": "#/components/schemas/NapLogProfileDeployment" } - }, - "predicate": { - "$ref": "#/components/schemas/MetricFilterPredicate" } } }, - "OrderDirection": { - "type": "string", - "enum": [ - "asc", - "desc" - ], - "x-enum-varnames": [ - "order_by_asc", - "order_by_desc" + "NapLogProfileDeployment": { + "description": "Detailed information about a NGINX App Protect log-profile deployment.", + "type": "object", + "allOf": [ + { + "$ref": "#/components/schemas/NapDeployment" + }, + { + "type": "object", + "required": [ + "nap_release", + "publication_object_id", + "associated_name", + "associated_type", + "associated_object_id", + "status", + "deployed_on" + ], + "properties": { + "nap_release": { + "description": "The compiler version of NGINX App Protect the log profile was deployed with.", + "type": "string" + }, + "latest_deployed": { + "$ref": "#/components/schemas/NapLatestDeployed" + } + } + } ], - "default": "desc" + "example": { + "nap_release": "5.10.0", + "publication_object_id": "pub_-uvR3F2TQGm18jnl7bpaGw", + "associated_name": "test-instance", + "associated_type": "instance", + "associated_object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", + "status": "deployed", + "deployed_on": "2023-12-06T22:37:24.120114Z", + "latest_deployed": "yes" + } }, - "OrderBy": { + "NapPolicyDeployment": { + "description": "Detailed information about a NGINX App Protect policy deployment.", "type": "object", - "description": "Sort order of the metric series in your results.\n\nUsage:\n* Provide all required elements. \n * `direction`: The sorting direction either `desc` or `asc`.\n * `dimension`: The dimension for ordering.\n", "required": [ - "direction", - "dimension" + "publication_object_id", + "associated_object_id", + "associated_name", + "associated_type", + "enforcement_mode", + "status", + "policy_version", + "policy_version_object_id", + "deployed_on" ], - "properties": { - "direction": { - "$ref": "#/components/schemas/OrderDirection" + "allOf": [ + { + "$ref": "#/components/schemas/NapPolicyVersionDeployment" }, - "dimension": { - "$ref": "#/components/schemas/MetricDimension" + { + "type": "object", + "required": [ + "enforcement_mode", + "policy_version", + "policy_version_object_id" + ], + "properties": { + "enforcement_mode": { + "$ref": "#/components/schemas/NapPolicyEnforcementMode" + }, + "policy_version": { + "description": "The version associated with the NGINX App Protect policy.", + "type": "string" + }, + "policy_version_object_id": { + "$ref": "#/components/schemas/NapPolicyVersionObjectID" + } + } } + ], + "example": { + "publication_object_id": "pub_-uvR3F2TQGm18jnl7bpaGw", + "associated_name": "test-instance", + "associated_type": "instance", + "associated_object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", + "status": "deployed", + "deployed_on": "2023-12-06T22:37:24.120114Z", + "enforcement_mode": "blocking", + "policy_version": "2023-12-06 22:37:24", + "policy_version_object_id": "pv_-abc3F2TQGm18jnl7bpaGw" } }, - "OrderSeriesBy": { + "NapPolicyDeploymentDetails": { "type": "object", - "description": "Sort order of the metric series in your results.\n\nUsage:\n* Provide all required elements. \n * `direction`: The sorting direction either `desc` or `asc`.\n * `aggregate`: The aggregating function.\n", "required": [ - "direction", - "aggregate" + "publication_object_id", + "associated_object_id", + "associated_name", + "associated_type", + "enforcement_mode", + "status", + "policy_version", + "policy_version_object_id", + "deployed_on", + "threat_campaign_version", + "attack_signature_version", + "bot_signature_version" ], - "properties": { - "direction": { - "$ref": "#/components/schemas/OrderDirection" + "allOf": [ + { + "$ref": "#/components/schemas/NapPolicyDeployment" }, - "aggregate": { - "$ref": "#/components/schemas/MetricAggregation", - "default": "sum" + { + "type": "object", + "properties": { + "threat_campaign_version": { + "$ref": "#/components/schemas/NapSignatureVersion" + }, + "attack_signature_version": { + "$ref": "#/components/schemas/NapSignatureVersion" + }, + "bot_signature_version": { + "$ref": "#/components/schemas/NapSignatureVersion" + } + } } + ], + "example": { + "publication_object_id": "pub_-uvR3F2TQGm18jnl7bpaGw", + "associated_name": "test-instance", + "associated_type": "instance", + "associated_object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", + "status": "deployed", + "policy_version": "2023-12-06 22:37:24", + "policy_version_object_id": "pv_-abc3F2TQGm18jnl7bpaGw", + "deployed_on": "2023-12-06T22:37:24.120114Z", + "enforcement_mode": "blocking", + "threat_campaign_version": "2023.12.06", + "attack_signature_version": "2023.12.06", + "bot_signature_version": "2023.12.06" } }, - "MetricName": { - "type": "string", - "description": "Metric names available for querying.\n", - "example": "nginx.http.request.count", - "oneOf": [ - { - "$ref": "#/components/schemas/MetricSystemCpuUtilization" - }, - { - "$ref": "#/components/schemas/MetricSystemFilesystemUsage" - }, - { - "$ref": "#/components/schemas/MetricSystemMemoryUsage" - }, - { - "$ref": "#/components/schemas/MetricSystemCpuLogicalCount" - }, - { - "$ref": "#/components/schemas/MetricSystemNetworkIo" - }, - { - "$ref": "#/components/schemas/MetricNginxHttpRequestCount" - }, - { - "$ref": "#/components/schemas/MetricNginxHttpResponseCount" - }, - { - "$ref": "#/components/schemas/MetricNginxHttpConnectionCount" - }, - { - "$ref": "#/components/schemas/MetricNginxHttpConnections" - }, - { - "$ref": "#/components/schemas/MetricNginxHttpUpstreamPeerCount" - }, - { - "$ref": "#/components/schemas/MetricNginxHttpUpstreamPeerHealthChecks" - }, - { - "$ref": "#/components/schemas/MetricNginxStreamUpstreamPeerHealthChecks" - }, + "NapPolicyDeploymentsListResponse": { + "description": "List of all NGINX App Protect deployments.", + "allOf": [ { - "$ref": "#/components/schemas/MetricNginxStreamUpstreamPeerCount" + "$ref": "#/components/schemas/PaginationResponse" }, { - "$ref": "#/components/schemas/MetricNginxHttpRequestIo" + "type": "object", + "required": [ + "items" + ], + "properties": { + "items": { + "description": "An array of NGINX App Protect deployments.", + "type": "array", + "items": { + "$ref": "#/components/schemas/NapPolicyDeploymentDetails" + } + } + }, + "example": { + "items": [ + { + "publication_object_id": "pub_-uvR3F2TQGm18jnl7bpaGw", + "associated_name": "test-instance", + "associated_type": "instance", + "associated_object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", + "status": "deployed", + "policy_version": "2023-12-06 22:37:24", + "policy_version_object_id": "pv_-abc3F2TQGm18jnl7bpaGw", + "deployed_on": "2023-12-06T22:37:24.120114Z", + "enforcement_mode": "blocking", + "threat_campaign_version": "2023.12.06", + "attack_signature_version": "2023.12.06", + "bot_signature_version": "2023.12.06" + } + ] + } } ] }, - "MetricSystemCpuUtilization": { - "type": "string", - "description": "Total system CPU use for 'system' or 'user' (percent). A filter is required to specify the mode.\n\nReplaces deprecated variants:\n * system.cpu.system\n * system.cpu.user\n\nSupported aggregations:\n * min\n * max\n * sum\n * avg\n * rate\n\nCatalog dimension filter:\n * mode (valid values:: 'system', 'user')\n\nSupported catalog dimensions:\n * instance_object_id\n * csg_object_id\n * ecp_object_id\n * system_id\n * parent_hostname\n * display_name\n * nginx_id\n * logical_number\n", - "enum": [ - "system.cpu.utilization" - ] - }, - "MetricSystemFilesystemUsage": { - "type": "string", - "description": "System disk usage statistic, percentage. A filter differentiator is needed for specific state(s).\n\nReplacement for deprecated variant(s):\n * system.disk.in_use\n * system.disk.total\n * system.disk.used\n\nAggregation(s) supported:\n * min\n * max\n * sum\n * avg\n * rate\n\nCatalog dimension filter differentiator:\n * state (applicable filter values: 'used', 'free', 'in_use')\n\nCatalog dimension(s) supported:\n * instance_object_id\n * csg_object_id\n * ecp_object_id\n * system_id\n * parent_hostname\n * display_name\n * nginx_id\n * mount_point\n", - "enum": [ - "system.filesystem.usage" - ] - }, - "MetricSystemMemoryUsage": { - "type": "string", - "description": "Total available statistic about system memory usage, bytes. A filter differentiator is needed for specific state(s).\n\nReplacement for deprecated variant(s):\n * system.mem.pct_used\n * system.mem.total\n * system.mem.used\n\nAggregation(s) supported:\n * min\n * max\n * sum\n * avg\n * rate \n\nCatalog dimension filter differentiator:\n * state (applicable filter values: 'used', 'free', 'total', 'pct_used')\n\nCatalog dimension(s) supported:\n * instance_object_id\n * csg_object_id\n * ecp_object_id\n * system_id\n * parent_hostname\n * display_name\n * nginx_id\n", - "enum": [ - "system.memory.usage" - ] - }, - "MetricSystemCpuLogicalCount": { - "type": "string", - "description": "Number of logical (virtual) processor cores created by the operating system.\n\nAggregation(s) supported:\n * min\n * max\n * sum\n * avg\n * rate \n\nCatalog dimension(s) supported:\n * instance_object_id\n * csg_object_id\n * ecp_object_id\n * system_id\n * parent_hostname\n * display_name\n * nginx_id\n", - "enum": [ - "system.cpu.logical.count" - ] - }, - "MetricNginxHttpConnectionCount": { - "type": "string", - "description": "Number of connections grouped by outcome ('ACTIVE', 'IDLE', 'READING', 'WRITING', 'WAITING').\nSupported aggregations:\n * min\n * max\n * sum\n * avg\n * rate\n\nSupported catalog dimensions:\n * instance_object_id\n * csg_object_id\n * ecp_object_id\n * system_id\n * parent_hostname\n * display_name\n * nginx_id\n * outcome\n", - "enum": [ - "nginx.http.connection.count" - ] - }, - "MetricNginxHttpConnections": { - "type": "string", - "description": "Total connections grouped by outcome ('ACCEPTED', 'HANDLED', 'DROPPED').\nSupported aggregations:\n * min\n * max\n * sum\n * avg\n * rate\n\nSupported catalog dimensions:\n * instance_object_id\n * csg_object_id\n * ecp_object_id\n * system_id\n * parent_hostname\n * display_name\n * nginx_id\n * outcome\n", - "enum": [ - "nginx.http.connections" - ] - }, - "MetricNginxHttpUpstreamPeerCount": { - "type": "string", - "description": "Number of upstream peers grouped by state ('CHECKING', 'DOWN', 'DRAINING', 'UNAVAILABLE', 'UNHEALTHY', 'UP').\nSupported aggregations:\n * min\n * max\n * sum\n * avg\n * rate\nSupported catalog dimensions:\n * instance_object_id\n * csg_object_id\n * ecp_object_id\n * system_id\n * parent_hostname\n * display_name\n * nginx_id\n * upstream_zone\n * upstream_name\n * peer_state\n", - "enum": [ - "nginx.http.upstream.peer.count" - ] - }, - "MetricNginxStreamUpstreamPeerCount": { - "type": "string", - "description": "Number of upstream peers grouped by state ('CHECKING', 'DOWN', 'DRAINING', 'UNAVAILABLE', 'UNHEALTHY', 'UP').\nSupported aggregations:\n * min\n * max\n * sum\n * avg\n * rate\nSupported catalog dimensions:\n * instance_object_id\n * csg_object_id\n * ecp_object_id\n * system_id\n * parent_hostname\n * display_name\n * nginx_id\n * upstream_zone\n * upstream_name\n * peer_state\n", - "enum": [ - "nginx.stream.upstream.peer.count" - ] - }, - "MetricNginxHttpUpstreamPeerHealthChecks": { - "type": "string", - "description": "The total number of health check requests made to a HTTP upstream peer.\nSupported aggregations:\n * min\n * max\n * sum\n * avg\n * rate\nSupported catalog dimensions:\n * instance_object_id\n * csg_object_id\n * ecp_object_id\n * system_id\n * parent_hostname\n * display_name\n * nginx_id\n * upstream_zone\n * upstream_name\n * peer_health_check\n * peer_address\n * peer_name\n", - "enum": [ - "nginx.http.upstream.peer.health_checks" - ] - }, - "MetricNginxStreamUpstreamPeerHealthChecks": { - "type": "string", - "description": "The total number of health check requests made to a stream upstream peer.\nSupported aggregations:\n * min\n * max\n * sum\n * avg\n * rate\nSupported catalog dimensions:\n * instance_object_id\n * csg_object_id\n * ecp_object_id\n * system_id\n * parent_hostname\n * display_name\n * nginx_id\n * upstream_zone\n * upstream_name\n * peer_health_check\n * peer_address\n * peer_name\n", - "enum": [ - "nginx.stream.upstream.peer.health_checks" - ] - }, - "MetricSystemNetworkIo": { - "type": "string", - "description": "Network I/O statistics. Number of bytes sent or received per network interface. A filter differentiator is needed for specific I/O direction(s).\n\nReplacement for deprecated variant(s):\n * system.net.bytes_rcvd\n * system.net.bytes_sent\n\nAggregation(s) supported:\n * min\n * max\n * sum\n * avg\n * accum_rate\n\nCatalog dimension filter differentiator:\n * io_direction (applicable filter values: 'transmit', 'receive')\n\nCatalog dimension(s) supported:\n * instance_object_id\n * csg_object_id\n * ecp_object_id\n * system_id\n * parent_hostname\n * display_name\n * nginx_id\n * network_interface\n", - "enum": [ - "system.network.io" - ] - }, - "MetricNginxHttpRequestCount": { - "type": "string", - "description": "The current number of client requests received from clients.\n\nReplacement for deprecated variant(s):\n * nginx.http.request.count\n * plus.http.request.count\n\nAggregation(s) supported:\n * min\n * max\n * sum\n * avg\n * rate\n\nCatalog dimension(s) supported:\n * instance_object_id\n * csg_object_id\n * ecp_object_id\n * system_id\n * parent_hostname\n * display_name\n * nginx_id\n * server_zone\n * location_zone\n", - "enum": [ - "nginx.http.request.count" - ] - }, - "MetricNginxHttpResponseCount": { - "type": "string", - "description": "The current number of responses, grouped by status code range. A filter differentiator is needed for specific status range(s).\n\nReplacement for deprecated variant(s):\n * nginx.http.status.4xx\n * plus.http.status.4xx\n\nAggregation(s) supported:\n * min\n * max\n * sum\n * avg\n * rate\n\nCatalog dimension filter differentiator:\n * status_range (applicable filter values: '4xx', '5xx')\n\nCatalog dimension(s) supported:\n * instance_object_id\n * csg_object_id\n * ecp_object_id\n * system_id\n * parent_hostname\n * display_name\n * nginx_id \n * server_zone\n * location_zone\n", - "enum": [ - "nginx.http.response.count" - ] - }, - "MetricNginxHttpRequestIo": { - "type": "string", - "description": "The total number of bytes sent or received. A filter differentiator is needed for specific I/O direction(s).\n\nReplacement for deprecated variant(s):\n * nginx.http.request.bytes_rcvd\n * nginx.http.request.bytes_sent\n\nAggregation(s) supported:\n * min\n * max\n * sum\n * avg\n * accum_rate\n\nCatalog dimension filter differentiator:\n * io_direction (applicable filter values: 'transmit', 'receive')\n\nCatalog dimension(s) supported:\n * instance_object_id\n * csg_object_id\n * ecp_object_id\n * system_id\n * parent_hostname\n * display_name\n * nginx_id\n * server_zone\n * location_zone\n", - "enum": [ - "nginx.http.request.io" + "NapLogProfileDeploymentsListResponse": { + "description": "List of all NGINX App Protect log profile deployments.", + "allOf": [ + { + "$ref": "#/components/schemas/PaginationResponse" + }, + { + "type": "object", + "required": [ + "items" + ], + "properties": { + "items": { + "description": "An array of NGINX App Protect log profile deployments.", + "type": "array", + "items": { + "$ref": "#/components/schemas/NapLogProfileDeployment" + } + } + }, + "example": { + "items": [ + { + "nap_release": "5.10.0", + "publication_object_id": "pub_-uvR3F2TQGm18jnl7bpaGw", + "associated_name": "test-instance", + "associated_type": "instance", + "associated_object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", + "status": "deployed", + "deployed_on": "2023-12-06T22:37:24.120114Z", + "latest_deployed": "yes" + } + ] + } + } ] }, - "SettingsInstanceCleanup": { + "NapPolicyVersionMetadata": { "type": "object", - "description": "Preferences for automatic cleanup of stale NGINX One Instances.", + "description": "Summary information about the specific NGINX App Protect policy version.", "required": [ - "age_out_duration" + "object_id", + "version", + "enforcement_mode", + "created_at" ], "properties": { - "age_out_duration": { - "type": "integer", - "format": "int32", - "description": "Specify the age of `unavailable` NGINX instances for clean up. NGINX instances older than this value in hours will be deleted automatically. Events related to automatically deleted NGINX instances will show up in `/events` API. '0' value disables the automatic clean up of `unavailable` NGINX instances.", - "default": 3, - "minimum": 0, - "maximum": 720 - } - }, - "example": { - "age_out_duration": 3 - } - }, - "HttpUsage": { - "type": "object", - "properties": { - "client": { - "allOf": [ - { - "$ref": "#/components/schemas/UsageMetrics" - }, - { - "type": "object", - "properties": { - "requests": { - "type": "integer", - "description": "Total requests handled by an NGINX Instance", - "minimum": 0 - } - } - } - ] + "object_id": { + "$ref": "#/components/schemas/NapPolicyVersionObjectID" }, - "upstream": { - "$ref": "#/components/schemas/UsageMetrics" + "version": { + "$ref": "#/components/schemas/NapSignatureVersion" + }, + "enforcement_mode": { + "$ref": "#/components/schemas/NapPolicyEnforcementMode" + }, + "created_at": { + "description": "The date and time when the NGINX App Protect policy version was created.", + "type": "string", + "format": "date-time" } } }, - "StreamUsage": { + "NapPolicyVersionDetails": { + "description": "Detailed information about NGINX App Protect policy version.", "type": "object", - "properties": { - "client": { - "$ref": "#/components/schemas/UsageMetrics" + "required": [ + "policy", + "object_id", + "version", + "enforcement_mode", + "created_at" + ], + "allOf": [ + { + "$ref": "#/components/schemas/NapPolicyVersionMetadata" }, - "upstream": { - "$ref": "#/components/schemas/UsageMetrics" + { + "$ref": "#/components/schemas/NapPolicy" + }, + { + "$ref": "#/components/schemas/NapPolicyVersionDeployments" } - } + ] }, - "UsageMetrics": { - "type": "object", - "properties": { - "received": { - "type": "integer", - "description": "Total bytes received by an NGINX Instance from clients/upstreams", - "minimum": 0 + "NapPolicyVersionObject": { + "description": "Summary information about NGINX App Protect policy version.", + "allOf": [ + { + "$ref": "#/components/schemas/NapPolicyVersionMetadata" }, - "sent": { - "type": "integer", - "description": "Total bytes sent by the NGINX Instance to clients/upstreams", - "minimum": 0 + { + "$ref": "#/components/schemas/NapPolicyVersionDeployments" }, - "connections": { - "type": "integer", - "description": "Total connections of the NGINX Instance with clients/upstreams", - "minimum": 0 + { + "type": "object", + "required": [ + "latest" + ], + "properties": { + "latest": { + "description": "Indicates whether the NGINX App Protect policy version is latest. Default (`false`) returns the current policy. \nWhen set to `true`, returns the latest policy.\n", + "type": "boolean", + "default": false + } + } } - } - }, - "NginxUsageHttp": { - "$ref": "#/components/schemas/HttpUsage" + ] }, - "NginxUsageStream": { - "$ref": "#/components/schemas/StreamUsage" + "NapPolicyVersionsListResponse": { + "description": "List of all NGINX App Protect versions.", + "allOf": [ + { + "$ref": "#/components/schemas/PaginationResponse" + }, + { + "type": "object", + "required": [ + "items" + ], + "properties": { + "items": { + "description": "An array of NGINX App Protect version objects.", + "type": "array", + "items": { + "$ref": "#/components/schemas/NapPolicyVersionObject" + } + } + }, + "example": { + "items": [ + { + "version": "2023-12-06 22:37:24", + "object_id": "pv_-uvR3F2TQGm18jnl7bpaGw", + "created_at": "2023-12-06T22:37:24.120114Z", + "enforcement_mode": "blocking", + "latest": false + } + ] + } + } + ] }, - "MetricStartTime": { - "description": "The start time of your metrics query.\n\nUsage:\n* `start_time` is required if `end_time` is specified.\n* If `start_time` and `end_time` isn't provided, the API returns metrics from the current time to the month before the current time.\n* The `start_time` cannot be older than 120 days before the current time.\n\nYou can set the `start_time` in these ways:\n* In ISO 8601 format. For example, \"2019-08-07T09:57:36.088757764Z\".\n* As an offset from the current time. For the offset, use `+` or `-`, followed by a number and unit [`y` (years), `M` (months), `w` (weeks), `d` (days), `h` (hours), `m` (minutes), or `s` (seconds)]. \n* Example of an offset: \"now-3h\" (3 hours before now).\n", - "type": "string", - "example": "2019-08-07T09:57:36.088757764Z" + "NapLogProfileListResponse": { + "allOf": [ + { + "$ref": "#/components/schemas/PaginationResponse" + }, + { + "type": "object", + "required": [ + "items" + ], + "properties": { + "items": { + "description": "An array of NGINX App Protect log profiles.", + "type": "array", + "items": { + "$ref": "#/components/schemas/NapLogProfileObject" + } + } + } + } + ] }, - "MetricEndTime": { - "description": "The end time of your metrics query.\n\nUsage:\n* Must be greater than `start_time`.\n* The time difference between `start_time` and `end_time` should be greater than an hour.\n* The default `end_time` is the current time.\n* The `end_time` cannot be older than 120 days before the current time.\n\nYou can set the `end_time` in these ways:\n* In ISO 8601 format. For example, \"2019-08-07T09:57:36.088757764Z\".\n* As an offset from the current time. For the offset, use `+` or `-`, followed by a number and unit [`y` (years), `M` (months), `w` (weeks), `d` (days), `h` (hours), `m` (minutes), or `s` (seconds)]. \n* Example of an offset: \"now-3h\" (3 hours before now).\n", - "type": "string", - "example": "2019-08-07T09:57:36.088757764Z" + "NapLogProfileObjectDetails": { + "allOf": [ + { + "$ref": "#/components/schemas/NapLogProfileObject" + }, + { + "type": "object", + "required": [ + "config" + ], + "properties": { + "config": { + "description": "The NGINX App Protect log profile configuration.", + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "bundles" + ], + "properties": { + "bundles": { + "description": "Compiled NGINX APP Protect log profile bundles for this specific log profile. \nShows compilation status of the latest log profile contents across different NAP release versions.\n", + "type": "array", + "items": { + "$ref": "#/components/schemas/NapCompileStatus" + } + } + } + } + ], + "example": { + "created_at": "2026-01-16T21:12:51.843434Z", + "hash": "oxiWKPqR/soi4MQCgVnW8KHt8Jk68AqCeQcQ1sed4Dk=", + "modified_at": "2026-01-16T21:12:51.843434Z", + "name": "test-log-profiles", + "object_id": "lp_XYxnZgVYQFKire4M1KcVVQ", + "is_f5_default": false, + "config": "eyJsb2dfc3RyZWFtIjogIntmb3JtYXQgY29tYmluZWQgZXg=", + "deployments": [ + { + "nap_release": "5.10.0", + "publication_object_id": "pub_-uvR3F2TQGm18jnl7bpaGw", + "associated_name": "test-instance", + "associated_type": "instance", + "associated_object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", + "status": "deployed", + "deployed_on": "2023-12-06T22:37:24.120114Z", + "latest_deployed": "yes" + } + ], + "bundles": [ + { + "nap_release": "5.10.0", + "status": "succeeded", + "created_at": "2026-01-13T18:54:19.140336Z", + "modified_at": "2026-01-13T18:56:31.264956Z" + }, + { + "nap_release": "5.9.0", + "status": "succeeded", + "created_at": "2026-01-13T18:54:19.140336Z", + "modified_at": "2026-01-13T18:56:31.264956Z" + } + ] + } }, - "InventoryMetricAggregation": { - "type": "string", - "description": "Static list of aggregation functions that can be applied to a compatible metric.\n * count\n * sum\n * avg\n * min\n * max\n", - "enum": [ - "count", - "sum", - "avg", - "min", - "max" + "NapLogProfileObject": { + "allOf": [ + { + "$ref": "#/components/schemas/NapLogProfileDeployments" + }, + { + "$ref": "#/components/schemas/NapLogProfileMetadata" + } ], - "x-enum-varnames": [ - "metric_aggregation_count", - "metric_aggregation_sum", - "metric_aggregation_avg", - "metric_aggregation_min", - "metric_aggregation_max" - ] + "example": { + "created_at": "2026-01-16T21:12:51.843434Z", + "hash": "oxiWKPqR/soi4MQCgVnW8KHt8Jk68AqCeQcQ1sed4Dk=", + "modified_at": "2026-01-16T21:12:51.843434Z", + "name": "test-log-profiles", + "object_id": "lp_XYxnZgVYQFKire4M1KcVVQ", + "is_f5_default": false, + "deployments": [ + { + "nap_release": "5.10.0", + "publication_object_id": "pub_-uvR3F2TQGm18jnl7bpaGw", + "associated_name": "test-instance", + "associated_type": "instance", + "associated_object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", + "status": "deployed", + "deployed_on": "2023-12-06T22:37:24.120114Z", + "latest_deployed": "yes" + } + ] + } }, - "BaseInventoryQueryRequest": { + "NapLogProfileMetadata": { "type": "object", "required": [ - "metrics" + "name", + "object_id", + "hash", + "is_f5_default", + "modified_at", + "created_at" ], "properties": { - "metrics": { - "$ref": "#/components/schemas/InventoryMetricNames" + "name": { + "type": "string", + "description": "The name of the NGINX App Protect log profile." }, - "start_time": { - "$ref": "#/components/schemas/MetricStartTime" + "object_id": { + "$ref": "#/components/schemas/NapLogProfileObjectID" }, - "end_time": { - "$ref": "#/components/schemas/MetricEndTime" + "hash": { + "type": "string", + "description": "The hash value of the NGINX App Protect log profile configs." + }, + "is_f5_default": { + "$ref": "#/components/schemas/IsF5Default" + }, + "description": { + "description": "Optional field to describe the NGINX App Protect log profile.", + "type": "string", + "minLength": 5, + "maxLength": 256 + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "The date and time when the log profile was created." + }, + "modified_at": { + "type": "string", + "format": "date-time", + "description": "The date and time when the log profile was last modified." } } }, - "InventoryMetricQueryRequest": { - "type": "object", + "NapGlobalSettingsListResponse": { "allOf": [ { - "$ref": "#/components/schemas/BaseInventoryQueryRequest" + "$ref": "#/components/schemas/PaginationResponse" + }, + { + "type": "object", + "required": [ + "items" + ], + "properties": { + "items": { + "description": "An array of NGINX App Protect global settings.", + "type": "array", + "items": { + "$ref": "#/components/schemas/NapGlobalSettingMetadata" + } + } + } } ] }, - "InventoryMetricNames": { - "type": "array", - "description": "Specify the metrics to collect.\n\nUsage: \n* List multiple metrics as JSON objects.\n* You can aggregate metrics with `count`, `sum`, `avg`, `min`, `max`.\n", - "items": { - "$ref": "#/components/schemas/InventoryMetricQuery" - }, - "example": [ + "NapGlobalSettingGetResponse": { + "allOf": [ { - "name": "nginx.plus.instances", - "aggregate": [ - "count" - ] + "$ref": "#/components/schemas/NapGlobalSettingMetadata" + }, + { + "type": "object", + "required": [ + "config" + ], + "properties": { + "config": { + "description": "The NGINX App Protect global setting configuration.", + "type": "string" + } + } } ] }, - "InventoryMetricQuery": { + "NapGlobalSettingMetadata": { "type": "object", "required": [ - "name" + "name", + "object_id" ], "properties": { "name": { - "$ref": "#/components/schemas/InventoryMetricName" + "type": "string", + "description": "The name of the NGINX App Protect global setting object." }, - "aggregate": { - "type": "array", - "items": { - "$ref": "#/components/schemas/InventoryMetricAggregation" - } + "description": { + "description": "Optional field to describe the NGINX App Protect global setting object.", + "type": "string", + "minLength": 5, + "maxLength": 256 + }, + "object_id": { + "$ref": "#/components/schemas/NapGlobalSettingObjectID" } } }, - "InventoryMetricName": { - "type": "string", - "description": "Metric names available for querying.\n", - "example": "nginx.plus.instances", - "oneOf": [ - { - "$ref": "#/components/schemas/MetricNginxInstancesPlus" + "NapLogProfileCreateRequest": { + "description": "Create NGINX App Protect log profile.", + "type": "object", + "required": [ + "name", + "config" + ], + "properties": { + "name": { + "description": "The name of the NGINX App Protect log profile.", + "type": "string", + "minLength": 1, + "maxLength": 128 }, - { - "$ref": "#/components/schemas/MetricK8sClusterNodes" + "description": { + "description": "Optional field to describe the NGINX App Protect log profile.", + "type": "string", + "minLength": 5, + "maxLength": 256 + }, + "config": { + "description": "The NGINX App Protect log profile configuration.", + "type": "string", + "format": "base64", + "maxLength": 3145728 } - ] - }, - "MetricNginxInstancesPlus": { - "type": "string", - "description": "Total number of nginx plus instances.\n\nAggregation(s) supported:\n * count\n * sum\n * avg\n * min\n * max\n", - "enum": [ - "nginx.plus.instances" - ] - }, - "MetricK8sClusterNodes": { - "type": "string", - "description": "Sum of the Kubernetes worker nodes where nginx plus instances are deployed in a Kubernetes cluster.\n\nAggregation(s) supported:\n * count\n * sum\n * avg\n * min\n * max\n", - "enum": [ - "k8s.cluster.nodes" - ] - }, - "FilterNameNapSignatures": { - "type": "string", - "description": "Keywords for NGINX App Protect signature filters.\nWhen filtering on `accuracy`, only the following `filter_values` are supported:\n * high\n * medium\n * low\nWhen filtering on `risk`, only the following `filter_values` are supported:\n * high\n * medium\n * low\nWhen filtering on `signature_type`, only the following `filter_values` are supported:\n * request\n * response\n", - "enum": [ - "accuracy", - "risk", - "signature_type" - ], - "x-enum-varnames": [ - "filter_name_nap_signature_accuracy", - "filter_name_nap_signature_risk", - "filter_name_nap_signature_signature_type" - ] - }, - "FilterNameNapSignatureSets": { - "type": "string", - "description": "Keywords for NGINX App Protect signature set filters.\nWhen filtering on `type`, only the following `filter_values` are supported:\n * filter-based\n * manual\n", - "enum": [ - "type", - "name" - ], - "x-enum-varnames": [ - "filter_name_nap_signature_set_type", - "filter_name_nap_signature_set_name" - ] - }, - "NapSignatureID": { - "description": "An unique identifier for the NGINX App Protect signature.", - "type": "integer", - "pattern": "^\\d{9}" - }, - "NapSignatureSetObjectID": { - "description": "A globally unique identifier for the NGINX App Protect signature set.", - "type": "string", - "format": "object_id", - "pattern": "^sigset_.*", - "x-go-type": "objects.ID", - "x-go-type-import": { - "name": "objects", - "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" } }, - "NapCompileStatus": { - "description": "Provide the status of the NGINX App Protect compilation request.", + "NapLogProfileUpdateRequest": { + "description": "Update NGINX App Protect log profile.", + "type": "object", "required": [ - "status", - "nap_release", - "created_at", - "modified_at" + "config" ], "properties": { - "nap_release": { - "description": "The NGINX App Protect release version the NGINX App Protect log profile compilation was requested for.", - "type": "string" - }, - "status": { - "description": "Status of the NGINX App Protect compilation request. * `pending` - The compilation request has been accepted and is currently processing. * `failed` - The compilation attempt failed. * `succeeded` - The compilation was successful.", - "type": "string", - "enum": [ - "pending", - "failed", - "succeeded" - ], - "x-enum-varnames": [ - "nap_compile_status_pending", - "nap_compile_status_failed", - "nap_compile_status_succeeded" - ] - }, - "failure_reason": { + "name": { + "description": "The name of the NGINX App Protect log profile.", "type": "string", - "description": "The failure reason populated when status is 'failed'." + "minLength": 1, + "maxLength": 128 }, - "created_at": { + "description": { + "description": "Optional field to describe describing the NGINX App Protect log profile.", "type": "string", - "format": "date-time", - "description": "The date and time when the compile request was created." + "minLength": 5, + "maxLength": 256 }, - "modified_at": { + "config": { + "description": "The NGINX App Protect log profile configuration.", "type": "string", - "format": "date-time", - "description": "The date and time when the compile request was last modified." + "format": "base64", + "minLength": 5, + "maxLength": 3145728 } - }, - "example": { - "nap_release": "5.10.0", - "status": "succeeded", - "created_at": "2026-01-13T18:54:19.140336Z", - "modified_at": "2026-01-13T18:56:31.264956Z" } }, - "VersionsList": { + "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": [ - "items" + "action", + "object_id" ], "properties": { - "items": { - "description": "An array of versions.", - "type": "array", - "items": { - "$ref": "#/components/schemas/NapSignatureVersion" - } + "object_id": { + "$ref": "#/components/schemas/NapPolicyObjectID" + }, + "action": { + "$ref": "#/components/schemas/BulkRequestAction" } + }, + "example": { + "object_id": "pol_-uvR3F2TQGm18jnl7bpaGw", + "action": "delete" } }, - "ThreatCampaignVersionsListResponse": { - "$ref": "#/components/schemas/VersionsList" - }, - "AttackSignatureVersionsListResponse": { - "$ref": "#/components/schemas/VersionsList" - }, - "BotSignatureVersionsListResponse": { - "$ref": "#/components/schemas/VersionsList" + "NapBulkResponse": { + "description": "The Nap policy bulk outcome.", + "type": "array", + "items": { + "$ref": "#/components/schemas/BulkRequestObjectStatus" + } }, - "NapPolicy": { - "description": "The base64-encoded contents of the NGINX App Protect policy.", - "type": "object", + "NapSignatureMeta": { "required": [ - "policy" + "signature_id", + "name", + "attack_type" ], "properties": { - "policy": { - "type": "string", - "format": "base64", - "maxLength": 3145728 + "name": { + "type": "string" + }, + "signature_id": { + "type": "integer" + }, + "attack_type": { + "type": "string" } } }, - "NapPolicyObject": { + "NapSignature": { + "description": "Detail information for NGINX App Protect signatures. Note: `description` is omitted for list operation.\n", "allOf": [ { - "$ref": "#/components/schemas/NapPolicyMetadata" + "$ref": "#/components/schemas/NapSignatureMeta" }, { - "$ref": "#/components/schemas/NapPolicyDeployments" + "type": "object", + "required": [ + "signature_type", + "risk", + "accuracy", + "has_cve", + "modified_at", + "systems" + ], + "properties": { + "accuracy": { + "default": "low", + "enum": [ + "high", + "low", + "medium" + ], + "x-enum-varnames": [ + "nap_signature_accuracy_high", + "nap_signature_accuracy_low", + "nap_signature_accuracy_medium" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "has_cve": { + "default": false, + "type": "boolean" + }, + "modified_at": { + "type": "string", + "format": "date-time", + "description": "The date and time when the signature was last modified." + }, + "references": { + "items": { + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "default": "nessus", + "enum": [ + "bugtraq", + "cve", + "nessus", + "url" + ], + "x-enum-varnames": [ + "nap_signature_references_type_bugtrag", + "nap_signature_references_type_cve", + "nap_signature_references_type_nessus", + "nap_signature_references_type_url" + ], + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "risk": { + "default": "low", + "enum": [ + "high", + "low", + "medium" + ], + "x-enum-varnames": [ + "nap_signature_risk_high", + "nap_signature_risk_low", + "nap_signature_risk_medium" + ], + "type": "string" + }, + "signature_type": { + "default": "request", + "enum": [ + "request", + "response" + ], + "type": "string", + "x-enum-varnames": [ + "nap_signature_signature_type_request", + "nap_signature_signature_type_response" + ] + }, + "systems": { + "items": { + "type": "string" + }, + "type": "array" + } + } } - ] + ], + "example": { + "signature_id": 123456789, + "name": "Example Signature", + "description": "This is an example signature.", + "signature_type": "request", + "attack_type": "SQL Injection", + "risk": "high", + "accuracy": "medium", + "has_cve": true, + "modified_at": "2023-10-01T12:00:00Z", + "references": [ + { + "type": "cve", + "value": "CVE-2023-12345" + } + ], + "systems": [ + "System A" + ] + } }, - "NapPolicyMetadata": { - "description": "Summary information about NGINX App Protect policy.", + "NapSignatureSet": { "type": "object", "required": [ "object_id", "name", - "latest" + "type", + "category", + "signature_count", + "accuracy", + "default_alarm", + "default_block", + "default_learn", + "systems", + "modified_at" ], "properties": { "object_id": { - "$ref": "#/components/schemas/NapPolicyObjectID" + "$ref": "#/components/schemas/NapSignatureSetObjectID" }, "name": { - "description": "The name of the NGINX App Protect policy.", "type": "string" }, - "description": { - "type": "string", - "description": "Some detail on the NGINX App Protect policy." + "accuracy": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "low", + "medium", + "high" + ], + "x-enum-varnames": [ + "nap_signature_set_accuracy_low", + "nap_signature_set_accuracy_medium", + "nap_signature_set_accuracy_high" + ] + } }, - "latest": { - "$ref": "#/components/schemas/NapPolicyVersionMetadata" - } - } - }, - "NapPolicyListResponse": { - "description": "List of all NGINX App Protect policies.", - "allOf": [ - { - "$ref": "#/components/schemas/PaginationResponse" + "signature_count": { + "type": "integer" }, - { - "description": "List of NGINX App Protect policies.", - "type": "object", - "required": [ - "items" + "category": { + "enum": [ + "User-defined", + "Basic", + "Attack Type Specific" + ], + "x-enum-varnames": [ + "nap_signature_set_category_user_defined", + "nap_signature_set_category_basic", + "nap_signature_set_category_attack_type_specific" ], + "type": "string" + }, + "default_alarm": { + "default": true, + "type": "boolean" + }, + "default_block": { + "default": true, + "type": "boolean" + }, + "default_learn": { + "default": true, + "type": "boolean" + }, + "filter": { "properties": { - "items": { - "description": "An array of NGINX App Protect policy objects.", - "type": "array", - "items": { - "$ref": "#/components/schemas/NapPolicyObject" - } - } - }, - "example": { - "items": [ - { - "object_id": "pol_-uvR3F2TQGm18jnl7bpaGw", - "name": "test-policy", - "description": "test policy", - "deployments": [ - { - "publication_object_id": "pub_-uvR3F2TQGm18jnl7bpaGw", - "associated_name": "test-instance", - "associated_type": "instance", - "associated_object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", - "status": "deployed", - "enforcement_mode": "blocking", - "policy_version": "2023-12-06 22:37:24", - "policy_version_object_id": "pv_-abc3F2TQGm18jnl7bpaGw", - "deployed_on": "2023-12-06T22:37:24.120114Z" - } - ], - "latest": { - "object_id": "pv_-uvR3F2TQGm18jnl7bpaGw", - "version": "2023-12-06 22:37:24", - "created_at": "2023-12-06T22:37:24.120114Z", - "deployment_status": "deployed", - "enforcement_mode": "blocking" + "accuracy_filter": { + "default": "ge", + "enum": [ + "all", + "eq", + "ge", + "le" + ], + "x-enum-varnames": [ + "nap_signature_set_filter_accuracy_filter_all", + "nap_signature_set_filter_accuracy_filter_eq", + "nap_signature_set_filter_accuracy_filter_ge", + "nap_signature_set_filter_accuracy_filter_le" + ], + "type": "string" + }, + "accuracy_value": { + "default": "all", + "enum": [ + "all", + "high", + "low", + "medium" + ], + "x-enum-varnames": [ + "nap_signature_set_filter_accuracy_value_all", + "nap_signature_set_filter_accuracy_value_high", + "nap_signature_set_filter_accuracy_value_low", + "nap_signature_set_filter_accuracy_value_medium" + ], + "type": "string" + }, + "attack_type": { + "properties": { + "name": { + "type": "string" } - } - ] - } - } - ] - }, - "NapPolicyVersionDeployments": { - "type": "object", - "properties": { - "deployments": { - "type": "array", - "items": { - "$ref": "#/components/schemas/NapPolicyVersionDeployment" - } - } - } - }, - "NapDeploymentAssociation": { - "type": "object", - "required": [ - "associated_type", - "associated_object_id", - "associated_name" - ], - "properties": { - "associated_type": { - "$ref": "#/components/schemas/DeploymentAssociatedType" + }, + "type": "object" + }, + "has_cve": { + "default": "all", + "enum": [ + "all", + "no", + "yes" + ], + "x-enum-varnames": [ + "nap_signature_set_filter_have_cve_all", + "nap_signature_set_filter_have_cve_no", + "nap_signature_set_filter_have_cve_yes" + ], + "type": "string" + }, + "modified_at_filter": { + "default": "all", + "enum": [ + "after", + "all", + "before" + ], + "x-enum-varnames": [ + "nap_signature_set_filter_modified_at_filter_after", + "nap_signature_set_filter_modified_at_filter_all", + "nap_signature_set_filter_modified_at_filter_before" + ], + "type": "string" + }, + "modified_at_value": { + "default": "1970-01-01", + "type": "string" + }, + "risk_filter": { + "default": "eq", + "enum": [ + "all", + "eq", + "ge", + "le" + ], + "x-enum-varnames": [ + "nap_signature_set_filter_risk_filter_all", + "nap_signature_set_filter_risk_filter_eq", + "nap_signature_set_filter_risk_filter_ge", + "nap_signature_set_filter_risk_filter_le" + ], + "type": "string" + }, + "risk_value": { + "default": "low", + "enum": [ + "all", + "high", + "low", + "medium" + ], + "x-enum-varnames": [ + "nap_signature_set_filter_risk_value_all", + "nap_signature_set_filter_risk_value_high", + "nap_signature_set_filter_risk_value_low", + "nap_signature_set_filter_risk_value_medium" + ], + "type": "string" + }, + "signature_type": { + "default": "request", + "enum": [ + "all", + "request", + "response" + ], + "x-enum-varnames": [ + "nap_signature_set_filter_signature_type_all", + "nap_signature_set_filter_signature_type_request", + "nap_signature_set_filter_signature_type_response" + ], + "type": "string" + }, + "user_defined_filter": { + "default": "all", + "enum": [ + "all", + "no", + "yes" + ], + "x-enum-varnames": [ + "nap_signature_set_filter_user_defined_filter_all", + "nap_signature_set_filter_user_defined_filter_no", + "nap_signature_set_filter_user_defined_filter_yes" + ], + "type": "string" + } + }, + "type": "object" }, - "associated_object_id": { - "$ref": "#/components/schemas/ObjectID" + "modified_at": { + "type": "string", + "format": "date-time", + "description": "The date and time when the signature-set was last modified." }, - "associated_name": { - "$ref": "#/components/schemas/DeploymentAssociatedName" + "systems": { + "items": { + "type": "string" + }, + "type": "array" + }, + "type": { + "default": "filter-based", + "enum": [ + "filter-based", + "manual" + ], + "x-enum-varnames": [ + "nap_signature_set_type_filter_based", + "nap_signature_set_type_manual" + ], + "type": "string" } + }, + "example": { + "default_block": true, + "default_learn": true, + "signature_count": 0, + "filter": { + "accuracy_value": "all", + "accuracy_filter": "all", + "attack_type": { + "name": "XML External Entities (XXE)" + }, + "risk_filter": "all", + "has_cve": "all", + "user_defined_filter": "all", + "risk_value": "all", + "modified_at_filter": "all", + "signature_type": "request" + }, + "assign_to_policy_by_default": false, + "default_alarm": true, + "accuracy": [], + "type": "filter-based", + "name": "XML External Entities (XXE) Signatures", + "object_id": "sigset_-ZMshmi83MBL97dr5d0a9w", + "category": "User-defined", + "modified_at": "2023-08-10T16:59:15Z", + "systems": [] } }, - "NapDeployment": { + "NapSignatureListResponse": { "allOf": [ { - "$ref": "#/components/schemas/NapDeploymentAssociation" + "$ref": "#/components/schemas/PaginationResponse" }, { "type": "object", - "description": "Information about a NGINX App Protect policy deployment.\n", "required": [ - "publication_object_id", - "status", - "deployed_on" + "items" ], "properties": { - "publication_object_id": { - "$ref": "#/components/schemas/PublicationObjectID" - }, - "status": { - "$ref": "#/components/schemas/NapDeploymentStatus" - }, - "deployed_on": { - "description": "Date and time of the deployment.", - "type": "string", - "format": "date-time" + "items": { + "description": "An array of NGINX App Protect signatures.", + "type": "array", + "items": { + "$ref": "#/components/schemas/NapSignature" + } } - }, - "example": { - "publication_object_id": "pub_-uvR3F2TQGm18jnl7bpaGw", - "associated_name": "test-instance", - "associated_type": "instance", - "associated_object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", - "status": "deployed", - "deployed_on": "2023-12-06T22:37:24.120114Z" } } ] }, - "NapPolicyVersionDeployment": { + "NapSignatureSetListResponse": { "allOf": [ { - "$ref": "#/components/schemas/NapDeploymentAssociation" + "$ref": "#/components/schemas/PaginationResponse" }, { "type": "object", - "description": "Information about a NGINX App Protect policy deployment.\n", "required": [ - "publication_object_id", - "status", - "deployed_on" + "items" ], "properties": { - "publication_object_id": { - "$ref": "#/components/schemas/PublicationObjectID" - }, - "status": { - "$ref": "#/components/schemas/NapDeploymentStatus" - }, - "deployed_on": { - "description": "Date and time of the deployment.", - "type": "string", - "format": "date-time" + "items": { + "description": "An array of NGINX App Protect signature sets.", + "type": "array", + "items": { + "$ref": "#/components/schemas/NapSignatureSet" + } } - }, - "example": { - "publication_object_id": "pub_-uvR3F2TQGm18jnl7bpaGw", - "associated_name": "test-instance", - "associated_type": "instance", - "associated_object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", - "status": "deployed", - "deployed_on": "2023-12-06T22:37:24.120114Z" } } ] }, - "NapPolicyDeployments": { - "type": "object", - "required": [ - "deployments" + "FilterNameNapLogProfile": { + "type": "string", + "description": "Keywords for NGINX App Protect log profile filters.\n", + "enum": [ + "name", + "object_id", + "deployment_status" ], - "properties": { - "deployments": { - "type": "array", - "items": { - "$ref": "#/components/schemas/NapPolicyDeployment" - } - } - } + "x-enum-varnames": [ + "filter_name_nap_log_profile_name", + "filter_name_nap_log_profile_object_id", + "filter_name_nap_log_profile_deployment_status" + ] }, - "NapLogProfileDeployments": { - "type": "object", - "properties": { - "deployments": { - "type": "array", - "items": { - "$ref": "#/components/schemas/NapLogProfileDeployment" - } - } + "IsF5Default": { + "type": "boolean", + "description": "Indicates whether this is an F5 default object (true) or a user-defined object (false)." + }, + "FilterNameNapLogProfileDeployment": { + "type": "string", + "description": "Keywords for NGINX App Protect log profile 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", + "status", + "object_id" + ], + "x-enum-varnames": [ + "filter_name_nap_deployment_name", + "filter_name_nap_deployment_type", + "filter_name_nap_deployment_status", + "filter_name_nap_deployment_object_id" + ] + }, + "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" + ] + }, + "NapGlobalSettingObjectID": { + "description": "A globally unique identifier for the App Protect global settings object.", + "type": "string", + "format": "object_id", + "pattern": "^gs_.*", + "x-go-type": "objects.ID", + "x-go-type-import": { + "name": "objects", + "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" } }, - "NapLogProfileDeployment": { - "description": "Detailed information about a NGINX App Protect log-profile deployment.", - "type": "object", - "allOf": [ - { - "$ref": "#/components/schemas/NapDeployment" - }, - { - "type": "object", - "required": [ - "nap_release", - "publication_object_id", - "associated_name", - "associated_type", - "associated_object_id", - "status", - "deployed_on" - ], - "properties": { - "nap_release": { - "description": "The compiler version of NGINX App Protect the log profile was deployed with.", - "type": "string" - }, - "latest_deployed": { - "$ref": "#/components/schemas/NapLatestDeployed" - } - } - } + "TemplateName": { + "type": "string", + "description": "The name of the template.\nMust be suitable for use as a file name and as an NGINX configuration include.\nOnly alphanumeric characters, underscores, dashes, and dots are allowed.\nNo spaces, slashes, or special characters.\n", + "minLength": 1, + "maxLength": 255, + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]*$", + "example": "reverse-proxy" + }, + "TemplateDescription": { + "type": "string", + "description": "A human-readable description of the template.", + "maxLength": 2048, + "example": "A base template for setting up a reverse proxy" + }, + "TemplateObjectID": { + "description": "A globally unique identifier for template.", + "type": "string", + "format": "object_id", + "pattern": "^tmpl_.*", + "x-go-type": "objects.ID", + "x-go-type-import": { + "name": "objects", + "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" + }, + "example": "tmpl_-uvR3F2TQGm18jnl7bpaGw" + }, + "TemplateVersionObjectID": { + "description": "A globally unique identifier for the template version.", + "type": "string", + "format": "object_id", + "pattern": "^tmplv_.*", + "x-go-type": "objects.ID", + "x-go-type-import": { + "name": "objects", + "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" + }, + "example": "tmplv_-ayR3F2TQGm18jnl7bpaGw" + }, + "TemplateType": { + "type": "string", + "description": "The type of the template.\n- `base`: A base template that defines the structure of an NGINX configuration.\n- `augment`: An augment template that extends or modifies an existing NGINX configuration defined by a base template.\n", + "enum": [ + "base", + "augment" ], - "example": { - "nap_release": "5.10.0", - "publication_object_id": "pub_-uvR3F2TQGm18jnl7bpaGw", - "associated_name": "test-instance", - "associated_type": "instance", - "associated_object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", - "status": "deployed", - "deployed_on": "2023-12-06T22:37:24.120114Z", - "latest_deployed": "yes" - } + "x-enum-varnames": [ + "template_type_base", + "template_type_augment" + ], + "example": "base" }, - "NapPolicyDeployment": { - "description": "Detailed information about a NGINX App Protect policy deployment.", - "type": "object", - "required": [ - "publication_object_id", - "associated_object_id", - "associated_name", - "associated_type", - "enforcement_mode", - "status", - "policy_version", - "policy_version_object_id", - "deployed_on" + "TemplateContextPath": { + "type": "string", + "description": "Specifies the full hierarchical context path within the NGINX configuration, using '/' as a separator.\n* \"main\": Refers to the top-level context of the NGINX configuration.\n* \"http\": Indicates the `http` block within the main context.\n* \"http/server\": Indicates the `server` block within the `http` context.\n* \"http/server/location\": Indicates the `location` block within the `server` context of the `http` block.\n* \"http/upstream\": Indicates the `upstream` block within the `http` context.\n* \"stream\": Indicates the `stream` block within the main context.\n* \"stream/server\": Indicates the `server` block within the `stream` context.\n* \"stream/upstream\": Indicates the `upstream` block within the `stream` context.\n", + "enum": [ + "main", + "http", + "http/server", + "http/server/location", + "http/upstream", + "stream", + "stream/server", + "stream/upstream" ], - "allOf": [ - { - "$ref": "#/components/schemas/NapPolicyVersionDeployment" - }, - { - "type": "object", - "required": [ - "enforcement_mode", - "policy_version", - "policy_version_object_id" - ], - "properties": { - "enforcement_mode": { - "$ref": "#/components/schemas/NapPolicyEnforcementMode" - }, - "policy_version": { - "description": "The version associated with the NGINX App Protect policy.", - "type": "string" - }, - "policy_version_object_id": { - "$ref": "#/components/schemas/NapPolicyVersionObjectID" - } - } - } + "x-enum-varnames": [ + "template_context_path_main", + "template_context_path_http", + "template_context_path_http_server", + "template_context_path_http_server_location", + "template_context_path_http_upstream", + "template_context_path_stream", + "template_context_path_stream_server", + "template_context_path_stream_upstream" ], - "example": { - "publication_object_id": "pub_-uvR3F2TQGm18jnl7bpaGw", - "associated_name": "test-instance", - "associated_type": "instance", - "associated_object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", - "status": "deployed", - "deployed_on": "2023-12-06T22:37:24.120114Z", - "enforcement_mode": "blocking", - "policy_version": "2023-12-06 22:37:24", - "policy_version_object_id": "pv_-abc3F2TQGm18jnl7bpaGw" - } + "example": "http/server/location" }, - "NapPolicyDeploymentDetails": { + "TemplateImportRequest": { "type": "object", + "description": "A request to import a template into the system. This can be either a *base template* or an *augment template*,\nas determined by the `type` field in the request body.\n\nBase templates define the structure of an NGINX configuration and may include hook points\nfor augment templates using custom Go template functions.\n\nAugment templates are reusable configuration snippets that can be applied to specific NGINX contexts\nwithin a base template, such as `http`, `http/server`, `stream` or `stream/server`.\n\nNginx One supports custom Go template functions for advanced configuration generation.\nSee [Template Functions](https://yourdocs.com/templates/functions) for a complete list of supported functions.\n", "required": [ - "publication_object_id", - "associated_object_id", - "associated_name", - "associated_type", - "enforcement_mode", - "status", - "policy_version", - "policy_version_object_id", - "deployed_on", - "threat_campaign_version", - "attack_signature_version", - "bot_signature_version" + "name", + "file", + "type" ], - "allOf": [ - { - "$ref": "#/components/schemas/NapPolicyDeployment" + "properties": { + "name": { + "$ref": "#/components/schemas/TemplateName" }, - { - "type": "object", - "properties": { - "threat_campaign_version": { - "$ref": "#/components/schemas/NapSignatureVersion" - }, - "attack_signature_version": { - "$ref": "#/components/schemas/NapSignatureVersion" - }, - "bot_signature_version": { - "$ref": "#/components/schemas/NapSignatureVersion" - } + "file": { + "type": "string", + "description": "A .tar.gz archive containing a template and any necessary supporting files for generating an NGINX configuration.\n\nThe archive must include the following at its root:\n- A template file (e.g., reverse_proxy_base.tmpl) written in valid Go template syntax for NGINX.\n- If the template uses input variables, a schema file is also required. This file defines and validates the expected input data.\n- The schema file could be a JSON schema or YAML (e.g., schema.json, schema.yaml).\n\nFile structure:\n├── reverse_proxy_base.tmpl # Required Go template file\n├── schema.json or schema.yaml # Required only if input variables are used\n", + "format": "binary", + "maxLength": 1000000, + "example": "template.tar.gz" + }, + "type": { + "$ref": "#/components/schemas/TemplateType" + }, + "description": { + "$ref": "#/components/schemas/TemplateDescription" + }, + "allowed_in_contexts": { + "type": "array", + "description": "Required when type is `augment`. Specifies the full hierarchical context path(s) within the NGINX configuration where the augment template output can be placed.\n", + "items": { + "$ref": "#/components/schemas/TemplateContextPath" } } - ], - "example": { - "publication_object_id": "pub_-uvR3F2TQGm18jnl7bpaGw", - "associated_name": "test-instance", - "associated_type": "instance", - "associated_object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", - "status": "deployed", - "policy_version": "2023-12-06 22:37:24", - "policy_version_object_id": "pv_-abc3F2TQGm18jnl7bpaGw", - "deployed_on": "2023-12-06T22:37:24.120114Z", - "enforcement_mode": "blocking", - "threat_campaign_version": "2023.12.06", - "attack_signature_version": "2023.12.06", - "bot_signature_version": "2023.12.06" } }, - "NapPolicyDeploymentsListResponse": { - "description": "List of all NGINX App Protect deployments.", + "TemplatesListResponse": { + "description": "List of all templates.", "allOf": [ { "$ref": "#/components/schemas/PaginationResponse" }, { + "description": "List of config templates.", "type": "object", "required": [ "items" ], "properties": { "items": { - "description": "An array of NGINX App Protect deployments.", + "description": "An array of templates.", "type": "array", "items": { - "$ref": "#/components/schemas/NapPolicyDeploymentDetails" + "$ref": "#/components/schemas/TemplateSummary" } } }, "example": { + "total": 101, + "count": 4, + "start_index": 1, + "items_per_page": 100, "items": [ { - "publication_object_id": "pub_-uvR3F2TQGm18jnl7bpaGw", - "associated_name": "test-instance", - "associated_type": "instance", - "associated_object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", - "status": "deployed", - "policy_version": "2023-12-06 22:37:24", - "policy_version_object_id": "pv_-abc3F2TQGm18jnl7bpaGw", - "deployed_on": "2023-12-06T22:37:24.120114Z", - "enforcement_mode": "blocking", - "threat_campaign_version": "2023.12.06", - "attack_signature_version": "2023.12.06", - "bot_signature_version": "2023.12.06" + "object_id": "tmpl_-uvR3F2TQGm18jnl7bpaGw", + "latest_template_version_object_id": "tmplv_-uvR3F2TQGm18jnl7bpaGw", + "version": 1, + "latest_version": 1, + "state": "final", + "name": "reverse-proxy", + "description": "A base template for setting up a reverse proxy", + "type": "base", + "allowed_in_contexts": [], + "augment_includes": [ + "http", + "http/server", + "http/upstream", + "http/server/location", + "stream", + "stream/upstream", + "stream/server" + ], + "created_at": "2026-09-01T12:00:00Z", + "modified_at": "2026-09-15T14:30:00Z" + }, + { + "object_id": "tmpl_-xeR3F2TQGm18jnl7bpaAw", + "latest_template_version_object_id": "tmplv_-xeR3F2TQGm18jnl7bpaAw", + "version": 1, + "latest_version": 1, + "state": "final", + "name": "gzip", + "description": "Augment template for enabling gzip compression", + "type": "augment", + "allowed_in_contexts": [ + "http", + "http/server" + ], + "augment_includes": [], + "created_at": "2026-09-01T12:00:00Z", + "modified_at": "2026-09-15T14:30:00Z" + }, + { + "object_id": "tmpl_-abR3F2TQGm18jnl7bpaXw", + "latest_template_version_object_id": "tmplv_-abR3F2TQGm18jnl7bpaXw", + "version": 1, + "latest_version": 1, + "state": "final", + "name": "rate-limiting-http", + "description": "Add rate limiting to HTTP requests", + "type": "augment", + "allowed_in_contexts": [ + "http", + "http/server" + ], + "augment_includes": [], + "created_at": "2026-09-01T12:00:00Z", + "modified_at": "2026-09-15T14:30:00Z" + }, + { + "object_id": "tmpl_-cdR3F2TQGm18jnl7bpaZw", + "latest_template_version_object_id": "tmplv_-cdR3F2TQGm18jnl7bpaZw", + "version": 1, + "latest_version": 1, + "state": "final", + "name": "limit-request", + "description": "Limit requests per second for a location", + "type": "augment", + "allowed_in_contexts": [ + "http/server/location" + ], + "augment_includes": [], + "created_at": "2026-09-01T12:00:00Z", + "modified_at": "2026-09-15T14:30:00Z" } ] } } ] }, - "NapLogProfileDeploymentsListResponse": { - "description": "List of all NGINX App Protect log profile deployments.", - "allOf": [ - { - "$ref": "#/components/schemas/PaginationResponse" - }, - { - "type": "object", - "required": [ - "items" - ], - "properties": { - "items": { - "description": "An array of NGINX App Protect log profile deployments.", - "type": "array", - "items": { - "$ref": "#/components/schemas/NapLogProfileDeployment" - } - } - }, - "example": { - "items": [ - { - "nap_release": "5.10.0", - "publication_object_id": "pub_-uvR3F2TQGm18jnl7bpaGw", - "associated_name": "test-instance", - "associated_type": "instance", - "associated_object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", - "status": "deployed", - "deployed_on": "2023-12-06T22:37:24.120114Z", - "latest_deployed": "yes" - } - ] - } - } - ] + "TemplateVersionState": { + "type": "string", + "description": "The state of a template version.\n- `draft`: Version is editable and not yet finalized.\n- `final`: Version is immutable and finalized. Version can't be transitioned back to draft.\n", + "enum": [ + "draft", + "final" + ], + "x-enum-varnames": [ + "template_version_state_draft", + "template_version_state_final" + ], + "example": "final" }, - "NapPolicyVersionMetadata": { + "TemplateVersionMetadata": { "type": "object", - "description": "Summary information about the specific NGINX App Protect policy version.", "required": [ + "created_at", + "modified_at", "object_id", + "latest_template_version_object_id", + "latest_version", "version", - "enforcement_mode", - "created_at" + "state" ], "properties": { + "created_at": { + "type": "string", + "format": "date-time", + "description": "The creation timestamp of the template." + }, + "modified_at": { + "type": "string", + "format": "date-time", + "description": "The last modification timestamp of the template." + }, "object_id": { - "$ref": "#/components/schemas/NapPolicyVersionObjectID" + "$ref": "#/components/schemas/TemplateObjectID" }, - "version": { - "$ref": "#/components/schemas/NapSignatureVersion" + "latest_template_version_object_id": { + "$ref": "#/components/schemas/TemplateVersionObjectID" }, - "enforcement_mode": { - "$ref": "#/components/schemas/NapPolicyEnforcementMode" + "latest_version": { + "type": "integer", + "description": "The latest version available for the template." }, - "created_at": { - "description": "The date and time when the NGINX App Protect policy version was created.", - "type": "string", - "format": "date-time" + "version": { + "type": "integer", + "description": "The version number of this template." + }, + "state": { + "$ref": "#/components/schemas/TemplateVersionState" } } }, - "NapPolicyVersionDetails": { - "description": "Detailed information about NGINX App Protect policy version.", + "TemplateSummaryBase": { + "description": "Base summary of a template object, including its metadata, allowed contexts and augment includes.\n", "type": "object", "required": [ - "policy", - "object_id", - "version", - "enforcement_mode", - "created_at" + "name", + "type", + "augment_includes" ], - "allOf": [ - { - "$ref": "#/components/schemas/NapPolicyVersionMetadata" + "properties": { + "name": { + "$ref": "#/components/schemas/TemplateName" }, - { - "$ref": "#/components/schemas/NapPolicy" + "type": { + "$ref": "#/components/schemas/TemplateType" }, - { - "$ref": "#/components/schemas/NapPolicyVersionDeployments" + "description": { + "$ref": "#/components/schemas/TemplateDescription" + }, + "allowed_in_contexts": { + "type": "array", + "description": "Specifies the full hierarchical context path(s) within the NGINX configuration where this template output can be placed.\n\nFor base templates, this list is empty. Instead, refer to `augment_includes` to see where augment output can be injected within the base template.\n", + "items": { + "$ref": "#/components/schemas/TemplateContextPath" + } + }, + "augment_includes": { + "type": "array", + "description": "Lists the explicit hierarchical context paths within the NGINX configuration where augment template output can be injected.\n\nEach entry corresponds to a location in the template where an `augment_includes` function is used, indicating a supported point for augment insertion (e.g., \"http/server\", \"stream/server\").\n", + "items": { + "$ref": "#/components/schemas/TemplateContextPath" + } } - ] + } }, - "NapPolicyVersionObject": { - "description": "Summary information about NGINX App Protect policy version.", + "TemplateSummary": { + "description": "A summary of a template object, including its metadata, allowed contexts and augment includes.\n", "allOf": [ { - "$ref": "#/components/schemas/NapPolicyVersionMetadata" + "$ref": "#/components/schemas/TemplateVersionMetadata" + }, + { + "$ref": "#/components/schemas/TemplateSummaryBase" + } + ], + "example": { + "object_id": "tmpl_-uvR3F2TQGm18jnl7bpaGw", + "latest_template_version_object_id": "tmplv_-uvR3F2TQGm18jnl7bpaGw", + "latest_version": 1, + "version": 1, + "state": "final", + "name": "reverse-proxy", + "description": "A base template for setting up a reverse proxy", + "type": "base", + "allowed_in_contexts": [], + "augment_includes": [ + "http", + "http/server", + "http/upstream", + "http/server/location" + ], + "created_at": "2023-09-01T12:00:00Z", + "modified_at": "2023-09-15T14:30:00Z" + } + }, + "TemplateFileData": { + "type": "object", + "description": "Details about the file in the template.\n", + "required": [ + "name", + "contents", + "file_type", + "file_format", + "mime_type", + "size", + "ctime" + ], + "properties": { + "name": { + "type": "string", + "description": "The name of a file inside a template archive (.tar.gz). File names must not be absolute paths or contain directory traversal components. For safety, leading slashes or \"..\" are not allowed.\n", + "minLength": 1, + "maxLength": 255, + "pattern": "^[a-zA-Z0-9_.\\-\\/]+$", + "example": "gzip-http.tmpl" + }, + "contents": { + "type": "string", + "description": "The contents of the file.\n- If `file_format` is \"plain\", this is a UTF-8 encoded string.\n- If `file_format` is \"bytes\", this is a Base64-encoded string.\n", + "maxLength": 1000000 + }, + "file_type": { + "type": "string", + "description": "The contents type of the file.\n* template: The file contains a Go template.\n* schema: The file contains a JSON or YAML schema for validating input data for the template. Optional if the template does not require input variables.\n", + "enum": [ + "template", + "schema" + ], + "x-enum-varnames": [ + "template_file_type_template", + "template_file_type_schema" + ] + }, + "file_format": { + "type": "string", + "description": "The encoding format of the contents in the file for transport.\n\n- `plain`: Human-readable content (plain UTF-8 string).\n- `bytes`: Base64-encoded binary content.\n", + "enum": [ + "plain", + "bytes" + ], + "x-enum-varnames": [ + "template_file_format_plain", + "template_file_format_bytes" + ] + }, + "mime_type": { + "type": "string", + "description": "The MIME type of the file, indicating its content type.\nFor example, `text/plain`, `application/json`, `application/gzip`.\n", + "enum": [ + "text/plain", + "application/json", + "application/yaml" + ] }, - { - "$ref": "#/components/schemas/NapPolicyVersionDeployments" + "size": { + "type": "integer", + "description": "The size of the file, in bytes." }, - { - "type": "object", - "required": [ - "latest" - ], - "properties": { - "latest": { - "description": "Indicates whether the NGINX App Protect policy version is latest. Default (`false`) returns the current policy. \nWhen set to `true`, returns the latest policy.\n", - "type": "boolean", - "default": false - } - } + "ctime": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the file was created." } - ] + }, + "example": { + "name": "nginx.tmpl", + "file_type": "template", + "file_format": "plain", + "mime_type": "text/plain", + "contents": "http {\n {{ augment_includes \"http\" . }}\n\n upstream backend {\n {{- range .upstream_servers }}\n server {{ . }};\n {{- end }}\n }\n\n server {\n listen 80;\n server_name {{ .server_name }};\n\n location / {\n proxy_pass {{ default \"http://backend\" .proxy_pass }};\n }\n }\n}", + "size": 345, + "ctime": "2026-09-01T12:00:00Z" + } }, - "NapPolicyVersionsListResponse": { - "description": "List of all NGINX App Protect versions.", + "TemplateCreationRequest": { + "description": "A request payload used to create a new template, including its metadata and associated file contents.", + "type": "object", "allOf": [ { - "$ref": "#/components/schemas/PaginationResponse" + "$ref": "#/components/schemas/TemplateSummaryBase" }, { "type": "object", @@ -12903,31 +15850,53 @@ ], "properties": { "items": { - "description": "An array of NGINX App Protect version objects.", + "description": "A list of files in the template.", "type": "array", "items": { - "$ref": "#/components/schemas/NapPolicyVersionObject" + "$ref": "#/components/schemas/TemplateFileData" } } - }, - "example": { - "items": [ - { - "version": "2023-12-06 22:37:24", - "object_id": "pv_-uvR3F2TQGm18jnl7bpaGw", - "created_at": "2023-12-06T22:37:24.120114Z", - "enforcement_mode": "blocking", - "latest": false - } - ] } } - ] + ], + "example": { + "name": "reverse-proxy", + "type": "base", + "allowed_in_contexts": [], + "augment_includes": [ + "http" + ], + "items": [ + { + "name": "nginx.tmpl", + "file_type": "template", + "file_format": "bytes", + "mime_type": "text/plain", + "contents": "aHR0cCB7XG4gIHt7IGF1Z21lbnRfaW5jbHVkZXMgXCJodHRwXCIgLiB9fVxuXG4gdXBzdHJlYW0gYmFja2VuZCB7XG4gIC17LSByYW5nZSAudXBzdHJlYW1fc2VydmVycyB9XG4gICAgc2VydmVyIHsgLiB9O1xuICB7LSBlbmQgfVxuIH1cblxuIHNlcnZlciB7XG4gIGxpc3RlbiA4MDtcbiAgc2VydmVyX25hbWUge3sgLnNlcnZlcl9uYW1lIH19O1xuXG4gIGxvY2F0aW9uIC8ge1xuICAgIHByb3h5X3Bhc3Mge3sgZGVmYXVsdCBcImh0dHA6Ly9iYWNrZW5kXCIgLnByb3h5X3Bhc3MgfX07XG4gIH1cbn1cbiIs", + "size": 1234, + "ctime": "2026-09-01T12:00:00Z" + }, + { + "name": "schema.json", + "file_type": "schema", + "file_format": "bytes", + "mime_type": "application/json", + "contents": "ewogICIkc2NoZW1hIjogImh0dHA6Ly9qc29uLXNjaGVtYS5vcmcvZHJhZnQtMDcvc2NoZW1hIyIsCiAgInR5cGUiOiAib2JqZWN0IiwKICAicHJvcGVydGllcyI6IHsKICAgICJ1cHN0cmVhbV9zZXJ2ZXJzIjogewogICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICJpdGVtcyI6IHsKICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICJmb3JtYXQiOiAiaG9zdG5hbWUiLAogICAgICAgICJwYXR0ZXJuIjogIl5bYS1aQS1aMC05Li1dKyg6WzAtOV0rKT8kIgogICAgICB9LAogICAgICAibWluSXRlbXMiOiAxCiAgICB9LAogICAgInNlcnZlcl9uYW1lIjogewogICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAicGF0dGVybiI6ICJeW2EtWkEtWjAtOS4tXSskIgogICAgfSwKICAgICJwcm94eV9wYXNzIjogewogICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAiZm9ybWF0IjogInVyaSIKICAgIH0KICB9LAogICJyZXF1aXJlZCI6IFsidXBzdHJlYW1fc2VydmVycyIsICJzZXJ2ZXJfbmFtZSJdLAogICJhZGRpdGlvbmFsUHJvcGVydGllcyI6IGZhbHNlCn0=", + "size": 456, + "ctime": "2026-09-01T12:00:00Z" + } + ] + } }, - "NapLogProfileListResponse": { + "TemplateDetailsResponse": { + "description": "Full detailed response about an existing template object including summary and file contents.", + "type": "object", "allOf": [ { - "$ref": "#/components/schemas/PaginationResponse" + "$ref": "#/components/schemas/TemplateVersionMetadata" + }, + { + "$ref": "#/components/schemas/TemplateSummaryBase" }, { "type": "object", @@ -12936,2462 +15905,2654 @@ ], "properties": { "items": { - "description": "An array of NGINX App Protect log profiles.", + "description": "A list of files in the template.", "type": "array", "items": { - "$ref": "#/components/schemas/NapLogProfileObject" + "$ref": "#/components/schemas/TemplateFileData" } } } } - ] + ], + "example": { + "object_id": "tmpl_-uvR3F2TQGm18jnl7bpaGw", + "created_at": "2026-09-01T12:00:00Z", + "modified_at": "2026-09-15T14:30:00Z", + "latest_template_version_object_id": "tmplv_-uvR3F2TQGm18jnl7bpaGw", + "version": 1, + "latest_version": 1, + "state": "final", + "name": "reverse-proxy", + "type": "base", + "allowed_in_contexts": [], + "augment_includes": [ + "http" + ], + "items": [ + { + "name": "nginx.tmpl", + "file_type": "template", + "file_format": "bytes", + "mime_type": "text/plain", + "contents": "aHR0cCB7XG4gIHt7IGF1Z21lbnRfaW5jbHVkZXMgXCJodHRwXCIgLiB9fVxuXG4gdXBzdHJlYW0gYmFja2VuZCB7XG4gIC17LSByYW5nZSAudXBzdHJlYW1fc2VydmVycyB9XG4gICAgc2VydmVyIHsgLiB9O1xuICB7LSBlbmQgfVxuIH1cblxuIHNlcnZlciB7XG4gIGxpc3RlbiA4MDtcbiAgc2VydmVyX25hbWUge3sgLnNlcnZlcl9uYW1lIH19O1xuXG4gIGxvY2F0aW9uIC8ge1xuICAgIHByb3h5X3Bhc3Mge3sgZGVmYXVsdCBcImh0dHA6Ly9iYWNrZW5kXCIgLnByb3h5X3Bhc3MgfX07XG4gIH1cbn1cbiIs", + "size": 1234, + "ctime": "2026-09-01T12:00:00Z" + }, + { + "name": "schema.json", + "file_type": "schema", + "file_format": "bytes", + "mime_type": "application/json", + "contents": "ewogICIkc2NoZW1hIjogImh0dHA6Ly9qc29uLXNjaGVtYS5vcmcvZHJhZnQtMDcvc2NoZW1hIyIsCiAgInR5cGUiOiAib2JqZWN0IiwKICAicHJvcGVydGllcyI6IHsKICAgICJ1cHN0cmVhbV9zZXJ2ZXJzIjogewogICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICJpdGVtcyI6IHsKICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICJmb3JtYXQiOiAiaG9zdG5hbWUiLAogICAgICAgICJwYXR0ZXJuIjogIl5bYS1aQS1aMC05Li1dKyg6WzAtOV0rKT8kIgogICAgICB9LAogICAgICAibWluSXRlbXMiOiAxCiAgICB9LAogICAgInNlcnZlcl9uYW1lIjogewogICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAicGF0dGVybiI6ICJeW2EtWkEtWjAtOS4tXSskIgogICAgfSwKICAgICJwcm94eV9wYXNzIjogewogICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAiZm9ybWF0IjogInVyaSIKICAgIH0KICB9LAogICJyZXF1aXJlZCI6IFsidXBzdHJlYW1fc2VydmVycyIsICJzZXJ2ZXJfbmFtZSJdLAogICJhZGRpdGlvbmFsUHJvcGVydGllcyI6IGZhbHNlCn0=", + "size": 456, + "ctime": "2026-09-01T12:00:00Z" + } + ] + } }, - "NapLogProfileObjectDetails": { - "allOf": [ - { - "$ref": "#/components/schemas/NapLogProfileObject" + "TemplateValuesRequest": { + "type": "object", + "description": "Key-value pairs for template rendering.", + "additionalProperties": true + }, + "TemplateSubmissionRequest": { + "type": "object", + "description": "Defines a request to render an NGINX configuration by combining a single base template \nwith zero or more augment templates.\n\n### Validations and Constraints:\n- All templates referenced by Object ID must be available in the system before submission.\n- Only one base template can be submitted.\n- The base template must explicitly use custom Go function `augment_includes (\"\", .)` to apply `augments`.\n- Its not required to include all augments in the request that base template supports.\n- The order of augments in the list determines the order in which they are rendered and applied.\n- Each augment must specify its `target_context`, indicating where it should be applied in \n the base template.\n- Input values for each template are passed independently via the `values` \n object, and validated against each template’s Schema.\n- The `payloads` for auxiliary files only accepts types of `managed_certificate` and `managed_key`.\n\n### Processing:\n- The `base_template` defines the starting point of the NGINX configuration rendering.\n- `conf_path` determines where the rendered configuration from base and augments should be placed within the NGINX directory structure.\n- Each `augment` template is applied in the order provided, inserted at the appropriate target context\n using the `augment_includes (\"\", .)` function declared in the base template.\n- The system validates that each augment is compatible with the specified target context.\n- The final composed configuration is validated to ensure correctness and prevent conflicts or misconfigurations.\n\n### External Template Documentation:\nFor more information on template functions and best practices, refer to:\n - [Template Function Reference](https://yourdocs.com/templates/functions)\n - [Template Authoring Guide](https://yourdocs.com/templates/guide)\n", + "required": [ + "conf_path", + "base_template", + "augments" + ], + "properties": { + "description": { + "type": "string", + "description": "Description of the submission, required when not rendering as preview only.", + "maxLength": 1024 }, - { - "type": "object", - "required": [ - "config" - ], - "properties": { - "config": { - "description": "The NGINX App Protect log profile configuration.", - "type": "string" - } + "target_object_ids": { + "type": "array", + "description": "The target object ID(s) for submitting the rendered configuration.\n", + "items": { + "$ref": "#/components/schemas/ObjectID" } }, - { - "type": "object", - "required": [ - "bundles" - ], - "properties": { - "bundles": { - "description": "Compiled NGINX APP Protect log profile bundles for this specific log profile. \nShows compilation status of the latest log profile contents across different NAP release versions.\n", - "type": "array", - "items": { - "$ref": "#/components/schemas/NapCompileStatus" - } - } + "conf_path": { + "$ref": "#/components/schemas/ConfigPath" + }, + "base_template": { + "$ref": "#/components/schemas/BaseTemplateSubmissionRequest" + }, + "augments": { + "type": "array", + "description": "Ordered list of augment templates to apply to the base template.\nAugments are rendered in the order provided.\n", + "items": { + "$ref": "#/components/schemas/AugmentTemplateSubmissionRequest" } + }, + "payloads": { + "$ref": "#/components/schemas/NginxConfigPayloads" } - ], + }, "example": { - "created_at": "2026-01-16T21:12:51.843434Z", - "hash": "oxiWKPqR/soi4MQCgVnW8KHt8Jk68AqCeQcQ1sed4Dk=", - "modified_at": "2026-01-16T21:12:51.843434Z", - "name": "test-log-profiles", - "object_id": "lp_XYxnZgVYQFKire4M1KcVVQ", - "config": "eyJsb2dfc3RyZWFtIjogIntmb3JtYXQgY29tYmluZWQgZXg=", - "deployments": [ - { - "nap_release": "5.10.0", - "publication_object_id": "pub_-uvR3F2TQGm18jnl7bpaGw", - "associated_name": "test-instance", - "associated_type": "instance", - "associated_object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", - "status": "deployed", - "deployed_on": "2023-12-06T22:37:24.120114Z", - "latest_deployed": "yes" + "conf_path": "/etc/nginx/nginx.conf", + "base_template": { + "object_id": "tmplv_-uvR3F2TQGm18jnl7bpaGw", + "values": { + "upstream_servers": [ + "10.0.0.1:8080", + "10.0.0.2:8080" + ], + "server_name": "example.com" } - ], - "bundles": [ + }, + "augments": [ { - "nap_release": "5.10.0", - "status": "succeeded", - "created_at": "2026-01-13T18:54:19.140336Z", - "modified_at": "2026-01-13T18:56:31.264956Z" + "object_id": "tmplv_-uvR3F2TQGm18jnl7bpaGw", + "target_context": "http/upstream", + "values": { + "upstream_servers": [ + "10.0.0.1:8080", + "10.0.0.2:8080" + ], + "server_name": "example.com" + } }, { - "nap_release": "5.9.0", - "status": "succeeded", - "created_at": "2026-01-13T18:54:19.140336Z", - "modified_at": "2026-01-13T18:56:31.264956Z" + "object_id": "tmplv_-xeR3F2TQGm18jnl7bpaAw", + "target_context": "http", + "values": { + "enabled": "on", + "types": "text/plain application/json" + } + }, + { + "object_id": "tmplv_-abR3F2TQGm18jnl7bpaXw", + "target_context": "http", + "values": { + "zone_name": "req_limit", + "memory": "10m", + "rate": "10r/s" + } + }, + { + "object_id": "tmplv_-cdR3F2TQGm18jnl7bpaZw", + "target_context": "http/server", + "values": { + "zone_name": "req_limit", + "burst": 5 + }, + "child_augments": [ + { + "object_id": "tmplv_-cdR3F2TQGm18jnl7bpaZw", + "target_context": "http/server/location", + "values": { + "zone_name": "req_limit", + "burst": 5 + } + } + ] } ] } }, - "NapLogProfileObject": { - "allOf": [ - { - "$ref": "#/components/schemas/NapLogProfileDeployments" + "BaseTemplateSubmissionRequest": { + "type": "object", + "required": [ + "object_id" + ], + "properties": { + "object_id": { + "$ref": "#/components/schemas/TemplateVersionObjectID" }, - { - "$ref": "#/components/schemas/NapLogProfileMetadata" + "values": { + "$ref": "#/components/schemas/TemplateValuesRequest" } - ], + }, "example": { - "created_at": "2026-01-16T21:12:51.843434Z", - "hash": "oxiWKPqR/soi4MQCgVnW8KHt8Jk68AqCeQcQ1sed4Dk=", - "modified_at": "2026-01-16T21:12:51.843434Z", - "name": "test-log-profiles", - "object_id": "lp_XYxnZgVYQFKire4M1KcVVQ", - "deployments": [ - { - "nap_release": "5.10.0", - "publication_object_id": "pub_-uvR3F2TQGm18jnl7bpaGw", - "associated_name": "test-instance", - "associated_type": "instance", - "associated_object_id": "inst_-uvR3F2TQGm18jnl7bpaGw", - "status": "deployed", - "deployed_on": "2023-12-06T22:37:24.120114Z", - "latest_deployed": "yes" - } - ] + "object_id": "tmplv_-uvR3F2TQGm18jnl7bpaGw", + "values": { + "upstream_servers": [ + "10.0.0.1:8080", + "10.0.0.2:8080" + ], + "server_name": "example.com" + } } }, - "NapLogProfileMetadata": { + "AugmentTemplateSubmissionRequest": { "type": "object", + "description": "Defines a request to apply an augment template to a specific target context within the base template.\n\nThis extends the `BaseTemplateSubmissionRequest`. Additionally adding,\n- `target_context`: Specifies the context within the base template where this augment should be applied.\n- `child_augments`: Optionally, an ordered list of nested augment templates to apply as children of this template.\n", "required": [ - "name", "object_id", - "hash", - "modified_at", - "created_at" + "target_context" ], "properties": { - "name": { - "type": "string", - "description": "The name of the NGINX App Protect log profile." - }, "object_id": { - "$ref": "#/components/schemas/NapLogProfileObjectID" - }, - "hash": { - "type": "string", - "description": "The hash value of the NGINX App Protect log profile configs." + "$ref": "#/components/schemas/TemplateVersionObjectID" }, - "description": { - "description": "Optional field to describe the NGINX App Protect log profile.", - "type": "string", - "minLength": 5, - "maxLength": 256 + "values": { + "$ref": "#/components/schemas/TemplateValuesRequest" }, - "created_at": { - "type": "string", - "format": "date-time", - "description": "The date and time when the log profile was created." + "target_context": { + "$ref": "#/components/schemas/TemplateContextPath" }, - "modified_at": { - "type": "string", - "format": "date-time", - "description": "The date and time when the log profile was last modified." + "child_augments": { + "type": "array", + "description": "Ordered list of nested augment templates to apply as children of this template.\n", + "items": { + "$ref": "#/components/schemas/AugmentTemplateSubmissionRequest" + } } - } - }, - "NapGlobalSettingsListResponse": { - "allOf": [ - { - "$ref": "#/components/schemas/PaginationResponse" + }, + "example": { + "object_id": "tmplv_-xeR3F2TQGm18jnl7bpaAw", + "target_context": "http/server", + "values": { + "enabled": "on", + "types": "text/plain application/json" }, - { - "type": "object", - "required": [ - "items" - ], - "properties": { - "items": { - "description": "An array of NGINX App Protect global settings.", - "type": "array", - "items": { - "$ref": "#/components/schemas/NapGlobalSettingMetadata" - } + "child_augments": [ + { + "object_id": "tmplv_-cdR3F2TQGm18jnl7bpaZw", + "target_context": "http/server/location", + "values": { + "zone_name": "req_limit", + "burst": 5 } } - } - ] + ] + } }, - "NapGlobalSettingGetResponse": { - "allOf": [ - { - "$ref": "#/components/schemas/NapGlobalSettingMetadata" + "PreviewNginxConfig": { + "type": "object", + "description": "The rendered NGINX configuration preview, along with any errors encountered during rendering.\n", + "required": [ + "config" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/NginxConfigObject" }, - { - "type": "object", - "required": [ - "config" - ], - "properties": { - "config": { - "description": "The NGINX App Protect global setting configuration.", - "type": "string" - } + "errors": { + "type": "array", + "description": "List of NGINX config parse errors encountered during rendering.", + "items": { + "$ref": "#/components/schemas/NginxConfigParseError" } } - ] + } }, - "NapGlobalSettingMetadata": { - "type": "object", + "TemplateSubmissionResponse": { + "description": "Details of a template submission and all target(s) status results.", "required": [ - "name", - "object_id" + "object_id", + "target_results" ], "properties": { - "name": { - "type": "string", - "description": "The name of the NGINX App Protect global setting object." - }, - "description": { - "description": "Optional field to describe the NGINX App Protect global setting object.", - "type": "string", - "minLength": 5, - "maxLength": 256 - }, "object_id": { - "$ref": "#/components/schemas/NapGlobalSettingObjectID" + "$ref": "#/components/schemas/ObjectID" + }, + "target_results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TemplateSubmissionTargetResult" + } } } }, - "NapLogProfileCreateRequest": { - "description": "Create NGINX App Protect log profile.", + "TemplateSubmissionTargetResult": { "type": "object", "required": [ - "name", - "config" + "target_object_id" ], "properties": { - "name": { - "description": "The name of the NGINX App Protect log profile.", - "type": "string", - "minLength": 1, - "maxLength": 128 + "target_object_id": { + "$ref": "#/components/schemas/ObjectID" }, - "description": { - "description": "Optional field to describe the NGINX App Protect log profile.", - "type": "string", - "minLength": 5, - "maxLength": 256 + "staged_config_status": { + "$ref": "#/components/schemas/StagedConfigSubmission" }, - "config": { - "description": "The NGINX App Protect log profile configuration.", - "type": "string", - "format": "base64", - "maxLength": 3145728 + "csg_publication_status": { + "$ref": "#/components/schemas/ConfigSyncGroupPublication" + }, + "instance_publication_status": { + "$ref": "#/components/schemas/PublicationInstance" } } }, - "NapLogProfileUpdateRequest": { - "description": "Update NGINX App Protect log profile.", + "NginxConfigParseError": { "type": "object", + "description": "Details about an error encountered during NGINX configuration rendering.", "required": [ - "config" + "file", + "error" ], "properties": { - "name": { - "description": "The name of the NGINX App Protect log profile.", + "file": { "type": "string", - "minLength": 1, - "maxLength": 128 + "description": "The name of the file where the error occurred." }, - "description": { - "description": "Optional field to describe describing the NGINX App Protect log profile.", - "type": "string", - "minLength": 5, - "maxLength": 256 + "line": { + "type": "integer", + "description": "The line number in the file where the error occurred." }, - "config": { - "description": "The NGINX App Protect log profile configuration.", + "error": { "type": "string", - "format": "base64", - "minLength": 5, - "maxLength": 3145728 + "description": "A human-readable error message describing the issue." } + }, + "example": { + "file": "nginx.conf", + "line": 1, + "error": "\"upstream\" directive is not allowed here in /etc/nginx/nginx.conf:1" } }, - "NapPolicyBulkRequest": { - "type": "array", - "items": { - "$ref": "#/components/schemas/NapPolicyBulkRequestData" + "TemplateSubmissionObjectID": { + "description": "A globally unique identifier for a template submission.", + "type": "string", + "format": "object_id", + "pattern": "^tmplsm_.*", + "x-go-type": "objects.ID", + "x-go-type-import": { + "name": "objects", + "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" }, - "minItems": 1, - "maxItems": 50, - "example": [ + "example": "tmplsm_frBobKIAQ_21grAwV83VYz" + }, + "TemplateSubmissionListResponse": { + "description": "List of template submissions.", + "allOf": [ { - "object_id": "pol_-uvR3F2TQGm18jnl7bpaGw", - "action": "delete" + "$ref": "#/components/schemas/PaginationResponse" }, { - "object_id": "pol_PL0c1XodRemmzVEjiXSsTg", - "action": "delete" + "description": "List of template submissions.", + "type": "object", + "required": [ + "items" + ], + "properties": { + "items": { + "description": "An array of template submissions.", + "type": "array", + "items": { + "$ref": "#/components/schemas/TemplateSubmissionSummary" + } + } + } } ] }, - "NapPolicyBulkRequestData": { + "TemplateSubmissionSummary": { + "description": "Summary of a template submission.", "type": "object", - "description": "Part of bulk operation on a Nap policy, only `delete` is supported.", "required": [ - "action", - "object_id" + "object_id", + "target_object_ids", + "created_at", + "modified_at", + "templates" ], "properties": { "object_id": { - "$ref": "#/components/schemas/NapPolicyObjectID" + "$ref": "#/components/schemas/TemplateSubmissionObjectID" }, - "action": { - "$ref": "#/components/schemas/BulkRequestAction" + "description": { + "type": "string", + "description": "Description of the submission." + }, + "target_object_ids": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ObjectID" + } + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "The creation timestamp of the submission." + }, + "modified_at": { + "type": "string", + "format": "date-time", + "description": "The last modification timestamp of the submission." + }, + "templates": { + "type": "array", + "description": "The templates associated with this submission (base + augments).", + "items": { + "$ref": "#/components/schemas/TemplateSubmissionTemplateSummary" + } } }, "example": { - "object_id": "pol_-uvR3F2TQGm18jnl7bpaGw", - "action": "delete" - } - }, - "NapBulkResponse": { - "description": "The Nap policy bulk outcome.", - "type": "array", - "items": { - "$ref": "#/components/schemas/BulkRequestObjectStatus" + "object_id": "tmplsm_frBobKIAQ_21grAwV83VYz", + "description": "Production reverse-proxy rollout", + "target_object_ids": [ + "sc_2CjPVkxoTcubUMOG9jD6yg" + ], + "created_at": "2023-09-01T12:00:00Z", + "modified_at": "2023-09-15T14:30:00Z", + "templates": [ + { + "template_object_id": "tmpl_-uvR3F2TQGm18jnl7bpaGw", + "template_version_object_id": "tmplv_kX9mR4pLSNqZwT1y6vHdJA", + "name": "reverse-proxy", + "type": "base", + "state": "final", + "version": 1, + "latest_version": 2, + "latest_template_version_object_id": "tmplv_Qm7nP8wKR2eYbA3x5cFgVw", + "allowed_in_contexts": [], + "augment_includes": [ + "http", + "http/server" + ], + "created_at": "2023-09-01T12:00:00Z", + "modified_at": "2023-09-15T14:30:00Z" + } + ] } }, - "NapSignatureMeta": { + "TemplateSubmissionTemplateSummary": { + "description": "A template entry within a submission, including the specific version used.", + "type": "object", "required": [ - "signature_id", + "template_object_id", + "template_version_object_id", "name", - "attack_type" + "type", + "state", + "version", + "latest_version", + "latest_template_version_object_id", + "created_at", + "modified_at" ], "properties": { + "template_object_id": { + "$ref": "#/components/schemas/TemplateObjectID" + }, + "template_version_object_id": { + "$ref": "#/components/schemas/TemplateVersionObjectID", + "description": "The specific template version used in this submission." + }, "name": { - "type": "string" + "type": "string", + "description": "The name of the template." }, - "signature_id": { - "type": "integer" + "description": { + "type": "string", + "description": "The description of the template." }, - "attack_type": { - "type": "string" - } - } - }, - "NapSignature": { - "description": "Detail information for NGINX App Protect signatures. Note: `description` is omitted for list operation.\n", - "allOf": [ - { - "$ref": "#/components/schemas/NapSignatureMeta" + "type": { + "$ref": "#/components/schemas/TemplateType" }, - { - "type": "object", - "required": [ - "signature_type", - "risk", - "accuracy", - "has_cve", - "modified_at", - "systems" - ], - "properties": { - "accuracy": { - "default": "low", - "enum": [ - "high", - "low", - "medium" - ], - "x-enum-varnames": [ - "nap_signature_accuracy_high", - "nap_signature_accuracy_low", - "nap_signature_accuracy_medium" - ], - "type": "string" - }, - "description": { - "type": "string" - }, - "has_cve": { - "default": false, - "type": "boolean" - }, - "modified_at": { - "type": "string", - "format": "date-time", - "description": "The date and time when the signature was last modified." - }, - "references": { - "items": { - "required": [ - "type", - "value" - ], - "properties": { - "type": { - "default": "nessus", - "enum": [ - "bugtraq", - "cve", - "nessus", - "url" - ], - "x-enum-varnames": [ - "nap_signature_references_type_bugtrag", - "nap_signature_references_type_cve", - "nap_signature_references_type_nessus", - "nap_signature_references_type_url" - ], - "type": "string" - }, - "value": { - "type": "string" - } - }, - "type": "object" - }, - "type": "array" - }, - "risk": { - "default": "low", - "enum": [ - "high", - "low", - "medium" - ], - "x-enum-varnames": [ - "nap_signature_risk_high", - "nap_signature_risk_low", - "nap_signature_risk_medium" - ], - "type": "string" - }, - "signature_type": { - "default": "request", - "enum": [ - "request", - "response" - ], - "type": "string", - "x-enum-varnames": [ - "nap_signature_signature_type_request", - "nap_signature_signature_type_response" - ] - }, - "systems": { - "items": { - "type": "string" - }, - "type": "array" - } + "state": { + "$ref": "#/components/schemas/TemplateVersionState" + }, + "version": { + "type": "integer", + "description": "The version number of the template version used in this submission." + }, + "latest_version": { + "type": "integer", + "description": "The latest version number generated for this template." + }, + "latest_template_version_object_id": { + "$ref": "#/components/schemas/TemplateVersionObjectID" + }, + "allowed_in_contexts": { + "type": "array", + "description": "The contexts this template is allowed in (augment templates only).", + "items": { + "$ref": "#/components/schemas/TemplateContextPath" } + }, + "augment_includes": { + "type": "array", + "description": "The augment context paths this template includes.", + "items": { + "$ref": "#/components/schemas/TemplateContextPath" + } + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "The creation timestamp of the template." + }, + "modified_at": { + "type": "string", + "format": "date-time", + "description": "The last modification timestamp of the template." } - ], + }, "example": { - "signature_id": 123456789, - "name": "Example Signature", - "description": "This is an example signature.", - "signature_type": "request", - "attack_type": "SQL Injection", - "risk": "high", - "accuracy": "medium", - "has_cve": true, - "modified_at": "2023-10-01T12:00:00Z", - "references": [ - { - "type": "cve", - "value": "CVE-2023-12345" - } + "template_object_id": "tmpl_-uvR3F2TQGm18jnl7bpaGw", + "template_version_object_id": "tmplv_kX9mR4pLSNqZwT1y6vHdJA", + "name": "reverse-proxy", + "description": "A base template for setting up a reverse proxy", + "type": "base", + "state": "final", + "version": 1, + "latest_version": 2, + "latest_template_version_object_id": "tmplv_Qm7nP8wKR2eYbA3x5cFgVw", + "allowed_in_contexts": [], + "augment_includes": [ + "http", + "http/server", + "http/upstream" ], - "systems": [ - "System A" - ] + "created_at": "2023-09-01T12:00:00Z", + "modified_at": "2023-09-15T14:30:00Z" } }, - "NapSignatureSet": { + "FilterNameTemplates": { + "type": "string", + "description": "Keywords for config templates filters.\n", + "enum": [ + "name", + "type", + "object_id", + "allowed_in_contexts" + ], + "x-enum-varnames": [ + "filter_name_templates_name", + "filter_name_templates_type", + "filter_name_templates_object_id", + "filter_name_templates_allowed_in_contexts" + ] + }, + "StagedConfigSubmission": { "type": "object", "required": [ - "object_id", - "name", - "type", - "category", - "signature_count", - "accuracy", - "default_alarm", - "default_block", - "default_learn", - "systems", - "modified_at" + "status" ], "properties": { "object_id": { - "$ref": "#/components/schemas/NapSignatureSetObjectID" + "$ref": "#/components/schemas/StagedConfigObjectID" }, "name": { "type": "string" }, - "accuracy": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "low", - "medium", - "high" - ], - "x-enum-varnames": [ - "nap_signature_set_accuracy_low", - "nap_signature_set_accuracy_medium", - "nap_signature_set_accuracy_high" - ] - } - }, - "signature_count": { - "type": "integer" - }, - "category": { + "status": { + "description": "Submission status for the staged config:\n* `failed` - The submission failed.\n* `succeeded` - The submission was successful.\n", + "type": "string", "enum": [ - "User-defined", - "Basic", - "Attack Type Specific" + "failed", + "succeeded" ], "x-enum-varnames": [ - "nap_signature_set_category_user_defined", - "nap_signature_set_category_basic", - "nap_signature_set_category_attack_type_specific" - ], - "type": "string" - }, - "default_alarm": { - "default": true, - "type": "boolean" - }, - "default_block": { - "default": true, - "type": "boolean" - }, - "default_learn": { - "default": true, - "type": "boolean" + "staged_config_status_failed", + "staged_config_status_succeeded" + ] }, - "filter": { - "properties": { - "accuracy_filter": { - "default": "ge", - "enum": [ - "all", - "eq", - "ge", - "le" - ], - "x-enum-varnames": [ - "nap_signature_set_filter_accuracy_filter_all", - "nap_signature_set_filter_accuracy_filter_eq", - "nap_signature_set_filter_accuracy_filter_ge", - "nap_signature_set_filter_accuracy_filter_le" - ], - "type": "string" - }, - "accuracy_value": { - "default": "all", - "enum": [ - "all", - "high", - "low", - "medium" - ], - "x-enum-varnames": [ - "nap_signature_set_filter_accuracy_value_all", - "nap_signature_set_filter_accuracy_value_high", - "nap_signature_set_filter_accuracy_value_low", - "nap_signature_set_filter_accuracy_value_medium" - ], - "type": "string" - }, - "attack_type": { - "properties": { - "name": { - "type": "string" - } - }, - "type": "object" - }, - "has_cve": { - "default": "all", - "enum": [ - "all", - "no", - "yes" - ], - "x-enum-varnames": [ - "nap_signature_set_filter_have_cve_all", - "nap_signature_set_filter_have_cve_no", - "nap_signature_set_filter_have_cve_yes" - ], - "type": "string" - }, - "modified_at_filter": { - "default": "all", - "enum": [ - "after", - "all", - "before" - ], - "x-enum-varnames": [ - "nap_signature_set_filter_modified_at_filter_after", - "nap_signature_set_filter_modified_at_filter_all", - "nap_signature_set_filter_modified_at_filter_before" - ], - "type": "string" - }, - "modified_at_value": { - "default": "1970-01-01", - "type": "string" - }, - "risk_filter": { - "default": "eq", - "enum": [ - "all", - "eq", - "ge", - "le" - ], - "x-enum-varnames": [ - "nap_signature_set_filter_risk_filter_all", - "nap_signature_set_filter_risk_filter_eq", - "nap_signature_set_filter_risk_filter_ge", - "nap_signature_set_filter_risk_filter_le" - ], - "type": "string" - }, - "risk_value": { - "default": "low", - "enum": [ - "all", - "high", - "low", - "medium" - ], - "x-enum-varnames": [ - "nap_signature_set_filter_risk_value_all", - "nap_signature_set_filter_risk_value_high", - "nap_signature_set_filter_risk_value_low", - "nap_signature_set_filter_risk_value_medium" - ], - "type": "string" - }, - "signature_type": { - "default": "request", - "enum": [ - "all", - "request", - "response" - ], - "x-enum-varnames": [ - "nap_signature_set_filter_signature_type_all", - "nap_signature_set_filter_signature_type_request", - "nap_signature_set_filter_signature_type_response" - ], - "type": "string" - }, - "user_defined_filter": { - "default": "all", - "enum": [ - "all", - "no", - "yes" - ], - "x-enum-varnames": [ - "nap_signature_set_filter_user_defined_filter_all", - "nap_signature_set_filter_user_defined_filter_no", - "nap_signature_set_filter_user_defined_filter_yes" - ], - "type": "string" - } - }, - "type": "object" + "status_cause": { + "type": "string", + "example": "staged config does not exist" + } + } + }, + "EventRequestOutcome": { + "type": "string", + "description": "Binary outcome of WAF processing for the request.", + "enum": [ + "passed", + "rejected" + ], + "x-enum-varnames": [ + "request_outcome_passed", + "request_outcome_rejected" + ] + }, + "SignatureAccuracy": { + "type": "string", + "description": "Confidence level that the signature accurately identifies the attack.", + "enum": [ + "low", + "medium", + "high" + ], + "x-enum-varnames": [ + "signature_accuracy_low", + "signature_accuracy_medium", + "signature_accuracy_high" + ] + }, + "SignatureRisk": { + "type": "string", + "description": "Risk level of the attack identified by the signature.", + "enum": [ + "low", + "medium", + "high", + "critical" + ], + "x-enum-varnames": [ + "signature_risk_low", + "signature_risk_medium", + "signature_risk_high", + "signature_risk_critical" + ] + }, + "RequestStatus": { + "type": "string", + "description": "WAF enforcement decision for the request.", + "enum": [ + "blocked", + "alerted", + "passed" + ], + "x-enum-varnames": [ + "request_status_blocked", + "request_status_alerted", + "request_status_passed" + ] + }, + "AttacksDimensionField": { + "type": "string", + "description": "Available dimensions for grouping and filtering attack analytics.\n", + "enum": [ + "request_status", + "request_outcome_reason", + "request_method", + "ip", + "country", + "policy", + "url", + "response_code", + "hostname", + "threat_campaign" + ], + "x-enum-varnames": [ + "attacks_dimension_request_status", + "attacks_dimension_request_outcome_reason", + "attacks_dimension_request_method", + "attacks_dimension_ip", + "attacks_dimension_country", + "attacks_dimension_policy", + "attacks_dimension_url", + "attacks_dimension_response_code", + "attacks_dimension_hostname", + "attacks_dimension_threat_campaign" + ] + }, + "AttacksTimeSeriesDimensionField": { + "type": "string", + "description": "Dimensions available for time-series grouping.\nLimited to fixed enum dimensions that can be efficiently aggregated per time bucket.\n", + "enum": [ + "request_status", + "request_outcome_reason" + ], + "x-enum-varnames": [ + "attacks_ts_dimension_request_status", + "attacks_ts_dimension_request_outcome_reason" + ] + }, + "Resolution": { + "type": "string", + "description": "Time bucket size for aggregation. Defaults to `1h` when not specified.\nPick a value that yields a reasonable number of buckets for the\nrequested time range (e.g. `30m` for 24h, `2h` for 7d, `12h` for 30d).\n", + "enum": [ + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "4h", + "6h", + "12h", + "1d" + ], + "x-enum-varnames": [ + "resolution_1m", + "resolution_5m", + "resolution_15m", + "resolution_30m", + "resolution_1h", + "resolution_2h", + "resolution_4h", + "resolution_6h", + "resolution_12h", + "resolution_1d" + ], + "example": "15m" + }, + "FilterOperator": { + "type": "string", + "description": "Filter operators that can be applied to a given list of dimension values.\n* `=` - Equals (uses first value only)\n* `!=` - Not equals (uses first value only)\n* `in` - Value is in the list (uses all values)\n* `not` - Value is not in the list (uses all values)\n", + "enum": [ + "=", + "!=", + "in", + "not" + ], + "x-enum-varnames": [ + "filter_operator_equal", + "filter_operator_not_equal", + "filter_operator_in", + "filter_operator_not" + ] + }, + "SortOrderDirection": { + "type": "string", + "description": "Sort direction for query results.", + "enum": [ + "asc", + "desc" + ], + "default": "desc", + "x-enum-varnames": [ + "order_direction_asc", + "order_direction_desc" + ] + }, + "AnalyticsFilterField": { + "type": "string", + "description": "Field names available for filtering analytics queries.\nThis is a superset of all group_by dimensions. You can filter by any field,\neven when not grouping by it.\n", + "enum": [ + "request_outcome", + "request_outcome_reason", + "request_method", + "response_code", + "ip", + "country", + "url", + "policy", + "instance_object_id", + "csg_object_id", + "threat_campaign", + "hostname", + "request_host", + "support_id", + "violation_rating", + "request_status", + "accuracy", + "risk", + "signature_id", + "signature_name", + "cve", + "violation", + "sub_violation", + "context", + "context_key", + "context_value" + ], + "x-enum-varnames": [ + "analytics_filter_field_request_outcome", + "analytics_filter_field_request_outcome_reason", + "analytics_filter_field_request_method", + "analytics_filter_field_response_code", + "analytics_filter_field_ip", + "analytics_filter_field_country", + "analytics_filter_field_url", + "analytics_filter_field_policy", + "analytics_filter_field_instance_object_id", + "analytics_filter_field_csg_object_id", + "analytics_filter_field_threat_campaign", + "analytics_filter_field_hostname", + "analytics_filter_field_request_host", + "analytics_filter_field_support_id", + "analytics_filter_field_violation_rating", + "analytics_filter_field_request_status", + "analytics_filter_field_accuracy", + "analytics_filter_field_risk", + "analytics_filter_field_signature_id", + "analytics_filter_field_signature_name", + "analytics_filter_field_cve", + "analytics_filter_field_violation", + "analytics_filter_field_sub_violation", + "analytics_filter_field_context", + "analytics_filter_field_context_key", + "analytics_filter_field_context_value" + ] + }, + "AnalyticsFilter": { + "type": "object", + "description": "A single filter condition.\nGeneric schema supporting both attacks and signature analytics filtering.\n", + "required": [ + "field", + "operator", + "values" + ], + "properties": { + "field": { + "$ref": "#/components/schemas/AnalyticsFilterField" }, - "modified_at": { - "type": "string", - "format": "date-time", - "description": "The date and time when the signature-set was last modified." + "operator": { + "$ref": "#/components/schemas/FilterOperator" }, - "systems": { + "values": { + "type": "array", + "description": "Values to filter by.\n- For `=` and `!=`: only the first value is used\n- For `in` and `not`: all values are used\n", "items": { "type": "string" }, - "type": "array" - }, - "type": { - "default": "filter-based", + "minItems": 1, + "example": [ + "blocked" + ] + } + } + }, + "AnalyticsOrderBy": { + "type": "object", + "description": "Specifies the sort order for dynamic dimension results.\n", + "properties": { + "field": { + "type": "string", + "description": "Field to sort by.\n- `count`: Sort by count (default)\n- `value`: Sort alphabetically by field value\n", "enum": [ - "filter-based", - "manual" - ], - "x-enum-varnames": [ - "nap_signature_set_type_filter_based", - "nap_signature_set_type_manual" + "count", + "value" ], - "type": "string" + "default": "count" + }, + "direction": { + "$ref": "#/components/schemas/SortOrderDirection" } }, "example": { - "default_block": true, - "default_learn": true, - "signature_count": 0, - "filter": { - "accuracy_value": "all", - "accuracy_filter": "all", - "attack_type": { - "name": "XML External Entities (XXE)" - }, - "risk_filter": "all", - "has_cve": "all", - "user_defined_filter": "all", - "risk_value": "all", - "modified_at_filter": "all", - "signature_type": "request" + "field": "count", + "direction": "desc" + } + }, + "BaseQueryRequest": { + "type": "object", + "description": "Base query request with common fields for both attacks and signature analytics.\nShared properties for all analytical query types.\n", + "required": [ + "start_time" + ], + "properties": { + "start_time": { + "type": "string", + "description": "Beginning of the time range (inclusive).\nAccepts ISO 8601 format (`2024-01-15T00:00:00Z`) or relative offset (`now-24h`, `now-1d`).\n", + "example": "now-24h" }, - "assign_to_policy_by_default": false, - "default_alarm": true, - "accuracy": [], - "type": "filter-based", - "name": "XML External Entities (XXE) Signatures", - "object_id": "sigset_-ZMshmi83MBL97dr5d0a9w", - "category": "User-defined", - "modified_at": "2023-08-10T16:59:15Z", - "systems": [] + "end_time": { + "type": "string", + "description": "End of the time range (exclusive).\nAccepts ISO 8601 format (`2024-01-15T00:00:00Z`) or relative offset (`now-24h`, `now-1d`).\n", + "default": "now", + "example": "now" + }, + "limit": { + "type": "integer", + "description": "Maximum items per dynamic dimension array (1-1000).\nDoes not apply to fixed enum dimensions.\n", + "minimum": 1, + "maximum": 1000, + "default": 100, + "example": 10 + } } }, - "NapSignatureListResponse": { + "AttacksQueryRequest": { "allOf": [ { - "$ref": "#/components/schemas/PaginationResponse" + "$ref": "#/components/schemas/BaseQueryRequest" }, { "type": "object", - "required": [ - "items" - ], + "description": "Request body for querying attack analytics.\n", "properties": { - "items": { - "description": "An array of NGINX App Protect signatures.", + "group_by": { + "allOf": [ + { + "$ref": "#/components/schemas/AttacksDimensionField" + }, + { + "description": "Dimension to aggregate results by.\n\n**Fixed enum dimensions** (returned as objects with known keys):\n* `request_status` - blocked, alerted, passed\n* `request_method` - GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH\n\n**Simple array dimensions** (returned as arrays with code/count):\n* `response_code` - HTTP response codes\n\n**Dynamic dimensions** (returned as arrays with cross-dimension context):\n* `ip`, `country`, `policy`, `url`, `hostname`\n\n**Response behavior:**\n- If omitted: Returns `total` count only\n- If specified: Returns dimensional breakdown, `total` is omitted\n", + "example": "request_status" + } + ] + }, + "filter": { "type": "array", + "description": "Pre-aggregation filter conditions.\nAll filters are combined with AND logic.\nUse the `in` operator to achieve `OR` within a single dimension.\n", "items": { - "$ref": "#/components/schemas/NapSignature" - } + "$ref": "#/components/schemas/AnalyticsFilter" + }, + "default": [] + }, + "order_by": { + "$ref": "#/components/schemas/AnalyticsOrderBy" } } } ] }, - "NapSignatureSetListResponse": { + "AttacksTimeSeriesQueryRequest": { "allOf": [ { - "$ref": "#/components/schemas/PaginationResponse" + "$ref": "#/components/schemas/BaseQueryRequest" }, { "type": "object", - "required": [ - "items" - ], + "description": "Request body for querying attack analytics time series.\n", "properties": { - "items": { - "description": "An array of NGINX App Protect signature sets.", + "resolution": { + "$ref": "#/components/schemas/Resolution" + }, + "group_by": { + "allOf": [ + { + "$ref": "#/components/schemas/AttacksTimeSeriesDimensionField" + }, + { + "description": "Dimension to break down time-series by.\nLimited to fixed enum dimensions for performance.\n\n* `request_status` - Returns `blocked`, `alerted`, `passed` series\n* `request_outcome_reason` - Returns the underlying reason for the outcome.\n\n**Common `request_outcome_reason` values:**\n- `SECURITY_WAF_OK`: Legitimate request, no violations.\n- `SECURITY_WAF_VIOLATION`: Request blocked due to signature or protocol violation.\n- `SECURITY_WAF_FLAGGED`: Violation detected, but request allowed (Transparent/Alert-only mode).\n- `SECURITY_WAF_VIOLATION_TRANSPARENT`: Request would have been blocked, but the policy/signature is in staging/transparent mode.\n- `SECURITY_NGINX_VIOLATION`: Request rejected due to NGINX-level constraints (e.g., malformed headers).\n- `SECURITY_WAF_BYPASS`: Request was explicitly allowed due to an allow-list or bypass rule.\n\n**Response behavior:**\n- If omitted: Returns `total` series only\n- If specified: Returns dimensional breakdown, `total` is omitted\n", + "example": "request_status" + } + ] + }, + "filter": { "type": "array", + "description": "Pre-aggregation filter conditions.\nAll filters are combined with AND logic.\nUse the `in` operator to achieve `OR` within a single dimension.\n", "items": { - "$ref": "#/components/schemas/NapSignatureSet" - } + "$ref": "#/components/schemas/AnalyticsFilter" + }, + "default": [] } } } ] }, - "FilterNameNapLogProfile": { - "type": "string", - "description": "Keywords for NGINX App Protect log profile filters.\n", - "enum": [ - "name", - "object_id", - "deployment_status" - ], - "x-enum-varnames": [ - "filter_name_nap_log_profile_name", - "filter_name_nap_log_profile_object_id", - "filter_name_nap_log_profile_deployment_status" - ] - }, - "FilterNameNapLogProfileDeployment": { - "type": "string", - "description": "Keywords for NGINX App Protect log profile 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", - "status", - "object_id" - ], - "x-enum-varnames": [ - "filter_name_nap_deployment_name", - "filter_name_nap_deployment_type", - "filter_name_nap_deployment_status", - "filter_name_nap_deployment_object_id" - ] - }, - "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" - ] - }, - "NapGlobalSettingObjectID": { - "description": "A globally unique identifier for the App Protect global settings object.", - "type": "string", - "format": "object_id", - "pattern": "^gs_.*", - "x-go-type": "objects.ID", - "x-go-type-import": { - "name": "objects", - "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" + "QueryMetadata": { + "type": "object", + "description": "Query metadata returned with analytics responses.\nReflects the actual time range and resolution used for the query.\n", + "properties": { + "start_time": { + "type": "string", + "format": "date-time", + "description": "The start of the query time range (inclusive)." + }, + "end_time": { + "type": "string", + "format": "date-time", + "description": "The end of the query time range (exclusive)." + }, + "resolution": { + "allOf": [ + { + "$ref": "#/components/schemas/Resolution" + }, + { + "description": "The time bucket size used for time-series queries.\nOnly present in time-series responses.\n" + } + ] + } + }, + "example": { + "start_time": "2024-01-15T00:00:00Z", + "end_time": "2024-01-15T23:59:59Z", + "resolution": "1h" } }, - "TemplateName": { - "type": "string", - "description": "The name of the template.\nMust be suitable for use as a file name and as an NGINX configuration include.\nOnly alphanumeric characters, underscores, dashes, and dots are allowed.\nNo spaces, slashes, or special characters.\n", - "minLength": 1, - "maxLength": 255, - "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]*$", - "example": "reverse-proxy" + "RequestStatusCountsResponse": { + "type": "object", + "description": "Attack counts grouped by WAF enforcement status.\nEach property represents a distinct status with its count.\n", + "properties": { + "blocked": { + "type": "integer", + "description": "Count of attacks that were blocked by the WAF." + }, + "alerted": { + "type": "integer", + "description": "Count of attacks that were alerted but not blocked (transparent mode)." + }, + "passed": { + "type": "integer", + "description": "Count of attacks that passed through with no violations." + } + }, + "example": { + "blocked": 1200, + "alerted": 200, + "passed": 100 + } }, - "TemplateDescription": { - "type": "string", - "description": "A human-readable description of the template.", - "example": "A base template for setting up a reverse proxy" + "RequestOutcomeReasonCountsResponse": { + "type": "object", + "description": "Total counts grouped by the underlying request outcome reason for the enforcement decision.\n", + "properties": { + "SECURITY_WAF_OK": { + "type": "integer", + "description": "Total requests passed with no security violations.", + "example": 1024 + }, + "SECURITY_WAF_VIOLATION": { + "type": "integer", + "description": "Total requests blocked due to a policy or signature violation.", + "example": 88 + }, + "SECURITY_WAF_FLAGGED": { + "type": "integer", + "description": "Total violations detected but allowed (Policy in Transparent/Alert mode).", + "example": 11 + }, + "SECURITY_WAF_VIOLATION_TRANSPARENT": { + "type": "integer", + "description": "Total violations detected but allowed (Individual signature in Staging).", + "example": 2 + }, + "SECURITY_NGINX_VIOLATION": { + "type": "integer", + "description": "Total requests rejected due to NGINX-level parsing errors.", + "example": 5 + }, + "SECURITY_WAF_BYPASS": { + "type": "integer", + "description": "Total requests explicitly allowed via allow-lists or bypass rules.", + "example": 0 + } + } }, - "TemplateObjectID": { - "description": "A globally unique identifier for template.", - "type": "string", - "format": "object_id", - "pattern": "^tmpl_.*", - "x-go-type": "objects.ID", - "x-go-type-import": { - "name": "objects", - "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" + "RequestMethodCountsResponse": { + "type": "object", + "description": "Attack counts grouped by HTTP request method.\nEach property represents an HTTP method with its count.\n", + "properties": { + "get": { + "type": "integer", + "description": "Count of attacks using GET method." + }, + "post": { + "type": "integer", + "description": "Count of attacks using POST method." + }, + "put": { + "type": "integer", + "description": "Count of attacks using PUT method." + }, + "delete": { + "type": "integer", + "description": "Count of attacks using DELETE method." + }, + "patch": { + "type": "integer", + "description": "Count of attacks using PATCH method." + }, + "connect": { + "type": "integer", + "description": "Count of attacks using CONNECT method." + }, + "head": { + "type": "integer", + "description": "Count of attacks using HEAD method." + }, + "options": { + "type": "integer", + "description": "Count of attacks using OPTIONS method." + }, + "trace": { + "type": "integer", + "description": "Count of attacks using TRACE method." + } }, - "example": "tmpl_-uvR3F2TQGm18jnl7bpaGw" + "example": { + "get": 800, + "post": 500, + "put": 50 + } }, - "TemplateVersionObjectID": { - "description": "A globally unique identifier for the template version.", - "type": "string", - "format": "object_id", - "pattern": "^tmplv_.*", - "x-go-type": "objects.ID", - "x-go-type-import": { - "name": "objects", - "path": "gitlab.com/f5/nginx/one/saas/control-plane/pkg/collections/objects" + "AccuracyCountsResponse": { + "type": "object", + "description": "Signature hit counts grouped by accuracy level.\nEach property represents an accuracy level with its count.\n", + "properties": { + "low": { + "type": "integer", + "description": "Count of signature hits with low accuracy." + }, + "medium": { + "type": "integer", + "description": "Count of signature hits with medium accuracy." + }, + "high": { + "type": "integer", + "description": "Count of signature hits with high accuracy." + } }, - "example": "tmplv_-ayR3F2TQGm18jnl7bpaGw" - }, - "TemplateType": { - "type": "string", - "description": "The type of the template.\n- `base`: A base template that defines the structure of an NGINX configuration.\n- `augment`: An augment template that extends or modifies an existing NGINX configuration defined by a base template.\n", - "enum": [ - "base", - "augment" - ], - "x-enum-varnames": [ - "template_type_base", - "template_type_augment" - ], - "example": "base" + "example": { + "low": 150, + "medium": 420, + "high": 700 + } }, - "TemplateContextPath": { - "type": "string", - "description": "Specifies the full hierarchical context path within the NGINX configuration, using '/' as a separator.\n* \"main\": Refers to the top-level context of the NGINX configuration.\n* \"http\": Indicates the `http` block within the main context.\n* \"http/server\": Indicates the `server` block within the `http` context.\n* \"http/server/location\": Indicates the `location` block within the `server` context of the `http` block.\n* \"http/upstream\": Indicates the `upstream` block within the `http` context.\n* \"stream\": Indicates the `stream` block within the main context.\n* \"stream/server\": Indicates the `server` block within the `stream` context.\n* \"stream/upstream\": Indicates the `upstream` block within the `stream` context.\n", - "enum": [ - "main", - "http", - "http/server", - "http/server/location", - "http/upstream", - "stream", - "stream/server", - "stream/upstream" - ], - "x-enum-varnames": [ - "template_context_path_main", - "template_context_path_http", - "template_context_path_http_server", - "template_context_path_http_server_location", - "template_context_path_http_upstream", - "template_context_path_stream", - "template_context_path_stream_server", - "template_context_path_stream_upstream" + "RiskCountsResponse": { + "type": "object", + "description": "Signature hit counts grouped by risk level.\nEach property represents a risk level with its count.\n", + "properties": { + "low": { + "type": "integer", + "description": "Count of signature hits with low risk." + }, + "medium": { + "type": "integer", + "description": "Count of signature hits with medium risk." + }, + "high": { + "type": "integer", + "description": "Count of signature hits with high risk." + }, + "critical": { + "type": "integer", + "description": "Count of signature hits with critical risk." + } + }, + "example": { + "low": 200, + "medium": 350, + "high": 520, + "critical": 200 + } + }, + "ResponseCodeItem": { + "type": "object", + "description": "Attack counts for a specific HTTP response code.\n", + "required": [ + "code", + "count" ], - "example": "http/server/location" + "properties": { + "code": { + "type": "string", + "description": "HTTP response code (e.g., \"403\", \"200\", \"500\").", + "example": "403" + }, + "count": { + "type": "integer", + "description": "Number of attacks resulting in this response code." + } + }, + "example": { + "code": "403", + "count": 450 + } }, - "TemplateImportRequest": { + "DistinctCounts": { "type": "object", - "description": "A request to import a template into the system. This can be either a *base template* or an *augment template*,\nas determined by the `type` field in the request body.\n\nBase templates define the structure of an NGINX configuration and may include hook points\nfor augment templates using custom Go template functions.\n\nAugment templates are reusable configuration snippets that can be applied to specific NGINX contexts\nwithin a base template, such as `http`, `http/server`, `stream` or `stream/server`.\n\nNginx One supports custom Go template functions for advanced configuration generation.\nSee [Template Functions](https://yourdocs.com/templates/functions) for a complete list of supported functions.\n", + "description": "Cross-dimension counts providing context about the attacks for a given dimension value.\nEach field represents a COUNT(DISTINCT ...) aggregation.\n\nFor example, when grouping by IP address:\n- `ips` will be 1 (the IP itself)\n- `urls` shows how many different URLs were targeted from this IP\n- `violations` shows how many different violation types were triggered\n- `policies` shows how many different WAF policies were matched\n", "required": [ - "name", - "file", - "type" + "ips", + "urls", + "violations", + "policies" ], "properties": { - "name": { - "$ref": "#/components/schemas/TemplateName" + "ips": { + "type": "integer", + "description": "Count of distinct source IP addresses associated with this dimension value." }, - "file": { + "urls": { + "type": "integer", + "description": "Count of distinct URLs targeted." + }, + "violations": { + "type": "integer", + "description": "Count of distinct violation types detected." + }, + "policies": { + "type": "integer", + "description": "Count of distinct WAF policies that were triggered." + } + }, + "example": { + "ips": 15, + "urls": 8, + "violations": 12, + "policies": 3 + } + }, + "DimensionItem": { + "type": "object", + "description": "A single item in a dimensional breakdown for dynamic dimensions.\n", + "required": [ + "value", + "count", + "distinct" + ], + "properties": { + "value": { "type": "string", - "description": "A .tar.gz archive containing a template and any necessary supporting files for generating an NGINX configuration.\n\nThe archive must include the following at its root:\n- A template file (e.g., reverse_proxy_base.tmpl) written in valid Go template syntax for NGINX.\n- If the template uses input variables, a schema file is also required. This file defines and validates the expected input data.\n- The schema file could be a JSON schema or YAML (e.g., schema.json, schema.yaml).\n\nFile structure:\n├── reverse_proxy_base.tmpl # Required Go template file\n├── schema.json or schema.yaml # Required only if input variables are used\n", - "format": "binary", - "maxLength": 1000000, - "example": "template.tar.gz" + "description": "The dimension value being grouped. Content depends on the `group_by` dimension:\n- `ip`: Client IP address (e.g., \"203.0.113.42\")\n- `country`: ISO 3166-1 alpha-2 country code (e.g., \"US\")\n- `url`: Request URL path (e.g., \"/api/login\")\n- `policy`: WAF policy name (e.g., \"strict-policy\")\n" }, - "type": { - "$ref": "#/components/schemas/TemplateType" + "count": { + "type": "integer", + "description": "Total number of attacks for this dimension value within the queried time range.\n" }, - "description": { - "$ref": "#/components/schemas/TemplateDescription" + "distinct": { + "$ref": "#/components/schemas/DistinctCounts" }, - "allowed_in_contexts": { - "type": "array", - "description": "Required when type is `augment`. Specifies the full hierarchical context path(s) within the NGINX configuration where the augment template output can be placed.\n", - "items": { - "$ref": "#/components/schemas/TemplateContextPath" - } + "country": { + "type": "string", + "maxLength": 2, + "description": "ISO 3166-1 alpha-2 country code for the IP address.\nOnly present when `group_by` is `ip`.\n" } + }, + "example": { + "value": "203.0.113.42", + "count": 450, + "distinct": { + "ips": 1, + "urls": 3, + "violations": 5, + "policies": 1 + }, + "country": "US" } }, - "TemplatesListResponse": { - "description": "List of all templates.", - "allOf": [ - { - "$ref": "#/components/schemas/PaginationResponse" + "AttacksQueryResponse": { + "type": "object", + "description": "Response for attack analytics query.\n\n**Response behavior:**\n- Without `group_by`: Returns `total` count and `threat_campaigns` (distinct count)\n- With `group_by`: Returns dimensional breakdown only (e.g., `request_status`), `total` and `threat_campaigns` are omitted\n\nThe `total`/`threat_campaigns` and dimensional breakdowns are mutually exclusive.\n", + "required": [ + "query_metadata" + ], + "properties": { + "query_metadata": { + "$ref": "#/components/schemas/QueryMetadata" }, - { - "description": "List of config templates.", - "type": "object", - "required": [ - "items" - ], - "properties": { - "items": { - "description": "An array of templates.", - "type": "array", - "items": { - "$ref": "#/components/schemas/TemplateSummary" - } - } - }, - "example": { - "total": 101, - "count": 4, - "start_index": 1, - "items_per_page": 100, - "items": [ - { - "object_id": "tmpl_-uvR3F2TQGm18jnl7bpaGw", - "latest_template_version_object_id": "tmplv_-uvR3F2TQGm18jnl7bpaGw", - "version": 1, - "latest_version": 1, - "state": "final", - "name": "reverse-proxy", - "description": "A base template for setting up a reverse proxy", - "type": "base", - "allowed_in_contexts": [], - "augment_includes": [ - "http", - "http/server", - "http/upstream", - "http/server/location", - "stream", - "stream/upstream", - "stream/server" - ], - "created_at": "2026-09-01T12:00:00Z", - "modified_at": "2026-09-15T14:30:00Z" - }, - { - "object_id": "tmpl_-xeR3F2TQGm18jnl7bpaAw", - "latest_template_version_object_id": "tmplv_-xeR3F2TQGm18jnl7bpaAw", - "version": 1, - "latest_version": 1, - "state": "final", - "name": "gzip", - "description": "Augment template for enabling gzip compression", - "type": "augment", - "allowed_in_contexts": [ - "http", - "http/server" - ], - "augment_includes": [], - "created_at": "2026-09-01T12:00:00Z", - "modified_at": "2026-09-15T14:30:00Z" - }, - { - "object_id": "tmpl_-abR3F2TQGm18jnl7bpaXw", - "latest_template_version_object_id": "tmplv_-abR3F2TQGm18jnl7bpaXw", - "version": 1, - "latest_version": 1, - "state": "final", - "name": "rate-limiting-http", - "description": "Add rate limiting to HTTP requests", - "type": "augment", - "allowed_in_contexts": [ - "http", - "http/server" - ], - "augment_includes": [], - "created_at": "2026-09-01T12:00:00Z", - "modified_at": "2026-09-15T14:30:00Z" - }, - { - "object_id": "tmpl_-cdR3F2TQGm18jnl7bpaZw", - "latest_template_version_object_id": "tmplv_-cdR3F2TQGm18jnl7bpaZw", - "version": 1, - "latest_version": 1, - "state": "final", - "name": "limit-request", - "description": "Limit requests per second for a location", - "type": "augment", - "allowed_in_contexts": [ - "http/server/location" - ], - "augment_includes": [], - "created_at": "2026-09-01T12:00:00Z", - "modified_at": "2026-09-15T14:30:00Z" - } - ] + "total": { + "type": "integer", + "description": "Total attack count for the query. Only present when no `group_by` is specified.\n" + }, + "threat_campaigns": { + "type": "integer", + "description": "Count of distinct threat campaigns in the queried time range.\nOnly present when no `group_by` is specified.\n" + }, + "request_status": { + "$ref": "#/components/schemas/RequestStatusCountsResponse" + }, + "request_outcome_reason": { + "$ref": "#/components/schemas/RequestOutcomeReasonCountsResponse" + }, + "request_method": { + "$ref": "#/components/schemas/RequestMethodCountsResponse" + }, + "ip": { + "type": "array", + "description": "Attack counts grouped by client IP address. Sorted by count descending.", + "items": { + "$ref": "#/components/schemas/DimensionItem" + } + }, + "country": { + "type": "array", + "description": "Attack counts grouped by source country. Sorted by count descending.", + "items": { + "$ref": "#/components/schemas/DimensionItem" + } + }, + "policy": { + "type": "array", + "description": "Attack counts grouped by WAF policy name. Sorted by count descending.", + "items": { + "$ref": "#/components/schemas/DimensionItem" + } + }, + "url": { + "type": "array", + "description": "Attack counts grouped by request URL. Sorted by count descending.", + "items": { + "$ref": "#/components/schemas/DimensionItem" + } + }, + "response_code": { + "type": "array", + "description": "Attack counts grouped by HTTP response code. Sorted by count descending.", + "items": { + "$ref": "#/components/schemas/ResponseCodeItem" + } + }, + "hostname": { + "type": "array", + "description": "Attack counts grouped by NGINX instance hostname. Sorted by count descending.", + "items": { + "$ref": "#/components/schemas/DimensionItem" + } + }, + "threat_campaign": { + "type": "array", + "description": "Attack counts grouped by threat campaign name. Sorted by count descending.", + "items": { + "$ref": "#/components/schemas/DimensionItem" } } - ] - }, - "TemplateVersionState": { - "type": "string", - "description": "The state of a template version.\n- `draft`: Version is editable and not yet finalized.\n- `final`: Version is immutable and finalized. Version can't be transitioned back to draft.\n", - "enum": [ - "draft", - "final" - ], - "x-enum-varnames": [ - "template_version_state_draft", - "template_version_state_final" - ], - "example": "final" + } }, - "TemplateVersionMetadata": { + "TimeSeriesDataPoint": { "type": "object", + "description": "A single data point in a time series for a given dimension.\n", "required": [ - "created_at", - "modified_at", - "object_id", - "latest_template_version_object_id", - "latest_version", - "version", - "state" + "timestamp", + "count" ], "properties": { - "created_at": { - "type": "string", - "format": "date-time", - "description": "The creation timestamp of the template." - }, - "modified_at": { + "timestamp": { "type": "string", "format": "date-time", - "description": "The last modification timestamp of the template." - }, - "object_id": { - "$ref": "#/components/schemas/TemplateObjectID" + "description": "The start time of this bucket." }, - "latest_template_version_object_id": { - "$ref": "#/components/schemas/TemplateVersionObjectID" - }, - "latest_version": { + "count": { "type": "integer", - "description": "The latest version available for the template." + "description": "The count for this time bucket.\nRepresents the pivot entity type:\n- **For attacks endpoint**: Count of attack events\n- **For signatures endpoint**: Count of signature hits (pattern occurrences)\n" + } + }, + "example": { + "timestamp": "2024-01-15T00:00:00Z", + "count": 120 + } + }, + "RequestStatusTimeSeries": { + "type": "object", + "description": "Time-series data grouped by WAF enforcement status.\nEach property contains an array of data points for that status.\n", + "properties": { + "blocked": { + "type": "array", + "description": "Time series of blocked attack counts.", + "items": { + "$ref": "#/components/schemas/TimeSeriesDataPoint" + } }, - "version": { - "type": "integer", - "description": "The version number of this template." + "alerted": { + "type": "array", + "description": "Time series of alerted attack counts (transparent mode).", + "items": { + "$ref": "#/components/schemas/TimeSeriesDataPoint" + } }, - "state": { - "$ref": "#/components/schemas/TemplateVersionState" + "passed": { + "type": "array", + "description": "Time series of passed attack counts (no violations).", + "items": { + "$ref": "#/components/schemas/TimeSeriesDataPoint" + } } } }, - "TemplateSummaryBase": { - "description": "Base summary of a template object, including its metadata, allowed contexts and augment includes.\n", + "RequestOutcomeReasonTimeSeries": { "type": "object", - "required": [ - "name", - "type", - "augment_includes" - ], + "description": "Time-series data grouped by the specific outcome reason for the enforcement decision.\nEach property contains an array of data points representing that specific reason's count over time.\n", "properties": { - "name": { - "$ref": "#/components/schemas/TemplateName" + "SECURITY_WAF_OK": { + "type": "array", + "description": "Request passed with no security violations detected.", + "items": { + "$ref": "#/components/schemas/TimeSeriesDataPoint" + } }, - "type": { - "$ref": "#/components/schemas/TemplateType" + "SECURITY_WAF_VIOLATION": { + "type": "array", + "description": "Request blocked due to a confirmed signature or protocol violation.", + "items": { + "$ref": "#/components/schemas/TimeSeriesDataPoint" + } }, - "description": { - "$ref": "#/components/schemas/TemplateDescription" + "SECURITY_WAF_FLAGGED": { + "type": "array", + "description": "Violation detected, but allowed due to policy-level transparent mode.", + "items": { + "$ref": "#/components/schemas/TimeSeriesDataPoint" + } }, - "allowed_in_contexts": { + "SECURITY_WAF_VIOLATION_TRANSPARENT": { "type": "array", - "description": "Specifies the full hierarchical context path(s) within the NGINX configuration where this template output can be placed.\n\nFor base templates, this list is empty. Instead, refer to `augment_includes` to see where augment output can be injected within the base template.\n", + "description": "Individual signature or violation was in staging/transparent mode and did not block.", "items": { - "$ref": "#/components/schemas/TemplateContextPath" + "$ref": "#/components/schemas/TimeSeriesDataPoint" } }, - "augment_includes": { + "SECURITY_NGINX_VIOLATION": { "type": "array", - "description": "Lists the explicit hierarchical context paths within the NGINX configuration where augment template output can be injected.\n\nEach entry corresponds to a location in the template where an `augment_includes` function is used, indicating a supported point for augment insertion (e.g., \"http/server\", \"stream/server\").\n", + "description": "Request rejected due to NGINX-level constraints (e.g., malformed headers).", "items": { - "$ref": "#/components/schemas/TemplateContextPath" + "$ref": "#/components/schemas/TimeSeriesDataPoint" } - } - } - }, - "TemplateSummary": { - "description": "A summary of a template object, including its metadata, allowed contexts and augment includes.\n", - "allOf": [ - { - "$ref": "#/components/schemas/TemplateVersionMetadata" }, - { - "$ref": "#/components/schemas/TemplateSummaryBase" + "SECURITY_WAF_BYPASS": { + "type": "array", + "description": "Request was explicitly allowed due to an allow-list or bypass rule.", + "items": { + "$ref": "#/components/schemas/TimeSeriesDataPoint" + } } - ], - "example": { - "object_id": "tmpl_-uvR3F2TQGm18jnl7bpaGw", - "latest_template_version_object_id": "tmplv_-uvR3F2TQGm18jnl7bpaGw", - "latest_version": 1, - "version": 1, - "state": "final", - "name": "reverse-proxy", - "description": "A base template for setting up a reverse proxy", - "type": "base", - "allowed_in_contexts": [], - "augment_includes": [ - "http", - "http/server", - "http/upstream", - "http/server/location" - ], - "created_at": "2023-09-01T12:00:00Z", - "modified_at": "2023-09-15T14:30:00Z" } }, - "TemplateFileData": { + "AttacksTimeSeriesQueryResponse": { "type": "object", - "description": "Details about the file in the template.\n", + "description": "Response for attack analytics time-series query.\n\n**Response behavior:**\n- Without `group_by`: Returns `total` series only (array of data points)\n- With `group_by`: Returns dimensional breakdown only (e.g., `request_status`), `total` is omitted\n\nThe `total` and dimensional breakdowns are mutually exclusive.\n\n**Time alignment:** All series arrays contain the same timestamps, aligned to the\nresolution boundary. Buckets with no events are zero-filled to ensure consistent\ndata points across all series for chart rendering.\n", "required": [ - "name", - "contents", - "file_type", - "file_format", - "mime_type", - "size", - "ctime" + "query_metadata" ], "properties": { - "name": { - "type": "string", - "description": "The name of a file inside a template archive (.tar.gz). File names must not be absolute paths or contain directory traversal components. For safety, leading slashes or \"..\" are not allowed.\n", - "minLength": 1, - "maxLength": 255, - "pattern": "^[a-zA-Z0-9_.\\-\\/]+$", - "example": "gzip-http.tmpl" - }, - "contents": { - "type": "string", - "description": "The contents of the file.\n- If `file_format` is \"plain\", this is a UTF-8 encoded string.\n- If `file_format` is \"bytes\", this is a Base64-encoded string.\n", - "maxLength": 1000000 - }, - "file_type": { - "type": "string", - "description": "The contents type of the file.\n* template: The file contains a Go template.\n* schema: The file contains a JSON or YAML schema for validating input data for the template. Optional if the template does not require input variables.\n", - "enum": [ - "template", - "schema" - ], - "x-enum-varnames": [ - "template_file_type_template", - "template_file_type_schema" - ] - }, - "file_format": { - "type": "string", - "description": "The encoding format of the contents in the file for transport.\n\n- `plain`: Human-readable content (plain UTF-8 string).\n- `bytes`: Base64-encoded binary content.\n", - "enum": [ - "plain", - "bytes" - ], - "x-enum-varnames": [ - "template_file_format_plain", - "template_file_format_bytes" - ] + "query_metadata": { + "$ref": "#/components/schemas/QueryMetadata" }, - "mime_type": { - "type": "string", - "description": "The MIME type of the file, indicating its content type.\nFor example, `text/plain`, `application/json`, `application/gzip`.\n", - "enum": [ - "text/plain", - "application/json", - "application/yaml" - ] + "total": { + "type": "array", + "description": "Total attack counts over time. Only present when no `group_by` is specified.\n", + "items": { + "$ref": "#/components/schemas/TimeSeriesDataPoint" + } }, - "size": { - "type": "integer", - "description": "The size of the file, in bytes." + "request_status": { + "$ref": "#/components/schemas/RequestStatusTimeSeries" }, - "ctime": { - "type": "string", - "format": "date-time", - "description": "Timestamp when the file was created." + "request_outcome_reason": { + "$ref": "#/components/schemas/RequestOutcomeReasonTimeSeries" } - }, - "example": { - "name": "nginx.tmpl", - "file_type": "template", - "file_format": "plain", - "mime_type": "text/plain", - "contents": "http {\n {{ augment_includes \"http\" . }}\n\n upstream backend {\n {{- range .upstream_servers }}\n server {{ . }};\n {{- end }}\n }\n\n server {\n listen 80;\n server_name {{ .server_name }};\n\n location / {\n proxy_pass {{ default \"http://backend\" .proxy_pass }};\n }\n }\n}", - "size": 345, - "ctime": "2026-09-01T12:00:00Z" } }, - "TemplateCreationRequest": { - "description": "A request payload used to create a new template, including its metadata and associated file contents.", - "type": "object", + "SignaturesDimensionField": { + "type": "string", + "description": "Available dimensions for grouping and filtering signature analytics.\n", + "enum": [ + "request_status", + "accuracy", + "risk", + "signature", + "cve" + ], + "x-enum-varnames": [ + "signatures_dimension_request_status", + "signatures_dimension_accuracy", + "signatures_dimension_risk", + "signatures_dimension_signature", + "signatures_dimension_cve" + ] + }, + "SignaturesTimeSeriesDimensionField": { + "type": "string", + "description": "Dimensions available for time-series grouping of signature data.\nLimited to fixed enum dimensions that can be efficiently aggregated per time bucket.\n", + "enum": [ + "request_status", + "accuracy", + "risk" + ], + "x-enum-varnames": [ + "signatures_ts_dimension_request_status", + "signatures_ts_dimension_accuracy", + "signatures_ts_dimension_risk" + ] + }, + "SignaturesQueryRequest": { "allOf": [ { - "$ref": "#/components/schemas/TemplateSummaryBase" + "$ref": "#/components/schemas/BaseQueryRequest" }, { "type": "object", - "required": [ - "items" - ], + "description": "Request body for querying signature analytics.\n", "properties": { - "items": { - "description": "A list of files in the template.", + "group_by": { + "allOf": [ + { + "$ref": "#/components/schemas/SignaturesDimensionField" + }, + { + "description": "Dimension to aggregate results by.\n\n**Fixed enum dimensions** (returned as objects with known keys):\n* `request_status` - blocked, alerted, passed\n* `accuracy` - low, medium, high\n* `risk` - low, medium, high, critical\n\n**Dynamic dimensions** (returned as arrays sorted by count descending):\n* `signature` - Individual signatures with id, name, accuracy, risk\n* `cve` - CVE identifiers\n\n**Response behavior:**\n- If omitted: Returns `total` (signature hits) and `unique` (distinct signatures)\n- If specified: Returns dimensional breakdown, `total` and `unique` are omitted\n", + "example": "signature" + } + ] + }, + "filter": { "type": "array", + "description": "Pre-aggregation filter conditions.\nAll filters are combined with AND logic.\nUse the `in` operator to achieve `OR` within a single dimension.\n", "items": { - "$ref": "#/components/schemas/TemplateFileData" - } + "$ref": "#/components/schemas/AnalyticsFilter" + }, + "default": [] + }, + "order_by": { + "$ref": "#/components/schemas/AnalyticsOrderBy" } } } - ], - "example": { - "name": "reverse-proxy", - "type": "base", - "allowed_in_contexts": [], - "augment_includes": [ - "http" - ], - "items": [ - { - "name": "nginx.tmpl", - "file_type": "template", - "file_format": "bytes", - "mime_type": "text/plain", - "contents": "aHR0cCB7XG4gIHt7IGF1Z21lbnRfaW5jbHVkZXMgXCJodHRwXCIgLiB9fVxuXG4gdXBzdHJlYW0gYmFja2VuZCB7XG4gIC17LSByYW5nZSAudXBzdHJlYW1fc2VydmVycyB9XG4gICAgc2VydmVyIHsgLiB9O1xuICB7LSBlbmQgfVxuIH1cblxuIHNlcnZlciB7XG4gIGxpc3RlbiA4MDtcbiAgc2VydmVyX25hbWUge3sgLnNlcnZlcl9uYW1lIH19O1xuXG4gIGxvY2F0aW9uIC8ge1xuICAgIHByb3h5X3Bhc3Mge3sgZGVmYXVsdCBcImh0dHA6Ly9iYWNrZW5kXCIgLnByb3h5X3Bhc3MgfX07XG4gIH1cbn1cbiIs", - "size": 1234, - "ctime": "2026-09-01T12:00:00Z" - }, - { - "name": "schema.json", - "file_type": "schema", - "file_format": "bytes", - "mime_type": "application/json", - "contents": "ewogICIkc2NoZW1hIjogImh0dHA6Ly9qc29uLXNjaGVtYS5vcmcvZHJhZnQtMDcvc2NoZW1hIyIsCiAgInR5cGUiOiAib2JqZWN0IiwKICAicHJvcGVydGllcyI6IHsKICAgICJ1cHN0cmVhbV9zZXJ2ZXJzIjogewogICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICJpdGVtcyI6IHsKICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICJmb3JtYXQiOiAiaG9zdG5hbWUiLAogICAgICAgICJwYXR0ZXJuIjogIl5bYS1aQS1aMC05Li1dKyg6WzAtOV0rKT8kIgogICAgICB9LAogICAgICAibWluSXRlbXMiOiAxCiAgICB9LAogICAgInNlcnZlcl9uYW1lIjogewogICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAicGF0dGVybiI6ICJeW2EtWkEtWjAtOS4tXSskIgogICAgfSwKICAgICJwcm94eV9wYXNzIjogewogICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAiZm9ybWF0IjogInVyaSIKICAgIH0KICB9LAogICJyZXF1aXJlZCI6IFsidXBzdHJlYW1fc2VydmVycyIsICJzZXJ2ZXJfbmFtZSJdLAogICJhZGRpdGlvbmFsUHJvcGVydGllcyI6IGZhbHNlCn0=", - "size": 456, - "ctime": "2026-09-01T12:00:00Z" - } - ] - } + ] }, - "TemplateDetailsResponse": { - "description": "Full detailed response about an existing template object including summary and file contents.", - "type": "object", + "SignaturesTimeSeriesQueryRequest": { "allOf": [ { - "$ref": "#/components/schemas/TemplateVersionMetadata" - }, - { - "$ref": "#/components/schemas/TemplateSummaryBase" + "$ref": "#/components/schemas/BaseQueryRequest" }, { "type": "object", - "required": [ - "items" - ], + "description": "Request body for querying signature analytics time series.\n", "properties": { - "items": { - "description": "A list of files in the template.", + "resolution": { + "$ref": "#/components/schemas/Resolution" + }, + "group_by": { + "allOf": [ + { + "$ref": "#/components/schemas/SignaturesTimeSeriesDimensionField" + }, + { + "description": "Dimension to break down time-series by.\nLimited to fixed enum dimensions for performance.\n\n* `request_status` - Returns `blocked`, `alerted`, `passed` series\n* `accuracy` - Returns `low`, `medium`, `high` series\n* `risk` - Returns `low`, `medium`, `high`, `critical` series\n\n**Response behavior:**\n- If omitted: Returns `total` series only\n- If specified: Returns dimensional breakdown, `total` is omitted\n", + "example": "request_status" + } + ] + }, + "filter": { "type": "array", + "description": "Pre-aggregation filter conditions.\nAll filters are combined with AND logic.\nUse the `in` operator to achieve `OR` within a single dimension.\n", "items": { - "$ref": "#/components/schemas/TemplateFileData" - } + "$ref": "#/components/schemas/AnalyticsFilter" + }, + "default": [] } } } - ], - "example": { - "object_id": "tmpl_-uvR3F2TQGm18jnl7bpaGw", - "created_at": "2026-09-01T12:00:00Z", - "modified_at": "2026-09-15T14:30:00Z", - "latest_template_version_object_id": "tmplv_-uvR3F2TQGm18jnl7bpaGw", - "version": 1, - "latest_version": 1, - "state": "final", - "name": "reverse-proxy", - "type": "base", - "allowed_in_contexts": [], - "augment_includes": [ - "http" - ], - "items": [ - { - "name": "nginx.tmpl", - "file_type": "template", - "file_format": "bytes", - "mime_type": "text/plain", - "contents": "aHR0cCB7XG4gIHt7IGF1Z21lbnRfaW5jbHVkZXMgXCJodHRwXCIgLiB9fVxuXG4gdXBzdHJlYW0gYmFja2VuZCB7XG4gIC17LSByYW5nZSAudXBzdHJlYW1fc2VydmVycyB9XG4gICAgc2VydmVyIHsgLiB9O1xuICB7LSBlbmQgfVxuIH1cblxuIHNlcnZlciB7XG4gIGxpc3RlbiA4MDtcbiAgc2VydmVyX25hbWUge3sgLnNlcnZlcl9uYW1lIH19O1xuXG4gIGxvY2F0aW9uIC8ge1xuICAgIHByb3h5X3Bhc3Mge3sgZGVmYXVsdCBcImh0dHA6Ly9iYWNrZW5kXCIgLnByb3h5X3Bhc3MgfX07XG4gIH1cbn1cbiIs", - "size": 1234, - "ctime": "2026-09-01T12:00:00Z" - }, - { - "name": "schema.json", - "file_type": "schema", - "file_format": "bytes", - "mime_type": "application/json", - "contents": "ewogICIkc2NoZW1hIjogImh0dHA6Ly9qc29uLXNjaGVtYS5vcmcvZHJhZnQtMDcvc2NoZW1hIyIsCiAgInR5cGUiOiAib2JqZWN0IiwKICAicHJvcGVydGllcyI6IHsKICAgICJ1cHN0cmVhbV9zZXJ2ZXJzIjogewogICAgICAidHlwZSI6ICJhcnJheSIsCiAgICAgICJpdGVtcyI6IHsKICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICJmb3JtYXQiOiAiaG9zdG5hbWUiLAogICAgICAgICJwYXR0ZXJuIjogIl5bYS1aQS1aMC05Li1dKyg6WzAtOV0rKT8kIgogICAgICB9LAogICAgICAibWluSXRlbXMiOiAxCiAgICB9LAogICAgInNlcnZlcl9uYW1lIjogewogICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAicGF0dGVybiI6ICJeW2EtWkEtWjAtOS4tXSskIgogICAgfSwKICAgICJwcm94eV9wYXNzIjogewogICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAiZm9ybWF0IjogInVyaSIKICAgIH0KICB9LAogICJyZXF1aXJlZCI6IFsidXBzdHJlYW1fc2VydmVycyIsICJzZXJ2ZXJfbmFtZSJdLAogICJhZGRpdGlvbmFsUHJvcGVydGllcyI6IGZhbHNlCn0=", - "size": 456, - "ctime": "2026-09-01T12:00:00Z" - } - ] - } - }, - "TemplateValuesRequest": { - "type": "object", - "description": "Key-value pairs for template rendering.", - "additionalProperties": true + ] }, - "TemplateSubmissionRequest": { + "SignatureDimensionItem": { "type": "object", - "description": "Defines a request to render an NGINX configuration by combining a single base template \nwith zero or more augment templates.\n\n### Validations and Constraints:\n- All templates referenced by Object ID must be available in the system before submission.\n- Only one base template can be submitted.\n- The base template must explicitly use custom Go function `augment_includes (\"\", .)` to apply `augments`.\n- Its not required to include all augments in the request that base template supports.\n- The order of augments in the list determines the order in which they are rendered and applied.\n- Each augment must specify its `target_context`, indicating where it should be applied in \n the base template.\n- Input values for each template are passed independently via the `values` \n object, and validated against each template’s Schema.\n\n### Processing:\n- The `base_template` defines the starting point of the NGINX configuration rendering.\n- `conf_path` determines where the rendered configuration from base and augments should be placed within the NGINX directory structure.\n- Each `augment` template is applied in the order provided, inserted at the appropriate target context\n using the `augment_includes (\"\", .)` function declared in the base template.\n- The system validates that each augment is compatible with the specified target context.\n- The final composed configuration is validated to ensure correctness and prevent conflicts or misconfigurations.\n\n### External Template Documentation:\nFor more information on template functions and best practices, refer to:\n - [Template Function Reference](https://yourdocs.com/templates/functions)\n - [Template Authoring Guide](https://yourdocs.com/templates/guide)\n", + "description": "A single item in the signature dimensional breakdown.\nIncludes signature metadata (id, name, accuracy, risk) along with hit count.\n", "required": [ - "conf_path", - "base_template", - "augments" + "signature_id", + "name", + "count", + "accuracy", + "risk" ], "properties": { - "conf_path": { - "$ref": "#/components/schemas/ConfigPath" + "signature_id": { + "type": "string", + "description": "The unique identifier for the signature.\n", + "example": "200001834" }, - "base_template": { - "$ref": "#/components/schemas/BaseTemplateSubmissionRequest" + "name": { + "type": "string", + "description": "The human-readable name of the signature.\n", + "example": "Unix hidden (dot-file)" }, - "augments": { - "type": "array", - "description": "Ordered list of augment templates to apply to the base template.\nAugments are rendered in the order provided.\n", - "items": { - "$ref": "#/components/schemas/AugmentTemplateSubmissionRequest" - } - } - }, - "example": { - "conf_path": "/etc/nginx/nginx.conf", - "base_template": { - "object_id": "tmplv_-uvR3F2TQGm18jnl7bpaGw", - "values": { - "upstream_servers": [ - "10.0.0.1:8080", - "10.0.0.2:8080" - ], - "server_name": "example.com" - } + "count": { + "type": "integer", + "description": "Number of times this signature was triggered within the queried time range.\n" }, - "augments": [ - { - "object_id": "tmplv_-uvR3F2TQGm18jnl7bpaGw", - "target_context": "http/upstream", - "values": { - "upstream_servers": [ - "10.0.0.1:8080", - "10.0.0.2:8080" - ], - "server_name": "example.com" - } - }, - { - "object_id": "tmplv_-xeR3F2TQGm18jnl7bpaAw", - "target_context": "http", - "values": { - "enabled": "on", - "types": "text/plain application/json" - } - }, - { - "object_id": "tmplv_-abR3F2TQGm18jnl7bpaXw", - "target_context": "http", - "values": { - "zone_name": "req_limit", - "memory": "10m", - "rate": "10r/s" + "accuracy": { + "allOf": [ + { + "$ref": "#/components/schemas/SignatureAccuracy" + }, + { + "description": "The accuracy level of the signature.", + "example": "high" } - }, - { - "object_id": "tmplv_-cdR3F2TQGm18jnl7bpaZw", - "target_context": "http/server", - "values": { - "zone_name": "req_limit", - "burst": 5 + ] + }, + "risk": { + "allOf": [ + { + "$ref": "#/components/schemas/SignatureRisk" }, - "child_augments": [ - { - "object_id": "tmplv_-cdR3F2TQGm18jnl7bpaZw", - "target_context": "http/server/location", - "values": { - "zone_name": "req_limit", - "burst": 5 - } - } - ] - } - ] + { + "description": "The risk level of the signature.", + "example": "medium" + } + ] + }, + "distinct": { + "$ref": "#/components/schemas/DistinctCounts" + } + }, + "example": { + "signature_id": "200001834", + "name": "Unix hidden (dot-file)", + "count": 141, + "accuracy": "high", + "risk": "medium", + "distinct": { + "ips": 12, + "urls": 5, + "violations": 3, + "policies": 2 + } } }, - "BaseTemplateSubmissionRequest": { + "CveDimensionItem": { "type": "object", + "description": "A single item in the CVE dimensional breakdown.\n", "required": [ - "object_id" + "value", + "count" ], "properties": { - "object_id": { - "$ref": "#/components/schemas/TemplateVersionObjectID" + "value": { + "type": "string", + "description": "The CVE identifier (e.g., \"CVE-2021-44228\").\n", + "example": "CVE-2021-44228" }, - "values": { - "$ref": "#/components/schemas/TemplateValuesRequest" + "count": { + "type": "integer", + "description": "Number of signature hits associated with this CVE.\n" + }, + "distinct": { + "$ref": "#/components/schemas/DistinctCounts" } }, "example": { - "object_id": "tmplv_-uvR3F2TQGm18jnl7bpaGw", - "values": { - "upstream_servers": [ - "10.0.0.1:8080", - "10.0.0.2:8080" - ], - "server_name": "example.com" + "value": "CVE-2021-44228", + "count": 450, + "distinct": { + "ips": 8, + "urls": 3, + "violations": 2, + "policies": 1 } } }, - "AugmentTemplateSubmissionRequest": { + "SignaturesQueryResponse": { "type": "object", - "description": "Defines a request to apply an augment template to a specific target context within the base template.\n\nThis extends the `BaseTemplateSubmissionRequest`. Additionally adding,\n- `target_context`: Specifies the context within the base template where this augment should be applied.\n- `child_augments`: Optionally, an ordered list of nested augment templates to apply as children of this template.\n", + "description": "Response for signature analytics query.\n\n**Response behavior:**\n- Without `group_by`: Returns `total` (signature hits) and `unique` (distinct signatures)\n- With `group_by`: Returns dimensional breakdown only, `total` and `unique` are omitted\n\nThe `total`/`unique` and dimensional breakdowns are mutually exclusive.\n", "required": [ - "object_id", - "target_context" + "query_metadata" ], "properties": { - "object_id": { - "$ref": "#/components/schemas/TemplateVersionObjectID" + "query_metadata": { + "$ref": "#/components/schemas/QueryMetadata" }, - "values": { - "$ref": "#/components/schemas/TemplateValuesRequest" + "total": { + "type": "integer", + "description": "Total signature hit count for the query.\nOnly present when no `group_by` is specified.\n" }, - "target_context": { - "$ref": "#/components/schemas/TemplateContextPath" + "unique": { + "type": "integer", + "description": "Count of distinct signatures triggered.\nOnly present when no `group_by` is specified.\n" }, - "child_augments": { + "request_status": { + "$ref": "#/components/schemas/RequestStatusCountsResponse" + }, + "accuracy": { + "$ref": "#/components/schemas/AccuracyCountsResponse" + }, + "risk": { + "$ref": "#/components/schemas/RiskCountsResponse" + }, + "signature": { "type": "array", - "description": "Ordered list of nested augment templates to apply as children of this template.\n", + "description": "Signature hit counts grouped by individual signature. Sorted by count descending.", "items": { - "$ref": "#/components/schemas/AugmentTemplateSubmissionRequest" + "$ref": "#/components/schemas/SignatureDimensionItem" + } + }, + "cve": { + "type": "array", + "description": "Signature hit counts grouped by CVE. Sorted by count descending.", + "items": { + "$ref": "#/components/schemas/CveDimensionItem" } } - }, - "example": { - "object_id": "tmplv_-xeR3F2TQGm18jnl7bpaAw", - "target_context": "http/server", - "values": { - "enabled": "on", - "types": "text/plain application/json" + } + }, + "AccuracyTimeSeries": { + "type": "object", + "description": "Time-series data grouped by signature accuracy level.\nEach property contains an array of data points for that accuracy.\n", + "properties": { + "low": { + "type": "array", + "description": "Time series of low-accuracy signature hit counts.", + "items": { + "$ref": "#/components/schemas/TimeSeriesDataPoint" + } }, - "child_augments": [ - { - "object_id": "tmplv_-cdR3F2TQGm18jnl7bpaZw", - "target_context": "http/server/location", - "values": { - "zone_name": "req_limit", - "burst": 5 - } + "medium": { + "type": "array", + "description": "Time series of medium-accuracy signature hit counts.", + "items": { + "$ref": "#/components/schemas/TimeSeriesDataPoint" } - ] + }, + "high": { + "type": "array", + "description": "Time series of high-accuracy signature hit counts.", + "items": { + "$ref": "#/components/schemas/TimeSeriesDataPoint" + } + } + } + }, + "RiskTimeSeries": { + "type": "object", + "description": "Time-series data grouped by signature risk level.\nEach property contains an array of data points for that risk level.\n", + "properties": { + "low": { + "type": "array", + "description": "Time series of low-risk signature hit counts.", + "items": { + "$ref": "#/components/schemas/TimeSeriesDataPoint" + } + }, + "medium": { + "type": "array", + "description": "Time series of medium-risk signature hit counts.", + "items": { + "$ref": "#/components/schemas/TimeSeriesDataPoint" + } + }, + "high": { + "type": "array", + "description": "Time series of high-risk signature hit counts.", + "items": { + "$ref": "#/components/schemas/TimeSeriesDataPoint" + } + }, + "critical": { + "type": "array", + "description": "Time series of critical-risk signature hit counts.", + "items": { + "$ref": "#/components/schemas/TimeSeriesDataPoint" + } + } } }, - "PreviewNginxConfig": { + "SignaturesTimeSeriesQueryResponse": { "type": "object", - "description": "The rendered NGINX configuration preview, along with any errors encountered during rendering.\n", + "description": "Response for signature analytics time-series query.\n\n**Response behavior:**\n- Without `group_by`: Returns `total` series only (array of data points)\n- With `group_by`: Returns dimensional breakdown only (e.g., `request_status`), `total` is omitted\n\nThe `total` and dimensional breakdowns are mutually exclusive.\n\n**Time alignment:** All series arrays contain the same timestamps, aligned to the\nresolution boundary. Buckets with no events are zero-filled to ensure consistent\ndata points across all series for chart rendering.\n", "required": [ - "config" + "query_metadata" ], "properties": { - "config": { - "$ref": "#/components/schemas/NginxConfigObject" + "query_metadata": { + "$ref": "#/components/schemas/QueryMetadata" }, - "errors": { + "total": { "type": "array", - "description": "List of NGINX config parse errors encountered during rendering.", + "description": "Total signature hit counts over time. Only present when no `group_by` is specified.\n", "items": { - "$ref": "#/components/schemas/NginxConfigParseError" + "$ref": "#/components/schemas/TimeSeriesDataPoint" } + }, + "request_status": { + "$ref": "#/components/schemas/RequestStatusTimeSeries" + }, + "accuracy": { + "$ref": "#/components/schemas/AccuracyTimeSeries" + }, + "risk": { + "$ref": "#/components/schemas/RiskTimeSeries" } } }, - "NginxConfigParseError": { + "HttpMetadata": { "type": "object", - "description": "Details about an error encountered during NGINX configuration rendering.", - "required": [ - "file", - "error" - ], + "description": "HTTP request and response metadata from the security event.\n", "properties": { - "file": { + "hostname": { "type": "string", - "description": "The name of the file where the error occurred." + "description": "The HTTP Host header value.", + "example": "example.com" }, - "line": { + "remote_addr": { + "type": "string", + "description": "Client IP address.", + "example": "192.168.1.100" + }, + "remote_port": { "type": "integer", - "description": "The line number in the file where the error occurred." + "description": "Client source port.", + "example": 54321 }, - "error": { + "server_addr": { "type": "string", - "description": "A human-readable error message describing the issue." + "description": "Server IP address that received the request.", + "example": "10.0.0.1" + }, + "server_port": { + "type": "integer", + "description": "Server port that received the request.", + "example": 443 + }, + "uri": { + "type": "string", + "description": "Request URI path including query string.", + "example": "/api/login?user=admin" + }, + "request_method": { + "type": "string", + "description": "HTTP request method.", + "example": "GET" + }, + "response_code": { + "type": "integer", + "description": "HTTP response status code.", + "example": 403 } - }, - "example": { - "file": "nginx.conf", - "line": 1, - "error": "\"upstream\" directive is not allowed here in /etc/nginx/nginx.conf:1" } }, - "FilterNameTemplates": { - "type": "string", - "description": "Keywords for config templates filters.\n", - "enum": [ - "name", - "type", - "object_id", - "allowed_in_contexts" - ], - "x-enum-varnames": [ - "filter_name_templates_name", - "filter_name_templates_type", - "filter_name_templates_object_id", - "filter_name_templates_allowed_in_contexts" - ] - }, - "EventRequestOutcome": { - "type": "string", - "description": "WAF enforcement decision for the request.", - "enum": [ - "blocked", - "passed", - "alerted" - ], - "x-enum-varnames": [ - "request_outcome_blocked", - "request_outcome_passed", - "request_outcome_alerted" - ] - }, - "EventLevel": { - "type": "string", - "description": "Log level classification for the security event.\nFollows standard logging convention for severity.\n", - "enum": [ - "DEBUG", - "INFO", - "WARNING", - "ERROR", - "CRITICAL" - ], - "x-enum-varnames": [ - "event_level_debug", - "event_level_info", - "event_level_warning", - "event_level_error", - "event_level_critical" - ] - }, - "SignatureAccuracy": { - "type": "string", - "description": "Confidence level that the signature accurately identifies the attack.", - "enum": [ - "low", - "medium", - "high" - ], - "x-enum-varnames": [ - "signature_accuracy_low", - "signature_accuracy_medium", - "signature_accuracy_high" - ] - }, - "SignatureRisk": { - "type": "string", - "description": "Risk level of the attack identified by the signature.", - "enum": [ - "low", - "medium", - "high", - "critical" - ], - "x-enum-varnames": [ - "signature_risk_low", - "signature_risk_medium", - "signature_risk_high", - "signature_risk_critical" - ] - }, - "RequestStatus": { - "type": "string", - "description": "Status of request processing by the WAF.", - "enum": [ - "complete", - "truncated", - "malformed", - "skipped", - "aborted" - ], - "x-enum-varnames": [ - "request_status_complete", - "request_status_truncated", - "request_status_malformed", - "request_status_skipped", - "request_status_aborted" - ] - }, - "AttacksDimensionField": { - "type": "string", - "description": "Available dimensions for grouping and filtering attack analytics.\n", - "enum": [ - "request_outcome", - "request_outcome_reason", - "request_method", - "ip", - "country", - "policy", - "url", - "response_code", - "instance_object_id", - "csg_object_id" - ], - "x-enum-varnames": [ - "attacks_dimension_request_outcome", - "attacks_dimension_request_outcome_reason", - "attacks_dimension_request_method", - "attacks_dimension_ip", - "attacks_dimension_country", - "attacks_dimension_policy", - "attacks_dimension_url", - "attacks_dimension_response_code", - "attacks_dimension_instance_object_id", - "attacks_dimension_csg_object_id" - ] - }, - "AttacksTimeSeriesDimensionField": { - "type": "string", - "description": "Dimensions available for time-series grouping.\nLimited to fixed enum dimensions that can be efficiently aggregated per time bucket.\n", - "enum": [ - "request_outcome", - "request_outcome_reason" - ], - "x-enum-varnames": [ - "attacks_ts_dimension_request_outcome", - "attacks_ts_dimension_request_outcome_reason" - ] - }, - "Resolution": { - "type": "string", - "description": "Time bucket size for aggregation. If not specified, auto-selected based on time range:\n* < 1 hour: 1m\n* 1-6 hours: 5m\n* 6-24 hours: 15m\n* 1-7 days: 1h\n* > 7 days: 1d\n", - "enum": [ - "1m", - "5m", - "15m", - "1h", - "1d" - ], - "x-enum-varnames": [ - "resolution_1m", - "resolution_5m", - "resolution_15m", - "resolution_1h", - "resolution_1d" - ], - "example": "15m" - }, - "FilterOperator": { - "type": "string", - "description": "Filter operators that can be applied to a given list of dimension values.\n* `=` - Equals (uses first value only)\n* `!=` - Not equals (uses first value only)\n* `in` - Value is in the list (uses all values)\n* `not` - Value is not in the list (uses all values)\n", - "enum": [ - "=", - "!=", - "in", - "not" - ], - "x-enum-varnames": [ - "filter_operator_equal", - "filter_operator_not_equal", - "filter_operator_in", - "filter_operator_not" - ] - }, - "SortOrderDirection": { - "type": "string", - "description": "Sort direction for query results.", - "enum": [ - "asc", - "desc" - ], - "default": "desc", - "x-enum-varnames": [ - "order_direction_asc", - "order_direction_desc" - ] - }, - "AnalyticsFilter": { + "SignatureDetail": { "type": "object", - "description": "A single filter condition on a dimension.\nGeneric schema supporting both attacks and signature analytics filtering.\n", + "description": "Details of a signature that was triggered by the security event.\nA single event can trigger multiple signatures.\n", "required": [ - "dimension", - "operator", - "values" + "id", + "name" ], "properties": { - "dimension": { + "id": { + "type": "integer", + "description": "Unique identifier of the signature.", + "example": 200001834 + }, + "name": { + "type": "string", + "description": "Human-readable name of the signature.", + "example": "XSS script tag end (Parameter)" + }, + "accuracy": { + "allOf": [ + { + "$ref": "#/components/schemas/SignatureAccuracy" + }, + { + "description": "Confidence level that this signature accurately identifies the attack.", + "example": "high" + } + ] + }, + "risk": { + "allOf": [ + { + "$ref": "#/components/schemas/SignatureRisk" + }, + { + "description": "Severity/risk level of the attack identified by this signature.", + "example": "high" + } + ] + }, + "cve": { "type": "string", - "description": "The dimension to filter by. Accepts any dimension from either\nAttacksDimensionField or SignaturesDimensionField enums.\n" + "description": "CVE identifier if this signature is associated with a known vulnerability.", + "example": "CVE-2021-44228" }, - "operator": { - "$ref": "#/components/schemas/FilterOperator" + "blocking_mask": { + "type": "string", + "description": "Bitmask indicating blocking behavior configuration.", + "example": "0x0" }, - "values": { - "type": "array", - "description": "Values to filter by.\n- For `=` and `!=`: only the first value is used\n- For `in` and `not`: all values are used\n", - "items": { - "type": "string" - }, - "minItems": 1, - "example": [ - "blocked" - ] + "buffer": { + "type": "string", + "description": "The buffer/location where the signature matched (e.g., parameter name, header).", + "example": "param" + }, + "offset": { + "type": "integer", + "description": "Byte offset within the payload where the signature match begins.", + "example": 0 + }, + "length": { + "type": "integer", + "description": "Length of the matched string in bytes.", + "example": 42 } } }, - "AnalyticsOrderBy": { + "ViolationDetail": { "type": "object", - "description": "Specifies the sort order for dynamic dimension results.\n", + "description": "Details of a violation detected in the security event.\nA single event can trigger multiple violations.\n", + "required": [ + "name" + ], "properties": { - "dimension": { + "name": { "type": "string", - "description": "Field to sort by.\n- `count`: Sort by count (default)\n- `value`: Sort alphabetically by dimension value\n", - "enum": [ - "count", - "value" - ], - "default": "count" + "description": "Primary violation name/type.", + "example": "Illegal meta character in value" }, - "direction": { - "$ref": "#/components/schemas/SortOrderDirection" + "sub_name": { + "type": "string", + "description": "Sub-category or additional violation classification.", + "example": "" + }, + "context": { + "type": "string", + "description": "The context where the violation was detected (e.g., parameter, header, uri).", + "example": "parameter" + }, + "detail_name": { + "type": "string", + "description": "Technical violation identifier (e.g., VIOL_PARAMETER_VALUE_METACHAR).", + "example": "VIOL_PARAMETER_VALUE_METACHAR" + }, + "detail_context": { + "type": "string", + "description": "Additional context for the violation detail.", + "example": "parameter" + }, + "field_name": { + "type": "string", + "description": "Name of the field that triggered the violation.", + "example": "param" + }, + "field_value": { + "type": "string", + "description": "The value that triggered the violation.", + "example": "" } - }, - "example": { - "dimension": "count", - "direction": "desc" } }, - "BaseQueryRequest": { + "SecurityEventBase": { "type": "object", - "description": "Base query request with common fields for both attacks and signature analytics.\nShared properties for all analytical query types.\n", + "description": "Base security event with common fields across all event types.\nSeverity is determined by violation_rating (0-5), not a separate field.\n", "required": [ - "start_time" + "timestamp", + "support_id" ], "properties": { - "start_time": { + "timestamp": { "type": "string", - "description": "Beginning of the time range (inclusive).\nAccepts ISO 8601 format (`2024-01-15T00:00:00Z`) or relative offset (`now-24h`, `now-1d`).\n", - "example": "now-24h" + "format": "date-time", + "description": "When the security event occurred.", + "example": "2024-01-22T12:13:25Z" }, - "end_time": { + "support_id": { "type": "string", - "description": "End of the time range (exclusive).\nAccepts ISO 8601 format (`2024-01-15T00:00:00Z`) or relative offset (`now-24h`, `now-1d`).\n", - "default": "now", - "example": "now" + "description": "WAF support identifier for correlating with support cases.", + "example": "1844305495056427365" }, - "limit": { + "policy_name": { + "type": "string", + "description": "Name of the WAF policy that processed the request.", + "example": "app_protect_default_policy" + }, + "country_code": { + "type": "string", + "maxLength": 2, + "description": "ISO 3166-1 alpha-2 country code of the client IP.", + "example": "US" + }, + "violation_rating": { "type": "integer", - "description": "Maximum items per dynamic dimension array (1-1000).\nDoes not apply to fixed enum dimensions.\n", - "minimum": 1, - "maximum": 1000, - "default": 100, - "example": 10 + "minimum": 0, + "maximum": 5, + "description": "Numeric violation severity rating (0-5).", + "example": 5 + }, + "instance_object_id": { + "type": "string", + "description": "NGINX One Console instance object identifier.", + "example": "inst_8Iwn7dT7RF-PRLxkSt5EYQ" + }, + "csg_object_id": { + "type": "string", + "description": "NGINX One Console Config Sync Group object identifier.", + "example": "csg_-uvR3F2TQGm18jnl7bpaGw" } } }, - "AttacksQueryRequest": { + "SecurityEvent": { "allOf": [ { - "$ref": "#/components/schemas/BaseQueryRequest" + "$ref": "#/components/schemas/SecurityEventBase" }, { "type": "object", - "description": "Request body for querying attack analytics.\n", + "description": "Full security event details including all metadata, violations, and signatures.\nUsed for the single event retrieval endpoint.\n", + "required": [ + "signatures", + "violations" + ], "properties": { - "group_by": { + "version": { + "type": "string", + "description": "Event schema version.", + "example": "v1.0" + }, + "system_id": { + "type": "string", + "description": "System identifier of the NGINX instance.", + "example": "31ed9d05-9cb0-48c3-9f97-d63b1b6dd342" + }, + "parent_hostname": { + "type": "string", + "description": "Hostname of the machine running NGINX.", + "example": "nginx-host-01" + }, + "http": { + "$ref": "#/components/schemas/HttpMetadata" + }, + "x_forwarded_for_header_value": { + "type": "string", + "description": "Value of the X-Forwarded-For header if present.", + "example": "203.0.113.42" + }, + "request_status": { + "allOf": [ + { + "$ref": "#/components/schemas/RequestStatus" + }, + { + "description": "WAF enforcement decision for the request.", + "example": "blocked" + } + ] + }, + "request_outcome": { + "allOf": [ + { + "$ref": "#/components/schemas/EventRequestOutcome" + }, + { + "description": "Binary outcome of WAF processing for the request.", + "example": "rejected" + } + ] + }, + "request_outcome_reason": { + "type": "string", + "description": "Reason code for the enforcement decision.", + "example": "SECURITY_WAF_VIOLATION" + }, + "blocking_exception_reason": { + "type": "string", + "description": "Reason if blocking was bypassed due to an exception.", + "example": "" + }, + "is_truncated": { + "type": "boolean", + "description": "Whether the request was truncated during processing.", + "example": false + }, + "signatures": { + "type": "array", + "description": "List of signatures triggered by this event.", + "items": { + "$ref": "#/components/schemas/SignatureDetail" + } + }, + "violations": { + "type": "array", + "description": "List of violations detected in this event.", + "items": { + "$ref": "#/components/schemas/ViolationDetail" + } + }, + "threat_campaign_names": { + "type": "array", + "description": "Names of threat campaigns associated with this event.", + "items": { + "type": "string" + }, + "example": [] + }, + "request": { + "type": "string", + "description": "Raw HTTP request (if available and not truncated).\nContains headers and body as received by the WAF.\n", + "example": "GET /?param=%3Cscript%3Ealert%27xss%27%3C%2Fscript%3E HTTP/1.1\r\nHost: example.com\r\nUser-Agent: curl/7.68.0\r\nAccept: */*\r\n\r\n" + } + } + } + ] + }, + "SecurityEventListItem": { + "allOf": [ + { + "$ref": "#/components/schemas/SecurityEventBase" + }, + { + "type": "object", + "description": "Summary of a security event for list display.\nContains key fields for quick scanning and filtering in the events list.\nThis is a subset of SecurityEvent optimized for the list view.\n", + "properties": { + "client_ip": { + "type": "string", + "description": "Client IP address that sent the request.", + "example": "192.168.1.100" + }, + "url": { + "type": "string", + "description": "Request URI path.", + "example": "/" + }, + "request_method": { + "type": "string", + "description": "HTTP request method.", + "example": "GET" + }, + "response_code": { + "type": "integer", + "description": "HTTP response status code.", + "example": 403 + }, + "request_status": { "allOf": [ { - "$ref": "#/components/schemas/AttacksDimensionField" + "$ref": "#/components/schemas/RequestStatus" }, { - "description": "Dimension to aggregate results by.\n\n**Fixed enum dimensions** (returned as objects with known keys):\n* `request_outcome` - blocked, passed, alerted\n* `request_method` - GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH\n\n**Simple array dimensions** (returned as arrays with code/count):\n* `response_code` - HTTP response codes\n\n**Dynamic dimensions** (returned as arrays with cross-dimension context):\n* `ip`, `country`, `policy`, `url`, `instance_object_id`, `csg_object_id`\n\n**Response behavior:**\n- If omitted: Returns `total` count only\n- If specified: Returns dimensional breakdown, `total` is omitted\n", - "example": "request_outcome" + "description": "WAF enforcement decision for the request.", + "example": "blocked" } ] - }, - "filter": { - "type": "array", - "description": "Pre-aggregation filter conditions.\nAll filters are combined with AND logic.\nUse the `in` operator to achieve `OR` within a single dimension.\n", - "items": { - "$ref": "#/components/schemas/AnalyticsFilter" - }, - "default": [] - }, - "order_by": { - "$ref": "#/components/schemas/AnalyticsOrderBy" } } } ] }, - "AttacksTimeSeriesQueryRequest": { + "SecurityEventListResponse": { "allOf": [ { - "$ref": "#/components/schemas/BaseQueryRequest" + "$ref": "#/components/schemas/PaginationResponse" }, { "type": "object", - "description": "Request body for querying attack analytics time series.\n", + "description": "Paginated list of security events.\n", + "required": [ + "items" + ], "properties": { - "resolution": { - "$ref": "#/components/schemas/Resolution" - }, - "group_by": { - "allOf": [ - { - "$ref": "#/components/schemas/AttacksTimeSeriesDimensionField" - }, - { - "description": "Dimension to break down time-series by.\nLimited to fixed enum dimensions for performance.\n\n* `request_outcome` - Returns `blocked`, `passed`, `alerted` series\n* `request_outcome_reason` - Returns the underlying reason for the outcome.\n\n**Common `request_outcome_reason` values:**\n- `SECURITY_WAF_OK`: Legitimate request, no violations.\n- `SECURITY_WAF_VIOLATION`: Request blocked due to signature or protocol violation.\n- `SECURITY_WAF_FLAGGED`: Violation detected, but request allowed (Transparent/Alert-only mode).\n- `SECURITY_WAF_VIOLATION_TRANSPARENT`: Request would have been blocked, but the policy/signature is in staging/transparent mode.\n- `SECURITY_NGINX_VIOLATION`: Request rejected due to NGINX-level constraints (e.g., malformed headers).\n- `SECURITY_WAF_BYPASS`: Request was explicitly allowed due to an allow-list or bypass rule.\n\n**Response behavior:**\n- If omitted: Returns `total` series only\n- If specified: Returns dimensional breakdown, `total` is omitted\n", - "example": "request_outcome" - } - ] - }, - "filter": { + "items": { "type": "array", - "description": "Pre-aggregation filter conditions.\nAll filters are combined with AND logic.\nUse the `in` operator to achieve `OR` within a single dimension.\n", + "description": "List of security events for the current page.", "items": { - "$ref": "#/components/schemas/AnalyticsFilter" - }, - "default": [] + "$ref": "#/components/schemas/SecurityEventListItem" + } } } } ] }, - "SignaturesDimensionField": { + "ViolationsMetricField": { "type": "string", - "description": "Available dimensions for grouping and filtering signature analytics.\n", + "description": "Count metric for violation context group_by queries.\n\n* hits: Total occurrence count (default)\n* unique: Distinct violation types per context\n", "enum": [ - "request_outcome", - "accuracy", - "risk", - "signature", - "cve" + "hits", + "unique" ], "x-enum-varnames": [ - "signatures_dimension_request_outcome", - "signatures_dimension_accuracy", - "signatures_dimension_risk", - "signatures_dimension_signature", - "signatures_dimension_cve" + "violations_metric_hits", + "violations_metric_unique" ] }, - "SignaturesTimeSeriesDimensionField": { + "ViolationsDimensionField": { "type": "string", - "description": "Dimensions available for time-series grouping of signature data.\nLimited to fixed enum dimensions that can be efficiently aggregated per time bucket.\n", + "description": "Available dimensions for grouping and filtering violation analytics.\n\n* violation: Primary violation type (e.g., \"Attack signature detected\", \"Illegal meta character in value\")\n* sub_violation: Sub-category or additional violation classification providing more granular detail. A value of \"N/A\" indicates no additional information.\n* context: Location where violation was detected (header, cookie, parameter, uri, request, other)\n* context_key: Field name within the detection context (cookie name, header name, parameter name)\n* context_value: Field value that triggered the violation\n", "enum": [ - "request_outcome", - "accuracy", - "risk" + "violation", + "sub_violation", + "context", + "context_key", + "context_value" ], "x-enum-varnames": [ - "signatures_ts_dimension_request_outcome", - "signatures_ts_dimension_accuracy", - "signatures_ts_dimension_risk" + "violations_dimension_violation", + "violations_dimension_sub_violation", + "violations_dimension_context", + "violations_dimension_context_key", + "violations_dimension_context_value" ] }, - "SignaturesQueryRequest": { + "ViolationsQueryRequest": { "allOf": [ { "$ref": "#/components/schemas/BaseQueryRequest" }, { "type": "object", - "description": "Request body for querying signature analytics.\n", + "description": "Request body for querying violation analytics.\n", "properties": { "group_by": { "allOf": [ { - "$ref": "#/components/schemas/SignaturesDimensionField" + "$ref": "#/components/schemas/ViolationsDimensionField" }, { - "description": "Dimension to aggregate results by.\n\n**Fixed enum dimensions** (returned as objects with known keys):\n* `request_outcome` - blocked, passed, alerted\n* `accuracy` - low, medium, high\n* `risk` - low, medium, high, critical\n\n**Dynamic dimensions** (returned as arrays sorted by count descending):\n* `signature` - Individual signatures with id, name, accuracy, risk\n* `cve` - CVE identifiers\n\n**Response behavior:**\n- If omitted: Returns `total` (signature hits) and `unique` (distinct signatures)\n- If specified: Returns dimensional breakdown, `total` and `unique` are omitted\n", - "example": "signature" + "description": "Dimension to aggregate results by.\n\n**Fixed enum dimensions** (returned as objects with known keys):\n* `context` - cookie, header, parameter, request, uri, other\n\n**Dynamic dimensions** (returned as arrays with cross-dimension context):\n* `violation` - WAF policy violation types (e.g., \"Attack signature detected\")\n* `sub_violation` - Specific subtypes providing granular detail (e.g., \"SQL-Injection\" or \"Missing Mandatory Host Header\"). Returns \"N/A\" if not applicable.\n\n**Response behavior:**\n- If omitted: Returns `total` (violation occurrences) and `unique` (distinct violation types)\n- If specified: Returns dimensional breakdown, `total` and `unique` are omitted\n", + "example": "violation" } ] }, - "filter": { - "type": "array", - "description": "Pre-aggregation filter conditions.\nAll filters are combined with AND logic.\nUse the `in` operator to achieve `OR` within a single dimension.\n", - "items": { - "$ref": "#/components/schemas/AnalyticsFilter" - }, - "default": [] - }, - "order_by": { - "$ref": "#/components/schemas/AnalyticsOrderBy" - } - } - } - ] - }, - "SignaturesTimeSeriesQueryRequest": { - "allOf": [ - { - "$ref": "#/components/schemas/BaseQueryRequest" - }, - { - "type": "object", - "description": "Request body for querying signature analytics time series.\n", - "properties": { - "resolution": { - "$ref": "#/components/schemas/Resolution" - }, - "group_by": { + "metric": { "allOf": [ { - "$ref": "#/components/schemas/SignaturesTimeSeriesDimensionField" + "$ref": "#/components/schemas/ViolationsMetricField" }, { - "description": "Dimension to break down time-series by.\nLimited to fixed enum dimensions for performance.\n\n* `request_outcome` - Returns `blocked`, `passed`, `alerted` series\n* `accuracy` - Returns `low`, `medium`, `high` series\n* `risk` - Returns `low`, `medium`, `high`, `critical` series\n\n**Response behavior:**\n- If omitted: Returns `total` series only\n- If specified: Returns dimensional breakdown, `total` is omitted\n", - "example": "request_outcome" + "description": "Count metric when `group_by=context`. Omit for default (`hits`).\n\n* `hits`: Total violation occurrence count per context\n* `unique`: Distinct violation types per context\n", + "example": "unique" } ] }, "filter": { "type": "array", - "description": "Pre-aggregation filter conditions.\nAll filters are combined with AND logic.\nUse the `in` operator to achieve `OR` within a single dimension.\n", + "description": "Pre-aggregation filter conditions.\nAll filters are combined with AND logic.\nUse the `in` operator to achieve `OR` within a single dimension.\n\nSupported filter dimensions include attack-level dimensions (policy, ip, url, etc.)\nin addition to violation-specific dimensions.\n", "items": { "$ref": "#/components/schemas/AnalyticsFilter" }, "default": [] + }, + "order_by": { + "$ref": "#/components/schemas/AnalyticsOrderBy" } } } ] }, - "HttpMetadata": { + "ViolationDistinctCounts": { "type": "object", - "description": "HTTP request and response metadata from the security event.\n", + "description": "Cross-dimension counts providing context about violations for a given dimension value.\nEach field represents a distinct count aggregation.\n", + "required": [ + "ips", + "urls", + "policies" + ], "properties": { - "hostname": { - "type": "string", - "description": "The HTTP Host header value.", - "example": "example.com" - }, - "remote_addr": { - "type": "string", - "description": "Client IP address.", - "example": "192.168.1.100" - }, - "remote_port": { + "ips": { "type": "integer", - "description": "Client source port.", - "example": 54321 - }, - "server_addr": { - "type": "string", - "description": "Server IP address that received the request.", - "example": "10.0.0.1" + "description": "Count of distinct source IP addresses associated with this violation type." }, - "server_port": { + "urls": { "type": "integer", - "description": "Server port that received the request.", - "example": 443 - }, - "uri": { - "type": "string", - "description": "Request URI path including query string.", - "example": "/api/login?user=admin" - }, - "request_method": { - "type": "string", - "description": "HTTP request method.", - "example": "GET" + "description": "Count of distinct URLs where this violation was triggered." }, - "response_code": { + "policies": { "type": "integer", - "description": "HTTP response status code.", - "example": 403 + "description": "Count of distinct WAF policies that triggered this violation." } + }, + "example": { + "ips": 15, + "urls": 8, + "policies": 3 } }, - "SignatureDetail": { + "ViolationDimensionItem": { "type": "object", - "description": "Details of a signature that was triggered by the security event.\nA single event can trigger multiple signatures.\n", + "description": "A single item in a violation dimensional breakdown.\n", "required": [ - "id", - "name" + "value", + "count", + "distinct" ], "properties": { - "id": { - "type": "integer", - "description": "Unique identifier of the signature.", - "example": 200001834 - }, - "name": { + "value": { "type": "string", - "description": "Human-readable name of the signature.", - "example": "XSS script tag end (Parameter)" - }, - "accuracy": { - "allOf": [ - { - "$ref": "#/components/schemas/SignatureAccuracy" - }, - { - "description": "Confidence level that this signature accurately identifies the attack.", - "example": "high" - } - ] + "description": "The violation or sub-violation name.\nExamples: \"Attack signature detected\", \"Illegal meta character in value\"\n" }, - "risk": { - "allOf": [ - { - "$ref": "#/components/schemas/SignatureRisk" - }, - { - "description": "Severity/risk level of the attack identified by this signature.", - "example": "high" - } - ] + "count": { + "type": "integer", + "description": "Total number of times this violation occurred within the queried time range.\n" }, - "cve": { - "type": "string", - "description": "CVE identifier if this signature is associated with a known vulnerability.", - "example": "CVE-2021-44228" + "distinct": { + "$ref": "#/components/schemas/ViolationDistinctCounts" + } + }, + "example": { + "value": "Illegal meta character in value", + "count": 1080, + "distinct": { + "ips": 1, + "urls": 1, + "policies": 1 + } + } + }, + "ViolationContextCountsResponse": { + "type": "object", + "description": "Violation counts grouped by context type.\nIndicates where in the HTTP request the violation was detected.\n", + "properties": { + "cookie": { + "type": "integer", + "description": "Count of violations detected in cookie values." }, - "blocking_mask": { - "type": "string", - "description": "Bitmask indicating blocking behavior configuration.", - "example": "0x0" + "header": { + "type": "integer", + "description": "Count of violations detected in HTTP headers." }, - "buffer": { - "type": "string", - "description": "The buffer/location where the signature matched (e.g., parameter name, header).", - "example": "param" + "parameter": { + "type": "integer", + "description": "Count of violations detected in request parameters (query string or body)." }, - "offset": { + "request": { "type": "integer", - "description": "Byte offset within the payload where the signature match begins.", - "example": 0 + "description": "Count of violations detected in the request body or general request context." }, - "length": { + "uri": { "type": "integer", - "description": "Length of the matched string in bytes.", - "example": 42 + "description": "Count of violations detected in the URI/URL path." } + }, + "example": { + "cookie": 0, + "header": 130, + "parameter": 1426, + "request": 302, + "uri": 0 } }, - "ViolationDetail": { + "ViolationsQueryResponse": { "type": "object", - "description": "Details of a violation detected in the security event.\nA single event can trigger multiple violations.\n", + "description": "Response for violation analytics query.\n\n**Response behavior:**\n- Without `group_by`: Returns `total` (total violation occurrences) and `unique` (distinct violation types)\n- With `group_by`: Returns dimensional breakdown only (e.g., `violation`, `context`), `total` and `unique` are omitted\n\nThe aggregate fields (`total`, `unique`) and dimensional breakdowns are mutually exclusive.\n", "required": [ - "name" + "query_metadata" ], "properties": { - "name": { - "type": "string", - "description": "Primary violation name/type.", - "example": "Illegal meta character in value" + "query_metadata": { + "$ref": "#/components/schemas/QueryMetadata" }, - "sub_name": { - "type": "string", - "description": "Sub-category or additional violation classification.", - "example": "" + "total": { + "type": "integer", + "description": "Total violation occurrence count for the query.\nOnly present when no `group_by` is specified.\n" + }, + "unique": { + "type": "integer", + "description": "Count of distinct violation types triggered.\nOnly present when no `group_by` is specified.\n" + }, + "violation": { + "type": "array", + "description": "Violation counts grouped by violation type.\nSorted by count descending.\n", + "items": { + "$ref": "#/components/schemas/ViolationDimensionItem" + } + }, + "sub_violation": { + "type": "array", + "description": "Violation counts grouped by sub-violation type.\nSorted by count descending.\n", + "items": { + "$ref": "#/components/schemas/ViolationDimensionItem" + } + }, + "context": { + "$ref": "#/components/schemas/ViolationContextCountsResponse" + }, + "context_key": { + "type": "array", + "description": "Violation counts grouped by detection context and field name.\nSorted by count descending. Only present when `group_by=context_key`.\n", + "items": { + "$ref": "#/components/schemas/ViolationContextKeyItem" + } }, + "context_value": { + "type": "array", + "description": "Violation counts grouped by detection context and field value.\nSorted by count descending. Only present when `group_by=context_value`.\n", + "items": { + "$ref": "#/components/schemas/ViolationContextValueItem" + } + } + } + }, + "ViolationContextKeyItem": { + "type": "object", + "description": "A single entry from a context_key dimension query.", + "properties": { "context": { "type": "string", - "description": "The context where the violation was detected (e.g., parameter, header, uri).", + "description": "Detection context (cookie, header, parameter, uri, request, other).", "example": "parameter" }, - "detail_name": { + "context_key": { "type": "string", - "description": "Technical violation identifier (e.g., VIOL_PARAMETER_VALUE_METACHAR).", - "example": "VIOL_PARAMETER_VALUE_METACHAR" + "description": "Field name within the context (e.g. cookie name, header name, parameter name).", + "example": "search" }, - "detail_context": { + "context_value": { "type": "string", - "description": "Additional context for the violation detail.", - "example": "parameter" + "description": "Most representative field value for this key.", + "example": "" }, - "field_name": { + "count": { + "type": "integer", + "description": "Number of times this key was involved in a violation.", + "example": 228 + } + } + }, + "ViolationContextValueItem": { + "type": "object", + "description": "A single entry from a context_value dimension query.", + "properties": { + "context": { "type": "string", - "description": "Name of the field that triggered the violation.", - "example": "param" + "description": "Detection context (cookie, header, parameter, uri, request, other).", + "example": "parameter" }, - "field_value": { + "context_value": { "type": "string", - "description": "The value that triggered the violation.", + "description": "Field value that triggered the violation.", "example": "" + }, + "count": { + "type": "integer", + "description": "Number of times this value was involved in a violation.", + "example": 228 } } }, - "SecurityEventBase": { + "BillingUsageEventsResponse": { "type": "object", - "description": "Base security event with common fields across all event types.\nSeverity is determined by violation_rating (0-5), not a separate field.\n", + "allOf": [ + { + "$ref": "#/components/schemas/PaginationResponse" + } + ], + "description": "Paginated response for billing usage events query.\n", "required": [ - "timestamp", - "support_id" + "items" ], "properties": { - "timestamp": { + "items": { + "type": "array", + "description": "List of billing usage events matching the query.", + "items": { + "$ref": "#/components/schemas/BillingUsageEvent" + } + } + } + }, + "BillingUsageEvent": { + "type": "object", + "description": "A single billing usage event containing NGINX information, usage metrics, NGINX metrics,\nNGINX deployment details, JWT token information, and event metadata.\n", + "required": [ + "event_id", + "jti", + "nginx_uid" + ], + "properties": { + "nginx_uid": { "type": "string", - "format": "date-time", - "description": "When the security event occurred.", - "example": "2024-01-22T12:13:25Z" + "format": "uuid", + "description": "Unique identifier for the NGINX instance.", + "example": "b84b6b2a-721b-46ce-87a4-449fcbc62bae" }, - "support_id": { + "nginx_version": { "type": "string", - "description": "WAF support identifier for correlating with support cases.", - "example": "1844305495056427365" + "description": "Version of the NGINX instance.", + "example": "1.29.3" }, - "request_outcome": { - "allOf": [ - { - "$ref": "#/components/schemas/EventRequestOutcome" - }, - { - "description": "WAF enforcement decision for the request.", - "example": "blocked" - } - ] + "nap_status": { + "$ref": "#/components/schemas/NAPStatus" }, - "policy_name": { + "start_time": { "type": "string", - "description": "Name of the WAF policy that processed the request.", - "example": "app_protect_default_policy" + "format": "date-time", + "description": "Start time of the event.", + "example": "2026-03-20T23:53:51.000Z" }, - "country_code": { + "end_time": { "type": "string", - "maxLength": 2, - "description": "ISO 3166-1 alpha-2 country code of the client IP.", - "example": "US" + "format": "date-time", + "description": "End time of the event.", + "example": "2026-03-23T19:33:19.000Z" }, - "violation_rating": { + "http_client_received": { "type": "integer", "minimum": 0, - "maximum": 5, - "description": "Numeric violation severity rating (0-5).", - "example": 5 + "description": "Bytes received from HTTP clients.", + "example": 11 }, - "instance_object_id": { + "http_client_sent": { + "type": "integer", + "minimum": 0, + "description": "Bytes sent to HTTP clients.", + "example": 12 + }, + "http_client_connections": { + "type": "integer", + "minimum": 0, + "description": "Number of HTTP client connections.", + "example": 13 + }, + "http_client_requests": { + "type": "integer", + "minimum": 0, + "description": "Number of HTTP client requests.", + "example": 14 + }, + "http_upstream_received": { + "type": "integer", + "minimum": 0, + "description": "Bytes received from HTTP upstreams.", + "example": 21 + }, + "http_upstream_sent": { + "type": "integer", + "minimum": 0, + "description": "Bytes sent to HTTP upstreams.", + "example": 22 + }, + "http_upstream_connections": { + "type": "integer", + "minimum": 0, + "description": "Number of HTTP upstream connections.", + "example": 23 + }, + "stream_client_received": { + "type": "integer", + "minimum": 0, + "description": "Bytes received from Stream clients.", + "example": 31 + }, + "stream_client_sent": { + "type": "integer", + "minimum": 0, + "description": "Bytes sent to Stream clients.", + "example": 32 + }, + "stream_client_connections": { + "type": "integer", + "minimum": 0, + "description": "Number of Stream client connections.", + "example": 33 + }, + "stream_upstream_received": { + "type": "integer", + "minimum": 0, + "description": "Bytes received from Stream upstreams.", + "example": 41 + }, + "stream_upstream_sent": { + "type": "integer", + "minimum": 0, + "description": "Bytes sent to Stream upstreams.", + "example": 42 + }, + "stream_upstream_connections": { + "type": "integer", + "minimum": 0, + "description": "Number of Stream upstream connections.", + "example": 43 + }, + "stream_connections": { + "type": "integer", + "minimum": 0, + "description": "Total number of stream connections.", + "example": 0 + }, + "user_agent": { "type": "string", - "description": "NGINX One Console instance object identifier.", - "example": "inst_8Iwn7dT7RF-PRLxkSt5EYQ" + "description": "User agent string.", + "example": "nginx/r36" }, - "csg_object_id": { + "workers": { + "type": "integer", + "minimum": 0, + "description": "Number of NGINX workers.", + "example": 51 + }, + "uptime": { + "type": "integer", + "minimum": 0, + "description": "NGINX uptime.", + "example": 52 + }, + "reloads": { + "type": "integer", + "minimum": 0, + "description": "Number of NGINX reloads.", + "example": 53 + }, + "deployment_cluster_id": { "type": "string", - "description": "NGINX One Console Config Sync Group object identifier.", - "example": "csg_-uvR3F2TQGm18jnl7bpaGw" - } - } - }, - "SecurityEvent": { - "allOf": [ - { - "$ref": "#/components/schemas/SecurityEventBase" + "format": "uuid", + "description": "Deployment cluster identifier.", + "example": "d24cdb86-9788-4bb5-8d3d-b95d914a618c" }, - { - "type": "object", - "description": "Full security event details including all metadata, violations, and signatures.\nUsed for the single event retrieval endpoint.\n", - "required": [ - "signatures", - "violations" - ], - "properties": { - "type": { - "type": "string", - "description": "Event type classification.", - "example": "Security Event" - }, - "version": { - "type": "string", - "description": "Event schema version.", - "example": "v1.0" - }, - "level": { - "allOf": [ - { - "$ref": "#/components/schemas/EventLevel" - }, - { - "description": "Log level classification for the security event.\n", - "example": "WARNING" - } - ] - }, - "service_id": { - "type": "string", - "description": "Service identifier that generated the event.", - "example": "2b63403b-b8fc-4dd5-a0e9-0ee7d2d252fb" - }, - "correlation_id": { - "type": "string", - "description": "Identifier for correlating related events.", - "example": "6707cc37-d416-4077-bd12-777491027011" - }, - "description": { - "type": "string", - "description": "Human-readable event description.", - "example": "Attack detected" - }, - "system_id": { - "type": "string", - "description": "System identifier of the NGINX instance.", - "example": "31ed9d05-9cb0-48c3-9f97-d63b1b6dd342" - }, - "parent_hostname": { - "type": "string", - "description": "Hostname of the machine running NGINX.", - "example": "nginx-host-01" - }, - "http": { - "$ref": "#/components/schemas/HttpMetadata" - }, - "x_forwarded_for_header_value": { - "type": "string", - "description": "Value of the X-Forwarded-For header if present.", - "example": "203.0.113.42" - }, - "request_status": { - "allOf": [ - { - "$ref": "#/components/schemas/RequestStatus" - }, - { - "description": "Status of request processing.", - "example": "complete" - } - ] - }, - "request_outcome_reason": { - "type": "string", - "description": "Reason code for the enforcement decision.", - "example": "SECURITY_WAF_VIOLATION" - }, - "blocking_exception_reason": { - "type": "string", - "description": "Reason if blocking was bypassed due to an exception.", - "example": "" - }, - "is_truncated": { - "type": "boolean", - "description": "Whether the request was truncated during processing.", - "example": false - }, - "signatures": { - "type": "array", - "description": "List of signatures triggered by this event.", - "items": { - "$ref": "#/components/schemas/SignatureDetail" - } - }, - "violations": { - "type": "array", - "description": "List of violations detected in this event.", - "items": { - "$ref": "#/components/schemas/ViolationDetail" - } - }, - "threat_campaign_names": { - "type": "array", - "description": "Names of threat campaigns associated with this event.", - "items": { - "type": "string" - }, - "example": [] - }, - "request": { - "type": "string", - "description": "Raw HTTP request (if available and not truncated).\nContains headers and body as received by the WAF.\n", - "example": "GET /?param=%3Cscript%3Ealert%27xss%27%3C%2Fscript%3E HTTP/1.1\r\nHost: example.com\r\nUser-Agent: curl/7.68.0\r\nAccept: */*\r\n\r\n" - } - } - } - ] - }, - "SecurityEventListItem": { - "allOf": [ - { - "$ref": "#/components/schemas/SecurityEventBase" + "deployment_cluster_node_count": { + "type": "integer", + "minimum": 0, + "description": "Number of nodes in the deployment cluster.", + "example": 5 }, - { - "type": "object", - "description": "Summary of a security event for list display.\nContains key fields for quick scanning and filtering in the events list.\nThis is a subset of SecurityEvent optimized for the list view.\n", - "properties": { - "client_ip": { - "type": "string", - "description": "Client IP address that sent the request.", - "example": "192.168.1.100" - }, - "url": { - "type": "string", - "description": "Request URI path.", - "example": "/" - }, - "method": { - "type": "string", - "description": "HTTP request method.", - "example": "GET" - }, - "response_code": { - "type": "integer", - "description": "HTTP response status code.", - "example": 403 - } - } - } - ] - }, - "SecurityEventListResponse": { - "allOf": [ - { - "$ref": "#/components/schemas/PaginationResponse" + "deployment_installation_id": { + "type": "string", + "format": "uuid", + "description": "Deployment installation identifier.", + "example": "c548592a-5afb-4e23-84f0-8a5b197dcf96" }, - { - "type": "object", - "description": "Paginated list of security events.\n", - "required": [ - "items" - ], - "properties": { - "items": { - "type": "array", - "description": "List of security events for the current page.", - "items": { - "$ref": "#/components/schemas/SecurityEventListItem" - } - } - } + "deployment_product_type": { + "$ref": "#/components/schemas/ProductType" + }, + "sub": { + "type": "string", + "description": "JWT subject claim identifying the subscription associated with this usage event.", + "example": "TST-ff13edf7-f912-42c0-ba2e-39c513bb3882" + }, + "jti": { + "type": "string", + "format": "uuid", + "description": "JWT Token ID.", + "example": "18a10260-0ec4-11f1-bbca-5d8e192a1888" + }, + "f5_sat": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "F5 service activation time expiry time, as a Unix epoch timestamp.", + "example": 1772323200 + }, + "f5_order_type": { + "type": "string", + "description": "F5 order type.", + "example": "paid" + }, + "aud": { + "type": "string", + "description": "JWT audience claim identifying the intended recipient of the token.", + "example": "urn:f5:teem" + }, + "iss": { + "type": "string", + "description": "JWT issuer claim identifying the entity that issued the token.", + "example": "F5 Inc." + }, + "iat": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "JWT issued-at time as a Unix epoch timestamp.", + "example": 1771637081 + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "dedup_version": { + "type": "string", + "format": "date-time", + "description": "Deduplication version timestamp assigned for storage-level upsert/deduplication.", + "example": "2026-03-23T19:33:32.284Z" + }, + "event_id": { + "type": "string", + "description": "Unique event identifier.", + "example": "4nNhnUFf23Zf4PExDYtcYZUkfHlyW48JouApQkxFqzo=" } - ] + } }, - "ViolationsDimensionField": { + "SourceType": { "type": "string", - "description": "Available dimensions for grouping and filtering violation analytics.\n\n* violation: Primary violation type (e.g., \"Attack signature detected\", \"Illegal meta character in value\")\n* sub_violation: Sub-category or additional violation classification providing more granular detail. A value of \"N/A\" indicates no additional information.\n* context: Location where violation was detected (header, cookie, parameter, uri, request, other)\n", + "description": "Source type of the billing usage event.\n* `SOURCE_TYPE_NGINX_ONE` - NGINX One\n* `SOURCE_TYPE_NIM` - NGINX Instance Manager\n", "enum": [ - "violation", - "sub_violation", - "context" + "SOURCE_TYPE_NGINX_ONE", + "SOURCE_TYPE_NIM" ], "x-enum-varnames": [ - "violations_dimension_violation", - "violations_dimension_sub_violation", - "violations_dimension_context" - ] + "source_type_nginx_one", + "source_type_nim" + ], + "example": "SOURCE_TYPE_NGINX_ONE" }, - "ViolationsQueryRequest": { - "allOf": [ - { - "$ref": "#/components/schemas/BaseQueryRequest" - }, - { - "type": "object", - "description": "Request body for querying violation analytics.\n", - "properties": { - "group_by": { - "allOf": [ - { - "$ref": "#/components/schemas/ViolationsDimensionField" - }, - { - "description": "Dimension to aggregate results by.\n\n**Fixed enum dimensions** (returned as objects with known keys):\n* `context` - cookie, header, parameter, request, uri, other\n\n**Dynamic dimensions** (returned as arrays with cross-dimension context):\n* `violation` - WAF policy violation types (e.g., \"Attack signature detected\")\n* `sub_violation` - Specific subtypes providing granular detail (e.g., \"SQL-Injection\" or \"Missing Mandatory Host Header\"). Returns \"N/A\" if not applicable.\n\n**Response behavior:**\n- If omitted: Returns `total` (violation occurrences) and `unique` (distinct violation types)\n- If specified: Returns dimensional breakdown, `total` and `unique` are omitted\n", - "example": "violation" - } - ] - }, - "filter": { - "type": "array", - "description": "Pre-aggregation filter conditions.\nAll filters are combined with AND logic.\nUse the `in` operator to achieve `OR` within a single dimension.\n\nSupported filter dimensions include attack-level dimensions (policy, ip, url, etc.)\nin addition to violation-specific dimensions.\n", - "items": { - "$ref": "#/components/schemas/AnalyticsFilter" - }, - "default": [] - }, - "order_by": { - "$ref": "#/components/schemas/AnalyticsOrderBy" - } - } - } - ] + "NAPStatus": { + "type": "string", + "description": "NGINX App Protect status of the instance.\n* `NAP_STATUS_INACTIVE_OR_UNSPECIFIED` - Not specified or inactive\n* `NAP_STATUS_ACTIVE` - Active\n", + "enum": [ + "NAP_STATUS_INACTIVE_OR_UNSPECIFIED", + "NAP_STATUS_ACTIVE" + ], + "x-enum-varnames": [ + "nap_status_inactive_or_unspecified", + "nap_status_active" + ], + "example": "NAP_STATUS_ACTIVE" + }, + "ProductType": { + "type": "string", + "description": "Deployment product type.\n* `PRODUCT_TYPE_UNSPECIFIED` - Not specified is treated as being NGINX+\n* `PRODUCT_TYPE_NIC` - NGINX Ingress Controller\n* `PRODUCT_TYPE_NGF` - NGINX Gateway Fabric\n", + "enum": [ + "PRODUCT_TYPE_UNSPECIFIED", + "PRODUCT_TYPE_NIC", + "PRODUCT_TYPE_NGF" + ], + "x-enum-varnames": [ + "product_type_unspecified", + "product_type_nic", + "product_type_ngf" + ], + "example": "PRODUCT_TYPE_NIC" } }, "examples": { @@ -15495,6 +18656,158 @@ ] } }, + "SubmissionWithPreviewOnly": { + "value": { + "conf_path": "/etc/nginx/nginx.conf", + "base_template": { + "object_id": "tmplv_-uvR3F2TQGm18jnl7bpaGw", + "values": { + "upstream_servers": [ + "10.0.0.1:8080", + "10.0.0.2:8080" + ], + "server_name": "example.com" + } + }, + "augments": [ + { + "object_id": "tmplv_-uvR3F2TQGm18jnl7bpaGw", + "target_context": "http/upstream", + "values": { + "upstream_servers": [ + "10.0.0.1:8080", + "10.0.0.2:8080" + ], + "server_name": "example.com" + } + }, + { + "object_id": "tmplv_-xeR3F2TQGm18jnl7bpaAw", + "target_context": "http", + "values": { + "enabled": "on", + "types": "text/plain application/json" + } + }, + { + "object_id": "tmplv_-abR3F2TQGm18jnl7bpaXw", + "target_context": "http", + "values": { + "zone_name": "req_limit", + "memory": "10m", + "rate": "10r/s" + } + }, + { + "object_id": "tmplv_-cdR3F2TQGm18jnl7bpaZw", + "target_context": "http/server", + "values": { + "zone_name": "req_limit", + "burst": 5 + }, + "child_augments": [ + { + "object_id": "tmplv_-cdR3F2TQGm18jnl7bpaZw", + "target_context": "http/server/location", + "values": { + "zone_name": "req_limit", + "burst": 5 + } + } + ] + } + ] + } + }, + "SubmissionForCreateNewStagedConfig": { + "value": { + "conf_path": "/etc/nginx/nginx.conf", + "base_template": { + "object_id": "tmplv_-uvR3F2TQGm18jnl7bpaGw", + "values": { + "upstream_servers": [ + "10.0.0.1:8080", + "10.0.0.2:8080" + ], + "server_name": "example.com" + } + }, + "augments": [ + { + "object_id": "tmplv_-abR3F2TQGm18jnl7bpaXw", + "target_context": "http", + "values": { + "zone_name": "req_limit", + "memory": "10m", + "rate": "10r/s" + } + } + ], + "payloads": [ + { + "type": "managed_certificate", + "object_id": "cert_rto8NYiCQputrIasNx2NOA", + "paths": [ + "/etc/nginx/cert.pem" + ] + }, + { + "type": "managed_key", + "object_id": "cert_rto8NYiCQputrIasNx2NOA", + "paths": [ + "/etc/nginx/key.pem" + ] + } + ], + "description": "Create a new staged config for reverse proxy with rate limiting" + } + }, + "SubmissionForUpdateExistingStagedConfigTarget": { + "value": { + "conf_path": "/etc/nginx/nginx.conf", + "base_template": { + "object_id": "tmplv_-uvR3F2TQGm18jnl7bpaGw", + "values": { + "upstream_servers": [ + "10.0.0.1:8080", + "10.0.0.2:8080" + ], + "server_name": "example.com" + } + }, + "augments": [ + { + "object_id": "tmplv_-abR3F2TQGm18jnl7bpaXw", + "target_context": "http", + "values": { + "zone_name": "req_limit", + "memory": "10m", + "rate": "10r/s" + } + } + ], + "payloads": [ + { + "type": "managed_certificate", + "object_id": "cert_rto8NYiCQputrIasNx2NOA", + "paths": [ + "/etc/nginx/cert.pem" + ] + }, + { + "type": "managed_key", + "object_id": "cert_rto8NYiCQputrIasNx2NOA", + "paths": [ + "/etc/nginx/key.pem" + ] + } + ], + "description": "Update existing staged config for reverse proxy with rate limiting", + "target_object_ids": [ + "sc_cEoiYCVJRuekVpYOvV1raA" + ] + } + }, "TemplateBaseSummary": { "value": { "name": "reverse_proxy", @@ -15608,6 +18921,12 @@ "tags": [ "Templates" ] + }, + { + "name": "NGINX One App Protect Analytics", + "tags": [ + "NGINX One App Protect" + ] } ] } \ No newline at end of file