Tenable.io / Tenable One
Pulls vulnerability workbench data from Tenable's cloud platform to derive KRIs for critical CVE age, scan coverage, SLA breach, internet-facing exposure, MTTR, VPR risk trajectory, and credentialed scan health.
At a glance
| Vendor | Tenable — Tenable.io (VM) and Tenable One (exposure management platform) |
|---|---|
| Source type | vulnerability |
| Vendor ID (slug) | tenable-io |
| Base URL | https://cloud.tenable.com — fixed for every customer. Tenable.sc (on-prem) is a different integration and not covered here. |
| Auth method | Tenable's two-key API format — X-ApiKeys: accessKey=<K>;secretKey=<S>. The Draxis form uses the OAuth2 two-field shape; map Client ID → Access Key, Client Secret → Secret Key. The connector composes the X-ApiKeys header manually and never sends Authorization Bearer. |
| Schedule default | daily — the MTTR KRI looks back 90 days so hourly adds no signal and multiplies API cost. |
| Licensing | Any Tenable.io or Tenable One tier. VPR requires the Vulnerability Priority Rating feature (included by default). Some workbench filters (e.g. asset.has_public_ip) need the full Asset Intelligence module; tenants without it will get 0 on the internet-facing KRI. |
| Availability | New in 2026.04. |
Required scopes & roles
Tenable API keys inherit the role of the user who mints them. For least privilege, create a dedicated service user with a custom read-only role and mint the key pair as that user. The connector needs only these capabilities:
- Can View — Vulnerabilities (workbench reads for 6 of the 7 KRIs).
- Can View — Assets (asset count, coverage, authenticated-scan status).
- Can View — Scans (reserved for future scan-history KRIs; not used by the current 7 KRIs, but safer to include up front so you don't have to re-issue keys later).
The built-in Tenable "Basic" role ships with these read permissions and nothing else — that's the simplest fit. Do not use the "Administrator" role or add "Can Scan", "Can Manage", or "Can Use" permissions — the connector never writes to Tenable.
Setup steps
- Create a dedicated service user. In the Tenable console, go to Settings → Access Control → Users → Create User. Name it
draxis-connector, use a role-mailbox email, and set a long random password. Assign the built-in Basic role (or a custom role with only the three "Can View" permissions above). - Scope the user to the right data. If you use Tenable's Access Groups to segment data (e.g. separate business units), assign the service user to the access group you want Draxis to cover. Every KRI query inherits that scope.
- Enable MFA on the service user (My Account → Multi-Factor Authentication, as that user). Treat this like any other admin account — MFA prevents credential theft from leaking into full API access.
- Sign in as the service user and generate the API key pair. Log out of your admin account, sign in as
draxis-connector, go to My Account → API Keys → Generate. Tenable shows the Access Key and the Secret Key once — copy both into your password manager immediately.
Critical: API keys inherit the minting user's role at generation time. Minting while logged in as an Administrator gives the keys Administrator reach regardless of which user you intended them for. Always sign in as the service user first, then click Generate. - (Optional) Restrict by IP. Tenable supports IP allowlisting on API keys (My Account → API Keys → Additional Options). Allowlist the Draxis egress range after you've confirmed the connector works.
Wire it into Draxis
- Open Settings → Integrations in your tenant.
- Click Add integration and pick Vulnerability Scanner as the source type.
- Pick Tenable.io / Tenable One from the vendor dropdown. Draxis auto-fills
https://cloud.tenable.comas the base URL and the daily schedule. - In Client ID, paste the Tenable Access Key from step 4.
- In Client Secret, paste the Tenable Secret Key. Draxis encrypts it server-side with
encryption.keybefore storage. - Click Test. Green means Draxis called
GET /sessionsuccessfully — the message includes your Tenable username and container (account) name so you can confirm the right user is wired up. - Under KRIs to import, tick the KRIs you want Draxis to manage. All seven
tenable_*KRIs are checked by default; uncheck any you don’t need. Selected rows are created on save with the seeded thresholds. Unchecking a previously-imported KRI deletes it on save. - Save. The connector runs
dailyby default; use Run now from run history to trigger the first sync immediately.
KRIs produced
| Slug | Meaning | Derivation |
|---|---|---|
tenable_critical_cves_30d_plus |
Open critical-severity vulnerabilities first found more than 30 days ago | GET /workbenches/vulnerabilities?filter severity=critical, state=open, plugin.first_found_days > 30, read total_vulnerability_count. |
tenable_asset_coverage_pct |
% of known assets scanned in the last 30 days | round((count(assets where last_scan_date within 30d) / count(all assets)) * 100, 1). Reports 100% on accounts with zero assets. |
tenable_vuln_sla_breach_total |
Sum of open vulns past their severity's patching SLA | Four workbench counts, summed: critical >7d + high >30d + medium >90d + low >180d. SLAs are hardcoded industry defaults — adjust by editing SLA_DAYS_BY_SEVERITY in the connector if your org policy differs. |
tenable_internet_facing_critical |
Open critical vulns on assets with a public IP | filter severity=critical, state=open, asset.has_public_ip=yes. |
tenable_mttr_critical_days |
Average days-to-fix for criticals fixed in the last 90 days | Enumerate fixed-critical vulns from the last 90d (paginated, capped at 500 pages × 200 = 100k), compute avg(last_fixed − first_found) in days. Returns 0 on accounts with no fixed criticals in the window. |
tenable_high_vpr_open_vulns |
Open vulnerabilities with VPR ≥ 7.0 | filter plugin.vpr_score >= 7, state=open. VPR = Vulnerability Priority Rating — blends CVSS + real-world exploit data into a 0–10 score. |
tenable_unauth_scan_coverage_gap |
Active assets with no successful authenticated scan in 30 days | filter asset.last_authenticated_results (date-lt) 30. Proxy for "scans that couldn't authenticate" — the operational consequence is the same, regardless of whether the scan failed, wasn't scheduled, or the credential was rejected. |
Each row is a slug the connector writes to. Draxis creates the matching kri rows automatically when you check them in the KRIs to import section of the integration form — no manual API call or seed script needed. Thresholds shown in the table are the seeded defaults; you can edit them freely in the KRIs tab afterwards.
Vendor quirks
- Two-key auth, not OAuth2. The Draxis form labels read "Client ID" and "Client Secret" — that's the underlying storage shape, not a protocol claim. For Tenable, map them to Access Key (Client ID) and Secret Key (Client Secret). The connector's authorization pill under the header reads
X-ApiKeys (via oauth2 form)as a reminder. - Keys inherit the minting user's role permanently. Generating keys while logged in as an Administrator gives them Administrator reach — forever. Always log out, sign in as the service user, then click Generate. (This is the single most common setup mistake.)
- SLA thresholds are hardcoded to 7/30/90/180 days. Industry-typical defaults for critical / high / medium / low. Different SLAs require editing
SLA_DAYS_BY_SEVERITYin the connector — one-line change. Per-integration overrides via extraConfig are intentionally not supported: SLA is an org policy, not an integration config, and divergence between docs + code is worse than slight friction to update. - MTTR enumerates fixed vulns, not a summary endpoint. Tenable has no "give me mean time to fix" endpoint. The connector paginates fixed criticals from the last 90d and averages (last_fixed − first_found). Capped at 100k rows — orgs with more fixed criticals in 90 days (very rare) should open a support request. Returns 0 if nothing fixed in the window, which is benign (no data) rather than alarming.
- VPR is a Tenable feature, not a CVSS score. VPR ≥ 7.0 roughly corresponds to CVE + active exploitation signal. It's narrower than CVSS 7.0+ because VPR discounts CVEs with no observed exploitation. If your org wants CVSS-based, change the filter to
plugin.cvss3_base_scoreorplugin.cvss_base_scorein the connector — one-line change. - "Unauthenticated scan coverage gap" is a proxy, not a scan-failure count. The KRI counts active assets without a recent authenticated scan — captures scans that couldn't authenticate, scans that weren't scheduled, and scans that were skipped due to agent issues. All three have the same operational consequence: Tenable isn't seeing deep-inspection data for these assets. A strict "scans that ran but had credential errors" count would require iterating scan run histories (expensive); on the roadmap.
- Access Groups scope every KRI. If you put the service user in a specific Access Group (step 2 of setup), every query is implicitly bounded to that group. Usually what you want for per-business-unit KRIs; unexpected if you assumed global visibility.
- Rate limits are reasonable. Tenable.io's default API rate limit is 3000 req/5min per API key. The connector makes ~12 calls per run (probe + 7 KRIs, with the SLA and MTTR KRIs each doing multiple calls internally). This is nowhere near the ceiling at daily schedule; even hourly is safe.
- Key rotation. Tenable API keys don't auto-expire, but security best practice is quarterly rotation. Rotate by generating a new pair, updating Draxis, then deleting the old pair under My Account → API Keys → Delete. Keep the gap short (minutes, not days) — both pairs are live until deletion, so overlap is safe.
- Tenable.sc (on-prem) is a different integration. This connector targets the cloud product at
cloud.tenable.com. Tenable.sc has a different API, different auth (username/password + session token), and requires a different connector — open a feature request if you need it.
Troubleshooting
- HTTP 401 on Test — access key or secret key is wrong, or the service user was deleted / locked. Generate a new pair under the service user.
- HTTP 403 on a specific workbench endpoint — the service user's role is missing that read permission (usually "Can View — Vulnerabilities" or "Can View — Assets"). Edit the role and re-try.
tenable_asset_coverage_pct= 100 but you know coverage is incomplete — the Tenable account has zero assets, so the connector reports 100% rather than dividing by zero. Import or scan some assets, or ignore the KRI until you have inventory.tenable_mttr_critical_days= 0 — usually means no critical vulns were fixed in the last 90 days (run log reportsmttr_sample_size). Benign if your remediation rate is low; concerning if you know you've been fixing criticals but they're not appearing asstate=fixed(rescan required).tenable_internet_facing_criticalis always 0 — your tenant may not have the Asset Intelligence module that populatesasset.has_public_ip. Check the filter works manually in the workbench UI before assuming the KRI is broken.rowsSkipped > 0androwsWritten = 0— your tenant hasn't imported any KRIs for this integration yet. Open the integration in Settings → Integrations, tick the KRIs under KRIs to import, and save.- Still stuck? Open a support ticket with the run ID (from Run history) and we'll dig in.