@grc-claw/integration-marketplace 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/dist/IntegrationMarketplace.d.ts +32 -0
- package/dist/IntegrationMarketplace.js +165 -0
- package/dist/connectors/AWSCloudTrailConnector.d.ts +12 -0
- package/dist/connectors/AWSCloudTrailConnector.js +77 -0
- package/dist/connectors/AWSIAMConnector.d.ts +12 -0
- package/dist/connectors/AWSIAMConnector.js +90 -0
- package/dist/connectors/AWSS3Connector.d.ts +12 -0
- package/dist/connectors/AWSS3Connector.js +112 -0
- package/dist/connectors/AzureADConnector.d.ts +12 -0
- package/dist/connectors/AzureADConnector.js +115 -0
- package/dist/connectors/AzureSentinelConnector.d.ts +12 -0
- package/dist/connectors/AzureSentinelConnector.js +88 -0
- package/dist/connectors/BambooHRConnector.d.ts +12 -0
- package/dist/connectors/BambooHRConnector.js +84 -0
- package/dist/connectors/CrowdStrikeConnector.d.ts +12 -0
- package/dist/connectors/CrowdStrikeConnector.js +86 -0
- package/dist/connectors/DatadogConnector.d.ts +12 -0
- package/dist/connectors/DatadogConnector.js +110 -0
- package/dist/connectors/DockerHubConnector.d.ts +12 -0
- package/dist/connectors/DockerHubConnector.js +80 -0
- package/dist/connectors/GCPIAMConnector.d.ts +12 -0
- package/dist/connectors/GCPIAMConnector.js +98 -0
- package/dist/connectors/GCPSCCConnector.d.ts +12 -0
- package/dist/connectors/GCPSCCConnector.js +94 -0
- package/dist/connectors/GitHubActionsConnector.d.ts +12 -0
- package/dist/connectors/GitHubActionsConnector.js +104 -0
- package/dist/connectors/GitHubConnector.d.ts +12 -0
- package/dist/connectors/GitHubConnector.js +135 -0
- package/dist/connectors/GitLabConnector.d.ts +12 -0
- package/dist/connectors/GitLabConnector.js +101 -0
- package/dist/connectors/HubSpotConnector.d.ts +12 -0
- package/dist/connectors/HubSpotConnector.js +77 -0
- package/dist/connectors/JiraConnector.d.ts +12 -0
- package/dist/connectors/JiraConnector.js +103 -0
- package/dist/connectors/KubernetesConnector.d.ts +12 -0
- package/dist/connectors/KubernetesConnector.js +109 -0
- package/dist/connectors/OktaConnector.d.ts +12 -0
- package/dist/connectors/OktaConnector.js +123 -0
- package/dist/connectors/PagerDutyConnector.d.ts +12 -0
- package/dist/connectors/PagerDutyConnector.js +106 -0
- package/dist/connectors/QualysConnector.d.ts +12 -0
- package/dist/connectors/QualysConnector.js +96 -0
- package/dist/connectors/SalesforceConnector.d.ts +12 -0
- package/dist/connectors/SalesforceConnector.js +91 -0
- package/dist/connectors/SlackConnector.d.ts +12 -0
- package/dist/connectors/SlackConnector.js +109 -0
- package/dist/connectors/SnowflakeConnector.d.ts +12 -0
- package/dist/connectors/SnowflakeConnector.js +105 -0
- package/dist/connectors/SnykConnector.d.ts +12 -0
- package/dist/connectors/SnykConnector.js +84 -0
- package/dist/connectors/TerraformCloudConnector.d.ts +12 -0
- package/dist/connectors/TerraformCloudConnector.js +106 -0
- package/dist/connectors/index.d.ts +25 -0
- package/dist/connectors/index.js +25 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +3 -0
- package/dist/index.test.d.ts +1 -0
- package/dist/index.test.js +138 -0
- package/dist/types.d.ts +57 -0
- package/dist/types.js +8 -0
- package/package.json +26 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { describe, it } from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { IntegrationMarketplace } from "./IntegrationMarketplace.js";
|
|
4
|
+
class MockConnector {
|
|
5
|
+
id;
|
|
6
|
+
name;
|
|
7
|
+
category = "version_control";
|
|
8
|
+
authType = "api_key";
|
|
9
|
+
capabilities = [
|
|
10
|
+
{ id: "test-cap", name: "Test Capability", description: "Test", evidenceCategories: ["test"] },
|
|
11
|
+
];
|
|
12
|
+
frameworks = ["SOC2"];
|
|
13
|
+
shouldFail = false;
|
|
14
|
+
constructor(id, name, fail = false) {
|
|
15
|
+
this.id = id;
|
|
16
|
+
this.name = name;
|
|
17
|
+
this.shouldFail = fail;
|
|
18
|
+
}
|
|
19
|
+
async collectEvidence() {
|
|
20
|
+
if (this.shouldFail)
|
|
21
|
+
throw new Error("Mock failure");
|
|
22
|
+
return [
|
|
23
|
+
{
|
|
24
|
+
id: `ev-${this.id}-1`,
|
|
25
|
+
connectorId: this.id,
|
|
26
|
+
capabilityId: "test-cap",
|
|
27
|
+
timestamp: new Date().toISOString(),
|
|
28
|
+
hash: "sha256:abc123",
|
|
29
|
+
framework: "SOC2",
|
|
30
|
+
controlId: "CC6.1",
|
|
31
|
+
source: `mock/${this.id}`,
|
|
32
|
+
status: "compliant",
|
|
33
|
+
data: { test: true },
|
|
34
|
+
metadata: {},
|
|
35
|
+
},
|
|
36
|
+
];
|
|
37
|
+
}
|
|
38
|
+
async testConnection() {
|
|
39
|
+
return !this.shouldFail;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const mockConfig = { apiToken: "test-token" };
|
|
43
|
+
describe("IntegrationMarketplace", () => {
|
|
44
|
+
it("should register 25 built-in connectors", () => {
|
|
45
|
+
const marketplace = new IntegrationMarketplace();
|
|
46
|
+
const stats = marketplace.getStats();
|
|
47
|
+
assert.equal(stats.totalConnectors, 25);
|
|
48
|
+
assert.ok(stats.totalCapabilities > 25);
|
|
49
|
+
});
|
|
50
|
+
it("should register a custom connector", () => {
|
|
51
|
+
const marketplace = new IntegrationMarketplace();
|
|
52
|
+
const custom = new MockConnector("custom-1", "Custom Tool");
|
|
53
|
+
marketplace.registerConnector(custom);
|
|
54
|
+
assert.ok(marketplace.getConnector("custom-1"));
|
|
55
|
+
});
|
|
56
|
+
it("should unregister a connector", () => {
|
|
57
|
+
const marketplace = new IntegrationMarketplace();
|
|
58
|
+
const custom = new MockConnector("custom-1", "Custom Tool");
|
|
59
|
+
marketplace.registerConnector(custom);
|
|
60
|
+
assert.ok(marketplace.unregisterConnector("custom-1"));
|
|
61
|
+
assert.equal(marketplace.getConnector("custom-1"), undefined);
|
|
62
|
+
});
|
|
63
|
+
it("should enable/disable connectors", () => {
|
|
64
|
+
const marketplace = new IntegrationMarketplace();
|
|
65
|
+
marketplace.disableConnector("github");
|
|
66
|
+
assert.equal(marketplace.getEnabledConnectors().length, 24);
|
|
67
|
+
marketplace.enableConnector("github");
|
|
68
|
+
assert.equal(marketplace.getEnabledConnectors().length, 25);
|
|
69
|
+
});
|
|
70
|
+
it("should filter connectors by category", () => {
|
|
71
|
+
const marketplace = new IntegrationMarketplace();
|
|
72
|
+
const cloudProviders = marketplace.getConnectorsByCategory("cloud_provider");
|
|
73
|
+
assert.ok(cloudProviders.length >= 4);
|
|
74
|
+
assert.ok(cloudProviders.every((c) => c.category === "cloud_provider"));
|
|
75
|
+
});
|
|
76
|
+
it("should filter connectors by framework", () => {
|
|
77
|
+
const marketplace = new IntegrationMarketplace();
|
|
78
|
+
const hipaaConnectors = marketplace.getConnectorsByFramework("HIPAA");
|
|
79
|
+
assert.ok(hipaaConnectors.length >= 2);
|
|
80
|
+
assert.ok(hipaaConnectors.every((c) => c.frameworks.includes("HIPAA")));
|
|
81
|
+
});
|
|
82
|
+
it("should collect from a custom connector", async () => {
|
|
83
|
+
const marketplace = new IntegrationMarketplace();
|
|
84
|
+
const custom = new MockConnector("custom-1", "Custom Tool");
|
|
85
|
+
marketplace.registerConnector(custom);
|
|
86
|
+
marketplace.setConfig("custom-1", mockConfig);
|
|
87
|
+
const job = await marketplace.collectFromConnector("custom-1");
|
|
88
|
+
assert.equal(job.status, "completed");
|
|
89
|
+
assert.equal(job.artifacts.length, 1);
|
|
90
|
+
assert.equal(job.connectorId, "custom-1");
|
|
91
|
+
});
|
|
92
|
+
it("should handle collection failures gracefully", async () => {
|
|
93
|
+
const marketplace = new IntegrationMarketplace();
|
|
94
|
+
const failing = new MockConnector("fail-1", "Failing Tool", true);
|
|
95
|
+
marketplace.registerConnector(failing);
|
|
96
|
+
marketplace.setConfig("fail-1", mockConfig);
|
|
97
|
+
const job = await marketplace.collectFromConnector("fail-1");
|
|
98
|
+
assert.equal(job.status, "failed");
|
|
99
|
+
assert.ok(job.error);
|
|
100
|
+
});
|
|
101
|
+
it("should return stats correctly", () => {
|
|
102
|
+
const marketplace = new IntegrationMarketplace();
|
|
103
|
+
const stats = marketplace.getStats();
|
|
104
|
+
assert.equal(stats.totalConnectors, 25);
|
|
105
|
+
assert.ok(Object.keys(stats.connectorsByCategory).length > 0);
|
|
106
|
+
assert.ok(stats.frameworksSupported.length > 0);
|
|
107
|
+
});
|
|
108
|
+
it("should track jobs", async () => {
|
|
109
|
+
const marketplace = new IntegrationMarketplace();
|
|
110
|
+
const custom = new MockConnector("custom-1", "Custom Tool");
|
|
111
|
+
marketplace.registerConnector(custom);
|
|
112
|
+
marketplace.setConfig("custom-1", mockConfig);
|
|
113
|
+
await marketplace.collectFromConnector("custom-1");
|
|
114
|
+
const jobs = marketplace.getJobs();
|
|
115
|
+
assert.equal(jobs.length, 1);
|
|
116
|
+
assert.equal(jobs[0].status, "completed");
|
|
117
|
+
});
|
|
118
|
+
it("should throw on collect from missing connector", async () => {
|
|
119
|
+
const marketplace = new IntegrationMarketplace();
|
|
120
|
+
await assert.rejects(() => marketplace.collectFromConnector("nonexistent"), /Connector not found/);
|
|
121
|
+
});
|
|
122
|
+
it("should throw on collect without config", async () => {
|
|
123
|
+
const marketplace = new IntegrationMarketplace();
|
|
124
|
+
const custom = new MockConnector("custom-1", "Custom Tool");
|
|
125
|
+
marketplace.registerConnector(custom);
|
|
126
|
+
await assert.rejects(() => marketplace.collectFromConnector("custom-1"), /No config/);
|
|
127
|
+
});
|
|
128
|
+
it("should test connections for enabled connectors", async () => {
|
|
129
|
+
const marketplace = new IntegrationMarketplace();
|
|
130
|
+
marketplace.registerConnector(new MockConnector("m1", "Mock1"));
|
|
131
|
+
marketplace.registerConnector(new MockConnector("m2", "Mock2", true));
|
|
132
|
+
marketplace.setConfig("m1", mockConfig);
|
|
133
|
+
marketplace.setConfig("m2", mockConfig);
|
|
134
|
+
const results = await marketplace.testAllConnections();
|
|
135
|
+
assert.equal(results.get("m1"), true);
|
|
136
|
+
assert.equal(results.get("m2"), false);
|
|
137
|
+
});
|
|
138
|
+
});
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export type IntegrationCategory = "version_control" | "cloud_provider" | "identity" | "siem" | "project_management" | "communication" | "incident_management" | "data_warehouse" | "monitoring" | "endpoint" | "vulnerability" | "iac" | "ci_cd" | "container" | "infrastructure" | "hr";
|
|
2
|
+
export type AuthType = "api_key" | "oauth2" | "bearer_token" | "basic_auth" | "service_account" | "webhook";
|
|
3
|
+
export type ComplianceFramework = "SOC2" | "ISO27001" | "NIST_CSF" | "HIPAA" | "PCI_DSS" | "GDPR" | "CIS";
|
|
4
|
+
export type EvidenceStatus = "compliant" | "non_compliant" | "partial" | "unknown";
|
|
5
|
+
export interface IntegrationCapability {
|
|
6
|
+
id: string;
|
|
7
|
+
name: string;
|
|
8
|
+
description: string;
|
|
9
|
+
evidenceCategories: string[];
|
|
10
|
+
}
|
|
11
|
+
export interface EvidenceArtifact {
|
|
12
|
+
id: string;
|
|
13
|
+
connectorId: string;
|
|
14
|
+
capabilityId: string;
|
|
15
|
+
timestamp: string;
|
|
16
|
+
hash: string;
|
|
17
|
+
framework: ComplianceFramework;
|
|
18
|
+
controlId: string;
|
|
19
|
+
source: string;
|
|
20
|
+
status: EvidenceStatus;
|
|
21
|
+
data: Record<string, unknown>;
|
|
22
|
+
metadata: Record<string, string>;
|
|
23
|
+
}
|
|
24
|
+
export interface ConnectorConfig {
|
|
25
|
+
baseUrl?: string;
|
|
26
|
+
apiToken?: string;
|
|
27
|
+
clientId?: string;
|
|
28
|
+
clientSecret?: string;
|
|
29
|
+
tenantId?: string;
|
|
30
|
+
region?: string;
|
|
31
|
+
accountId?: string;
|
|
32
|
+
extra?: Record<string, string>;
|
|
33
|
+
}
|
|
34
|
+
export interface IntegrationConnector {
|
|
35
|
+
readonly id: string;
|
|
36
|
+
readonly name: string;
|
|
37
|
+
readonly category: IntegrationCategory;
|
|
38
|
+
readonly authType: AuthType;
|
|
39
|
+
readonly capabilities: IntegrationCapability[];
|
|
40
|
+
readonly frameworks: ComplianceFramework[];
|
|
41
|
+
collectEvidence(config: ConnectorConfig): Promise<EvidenceArtifact[]>;
|
|
42
|
+
testConnection(config: ConnectorConfig): Promise<boolean>;
|
|
43
|
+
}
|
|
44
|
+
export interface MarketplaceStats {
|
|
45
|
+
totalConnectors: number;
|
|
46
|
+
connectorsByCategory: Record<IntegrationCategory, number>;
|
|
47
|
+
totalCapabilities: number;
|
|
48
|
+
frameworksSupported: ComplianceFramework[];
|
|
49
|
+
}
|
|
50
|
+
export interface ConnectorRegistration {
|
|
51
|
+
connector: IntegrationConnector;
|
|
52
|
+
enabled: boolean;
|
|
53
|
+
lastCollectedAt?: string;
|
|
54
|
+
errorCount: number;
|
|
55
|
+
}
|
|
56
|
+
export declare function hashEvidence(data: Record<string, unknown>): string;
|
|
57
|
+
export declare function generateEvidenceId(): string;
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
+
export function hashEvidence(data) {
|
|
3
|
+
const payload = JSON.stringify(data, Object.keys(data).sort());
|
|
4
|
+
return `sha256:${createHash("sha256").update(payload).digest("hex")}`;
|
|
5
|
+
}
|
|
6
|
+
export function generateEvidenceId() {
|
|
7
|
+
return `ev-${randomUUID()}`;
|
|
8
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@grc-claw/integration-marketplace",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Marketplace of 25+ SaaS integrations for automated GRC evidence collection",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc -p tsconfig.json",
|
|
17
|
+
"test": "node --import tsx --test src/**/*.test.ts"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist"
|
|
21
|
+
],
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"typescript": "^5.7.0",
|
|
24
|
+
"tsx": "^4.19.0"
|
|
25
|
+
}
|
|
26
|
+
}
|