n8n-nodes-tenable 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,137 @@
1
+ # n8n-nodes-tenable
2
+
3
+ This package provides n8n community nodes for interacting with Tenable APIs:
4
+
5
+ - **Tenable Vulnerability Management** - Full-featured node for vulnerability scanning, asset management, and security assessments
6
+ - **Tenable One** - Node for Tenable One Exposure Management platform
7
+
8
+ ## Installation
9
+
10
+ ### Community Nodes (Recommended)
11
+
12
+ 1. Go to **Settings > Community Nodes**
13
+ 2. Select **Install**
14
+ 3. Enter `n8n-nodes-tenable`
15
+ 4. Agree to the risks and select **Install**
16
+
17
+ ### Manual Installation
18
+
19
+ ```bash
20
+ npm install n8n-nodes-tenable
21
+ ```
22
+
23
+ ## Credentials
24
+
25
+ Both nodes use the same Tenable API credentials:
26
+
27
+ 1. In n8n, go to **Credentials > New**
28
+ 2. Search for "Tenable API"
29
+ 3. Enter your Tenable API credentials:
30
+ - **Access Key**: Your Tenable API access key
31
+ - **Secret Key**: Your Tenable API secret key
32
+ - **Base URL**: Usually `https://cloud.tenable.com`
33
+
34
+ To generate API keys, go to your Tenable.io account settings.
35
+
36
+ ## Tenable Vulnerability Management Node
37
+
38
+ ### Resources & Operations
39
+
40
+ #### Scan
41
+ - **Create** - Create a new scan configuration
42
+ - **Delete** - Delete a scan
43
+ - **Get** - Get scan details
44
+ - **Get Many** - List all scans
45
+ - **Launch** - Launch a scan
46
+ - **Pause** - Pause a running scan
47
+ - **Resume** - Resume a paused scan
48
+ - **Stop** - Stop a running scan
49
+
50
+ #### Asset
51
+ - **Get** - Get asset details
52
+ - **Get Many** - List all assets
53
+ - **Import** - Import assets
54
+
55
+ #### Export
56
+ - **Start Assets Export** - Start an assets export job
57
+ - **Start Vulnerabilities Export** - Start a vulnerabilities export job
58
+ - **Start Compliance Export** - Start a compliance export job
59
+ - **Get Status** - Get export job status
60
+ - **Cancel** - Cancel an export job
61
+ - **Download Chunk** - Download an export chunk
62
+
63
+ #### Folder
64
+ - **Create** - Create a folder
65
+ - **Delete** - Delete a folder
66
+ - **Get Many** - List all folders
67
+ - **Update** - Rename a folder
68
+
69
+ #### Plugin
70
+ - **Get** - Get plugin details
71
+ - **Get Families** - List all plugin families
72
+ - **Get Family Plugins** - List plugins in a family
73
+
74
+ #### Policy
75
+ - **Copy** - Copy a policy
76
+ - **Create** - Create a policy
77
+ - **Delete** - Delete a policy
78
+ - **Get** - Get policy details
79
+ - **Get Many** - List all policies
80
+
81
+ #### Vulnerability
82
+ - **Get Many** - List vulnerabilities
83
+
84
+ #### Workbench
85
+ - **Get Assets** - Get assets from workbench
86
+ - **Get Asset Info** - Get detailed asset information
87
+ - **Get Asset Vulnerabilities** - Get vulnerabilities for an asset
88
+ - **Get Vulnerabilities** - Get vulnerabilities from workbench
89
+
90
+ ## Tenable One Node
91
+
92
+ ### Resources & Operations
93
+
94
+ #### Attack Path
95
+ - **Search Attack Paths** - Search for top attack paths
96
+ - **Search Attack Techniques** - Search for top attack techniques (MITRE ATT&CK)
97
+
98
+ #### Exposure View
99
+ - **Get Cards** - Get all exposure view cards
100
+ - **Get Card** - Get a specific card
101
+
102
+ #### Inventory
103
+ - **Search Assets** - Search for assets
104
+ - **Search Findings** - Search for findings
105
+ - **Search Software** - Search for software
106
+ - **Get Asset Properties** - Get available asset properties for filtering
107
+ - **Get Finding Properties** - Get available finding properties
108
+ - **Get Software Properties** - Get available software properties
109
+
110
+ #### Inventory Export
111
+ - **Start Assets Export** - Start an assets export
112
+ - **Start Findings Export** - Start a findings export
113
+ - **Get Status** - Get export status
114
+ - **Get Export Status** - Get specific export status
115
+ - **Download Chunk** - Download an export chunk
116
+
117
+ #### Tag
118
+ - **Search** - Search for tags
119
+ - **Get Properties** - Get available tag properties
120
+
121
+ ## Query Examples
122
+
123
+ ### Tenable One Inventory Search (Advanced Mode)
124
+
125
+ Find cloud assets with critical vulnerabilities:
126
+ ```
127
+ Assets HAS sources = "CLOUD" WITH Weakness HAS severity = "Critical"
128
+ ```
129
+
130
+ Find assets with high AES score:
131
+ ```
132
+ Assets HAS aes >= 700
133
+ ```
134
+
135
+ ## License
136
+
137
+ MIT
@@ -0,0 +1,9 @@
1
+ import type { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
2
+ export declare class TenableApi implements ICredentialType {
3
+ name: string;
4
+ displayName: string;
5
+ documentationUrl: string;
6
+ properties: INodeProperties[];
7
+ authenticate: IAuthenticateGeneric;
8
+ test: ICredentialTestRequest;
9
+ }
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TenableApi = void 0;
4
+ class TenableApi {
5
+ constructor() {
6
+ this.name = 'tenableApi';
7
+ this.displayName = 'Tenable API';
8
+ this.documentationUrl = 'https://developer.tenable.com/docs/authorization';
9
+ this.properties = [
10
+ {
11
+ displayName: 'Access Key',
12
+ name: 'accessKey',
13
+ type: 'string',
14
+ typeOptions: { password: true },
15
+ default: '',
16
+ required: true,
17
+ description: 'Your Tenable API access key',
18
+ },
19
+ {
20
+ displayName: 'Secret Key',
21
+ name: 'secretKey',
22
+ type: 'string',
23
+ typeOptions: { password: true },
24
+ default: '',
25
+ required: true,
26
+ description: 'Your Tenable API secret key',
27
+ },
28
+ {
29
+ displayName: 'Base URL',
30
+ name: 'baseUrl',
31
+ type: 'string',
32
+ default: 'https://cloud.tenable.com',
33
+ description: 'The base URL for your Tenable instance',
34
+ },
35
+ ];
36
+ this.authenticate = {
37
+ type: 'generic',
38
+ properties: {
39
+ headers: {
40
+ 'X-ApiKeys': '=accessKey={{$credentials.accessKey}};secretKey={{$credentials.secretKey}}',
41
+ },
42
+ },
43
+ };
44
+ this.test = {
45
+ request: {
46
+ baseURL: '={{$credentials.baseUrl}}',
47
+ url: '/folders',
48
+ },
49
+ };
50
+ }
51
+ }
52
+ exports.TenableApi = TenableApi;
@@ -0,0 +1,4 @@
1
+ import type { IDataObject, IExecuteFunctions, IHttpRequestMethods, ILoadOptionsFunctions } from 'n8n-workflow';
2
+ export declare function tenableApiRequest(this: IExecuteFunctions | ILoadOptionsFunctions, method: IHttpRequestMethods, endpoint: string, body?: IDataObject, qs?: IDataObject): Promise<IDataObject | IDataObject[]>;
3
+ export declare function tenableApiRequestAllItems(this: IExecuteFunctions | ILoadOptionsFunctions, method: IHttpRequestMethods, endpoint: string, propertyName: string, body?: IDataObject, qs?: IDataObject): Promise<IDataObject[]>;
4
+ export declare function validateJSON(json: string | undefined): IDataObject | undefined;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.tenableApiRequest = tenableApiRequest;
4
+ exports.tenableApiRequestAllItems = tenableApiRequestAllItems;
5
+ exports.validateJSON = validateJSON;
6
+ const n8n_workflow_1 = require("n8n-workflow");
7
+ async function tenableApiRequest(method, endpoint, body = {}, qs = {}) {
8
+ const credentials = await this.getCredentials('tenableApi');
9
+ const options = {
10
+ method,
11
+ url: `${credentials.baseUrl}${endpoint}`,
12
+ headers: {
13
+ 'Accept': 'application/json',
14
+ 'Content-Type': 'application/json',
15
+ },
16
+ qs,
17
+ body,
18
+ json: true,
19
+ };
20
+ if (Object.keys(body).length === 0) {
21
+ delete options.body;
22
+ }
23
+ if (Object.keys(qs).length === 0) {
24
+ delete options.qs;
25
+ }
26
+ try {
27
+ const response = await this.helpers.httpRequestWithAuthentication.call(this, 'tenableApi', options);
28
+ return response;
29
+ }
30
+ catch (error) {
31
+ throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
32
+ }
33
+ }
34
+ async function tenableApiRequestAllItems(method, endpoint, propertyName, body = {}, qs = {}) {
35
+ const returnData = [];
36
+ let responseData;
37
+ let offset = 0;
38
+ const limit = 100;
39
+ do {
40
+ qs.offset = offset;
41
+ qs.limit = limit;
42
+ responseData = (await tenableApiRequest.call(this, method, endpoint, body, qs));
43
+ const items = responseData[propertyName];
44
+ if (items) {
45
+ returnData.push(...items);
46
+ }
47
+ offset += limit;
48
+ } while (responseData[propertyName] &&
49
+ responseData[propertyName].length === limit);
50
+ return returnData;
51
+ }
52
+ function validateJSON(json) {
53
+ if (json === undefined || json === '') {
54
+ return undefined;
55
+ }
56
+ try {
57
+ return JSON.parse(json);
58
+ }
59
+ catch {
60
+ return undefined;
61
+ }
62
+ }
@@ -0,0 +1,5 @@
1
+ import type { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
2
+ export declare class TenableOne implements INodeType {
3
+ description: INodeTypeDescription;
4
+ execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
5
+ }