Skip to content

Bug: tenable_one.attack_path.vectors.top_attack_paths_search() always fails with 403 because it calls an undocumented path #1052

Open

Description

@lanz

Describe the bug

TenableOne.attack_path.vectors.top_attack_paths_search() fails on every call with 403 Forbidden ("Insufficient scope"). It POSTs to /api/v1/t1/top-attack-paths/search, but the documented endpoint is POST /api/v1/t1/apa/top-attack-paths/search, with an apa/ segment.

This is the documented replacement for the Attack Path Analysis list endpoints, which were deprecated and removed on 2025-10-30 (Attack Path Analysis: Deprecated Endpoints). As a result, pyTenable has no working way to search attack paths.

Even with the path corrected, the method has more problems:

  • No paging. There's no offset argument, so callers can't get past the first page.
  • Pagination is lost. The response model expects a top-level total, but the API returns {"data": [...], "pagination": {"total", "offset", "limit", "sort"}}. So response.total is always None, and the pagination details are dropped.
  • Missing row fields. The row model is missing priority, graph_node and mitigations, which the API returns on every row. The docstring example attack_path.priority raises AttributeError.
  • Broken examples. The docstring filter examples use the operators gte and in, which the API rejects with 400.

There's also no method for the sibling replacement endpoint, POST /api/v1/t1/apa/top-attack-techniques/search.

To Reproduce

from tenable.tenableone import TenableOne

t1 = TenableOne(access_key='...', secret_key='...')
t1.attack_path.vectors.top_attack_paths_search()
# tenable.errors.ForbiddenError: [403: POST] https://cloud.tenable.com/api/v1/t1/top-attack-paths/search?limit=1000&exclude_resolved=True
#   body=b'{"statusCode":403,"error":"Forbidden","message":"Insufficient scope"}'

The same API keys return 200 from the documented path:

t1.post('api/v1/t1/apa/top-attack-paths/search', params={'limit': 1000})

Expected behavior

top_attack_paths_search() calls the documented endpoint, supports offset, and returns the attack paths with their pagination details. A top_attack_techniques_search() method covers the other replacement endpoint.

The attack_path.vectors.list() and attack_path.findings.list() methods, which wrap the deprecated GET endpoints, emit a DeprecationWarning pointing to the search methods.

Workaround

Call the documented endpoint directly:

page = t1.post('api/v1/t1/apa/top-attack-paths/search',
               params={'limit': 1000, 'offset': 0}, json={})

System Information:

Additional context

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions