generated: '2026-08-04' method: searched source: >- openapi/malwarebytes-threatdown-nebula-openapi.json, openapi/malwarebytes-threatdown-oneview-openapi.json (info.description "Authentication", "Access' scopes" and "User permissions" sections) docs: https://api.threatdown.com/nebula/v1/docs summary: >- ThreatDown authenticates with OAuth 2.0 client credentials and carries the resulting bearer token in an `authorization` header, alongside a required `accountid` tenant header on Nebula. Authorization is then evaluated twice — once against the token's OAuth scope and once against the granular permission held by the user who created the application. There is no OpenID Connect, no discovery metadata, no mTLS and no API-key alternative. summary_types: types: [oauth2, http] oauth2_flows: [clientCredentials] openid_connect: false mtls: false api_key: false schemes: - name: client_credentials type: oauth2 primary: true flows: - flow: clientCredentials tokenUrl: /token tokenUrl_actual: https://api.threatdown.com/oauth2/token tokenUrl_oneview: https://api.threatdown.com/oneview/oauth2/token scopes: 3 scope_names: [read, write, execute] sources: - openapi/malwarebytes-threatdown-nebula-openapi.json - openapi/malwarebytes-threatdown-oneview-openapi.json defect: >- The declared tokenUrl is the relative string "/token" and does not match the token operation in the same definition (POST /oauth2/token). Generated clients will fail to resolve it. - name: user_permissions type: http scheme: bearer primary: false sources: - openapi/malwarebytes-threatdown-nebula-openapi.json - openapi/malwarebytes-threatdown-oneview-openapi.json clarification: >- Despite being modelled as a second HTTP bearer securityScheme, this is NOT a second credential. It is how the definition expresses the granular permission requirement (e.g. endpoints.performActions, detections.view) that the SAME token must satisfy via the identity of the user who created the OAuth application. Tooling that reads this as an alternative auth method will generate a misleading client. token_exchange: operation_id: api.oauth2.token method: POST url: https://api.threatdown.com/oauth2/token grant_type: client_credentials credentials: client_id: from the console Integrate page client_secret: from the console Integrate page response_fields: - name: access_token description: Access token to be used to authenticate in API requests - name: expires_in description: Time in seconds before the token expires - name: scope description: The granted scope for this access token - name: token_type description: The type of the token - name: refresh_token description: >- Present only "with grant type authorization code" per the schema title — not returned for client credentials. - name: id_token description: >- Present only "with grant type authorization code" per the schema title. No authorization-code flow is declared or documented for the public API, so these two fields appear to be residue from the console's own auth path. refresh_guidance: Refresh on expires_in rather than reacting to a 401. request_headers: - name: authorization required: true in: header value: the bearer access_token present_on_nebula: 439 of 440 operations present_on_oneview: 400 of 401 operations defect: >- Declared as an ordinary required STRING parameter on nearly every operation IN ADDITION to being expressed by the securityScheme. Generated clients commonly emit the header twice. It should be carried by the security requirement alone. - name: accountid required: true in: header scope: nebula present_on: 433 of 440 operations format: UUID pattern: '[\da-fA-F]{8}-?[\da-fA-F]{4}-?[\da-fA-F]{4}-?[\da-fA-F]{4}-?[\da-fA-F]{12}$' description: The Nebula account (tenant) the request addresses. - name: on-behalf-of required: false in: header scope: oneview present_on: 7 operations description: Act as a specific user within a customer tenant rather than sharing credentials. authorization_model: gates: 2 gate_1: name: OAuth2 scope values: [read, write, execute] granted_at: application creation in the console Integrate page mutable: false note: Changing scope requires issuing new credentials. gate_2: name: user permission distinct_values_nebula: 86 distinct_values_oneview: 84 held_by: the console user who created the OAuth2 application evidence: >- "The user associated with the client (i.e. the user that created the OAuth2 application) must have the required permissions to perform the requested operation. If the user does not have sufficient permissions, the API will respond with a `403 Forbidden` status code." failure_status: 403 discriminable: false discriminability_note: >- Both gates return a bare 403 with the generic {statusCode, error, message} envelope. An operator cannot tell from the response whether to widen the application scope or change the user's role. see_also: scopes/malwarebytes-scopes.yml credential_provisioning: self_service: false console_only: true role_required: Super Admin path: >- Nebula or OneView console → Integrate → Add → name the application, select read / write / execute → Save programmatic_issuance: false sales_gate: >- "To get started, you need a client credential pair (OAuth2 application). You can get a valid application through our sales team." There is no public sign-up, free tier, or sandbox tenant for the ThreatDown API — evaluation requires a commercial relationship. rotation_documented: false revocation_endpoint: null transport_security: https_required: true tls_version_observed: TLSv1.3 hsts_on_api_host: false see_also: security/malwarebytes-domain-security.yml cors: policy: wildcard same-origin on all responses quoted: >- "All responses have a wildcard same-origin which makes them completely public and accessible to everyone, including any code on any site." assessment: >- Notable for an API that can isolate and reboot production machines and reveal drive recovery keys. Bearer tokens are not automatically attached by browsers, so this is not itself a CSRF vector, but it does mean any page can call the API with a token it has obtained. authentication_order_defect: observed: >- Schema validation runs BEFORE authentication. An anonymous request with a malformed path parameter receives a detailed 400 naming the failing member and its regex, without ever presenting a credential. evidence: >- GET https://api.threatdown.com/nebula/v1/endpoints/abc (no authorization header) returned 400 {"statusCode":400,"error":"Bad Request","message":"params/id must match pattern \"...\""} probed: '2026-08-04' gaps: - No OpenID Connect and no /.well-known/openid-configuration on any host. - No RFC 8414 OAuth Authorization Server Metadata — the token endpoint is undiscoverable. - No documented token revocation or introspection endpoint. - No mutual TLS or private-key-JWT client authentication option for a security-management API. - No documented credential rotation procedure or secret expiry. - >- tokenUrl in securitySchemes is relative and incorrect, so generated SDKs cannot perform the token exchange without hand-editing. - >- No public sign-up or trial credential — the API cannot be evaluated without going through sales.