@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.
Files changed (61) hide show
  1. package/dist/IntegrationMarketplace.d.ts +32 -0
  2. package/dist/IntegrationMarketplace.js +165 -0
  3. package/dist/connectors/AWSCloudTrailConnector.d.ts +12 -0
  4. package/dist/connectors/AWSCloudTrailConnector.js +77 -0
  5. package/dist/connectors/AWSIAMConnector.d.ts +12 -0
  6. package/dist/connectors/AWSIAMConnector.js +90 -0
  7. package/dist/connectors/AWSS3Connector.d.ts +12 -0
  8. package/dist/connectors/AWSS3Connector.js +112 -0
  9. package/dist/connectors/AzureADConnector.d.ts +12 -0
  10. package/dist/connectors/AzureADConnector.js +115 -0
  11. package/dist/connectors/AzureSentinelConnector.d.ts +12 -0
  12. package/dist/connectors/AzureSentinelConnector.js +88 -0
  13. package/dist/connectors/BambooHRConnector.d.ts +12 -0
  14. package/dist/connectors/BambooHRConnector.js +84 -0
  15. package/dist/connectors/CrowdStrikeConnector.d.ts +12 -0
  16. package/dist/connectors/CrowdStrikeConnector.js +86 -0
  17. package/dist/connectors/DatadogConnector.d.ts +12 -0
  18. package/dist/connectors/DatadogConnector.js +110 -0
  19. package/dist/connectors/DockerHubConnector.d.ts +12 -0
  20. package/dist/connectors/DockerHubConnector.js +80 -0
  21. package/dist/connectors/GCPIAMConnector.d.ts +12 -0
  22. package/dist/connectors/GCPIAMConnector.js +98 -0
  23. package/dist/connectors/GCPSCCConnector.d.ts +12 -0
  24. package/dist/connectors/GCPSCCConnector.js +94 -0
  25. package/dist/connectors/GitHubActionsConnector.d.ts +12 -0
  26. package/dist/connectors/GitHubActionsConnector.js +104 -0
  27. package/dist/connectors/GitHubConnector.d.ts +12 -0
  28. package/dist/connectors/GitHubConnector.js +135 -0
  29. package/dist/connectors/GitLabConnector.d.ts +12 -0
  30. package/dist/connectors/GitLabConnector.js +101 -0
  31. package/dist/connectors/HubSpotConnector.d.ts +12 -0
  32. package/dist/connectors/HubSpotConnector.js +77 -0
  33. package/dist/connectors/JiraConnector.d.ts +12 -0
  34. package/dist/connectors/JiraConnector.js +103 -0
  35. package/dist/connectors/KubernetesConnector.d.ts +12 -0
  36. package/dist/connectors/KubernetesConnector.js +109 -0
  37. package/dist/connectors/OktaConnector.d.ts +12 -0
  38. package/dist/connectors/OktaConnector.js +123 -0
  39. package/dist/connectors/PagerDutyConnector.d.ts +12 -0
  40. package/dist/connectors/PagerDutyConnector.js +106 -0
  41. package/dist/connectors/QualysConnector.d.ts +12 -0
  42. package/dist/connectors/QualysConnector.js +96 -0
  43. package/dist/connectors/SalesforceConnector.d.ts +12 -0
  44. package/dist/connectors/SalesforceConnector.js +91 -0
  45. package/dist/connectors/SlackConnector.d.ts +12 -0
  46. package/dist/connectors/SlackConnector.js +109 -0
  47. package/dist/connectors/SnowflakeConnector.d.ts +12 -0
  48. package/dist/connectors/SnowflakeConnector.js +105 -0
  49. package/dist/connectors/SnykConnector.d.ts +12 -0
  50. package/dist/connectors/SnykConnector.js +84 -0
  51. package/dist/connectors/TerraformCloudConnector.d.ts +12 -0
  52. package/dist/connectors/TerraformCloudConnector.js +106 -0
  53. package/dist/connectors/index.d.ts +25 -0
  54. package/dist/connectors/index.js +25 -0
  55. package/dist/index.d.ts +5 -0
  56. package/dist/index.js +3 -0
  57. package/dist/index.test.d.ts +1 -0
  58. package/dist/index.test.js +138 -0
  59. package/dist/types.d.ts +57 -0
  60. package/dist/types.js +8 -0
  61. package/package.json +26 -0
