generated: '2026-08-04' method: searched source: >- openapi/malwarebytes-threatdown-nebula-openapi.json, openapi/malwarebytes-threatdown-oneview-openapi.json (info.description "Access' scopes" and "User permissions" sections, plus per-operation security requirements) docs: https://api.threatdown.com/nebula/v1/docs summary: >- Authorization is TWO independent layers, and reading only the OAuth scopes gives a misleading picture. Layer one is a three-value OAuth2 scope (read / write / execute) fixed when the application is created. Layer two is a granular permission model — 86 distinct permissions on Nebula, 84 on OneView — held by the USER who created the application. Both must pass. Both fail as a bare 403 with no way to tell which gate closed. oauth2: grant: client_credentials token_endpoints: - api: nebula url: https://api.threatdown.com/oauth2/token operation_id: api.oauth2.token - api: oneview url: https://api.threatdown.com/oneview/oauth2/token operation_id: api.oneview.oauth2.token spec_defect: >- securitySchemes declares tokenUrl "/token" on the Nebula definition, which does not match the documented operation POST /oauth2/token. Relative and wrong. provisioning: >- Console-only, Super Admin required. Nebula/OneView → Integrate → Add → name the application, check read and/or write and/or execute → Save. Scope is FIXED at creation; widening it requires issuing new credentials. There is no programmatic credential-issuance API. granularity_note: >- Three scopes for 841 operations is very coarse. `read` grants read access to the entire account — endpoints, detections, EDR telemetry, vulnerability data, drive encryption state — with no resource-level narrowing. Least privilege has to be achieved through the user-permission layer instead, which means it depends on the role of whoever clicked "Add" in the console. schemes: - name: client_credentials source: openapi/malwarebytes-threatdown-nebula-openapi.json flows: - flow: clientCredentials tokenUrl: /token tokenUrl_actual: https://api.threatdown.com/oauth2/token - name: client_credentials source: openapi/malwarebytes-threatdown-oneview-openapi.json flows: - flow: clientCredentials tokenUrl: /oneview/oauth2/token scopes: - scope: read description: Read data of your Nebula account flows: [clientCredentials] operations_nebula: 253 operations_oneview: 226 sources: - openapi/malwarebytes-threatdown-nebula-openapi.json - openapi/malwarebytes-threatdown-oneview-openapi.json note: >- The OneView definition carries this same "Nebula account" wording, un-adapted from the sibling spec. - scope: write description: >- Write data, such as groups, policies, exclusions. Create Webhook subscriptions. (OneView wording: "Write access. Create Users, Sites, Policies, Exclusions and other resources.") flows: [clientCredentials] operations_nebula: 148 operations_oneview: 124 sources: - openapi/malwarebytes-threatdown-nebula-openapi.json - openapi/malwarebytes-threatdown-oneview-openapi.json - scope: execute description: Issue jobs on your endpoints, like Scan, Reboot or Isolate. flows: [clientCredentials] operations_nebula: 51 operations_oneview: 55 consequence: destructive note: >- The blast-radius scope. It authorizes real action on production machines. Grant it to a separate application from any read-only reporting integration — ThreatDown's own documentation makes exactly this recommendation. sources: - openapi/malwarebytes-threatdown-nebula-openapi.json - openapi/malwarebytes-threatdown-oneview-openapi.json user_permissions: model: >- A second authorization layer, declared per-operation in the OpenAPI as a `user_permissions` security requirement. The user who created the OAuth2 application must hold the named permission or the call returns 403 regardless of scope. distinct_permissions_nebula: 86 distinct_permissions_oneview: 84 naming_convention: '.' actions_observed: [view, manage, edit, create, delete, install, performActions, enable, viewOwn, editOwn, createOwn, deleteOwn, viewOthers, editOthers, deleteOthers, createRule, editRule, deleteRule, createPolicy, editPolicy, deletePolicy, createAllowlistRule, editAllowlistRule, deleteAllowlistRule] ownership_split: >- Notifications and reports distinguish Own from Others (notifications.viewOwn vs notifications.viewOthers), so a delegated integration can be confined to the objects it created. conditional_permissions: >- Some operations require an ADDITIONAL permission determined by the request body, not just the route: jobs issuance requires .performActions depending on `command` (entity is endpoints, softwareInventory or detections); notifications create/update requires .view depending on `category`; reports create/update requires .view depending on `type`. A static permission audit of the route table will therefore under-report what an integration actually needs. top_permissions_nebula: emailSecurity.view: 41 xdr.update: 27 xdr.view: 24 dnsFiltering.view: 18 vulnerabilities.view: 18 endpoints.view: 14 detections.view: 13 deviceControl.view: 12 edr.view: 12 tasks.view: 11 firewall.view: 10 patchManagement.view: 10 top_permissions_oneview: emailSecurity.view: 44 dnsFiltering.view: 19 vulnerabilities.view: 18 detections.view: 15 endpoints.view: 15 deviceControl.view: 13 edr.view: 12 account.view: 11 sites.view: 10 tasks.view: 10 high_consequence_permissions: - endpoints.performActions - detections.performActions - endpoints.delete - policies.delete - tamperProtection.manage - driveEncryption.manage - account.manage least_privilege_guidance: - >- Create one application per integration purpose, not one shared credential. ThreatDown's own example: give IT `execute` to isolate infected endpoints, give analysts `read` only for reporting. - >- Because scope is frozen at creation, decide the scope before the credential is issued — there is no narrowing later. - >- The creating user's role is the real permission ceiling. Provision a dedicated service user with exactly the permissions the integration needs rather than creating the application as an admin. gaps: - Only three OAuth scopes for 841 operations — no resource-scoped or read-subset scopes. - >- No documented way to distinguish a scope 403 from a permission 403, so operators cannot self-diagnose an authorization failure. - >- No published permissions reference page. The 86/84 permissions are discoverable only by reading per-operation security requirements in the OpenAPI, or via the console tooltip. - No refresh-token or token-revocation endpoint documented for the client-credentials flow. - No OAuth 2.0 Authorization Server Metadata (RFC 8414) document on any host.