> ## Documentation Index
> Fetch the complete documentation index at: https://docs.casebender.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Tenable.io

> Ingest Tenable.io vulnerability findings into CaseBender by automatic polling (pull) using the Vulnerability Export API.

## Overview

The Tenable.io integration (**INT-003**) ingests vulnerability findings into CaseBender,
enriches them with CVSS-based severity and CVE observables, and turns them into alerts (and
optionally cases).

<Tip>
  **Recommended: enable Automatic polling.** CaseBender pulls new vulnerabilities
  directly from Tenable.io on a schedule using the Vulnerability Export API — no
  inbound endpoint is required. See
  [Automatic polling](#inbound-automatic-polling-recommended).
</Tip>

<Note>
  Polling uses the **Tenable.io Vulnerability Export API**, authenticated with an
  **API key pair** (access key + secret key).
</Note>

## Capabilities

| Capability                       | Direction | Description                                                               |
| -------------------------------- | --------- | ------------------------------------------------------------------------- |
| **Vulnerability polling (pull)** | Inbound   | CaseBender exports vulnerabilities on a schedule and ingests new findings |
| Observable extraction            | Inbound   | Host IPs, hostnames, and CVEs                                             |
| CVSS severity mapping            | Inbound   | Findings are mapped to CaseBender severity from CVSS                      |
| Severity threshold               | Inbound   | Optionally pull only findings at/above a minimum severity                 |

## Prerequisites

<Steps>
  <Step title="Create API keys">
    In Tenable.io, go to **Settings → My Account → API Keys** and generate a key pair. Copy the
    **Access Key** and **Secret Key**.
  </Step>

  <Step title="Network egress">
    The CaseBender poller must reach `https://cloud.tenable.com` (or your private Tenable.io
    region URL).
  </Step>
</Steps>

## Configure the integration in CaseBender

<Steps>
  <Step title="Open the integration catalog">
    Go to **Settings → Integrations → Create**, then choose **Tenable.io** from the
    **Vulnerability Management** category.
  </Step>

  <Step title="Enter API keys">
    | Field                       | Description                                                                            |
    | --------------------------- | -------------------------------------------------------------------------------------- |
    | Access Key                  | Tenable.io API access key                                                              |
    | Secret Key                  | Tenable.io API secret key                                                              |
    | API URL (optional)          | Defaults to `https://cloud.tenable.com`                                                |
    | Minimum severity (optional) | One of `info`, `low`, `medium`, `high`, `critical` — only findings at/above are pulled |
  </Step>

  <Step title="Enable automatic polling (recommended)">
    | Option                        | Effect                                                                            |
    | ----------------------------- | --------------------------------------------------------------------------------- |
    | `pollingEnabled`              | Turn on scheduled export + ingestion                                              |
    | `pollingIntervalMinutes`      | How often to poll (default `15`; exports are asynchronous, so 15+ is recommended) |
    | `pollingInitialLookbackHours` | On first run, import findings updated within this window (default `24`)           |
    | `pollMaxItemsPerRun`          | Safety cap on items ingested per run (default `500`)                              |
  </Step>

  <Step title="Configure auto-case creation">
    | Option               | Effect                                                         |
    | -------------------- | -------------------------------------------------------------- |
    | `autoCreateCases`    | Promote each finding to a **Case** (deduped by asset + plugin) |
    | `minSeverityForCase` | Only auto-create cases at/above this severity                  |
  </Step>
</Steps>

## Inbound (automatic polling, recommended)

Tenable exposes incremental vulnerability data through an **asynchronous export job**. CaseBender
manages that flow automatically:

<Steps>
  <Step title="Request an export">
    On each interval, CaseBender requests an export of `OPEN`/`REOPENED` vulnerabilities updated
    since the last cursor (optionally severity-filtered). On first run, the window is
    `pollingInitialLookbackHours`.
  </Step>

  <Step title="Wait + resume">
    CaseBender waits (bounded) for the export to finish and downloads its chunks. If the export
    is still building when the in-tick budget elapses, its ID is saved and the next tick resumes
    it — no data is lost.
  </Step>

  <Step title="Cursor + deduplication">
    After a completed export, the cursor advances to the run time. Findings are **deduplicated by
    `asset.uuid` + `plugin.id`**, so overlapping windows never create duplicates.
  </Step>
</Steps>

<Info>
  Because exports are asynchronous, findings may appear a few minutes after they are updated in
  Tenable. This is expected for vulnerability data and controlled by `pollingIntervalMinutes`.
</Info>

## Security considerations

* **Secret handling** — the API keys are stored in the integration settings; rotate on your
  organization's schedule.
* **Least privilege** — use keys tied to a user account with read access to vulnerabilities.
* **Network** — restrict egress to your Tenable.io region URL.

## Troubleshooting

<AccordionGroup>
  <Accordion title="Polling is enabled but no findings appear">
    Confirm the access/secret keys are valid and there are `OPEN`/`REOPENED` findings updated
    since the cursor. Exports take time; allow at least one full interval. Lower the `Minimum
            severity` if it filters everything out.

    **Make sure all CaseBender services are running** — with Docker, `docker compose ps` should
    show the `worker` and `misp-processor` services `Up`.
  </Accordion>

  <Accordion title="Export failed">
    A `Tenable export … failed` error indicates the export job errored server-side. It will be
    retried on the next interval. Verify the keys have vulnerability export permission.
  </Accordion>
</AccordionGroup>

## Related documentation

* [Integrations overview](./introduction.mdx)
* [Tenable Developer Portal](https://developer.tenable.com/)
