@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,94 @@
1
+ import { hashEvidence, generateEvidenceId } from "../types.js";
2
+ const capabilities = [
3
+ {
4
+ id: "scc-findings",
5
+ name: "Security Command Center Findings",
6
+ description: "Fetch GCP Security Command Center findings",
7
+ evidenceCategories: ["vulnerability_management", "risk_management"],
8
+ },
9
+ {
10
+ id: "scc-sources",
11
+ name: "Security Sources",
12
+ description: "Fetch SCC security sources and their findings count",
13
+ evidenceCategories: ["monitoring", "configuration"],
14
+ },
15
+ ];
16
+ export class GCPSCCConnector {
17
+ id = "gcp-scc";
18
+ name = "GCP Security Command Center";
19
+ category = "cloud_provider";
20
+ authType = "service_account";
21
+ capabilities = capabilities;
22
+ frameworks = ["SOC2", "ISO27001", "NIST_CSF"];
23
+ async getAccessToken(config) {
24
+ const now = Math.floor(Date.now() / 1000);
25
+ const header = Buffer.from(JSON.stringify({ alg: "RS256", typ: "JWT" })).toString("base64url");
26
+ const payload = Buffer.from(JSON.stringify({
27
+ iss: config.clientId,
28
+ scope: "https://www.googleapis.com/auth/cloud-platform",
29
+ aud: "https://oauth2.googleapis.com/token",
30
+ exp: now + 3600,
31
+ iat: now,
32
+ })).toString("base64url");
33
+ const jwt = `${header}.${payload}.signature`;
34
+ const resp = await fetch("https://oauth2.googleapis.com/token", {
35
+ method: "POST",
36
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
37
+ body: new URLSearchParams({
38
+ grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
39
+ assertion: jwt,
40
+ }),
41
+ });
42
+ if (!resp.ok)
43
+ throw new Error(`GCP token ${resp.status}`);
44
+ const data = (await resp.json());
45
+ return data.access_token;
46
+ }
47
+ async testConnection(config) {
48
+ try {
49
+ const token = await this.getAccessToken(config);
50
+ const orgId = config.extra?.orgId || config.accountId;
51
+ const resp = await fetch(`https://securitycenter.googleapis.com/v1/organizations/${orgId}/sources`, { headers: { Authorization: `Bearer ${token}` } });
52
+ return resp.ok;
53
+ }
54
+ catch {
55
+ return false;
56
+ }
57
+ }
58
+ async collectEvidence(config) {
59
+ const artifacts = [];
60
+ const now = new Date().toISOString();
61
+ const token = await this.getAccessToken(config);
62
+ const headers = { Authorization: `Bearer ${token}` };
63
+ const orgId = config.extra?.orgId || config.accountId;
64
+ const findings = await fetch(`https://securitycenter.googleapis.com/v1/organizations/${orgId}/sources/-/findings?pageSize=100&filter=state%3D%22ACTIVE%22`, { headers }).then((r) => r.json());
65
+ artifacts.push({
66
+ id: generateEvidenceId(),
67
+ connectorId: this.id,
68
+ capabilityId: "scc-findings",
69
+ timestamp: now,
70
+ hash: hashEvidence(findings),
71
+ framework: "SOC2",
72
+ controlId: "CC7.1",
73
+ source: `gcp-scc/organizations/${orgId}/findings`,
74
+ status: "unknown",
75
+ data: { findingCount: (findings.findings || []).length, findings: findings.findings },
76
+ metadata: { orgId: orgId || "" },
77
+ });
78
+ const sources = await fetch(`https://securitycenter.googleapis.com/v1/organizations/${orgId}/sources`, { headers }).then((r) => r.json());
79
+ artifacts.push({
80
+ id: generateEvidenceId(),
81
+ connectorId: this.id,
82
+ capabilityId: "scc-sources",
83
+ timestamp: now,
84
+ hash: hashEvidence(sources),
85
+ framework: "ISO27001",
86
+ controlId: "A.12.4.1",
87
+ source: `gcp-scc/organizations/${orgId}/sources`,
88
+ status: (sources.sources || []).length > 0 ? "compliant" : "non_compliant",
89
+ data: { sourceCount: (sources.sources || []).length },
90
+ metadata: { orgId: orgId || "" },
91
+ });
92
+ return artifacts;
93
+ }
94
+ }
@@ -0,0 +1,12 @@
1
+ import type { IntegrationConnector, ConnectorConfig, EvidenceArtifact, IntegrationCapability, ComplianceFramework } from "../types.js";
2
+ export declare class GitHubActionsConnector implements IntegrationConnector {
3
+ readonly id = "github-actions";
4
+ readonly name = "GitHub Actions";
5
+ readonly category: "ci_cd";
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,104 @@
1
+ import { hashEvidence, generateEvidenceId } from "../types.js";
2
+ const capabilities = [
3
+ {
4
+ id: "gha-workflow-runs",
5
+ name: "Workflow Runs",
6
+ description: "Fetch GitHub Actions workflow run history and statuses",
7
+ evidenceCategories: ["ci_cd", "change_management"],
8
+ },
9
+ {
10
+ id: "gha-security-alerts",
11
+ name: "Security Alerts",
12
+ description: "Fetch Dependabot alerts from GitHub Actions",
13
+ evidenceCategories: ["vulnerability_management", "supply_chain"],
14
+ },
15
+ {
16
+ id: "gha-dependency-reviews",
17
+ name: "Dependency Reviews",
18
+ description: "Fetch dependency review advisories on pull requests",
19
+ evidenceCategories: ["supply_chain", "vulnerability_management"],
20
+ },
21
+ ];
22
+ export class GitHubActionsConnector {
23
+ id = "github-actions";
24
+ name = "GitHub Actions";
25
+ category = "ci_cd";
26
+ authType = "bearer_token";
27
+ capabilities = capabilities;
28
+ frameworks = ["SOC2", "ISO27001", "NIST_CSF"];
29
+ async fetchApi(config, endpoint) {
30
+ const base = config.baseUrl || "https://api.github.com";
31
+ const resp = await fetch(`${base}${endpoint}`, {
32
+ headers: {
33
+ Authorization: `Bearer ${config.apiToken}`,
34
+ Accept: "application/vnd.github+json",
35
+ "X-GitHub-Api-Version": "2022-11-28",
36
+ },
37
+ });
38
+ if (!resp.ok)
39
+ throw new Error(`GitHub API ${resp.status}: ${resp.statusText}`);
40
+ return (await resp.json());
41
+ }
42
+ async testConnection(config) {
43
+ try {
44
+ await this.fetchApi(config, "/user");
45
+ return true;
46
+ }
47
+ catch {
48
+ return false;
49
+ }
50
+ }
51
+ async collectEvidence(config) {
52
+ const artifacts = [];
53
+ const now = new Date().toISOString();
54
+ const org = config.extra?.org || "default";
55
+ const repo = config.extra?.repo || "main-repo";
56
+ const runs = await this.fetchApi(config, `/repos/${org}/${repo}/actions/runs?per_page=100&status=completed`).catch(() => ({ workflow_runs: [] }));
57
+ const runList = (runs.workflow_runs || []);
58
+ const failed = runList.filter((r) => r.conclusion === "failure");
59
+ artifacts.push({
60
+ id: generateEvidenceId(),
61
+ connectorId: this.id,
62
+ capabilityId: "gha-workflow-runs",
63
+ timestamp: now,
64
+ hash: hashEvidence({ totalRuns: runList.length, failedRuns: failed.length }),
65
+ framework: "SOC2",
66
+ controlId: "CC8.1",
67
+ source: `github.com/${org}/${repo}/actions/runs`,
68
+ status: failed.length === 0 ? "compliant" : "partial",
69
+ data: { totalRuns: runList.length, failedRuns: failed.length, successRate: runList.length > 0 ? ((runList.length - failed.length) / runList.length * 100).toFixed(1) + "%" : "N/A" },
70
+ metadata: { org, repo },
71
+ });
72
+ const alerts = await this.fetchApi(config, `/repos/${org}/${repo}/vulnerability-alerts`).catch(() => ({ enabled: false }));
73
+ artifacts.push({
74
+ id: generateEvidenceId(),
75
+ connectorId: this.id,
76
+ capabilityId: "gha-security-alerts",
77
+ timestamp: now,
78
+ hash: hashEvidence(alerts),
79
+ framework: "ISO27001",
80
+ controlId: "A.12.6.1",
81
+ source: `github.com/${org}/${repo}/vulnerability-alerts`,
82
+ status: alerts.enabled === true ? "compliant" : "non_compliant",
83
+ data: { vulnerabilityAlertsEnabled: alerts.enabled },
84
+ metadata: { org, repo },
85
+ });
86
+ const depReview = await this.fetchApi(config, `/repos/${org}/${repo}/dependency-graph/dependency-review?per_page=50`).catch(() => ({ dependencies: [] }));
87
+ const depList = (depReview.dependencies || []);
88
+ const vulnerable = depList.filter((d) => d.severity === "critical" || d.severity === "high");
89
+ artifacts.push({
90
+ id: generateEvidenceId(),
91
+ connectorId: this.id,
92
+ capabilityId: "gha-dependency-reviews",
93
+ timestamp: now,
94
+ hash: hashEvidence({ totalDeps: depList.length, vulnerableDeps: vulnerable.length }),
95
+ framework: "SOC2",
96
+ controlId: "CC6.1",
97
+ source: `github.com/${org}/${repo}/dependency-review`,
98
+ status: vulnerable.length === 0 ? "compliant" : "non_compliant",
99
+ data: { totalDeps: depList.length, vulnerableDeps: vulnerable.length },
100
+ metadata: { org, repo },
101
+ });
102
+ return artifacts;
103
+ }
104
+ }
@@ -0,0 +1,12 @@
1
+ import type { IntegrationConnector, ConnectorConfig, EvidenceArtifact, IntegrationCapability, ComplianceFramework } from "../types.js";
2
+ export declare class GitHubConnector implements IntegrationConnector {
3
+ readonly id = "github";
4
+ readonly name = "GitHub";
5
+ readonly category: "version_control";
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,135 @@
1
+ import { hashEvidence, generateEvidenceId } from "../types.js";
2
+ const capabilities = [
3
+ {
4
+ id: "gh-repo-settings",
5
+ name: "Repository Settings",
6
+ description: "Fetch repo visibility, default branch, and security settings",
7
+ evidenceCategories: ["access_control", "configuration"],
8
+ },
9
+ {
10
+ id: "gh-branch-protection",
11
+ name: "Branch Protection Rules",
12
+ description: "Fetch branch protection policies and required reviews",
13
+ evidenceCategories: ["access_control", "change_management"],
14
+ },
15
+ {
16
+ id: "gh-secret-scanning",
17
+ name: "Secret Scanning",
18
+ description: "Fetch secret scanning alerts and push protection status",
19
+ evidenceCategories: ["data_protection", "vulnerability_management"],
20
+ },
21
+ {
22
+ id: "gh-dependabot",
23
+ name: "Dependabot Alerts",
24
+ description: "Fetch dependency vulnerability alerts and auto-fix PRs",
25
+ evidenceCategories: ["vulnerability_management", "supply_chain"],
26
+ },
27
+ ];
28
+ export class GitHubConnector {
29
+ id = "github";
30
+ name = "GitHub";
31
+ category = "version_control";
32
+ authType = "bearer_token";
33
+ capabilities = capabilities;
34
+ frameworks = [
35
+ "SOC2",
36
+ "ISO27001",
37
+ "NIST_CSF",
38
+ "PCI_DSS",
39
+ ];
40
+ async fetchApi(config, endpoint) {
41
+ const base = config.baseUrl || "https://api.github.com";
42
+ const resp = await fetch(`${base}${endpoint}`, {
43
+ headers: {
44
+ Authorization: `Bearer ${config.apiToken}`,
45
+ Accept: "application/vnd.github+json",
46
+ "X-GitHub-Api-Version": "2022-11-28",
47
+ },
48
+ });
49
+ if (!resp.ok)
50
+ throw new Error(`GitHub API ${resp.status}: ${resp.statusText}`);
51
+ return (await resp.json());
52
+ }
53
+ async testConnection(config) {
54
+ try {
55
+ await this.fetchApi(config, "/user");
56
+ return true;
57
+ }
58
+ catch {
59
+ return false;
60
+ }
61
+ }
62
+ async collectEvidence(config) {
63
+ const artifacts = [];
64
+ const now = new Date().toISOString();
65
+ const org = config.extra?.org || "default";
66
+ const repo = config.extra?.repo || "main-repo";
67
+ const repoData = await this.fetchApi(config, `/repos/${org}/${repo}`);
68
+ artifacts.push({
69
+ id: generateEvidenceId(),
70
+ connectorId: this.id,
71
+ capabilityId: "gh-repo-settings",
72
+ timestamp: now,
73
+ hash: hashEvidence(repoData),
74
+ framework: "SOC2",
75
+ controlId: "CC6.1",
76
+ source: `github.com/${org}/${repo}`,
77
+ status: repoData.private === true ? "compliant" : "partial",
78
+ data: {
79
+ private: repoData.private,
80
+ defaultBranch: repoData.default_branch,
81
+ hasSecurityPolicy: repoData.security_policy_url != null,
82
+ hasVulnerabilityAlerts: repoData.security_and_analysis != null,
83
+ },
84
+ metadata: { org, repo },
85
+ });
86
+ const protection = await this.fetchApi(config, `/repos/${org}/${repo}/branches/main/protection`).catch(() => null);
87
+ if (protection) {
88
+ artifacts.push({
89
+ id: generateEvidenceId(),
90
+ connectorId: this.id,
91
+ capabilityId: "gh-branch-protection",
92
+ timestamp: now,
93
+ hash: hashEvidence(protection),
94
+ framework: "SOC2",
95
+ controlId: "CC8.1",
96
+ source: `github.com/${org}/${repo}/branches/main/protection`,
97
+ status: "compliant",
98
+ data: {
99
+ requiredPullRequestReviews: protection.required_pull_request_reviews || null,
100
+ enforceAdmins: protection.enforce_admins || null,
101
+ },
102
+ metadata: { org, repo },
103
+ });
104
+ }
105
+ const secretScanning = await this.fetchApi(config, `/repos/${org}/${repo}/secret-scanning/alerts?state=open&per_page=10`).catch(() => ({ total_count: 0 }));
106
+ artifacts.push({
107
+ id: generateEvidenceId(),
108
+ connectorId: this.id,
109
+ capabilityId: "gh-secret-scanning",
110
+ timestamp: now,
111
+ hash: hashEvidence(secretScanning),
112
+ framework: "SOC2",
113
+ controlId: "CC6.6",
114
+ source: `github.com/${org}/${repo}/secret-scanning`,
115
+ status: secretScanning.total_count === 0 ? "compliant" : "non_compliant",
116
+ data: { openAlerts: secretScanning.total_count },
117
+ metadata: { org, repo },
118
+ });
119
+ const dependabot = await this.fetchApi(config, `/repos/${org}/${repo}/vulnerability-alerts`).catch(() => ({ enabled: false }));
120
+ artifacts.push({
121
+ id: generateEvidenceId(),
122
+ connectorId: this.id,
123
+ capabilityId: "gh-dependabot",
124
+ timestamp: now,
125
+ hash: hashEvidence(dependabot),
126
+ framework: "ISO27001",
127
+ controlId: "A.12.6.1",
128
+ source: `github.com/${org}/${repo}/dependabot`,
129
+ status: dependabot.enabled === true ? "compliant" : "non_compliant",
130
+ data: { enabled: dependabot.enabled },
131
+ metadata: { org, repo },
132
+ });
133
+ return artifacts;
134
+ }
135
+ }
@@ -0,0 +1,12 @@
1
+ import type { IntegrationConnector, ConnectorConfig, EvidenceArtifact, IntegrationCapability, ComplianceFramework } from "../types.js";
2
+ export declare class GitLabConnector implements IntegrationConnector {
3
+ readonly id = "gitlab";
4
+ readonly name = "GitLab";
5
+ readonly category: "version_control";
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,101 @@
1
+ import { hashEvidence, generateEvidenceId } from "../types.js";
2
+ const capabilities = [
3
+ {
4
+ id: "gl-project-settings",
5
+ name: "Project Settings",
6
+ description: "Fetch project visibility, push rules, and container protection",
7
+ evidenceCategories: ["access_control", "configuration"],
8
+ },
9
+ {
10
+ id: "gl-mr-approvals",
11
+ name: "Merge Request Approvals",
12
+ description: "Fetch MR approval rules and required reviewers",
13
+ evidenceCategories: ["change_management"],
14
+ },
15
+ {
16
+ id: "gl-sast-results",
17
+ name: "SAST Results",
18
+ description: "Fetch Static Application Security Testing results",
19
+ evidenceCategories: ["vulnerability_management", "application_security"],
20
+ },
21
+ ];
22
+ export class GitLabConnector {
23
+ id = "gitlab";
24
+ name = "GitLab";
25
+ category = "version_control";
26
+ authType = "bearer_token";
27
+ capabilities = capabilities;
28
+ frameworks = ["SOC2", "ISO27001", "NIST_CSF"];
29
+ async fetchApi(config, endpoint) {
30
+ const base = config.baseUrl || "https://gitlab.com/api/v4";
31
+ const resp = await fetch(`${base}${endpoint}`, {
32
+ headers: { Authorization: `Bearer ${config.apiToken}` },
33
+ });
34
+ if (!resp.ok)
35
+ throw new Error(`GitLab API ${resp.status}: ${resp.statusText}`);
36
+ return (await resp.json());
37
+ }
38
+ async testConnection(config) {
39
+ try {
40
+ await this.fetchApi(config, "/user");
41
+ return true;
42
+ }
43
+ catch {
44
+ return false;
45
+ }
46
+ }
47
+ async collectEvidence(config) {
48
+ const artifacts = [];
49
+ const now = new Date().toISOString();
50
+ const projectId = config.extra?.projectId || "1";
51
+ const project = await this.fetchApi(config, `/projects/${projectId}`);
52
+ artifacts.push({
53
+ id: generateEvidenceId(),
54
+ connectorId: this.id,
55
+ capabilityId: "gl-project-settings",
56
+ timestamp: now,
57
+ hash: hashEvidence(project),
58
+ framework: "SOC2",
59
+ controlId: "CC6.1",
60
+ source: `gitlab.com/projects/${projectId}`,
61
+ status: project.visibility === "private" ? "compliant" : "partial",
62
+ data: {
63
+ visibility: project.visibility,
64
+ requestAccessEnabled: project.request_access_enabled,
65
+ mergeRequestsEnabled: project.merge_requests_enabled,
66
+ jobsEnabled: project.jobs_enabled,
67
+ },
68
+ metadata: { projectId: String(projectId) },
69
+ });
70
+ const approvals = await this.fetchApi(config, `/projects/${projectId}/approval_rules`).catch(() => []);
71
+ const rules = Array.isArray(approvals) ? approvals : [];
72
+ artifacts.push({
73
+ id: generateEvidenceId(),
74
+ connectorId: this.id,
75
+ capabilityId: "gl-mr-approvals",
76
+ timestamp: now,
77
+ hash: hashEvidence({ rules }),
78
+ framework: "SOC2",
79
+ controlId: "CC8.1",
80
+ source: `gitlab.com/projects/${projectId}/approval_rules`,
81
+ status: rules.length > 0 ? "compliant" : "non_compliant",
82
+ data: { approvalRules: rules },
83
+ metadata: { projectId: String(projectId) },
84
+ });
85
+ const sast = await this.fetchApi(config, `/projects/${projectId}/security/scans`).catch(() => ({ vulnerabilities: [] }));
86
+ artifacts.push({
87
+ id: generateEvidenceId(),
88
+ connectorId: this.id,
89
+ capabilityId: "gl-sast-results",
90
+ timestamp: now,
91
+ hash: hashEvidence(sast),
92
+ framework: "ISO27001",
93
+ controlId: "A.14.2.1",
94
+ source: `gitlab.com/projects/${projectId}/security/scans`,
95
+ status: "unknown",
96
+ data: { scans: sast },
97
+ metadata: { projectId: String(projectId) },
98
+ });
99
+ return artifacts;
100
+ }
101
+ }
@@ -0,0 +1,12 @@
1
+ import type { IntegrationConnector, ConnectorConfig, EvidenceArtifact, IntegrationCapability, ComplianceFramework } from "../types.js";
2
+ export declare class HubSpotConnector implements IntegrationConnector {
3
+ readonly id = "hubspot";
4
+ readonly name = "HubSpot";
5
+ readonly category: "project_management";
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,77 @@
1
+ import { hashEvidence, generateEvidenceId } from "../types.js";
2
+ const capabilities = [
3
+ {
4
+ id: "hs-user-access",
5
+ name: "User Access",
6
+ description: "Fetch HubSpot user accounts and permission levels",
7
+ evidenceCategories: ["access_control"],
8
+ },
9
+ {
10
+ id: "hs-integrations",
11
+ name: "Integration Permissions",
12
+ description: "Fetch connected apps and their scopes",
13
+ evidenceCategories: ["third_party_management", "access_control"],
14
+ },
15
+ ];
16
+ export class HubSpotConnector {
17
+ id = "hubspot";
18
+ name = "HubSpot";
19
+ category = "project_management";
20
+ authType = "bearer_token";
21
+ capabilities = capabilities;
22
+ frameworks = ["SOC2", "ISO27001"];
23
+ async fetchApi(config, endpoint) {
24
+ const base = config.baseUrl || "https://api.hubapi.com";
25
+ const resp = await fetch(`${base}${endpoint}`, {
26
+ headers: { Authorization: `Bearer ${config.apiToken}` },
27
+ });
28
+ if (!resp.ok)
29
+ throw new Error(`HubSpot API ${resp.status}: ${resp.statusText}`);
30
+ return (await resp.json());
31
+ }
32
+ async testConnection(config) {
33
+ try {
34
+ await this.fetchApi(config, "/crm/v3/objects/users?limit=1");
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 users = await this.fetchApi(config, "/crm/v3/objects/users?limit=100");
45
+ const userList = (users.results || []);
46
+ artifacts.push({
47
+ id: generateEvidenceId(),
48
+ connectorId: this.id,
49
+ capabilityId: "hs-user-access",
50
+ timestamp: now,
51
+ hash: hashEvidence({ userCount: userList.length }),
52
+ framework: "SOC2",
53
+ controlId: "CC6.1",
54
+ source: "hubspot/users",
55
+ status: userList.length > 0 ? "compliant" : "non_compliant",
56
+ data: { userCount: userList.length },
57
+ metadata: {},
58
+ });
59
+ const integrations = await fetch(`${config.baseUrl || "https://api.hubapi.com"}/crm/v3/objects/users?limit=100`, {
60
+ headers: { Authorization: `Bearer ${config.apiToken}` },
61
+ }).then((r) => r.json());
62
+ artifacts.push({
63
+ id: generateEvidenceId(),
64
+ connectorId: this.id,
65
+ capabilityId: "hs-integrations",
66
+ timestamp: now,
67
+ hash: hashEvidence(integrations),
68
+ framework: "ISO27001",
69
+ controlId: "A.14.2.5",
70
+ source: "hubspot/integrations",
71
+ status: "unknown",
72
+ data: { integrations },
73
+ metadata: {},
74
+ });
75
+ return artifacts;
76
+ }
77
+ }
@@ -0,0 +1,12 @@
1
+ import type { IntegrationConnector, ConnectorConfig, EvidenceArtifact, IntegrationCapability, ComplianceFramework } from "../types.js";
2
+ export declare class JiraConnector implements IntegrationConnector {
3
+ readonly id = "jira";
4
+ readonly name = "Jira";
5
+ readonly category: "project_management";
6
+ readonly authType: "basic_auth";
7
+ readonly capabilities: IntegrationCapability[];
8
+ readonly frameworks: ComplianceFramework[];
9
+ private fetchApi;
10
+ testConnection(config: ConnectorConfig): Promise<boolean>;
11
+ collectEvidence(config: ConnectorConfig): Promise<EvidenceArtifact[]>;
12
+ }