@@ -0,0 +1,91 @@
1
+ import { hashEvidence, generateEvidenceId } from "../types.js";
2
+ const capabilities = [
3
+ {
4
+ id: "sf-user-permissions",
5
+ name: "User Permissions",
6
+ description: "Fetch Salesforce user permission sets and profiles",
7
+ evidenceCategories: ["access_control", "authorization"],
8
+ },
9
+ {
10
+ id: "sf-field-security",
11
+ name: "Field-Level Security",
12
+ description: "Fetch field-level security configurations on sensitive objects",
13
+ evidenceCategories: ["data_protection", "access_control"],
14
+ },
15
+ ];
16
+ export class SalesforceConnector {
17
+ id = "salesforce";
18
+ name = "Salesforce";
19
+ category = "hr";
20
+ authType = "oauth2";
21
+ capabilities = capabilities;
22
+ frameworks = ["SOC2", "ISO27001", "HIPAA"];
23
+ async getAccessToken(config) {
24
+ const resp = await fetch(`${config.baseUrl || "https://login.salesforce.com"}/services/oauth2/token`, {
25
+ method: "POST",
26
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
27
+ body: new URLSearchParams({
28
+ grant_type: "client_credentials",
29
+ client_id: config.clientId || "",
30
+ client_secret: config.clientSecret || "",
31
+ }),
32
+ });
33
+ if (!resp.ok)
34
+ throw new Error(`Salesforce token ${resp.status}`);
35
+ const data = (await resp.json());
36
+ return data.access_token;
37
+ }
38
+ async testConnection(config) {
39
+ try {
40
+ const token = await this.getAccessToken(config);
41
+ const instanceUrl = config.extra?.instanceUrl || "https://your-instance.salesforce.com";
42
+ const resp = await fetch(`${instanceUrl}/services/data/v59.0/limits`, {
43
+ headers: { Authorization: `Bearer ${token}` },
44
+ });
45
+ return resp.ok;
46
+ }
47
+ catch {
48
+ return false;
49
+ }
50
+ }
51
+ async collectEvidence(config) {
52
+ const artifacts = [];
53
+ const now = new Date().toISOString();
54
+ const token = await this.getAccessToken(config);
55
+ const instanceUrl = config.extra?.instanceUrl || "https://your-instance.salesforce.com";
56
+ const headers = { Authorization: `Bearer ${token}` };
57
+ const users = await fetch(`${instanceUrl}/services/data/v59.0/query?q=SELECT+Id,Username,ProfileId,IsActive+FROM+User+WHERE+IsActive=TRUE+LIMIT+200`, { headers }).then((r) => r.json());
58
+ const userList = (users.records || []);
59
+ artifacts.push({
60
+ id: generateEvidenceId(),
61
+ connectorId: this.id,
62
+ capabilityId: "sf-user-permissions",
63
+ timestamp: now,
64
+ hash: hashEvidence({ userCount: userList.length }),
65
+ framework: "SOC2",
66
+ controlId: "CC6.1",
67
+ source: "salesforce/users",
68
+ status: "unknown",
69
+ data: { activeUserCount: userList.length },
70
+ metadata: { instanceUrl },
71
+ });
72
+ const fieldPerms = await fetch(`${instanceUrl}/services/data/v59.0/query?q=SELECT+ParentId,Field,Editable+FROM+FieldPermission+WHERE+Parent.Profile.Name='Standard+User'+LIMIT+100`, { headers }).then((r) => r.json());
73
+ const permRecords = (fieldPerms.records || []);
74
+ const editableSensitive = permRecords.filter((p) => p.Editable === true &&
75
+ (p.Field || "").includes("Email"));
76
+ artifacts.push({
77
+ id: generateEvidenceId(),
78
+ connectorId: this.id,
79
+ capabilityId: "sf-field-security",
80
+ timestamp: now,
81
+ hash: hashEvidence({ permissionCount: permRecords.length }),
82
+ framework: "ISO27001",
83
+ controlId: "A.9.4.1",
84
+ source: "salesforce/fieldPermissions",
85
+ status: editableSensitive.length === 0 ? "compliant" : "partial",
86
+ data: { fieldPermissionCount: permRecords.length, editableSensitiveFields: editableSensitive.length },
87
+ metadata: { instanceUrl },
88
+ });
89
+ return artifacts;
90
+ }
91
+ }
@@ -0,0 +1,12 @@
1
+ import type { IntegrationConnector, ConnectorConfig, EvidenceArtifact, IntegrationCapability, ComplianceFramework } from "../types.js";
2
+ export declare class SlackConnector implements IntegrationConnector {
3
+ readonly id = "slack";
4
+ readonly name = "Slack";
5
+ readonly category: "communication";
6
+ readonly authType: "bearer_token";
7
+ readonly capabilities: IntegrationCapability[];
8
+ readonly frameworks: ComplianceFramework[];
9
+ private fetchApi;
10
+ testConnection(config: ConnectorConfig): Promise<boolean>;
11
+ collectEvidence(config: ConnectorConfig): Promise<EvidenceArtifact[]>;
12
+ }
@@ -0,0 +1,109 @@
1
+ import { hashEvidence, generateEvidenceId } from "../types.js";
2
+ const capabilities = [
3
+ {
4
+ id: "slack-workspace",
5
+ name: "Workspace Settings",
6
+ description: "Fetch Slack workspace security and compliance settings",
7
+ evidenceCategories: ["configuration", "access_control"],
8
+ },
9
+ {
10
+ id: "slack-apps",
11
+ name: "App Installations",
12
+ description: "Fetch installed apps and their permissions",
13
+ evidenceCategories: ["access_control", "third_party_management"],
14
+ },
15
+ {
16
+ id: "slack-channels",
17
+ name: "Channel Access",
18
+ description: "Fetch channel privacy and access controls",
19
+ evidenceCategories: ["access_control", "data_protection"],
20
+ },
21
+ ];
22
+ export class SlackConnector {
23
+ id = "slack";
24
+ name = "Slack";
25
+ category = "communication";
26
+ authType = "bearer_token";
27
+ capabilities = capabilities;
28
+ frameworks = ["SOC2", "ISO27001"];
29
+ async fetchApi(config, endpoint) {
30
+ const base = config.baseUrl || "https://slack.com/api";
31
+ const resp = await fetch(`${base}${endpoint}`, {
32
+ headers: { Authorization: `Bearer ${config.apiToken}` },
33
+ });
34
+ if (!resp.ok)
35
+ throw new Error(`Slack API ${resp.status}: ${resp.statusText}`);
36
+ const data = (await resp.json());
37
+ if (data.ok === false)
38
+ throw new Error(`Slack error: ${data.error}`);
39
+ return data;
40
+ }
41
+ async testConnection(config) {
42
+ try {
43
+ await this.fetchApi(config, "/auth.test");
44
+ return true;
45
+ }
46
+ catch {
47
+ return false;
48
+ }
49
+ }
50
+ async collectEvidence(config) {
51
+ const artifacts = [];
52
+ const now = new Date().toISOString();
53
+ const team = await this.fetchApi(config, "/team.info");
54
+ const teamData = (team.team || {});
55
+ artifacts.push({
56
+ id: generateEvidenceId(),
57
+ connectorId: this.id,
58
+ capabilityId: "slack-workspace",
59
+ timestamp: now,
60
+ hash: hashEvidence(team),
61
+ framework: "SOC2",
62
+ controlId: "CC6.1",
63
+ source: "slack/team.info",
64
+ status: "compliant",
65
+ data: {
66
+ teamId: teamData.id,
67
+ teamName: teamData.name,
68
+ domain: teamData.domain,
69
+ emailDomain: teamData.email_domain,
70
+ },
71
+ metadata: { workspace: String(teamData.domain || "") },
72
+ });
73
+ const apps = await this.fetchApi(config, "/apps.permissions.list").catch(() => ({
74
+ scopes: [],
75
+ }));
76
+ artifacts.push({
77
+ id: generateEvidenceId(),
78
+ connectorId: this.id,
79
+ capabilityId: "slack-apps",
80
+ timestamp: now,
81
+ hash: hashEvidence(apps),
82
+ framework: "ISO27001",
83
+ controlId: "A.14.2.5",
84
+ source: "slack/apps.permissions.list",
85
+ status: "unknown",
86
+ data: { appScopes: apps.scopes },
87
+ metadata: { workspace: String(teamData.domain || "") },
88
+ });
89
+ const channels = await this.fetchApi(config, "/conversations.list?types=public_channel,private_channel&limit=200").catch(() => ({
90
+ channels: [],
91
+ }));
92
+ const channelList = (channels.channels || []);
93
+ const privateChannels = channelList.filter((c) => c.is_private === true);
94
+ artifacts.push({
95
+ id: generateEvidenceId(),
96
+ connectorId: this.id,
97
+ capabilityId: "slack-channels",
98
+ timestamp: now,
99
+ hash: hashEvidence({ total: channelList.length, private: privateChannels.length }),
100
+ framework: "SOC2",
101
+ controlId: "CC6.4",
102
+ source: "slack/conversations.list",
103
+ status: "unknown",
104
+ data: { totalChannels: channelList.length, privateChannels: privateChannels.length },
105
+ metadata: { workspace: String(teamData.domain || "") },
106
+ });
107
+ return artifacts;
108
+ }
109
+ }
@@ -0,0 +1,12 @@
1
+ import type { IntegrationConnector, ConnectorConfig, EvidenceArtifact, IntegrationCapability, ComplianceFramework } from "../types.js";
2
+ export declare class SnowflakeConnector implements IntegrationConnector {
3
+ readonly id = "snowflake";
4
+ readonly name = "Snowflake";
5
+ readonly category: "data_warehouse";
6
+ readonly authType: "basic_auth";
7
+ readonly capabilities: IntegrationCapability[];
8
+ readonly frameworks: ComplianceFramework[];
9
+ private querySnowflake;
10
+ testConnection(config: ConnectorConfig): Promise<boolean>;
11
+ collectEvidence(config: ConnectorConfig): Promise<EvidenceArtifact[]>;
12
+ }
@@ -0,0 +1,105 @@
1
+ import { hashEvidence, generateEvidenceId } from "../types.js";
2
+ const capabilities = [
3
+ {
4
+ id: "sf-access-policies",
5
+ name: "Access Policies",
6
+ description: "Fetch Snowflake access policies and role hierarchy",
7
+ evidenceCategories: ["access_control"],
8
+ },
9
+ {
10
+ id: "sf-query-history",
11
+ name: "Query History",
12
+ description: "Fetch query history for data access auditing",
13
+ evidenceCategories: ["audit", "data_access"],
14
+ },
15
+ {
16
+ id: "sf-data-access",
17
+ name: "Data Access Logs",
18
+ description: "Fetch COPY history and data loading access logs",
19
+ evidenceCategories: ["data_protection", "logging"],
20
+ },
21
+ ];
22
+ export class SnowflakeConnector {
23
+ id = "snowflake";
24
+ name = "Snowflake";
25
+ category = "data_warehouse";
26
+ authType = "basic_auth";
27
+ capabilities = capabilities;
28
+ frameworks = ["SOC2", "ISO27001", "HIPAA"];
29
+ async querySnowflake(config, sql) {
30
+ const account = config.extra?.account || "your-account";
31
+ const resp = await fetch(`https://${account}.snowflakecomputing.com/api/v2/statements`, {
32
+ method: "POST",
33
+ headers: {
34
+ Authorization: `Basic ${Buffer.from(`${config.clientId}:${config.apiToken}`).toString("base64")}`,
35
+ "Content-Type": "application/json",
36
+ "X-Snowflake-Database": config.extra?.database || "MAIN",
37
+ "X-Snowflake-Schema": config.extra?.schema || "PUBLIC",
38
+ "X-Snowflake-Role": config.extra?.role || "ACCOUNTADMIN",
39
+ },
40
+ body: JSON.stringify({ statement: sql, timeout: 30 }),
41
+ });
42
+ if (!resp.ok)
43
+ throw new Error(`Snowflake ${resp.status}: ${resp.statusText}`);
44
+ return (await resp.json());
45
+ }
46
+ async testConnection(config) {
47
+ try {
48
+ await this.querySnowflake(config, "SELECT CURRENT_VERSION()");
49
+ return true;
50
+ }
51
+ catch {
52
+ return false;
53
+ }
54
+ }
55
+ async collectEvidence(config) {
56
+ const artifacts = [];
57
+ const now = new Date().toISOString();
58
+ const policies = await this.querySnowflake(config, "SELECT * FROM information_schema.policy_references WHERE POLICY_KIND = 'ROW_ACCESS_POLICY'").catch(() => ({ result: { rowset: [] } }));
59
+ const policyRowset = (policies.result?.rowset || []);
60
+ artifacts.push({
61
+ id: generateEvidenceId(),
62
+ connectorId: this.id,
63
+ capabilityId: "sf-access-policies",
64
+ timestamp: now,
65
+ hash: hashEvidence({ policyCount: policyRowset.length }),
66
+ framework: "SOC2",
67
+ controlId: "CC6.1",
68
+ source: "snowflake/policy_references",
69
+ status: "unknown",
70
+ data: { policies: policyRowset },
71
+ metadata: { account: config.extra?.account || "" },
72
+ });
73
+ const queries = await this.querySnowflake(config, "SELECT query_text, user_name, start_time FROM table(information_schema.query_history(limit => 100)) ORDER BY start_time DESC").catch(() => ({ result: { rowset: [] } }));
74
+ const queryRowset = (queries.result?.rowset || []);
75
+ artifacts.push({
76
+ id: generateEvidenceId(),
77
+ connectorId: this.id,
78
+ capabilityId: "sf-query-history",
79
+ timestamp: now,
80
+ hash: hashEvidence({ queryCount: queryRowset.length }),
81
+ framework: "SOC2",
82
+ controlId: "CC7.1",
83
+ source: "snowflake/query_history",
84
+ status: "unknown",
85
+ data: { queryCount: queryRowset.length },
86
+ metadata: { account: config.extra?.account || "" },
87
+ });
88
+ const copyHistory = await this.querySnowflake(config, "SELECT * FROM table(information_schema.copy_history(table_name => '%%', start_time => dateadd(day, -7, current_timestamp())))").catch(() => ({ result: { rowset: [] } }));
89
+ const copyRowset = (copyHistory.result?.rowset || []);
90
+ artifacts.push({
91
+ id: generateEvidenceId(),
92
+ connectorId: this.id,
93
+ capabilityId: "sf-data-access",
94
+ timestamp: now,
95
+ hash: hashEvidence({ copyOperations: copyRowset.length }),
96
+ framework: "ISO27001",
97
+ controlId: "A.12.4.1",
98
+ source: "snowflake/copy_history",
99
+ status: "unknown",
100
+ data: { copyOperations: copyRowset.length },
101
+ metadata: { account: config.extra?.account || "" },
102
+ });
103
+ return artifacts;
104
+ }
105
+ }
@@ -0,0 +1,12 @@
1
+ import type { IntegrationConnector, ConnectorConfig, EvidenceArtifact, IntegrationCapability, ComplianceFramework } from "../types.js";
2
+ export declare class SnykConnector implements IntegrationConnector {
3
+ readonly id = "snyk";
4
+ readonly name = "Snyk";
5
+ readonly category: "vulnerability";
6
+ readonly authType: "bearer_token";
7
+ readonly capabilities: IntegrationCapability[];
8
+ readonly frameworks: ComplianceFramework[];
9
+ private fetchApi;
10
+ testConnection(config: ConnectorConfig): Promise<boolean>;
11
+ collectEvidence(config: ConnectorConfig): Promise<EvidenceArtifact[]>;
12
+ }
@@ -0,0 +1,84 @@
1
+ import { hashEvidence, generateEvidenceId } from "../types.js";
2
+ const capabilities = [
3
+ {
4
+ id: "snyk-vulns",
5
+ name: "Vulnerabilities",
6
+ description: "Fetch Snyk project vulnerabilities by severity",
7
+ evidenceCategories: ["vulnerability_management", "application_security"],
8
+ },
9
+ {
10
+ id: "snyk-license",
11
+ name: "License Compliance",
12
+ description: "Fetch open-source license compliance issues",
13
+ evidenceCategories: ["license_compliance", "supply_chain"],
14
+ },
15
+ ];
16
+ export class SnykConnector {
17
+ id = "snyk";
18
+ name = "Snyk";
19
+ category = "vulnerability";
20
+ authType = "bearer_token";
21
+ capabilities = capabilities;
22
+ frameworks = ["SOC2", "ISO27001", "NIST_CSF"];
23
+ async fetchApi(config, endpoint) {
24
+ const base = config.baseUrl || "https://api.snyk.io/v1";
25
+ const resp = await fetch(`${base}${endpoint}`, {
26
+ headers: { Authorization: `token ${config.apiToken}` },
27
+ });
28
+ if (!resp.ok)
29
+ throw new Error(`Snyk API ${resp.status}: ${resp.statusText}`);
30
+ return (await resp.json());
31
+ }
32
+ async testConnection(config) {
33
+ try {
34
+ await this.fetchApi(config, "/user/me");
35
+ return true;
36
+ }
37
+ catch {
38
+ return false;
39
+ }
40
+ }
41
+ async collectEvidence(config) {
42
+ const artifacts = [];
43
+ const now = new Date().toISOString();
44
+ const orgId = config.extra?.orgId || "";
45
+ const projectId = config.extra?.projectId || "";
46
+ const issues = await this.fetchApi(config, `/orgs/${orgId}/projects/${projectId}/issues?severityThreshold=low`).catch(() => ({ issues: [] }));
47
+ const issueList = (issues.issues || []);
48
+ const bySeverity = {
49
+ critical: issueList.filter((i) => i.severity === "critical").length,
50
+ high: issueList.filter((i) => i.severity === "high").length,
51
+ medium: issueList.filter((i) => i.severity === "medium").length,
52
+ low: issueList.filter((i) => i.severity === "low").length,
53
+ };
54
+ artifacts.push({
55
+ id: generateEvidenceId(),
56
+ connectorId: this.id,
57
+ capabilityId: "snyk-vulns",
58
+ timestamp: now,
59
+ hash: hashEvidence({ issueCount: issueList.length, bySeverity }),
60
+ framework: "ISO27001",
61
+ controlId: "A.12.6.1",
62
+ source: `snyk/orgs/${orgId}/projects/${projectId}/issues`,
63
+ status: bySeverity.critical === 0 ? "compliant" : "non_compliant",
64
+ data: { totalIssues: issueList.length, bySeverity },
65
+ metadata: { orgId, projectId },
66
+ });
67
+ const licenses = await this.fetchApi(config, `/orgs/${orgId}/projects/${projectId}/issues?severityThreshold=low&types=license`).catch(() => ({ issues: [] }));
68
+ const licenseIssues = (licenses.issues || []);
69
+ artifacts.push({
70
+ id: generateEvidenceId(),
71
+ connectorId: this.id,
72
+ capabilityId: "snyk-license",
73
+ timestamp: now,
74
+ hash: hashEvidence({ licenseIssueCount: licenseIssues.length }),
75
+ framework: "ISO27001",
76
+ controlId: "A.18.1.5",
77
+ source: `snyk/orgs/${orgId}/projects/${projectId}/licenses`,
78
+ status: licenseIssues.length === 0 ? "compliant" : "non_compliant",
79
+ data: { licenseIssues: licenseIssues.length },
80
+ metadata: { orgId, projectId },
81
+ });
82
+ return artifacts;
83
+ }
84
+ }
@@ -0,0 +1,12 @@
1
+ import type { IntegrationConnector, ConnectorConfig, EvidenceArtifact, IntegrationCapability, ComplianceFramework } from "../types.js";
2
+ export declare class TerraformCloudConnector implements IntegrationConnector {
3
+ readonly id = "terraform-cloud";
4
+ readonly name = "Terraform Cloud";
5
+ readonly category: "iac";
6
+ readonly authType: "bearer_token";
7
+ readonly capabilities: IntegrationCapability[];
8
+ readonly frameworks: ComplianceFramework[];
9
+ private fetchApi;
10
+ testConnection(config: ConnectorConfig): Promise<boolean>;
11
+ collectEvidence(config: ConnectorConfig): Promise<EvidenceArtifact[]>;
12
+ }
@@ -0,0 +1,106 @@
1
+ import { hashEvidence, generateEvidenceId } from "../types.js";
2
+ const capabilities = [
3
+ {
4
+ id: "tfc-workspaces",
5
+ name: "Workspace Configs",
6
+ description: "Fetch Terraform Cloud workspace configurations and variables",
7
+ evidenceCategories: ["iac", "configuration"],
8
+ },
9
+ {
10
+ id: "tfc-state",
11
+ name: "State Files",
12
+ description: "Fetch state file metadata and resource counts",
13
+ evidenceCategories: ["iac", "change_management"],
14
+ },
15
+ {
16
+ id: "tfc-drift",
17
+ name: "Drift Detection",
18
+ description: "Fetch drift detection results and policy violations",
19
+ evidenceCategories: ["iac", "compliance"],
20
+ },
21
+ ];
22
+ export class TerraformCloudConnector {
23
+ id = "terraform-cloud";
24
+ name = "Terraform Cloud";
25
+ category = "iac";
26
+ authType = "bearer_token";
27
+ capabilities = capabilities;
28
+ frameworks = ["SOC2", "ISO27001", "NIST_CSF"];
29
+ async fetchApi(config, endpoint) {
30
+ const base = config.baseUrl || "https://app.terraform.io/api/v2";
31
+ const resp = await fetch(`${base}${endpoint}`, {
32
+ headers: {
33
+ Authorization: `Bearer ${config.apiToken}`,
34
+ "Content-Type": "application/vnd.api+json",
35
+ },
36
+ });
37
+ if (!resp.ok)
38
+ throw new Error(`Terraform Cloud API ${resp.status}: ${resp.statusText}`);
39
+ return (await resp.json());
40
+ }
41
+ async testConnection(config) {
42
+ try {
43
+ await this.fetchApi(config, "/organizations?filter[name]=default");
44
+ return true;
45
+ }
46
+ catch {
47
+ return false;
48
+ }
49
+ }
50
+ async collectEvidence(config) {
51
+ const artifacts = [];
52
+ const now = new Date().toISOString();
53
+ const org = config.extra?.org || "default";
54
+ const workspaces = await this.fetchApi(config, `/organizations/${org}/workspaces`).catch(() => ({ data: [] }));
55
+ const wsList = Array.isArray(workspaces.data) ? workspaces.data : [];
56
+ artifacts.push({
57
+ id: generateEvidenceId(),
58
+ connectorId: this.id,
59
+ capabilityId: "tfc-workspaces",
60
+ timestamp: now,
61
+ hash: hashEvidence({ workspaceCount: wsList.length }),
62
+ framework: "SOC2",
63
+ controlId: "CC8.1",
64
+ source: `terraform-cloud/organizations/${org}/workspaces`,
65
+ status: "unknown",
66
+ data: { workspaceCount: wsList.length },
67
+ metadata: { org },
68
+ });
69
+ const wsId = config.extra?.workspaceId || wsList[0]?.id || "";
70
+ const state = wsId
71
+ ? await this.fetchApi(config, `/workspaces/${wsId}/current-state-version`)
72
+ .catch(() => ({ data: null }))
73
+ : { data: null };
74
+ artifacts.push({
75
+ id: generateEvidenceId(),
76
+ connectorId: this.id,
77
+ capabilityId: "tfc-state",
78
+ timestamp: now,
79
+ hash: hashEvidence(state),
80
+ framework: "ISO27001",
81
+ controlId: "A.12.3.1",
82
+ source: `terraform-cloud/workspaces/${wsId}/state`,
83
+ status: state.data ? "compliant" : "non_compliant",
84
+ data: { stateVersion: state.data },
85
+ metadata: { org, workspaceId: wsId },
86
+ });
87
+ const runs = wsId
88
+ ? await this.fetchApi(config, `/workspaces/${wsId}/runs?filter[status]=planned,errored&filter[kinds][]=drift`).catch(() => ({ data: [] }))
89
+ : { data: [] };
90
+ const runList = Array.isArray(runs.data) ? runs.data : [];
91
+ artifacts.push({
92
+ id: generateEvidenceId(),
93
+ connectorId: this.id,
94
+ capabilityId: "tfc-drift",
95
+ timestamp: now,
96
+ hash: hashEvidence({ driftRuns: runList.length }),
97
+ framework: "SOC2",
98
+ controlId: "CC8.1",
99
+ source: `terraform-cloud/workspaces/${wsId}/drift`,
100
+ status: runList.length === 0 ? "compliant" : "non_compliant",
101
+ data: { driftRuns: runList.length },
102
+ metadata: { org, workspaceId: wsId },
103
+ });
104
+ return artifacts;
105
+ }
106
+ }
@@ -0,0 +1,25 @@
1
+ export { GitHubConnector } from "./GitHubConnector.js";
2
+ export { GitLabConnector } from "./GitLabConnector.js";
3
+ export { AWSIAMConnector } from "./AWSIAMConnector.js";
4
+ export { AWSS3Connector } from "./AWSS3Connector.js";
5
+ export { AWSCloudTrailConnector } from "./AWSCloudTrailConnector.js";
6
+ export { AzureADConnector } from "./AzureADConnector.js";
7
+ export { AzureSentinelConnector } from "./AzureSentinelConnector.js";
8
+ export { GCPIAMConnector } from "./GCPIAMConnector.js";
9
+ export { GCPSCCConnector } from "./GCPSCCConnector.js";
10
+ export { OktaConnector } from "./OktaConnector.js";
11
+ export { JiraConnector } from "./JiraConnector.js";
12
+ export { SlackConnector } from "./SlackConnector.js";
13
+ export { PagerDutyConnector } from "./PagerDutyConnector.js";
14
+ export { SnowflakeConnector } from "./SnowflakeConnector.js";
15
+ export { DatadogConnector } from "./DatadogConnector.js";
16
+ export { CrowdStrikeConnector } from "./CrowdStrikeConnector.js";
17
+ export { QualysConnector } from "./QualysConnector.js";
18
+ export { SnykConnector } from "./SnykConnector.js";
19
+ export { TerraformCloudConnector } from "./TerraformCloudConnector.js";
20
+ export { GitHubActionsConnector } from "./GitHubActionsConnector.js";
21
+ export { DockerHubConnector } from "./DockerHubConnector.js";
22
+ export { KubernetesConnector } from "./KubernetesConnector.js";
23
+ export { SalesforceConnector } from "./SalesforceConnector.js";
24
+ export { HubSpotConnector } from "./HubSpotConnector.js";
25
+ export { BambooHRConnector } from "./BambooHRConnector.js";
@@ -0,0 +1,25 @@
1
+ export { GitHubConnector } from "./GitHubConnector.js";
2
+ export { GitLabConnector } from "./GitLabConnector.js";
3
+ export { AWSIAMConnector } from "./AWSIAMConnector.js";
4
+ export { AWSS3Connector } from "./AWSS3Connector.js";
5
+ export { AWSCloudTrailConnector } from "./AWSCloudTrailConnector.js";
6
+ export { AzureADConnector } from "./AzureADConnector.js";
7
+ export { AzureSentinelConnector } from "./AzureSentinelConnector.js";
8
+ export { GCPIAMConnector } from "./GCPIAMConnector.js";
9
+ export { GCPSCCConnector } from "./GCPSCCConnector.js";
10
+ export { OktaConnector } from "./OktaConnector.js";
11
+ export { JiraConnector } from "./JiraConnector.js";
12
+ export { SlackConnector } from "./SlackConnector.js";
13
+ export { PagerDutyConnector } from "./PagerDutyConnector.js";
14
+ export { SnowflakeConnector } from "./SnowflakeConnector.js";
15
+ export { DatadogConnector } from "./DatadogConnector.js";
16
+ export { CrowdStrikeConnector } from "./CrowdStrikeConnector.js";
17
+ export { QualysConnector } from "./QualysConnector.js";
18
+ export { SnykConnector } from "./SnykConnector.js";
19
+ export { TerraformCloudConnector } from "./TerraformCloudConnector.js";
20
+ export { GitHubActionsConnector } from "./GitHubActionsConnector.js";
21
+ export { DockerHubConnector } from "./DockerHubConnector.js";
22
+ export { KubernetesConnector } from "./KubernetesConnector.js";
23
+ export { SalesforceConnector } from "./SalesforceConnector.js";
24
+ export { HubSpotConnector } from "./HubSpotConnector.js";
25
+ export { BambooHRConnector } from "./BambooHRConnector.js";
@@ -0,0 +1,5 @@
1
+ export { IntegrationMarketplace } from "./IntegrationMarketplace.js";
2
+ export type { CollectionJob } from "./IntegrationMarketplace.js";
3
+ export { GitHubConnector, GitLabConnector, AWSIAMConnector, AWSS3Connector, AWSCloudTrailConnector, AzureADConnector, AzureSentinelConnector, GCPIAMConnector, GCPSCCConnector, OktaConnector, JiraConnector, SlackConnector, PagerDutyConnector, SnowflakeConnector, DatadogConnector, CrowdStrikeConnector, QualysConnector, SnykConnector, TerraformCloudConnector, GitHubActionsConnector, DockerHubConnector, KubernetesConnector, SalesforceConnector, HubSpotConnector, BambooHRConnector, } from "./connectors/index.js";
4
+ export type { IntegrationConnector, ConnectorConfig, ConnectorRegistration, EvidenceArtifact, IntegrationCapability, IntegrationCategory, AuthType, ComplianceFramework, EvidenceStatus, MarketplaceStats, } from "./types.js";
5
+ export { hashEvidence, generateEvidenceId } from "./types.js";
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { IntegrationMarketplace } from "./IntegrationMarketplace.js";
2
+ export { GitHubConnector, GitLabConnector, AWSIAMConnector, AWSS3Connector, AWSCloudTrailConnector, AzureADConnector, AzureSentinelConnector, GCPIAMConnector, GCPSCCConnector, OktaConnector, JiraConnector, SlackConnector, PagerDutyConnector, SnowflakeConnector, DatadogConnector, CrowdStrikeConnector, QualysConnector, SnykConnector, TerraformCloudConnector, GitHubActionsConnector, DockerHubConnector, KubernetesConnector, SalesforceConnector, HubSpotConnector, BambooHRConnector, } from "./connectors/index.js";
3
+ export { hashEvidence, generateEvidenceId } from "./types.js";
@@ -0,0 +1 @@
1
+ export {};