chore: import upstream snapshot with attribution
Publish CLI Package / publish-npm (push) Waiting to run
Publish Python SDK / publish-pypi (push) Waiting to run
Publish TypeScript SDK / publish-npm (push) Waiting to run
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:20:55 +08:00
commit d25d482dc2
13754 changed files with 4996608 additions and 0 deletions
@@ -0,0 +1,74 @@
import type { ToolConfig } from '@/tools/types'
import type {
VantaDownloadDocumentFileParams,
VantaDownloadDocumentFileResponse,
} from '@/tools/vanta/types'
import { createVantaTransformResponse } from '@/tools/vanta/utils'
export const vantaDownloadDocumentFileTool: ToolConfig<
VantaDownloadDocumentFileParams,
VantaDownloadDocumentFileResponse
> = {
id: 'vanta_download_document_file',
name: 'Vanta Download Document File',
description:
'Download a file previously uploaded to a Vanta evidence document and store it in execution files',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
documentId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique ID of the document',
},
uploadedFileId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique ID of the uploaded file (from List Document Uploads)',
},
},
request: {
url: '/api/tools/vanta/download',
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
documentId: params.documentId,
uploadedFileId: params.uploadedFileId,
}),
},
transformResponse: createVantaTransformResponse<VantaDownloadDocumentFileResponse>(
'Failed to download Vanta document file'
),
outputs: {
file: { type: 'file', description: 'Downloaded file stored in execution files' },
name: { type: 'string', description: 'Name of the downloaded file' },
mimeType: { type: 'string', description: 'MIME type of the downloaded file' },
size: { type: 'number', description: 'Size of the downloaded file in bytes' },
},
}
+64
View File
@@ -0,0 +1,64 @@
import type { ToolConfig } from '@/tools/types'
import { VANTA_CONTROL_DETAIL_OUTPUT_PROPERTIES } from '@/tools/vanta/outputs'
import type { VantaGetControlParams, VantaGetControlResponse } from '@/tools/vanta/types'
import { createVantaTransformResponse, VANTA_QUERY_ROUTE } from '@/tools/vanta/utils'
export const vantaGetControlTool: ToolConfig<VantaGetControlParams, VantaGetControlResponse> = {
id: 'vanta_get_control',
name: 'Vanta Get Control',
description:
'Get a Vanta security control by ID, including its status and evidence pass/fail counts',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
controlId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique ID of the control',
},
},
request: {
url: VANTA_QUERY_ROUTE,
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
operation: 'vanta_get_control',
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
controlId: params.controlId,
}),
},
transformResponse: createVantaTransformResponse<VantaGetControlResponse>(
'Failed to get Vanta control'
),
outputs: {
control: {
type: 'json',
description: 'The requested control with status and evidence counts',
properties: VANTA_CONTROL_DETAIL_OUTPUT_PROPERTIES,
},
},
}
+64
View File
@@ -0,0 +1,64 @@
import type { ToolConfig } from '@/tools/types'
import { VANTA_DOCUMENT_DETAIL_OUTPUT_PROPERTIES } from '@/tools/vanta/outputs'
import type { VantaGetDocumentParams, VantaGetDocumentResponse } from '@/tools/vanta/types'
import { createVantaTransformResponse, VANTA_QUERY_ROUTE } from '@/tools/vanta/utils'
export const vantaGetDocumentTool: ToolConfig<VantaGetDocumentParams, VantaGetDocumentResponse> = {
id: 'vanta_get_document',
name: 'Vanta Get Document',
description:
'Get a Vanta evidence document by ID, including its renewal schedule and deactivation status',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
documentId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique ID of the document',
},
},
request: {
url: VANTA_QUERY_ROUTE,
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
operation: 'vanta_get_document',
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
documentId: params.documentId,
}),
},
transformResponse: createVantaTransformResponse<VantaGetDocumentResponse>(
'Failed to get Vanta document'
),
outputs: {
document: {
type: 'json',
description: 'The requested document',
properties: VANTA_DOCUMENT_DETAIL_OUTPUT_PROPERTIES,
},
},
}
+65
View File
@@ -0,0 +1,65 @@
import type { ToolConfig } from '@/tools/types'
import { VANTA_FRAMEWORK_DETAIL_OUTPUT_PROPERTIES } from '@/tools/vanta/outputs'
import type { VantaGetFrameworkParams, VantaGetFrameworkResponse } from '@/tools/vanta/types'
import { createVantaTransformResponse, VANTA_QUERY_ROUTE } from '@/tools/vanta/utils'
export const vantaGetFrameworkTool: ToolConfig<VantaGetFrameworkParams, VantaGetFrameworkResponse> =
{
id: 'vanta_get_framework',
name: 'Vanta Get Framework',
description:
'Get a Vanta compliance framework by ID, including its requirement categories and mapped controls',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
frameworkId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique ID of the framework (e.g., soc2)',
},
},
request: {
url: VANTA_QUERY_ROUTE,
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
operation: 'vanta_get_framework',
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
frameworkId: params.frameworkId,
}),
},
transformResponse: createVantaTransformResponse<VantaGetFrameworkResponse>(
'Failed to get Vanta framework'
),
outputs: {
framework: {
type: 'json',
description: 'The requested framework with requirement categories',
properties: VANTA_FRAMEWORK_DETAIL_OUTPUT_PROPERTIES,
},
},
}
+64
View File
@@ -0,0 +1,64 @@
import type { ToolConfig } from '@/tools/types'
import { VANTA_PERSON_OUTPUT_PROPERTIES } from '@/tools/vanta/outputs'
import type { VantaGetPersonParams, VantaGetPersonResponse } from '@/tools/vanta/types'
import { createVantaTransformResponse, VANTA_QUERY_ROUTE } from '@/tools/vanta/utils'
export const vantaGetPersonTool: ToolConfig<VantaGetPersonParams, VantaGetPersonResponse> = {
id: 'vanta_get_person',
name: 'Vanta Get Person',
description:
'Get a person tracked in Vanta by ID, including employment, leave, and security task status',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
personId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique ID of the person',
},
},
request: {
url: VANTA_QUERY_ROUTE,
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
operation: 'vanta_get_person',
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
personId: params.personId,
}),
},
transformResponse: createVantaTransformResponse<VantaGetPersonResponse>(
'Failed to get Vanta person'
),
outputs: {
person: {
type: 'json',
description: 'The requested person',
properties: VANTA_PERSON_OUTPUT_PROPERTIES,
},
},
}
+64
View File
@@ -0,0 +1,64 @@
import type { ToolConfig } from '@/tools/types'
import { VANTA_POLICY_OUTPUT_PROPERTIES } from '@/tools/vanta/outputs'
import type { VantaGetPolicyParams, VantaGetPolicyResponse } from '@/tools/vanta/types'
import { createVantaTransformResponse, VANTA_QUERY_ROUTE } from '@/tools/vanta/utils'
export const vantaGetPolicyTool: ToolConfig<VantaGetPolicyParams, VantaGetPolicyResponse> = {
id: 'vanta_get_policy',
name: 'Vanta Get Policy',
description:
'Get a Vanta security policy by ID, including its approval status and latest approved version documents',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
policyId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique ID of the policy',
},
},
request: {
url: VANTA_QUERY_ROUTE,
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
operation: 'vanta_get_policy',
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
policyId: params.policyId,
}),
},
transformResponse: createVantaTransformResponse<VantaGetPolicyResponse>(
'Failed to get Vanta policy'
),
outputs: {
policy: {
type: 'json',
description: 'The requested policy',
properties: VANTA_POLICY_OUTPUT_PROPERTIES,
},
},
}
+67
View File
@@ -0,0 +1,67 @@
import type { ToolConfig } from '@/tools/types'
import { VANTA_RISK_SCENARIO_OUTPUT_PROPERTIES } from '@/tools/vanta/outputs'
import type { VantaGetRiskScenarioParams, VantaGetRiskScenarioResponse } from '@/tools/vanta/types'
import { createVantaTransformResponse, VANTA_QUERY_ROUTE } from '@/tools/vanta/utils'
export const vantaGetRiskScenarioTool: ToolConfig<
VantaGetRiskScenarioParams,
VantaGetRiskScenarioResponse
> = {
id: 'vanta_get_risk_scenario',
name: 'Vanta Get Risk Scenario',
description:
'Get a Vanta risk scenario by ID, including its scores, treatment decision, and review status',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
riskScenarioId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique ID of the risk scenario',
},
},
request: {
url: VANTA_QUERY_ROUTE,
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
operation: 'vanta_get_risk_scenario',
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
riskScenarioId: params.riskScenarioId,
}),
},
transformResponse: createVantaTransformResponse<VantaGetRiskScenarioResponse>(
'Failed to get Vanta risk scenario'
),
outputs: {
riskScenario: {
type: 'json',
description: 'The requested risk scenario',
properties: VANTA_RISK_SCENARIO_OUTPUT_PROPERTIES,
},
},
}
+62
View File
@@ -0,0 +1,62 @@
import type { ToolConfig } from '@/tools/types'
import { VANTA_TEST_OUTPUT_PROPERTIES } from '@/tools/vanta/outputs'
import type { VantaGetTestParams, VantaGetTestResponse } from '@/tools/vanta/types'
import { createVantaTransformResponse, VANTA_QUERY_ROUTE } from '@/tools/vanta/utils'
export const vantaGetTestTool: ToolConfig<VantaGetTestParams, VantaGetTestResponse> = {
id: 'vanta_get_test',
name: 'Vanta Get Test',
description:
'Get a Vanta automated compliance test by ID, including its status and remediation info',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
testId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique ID of the test (e.g., test-aws-cloudtrail-enabled)',
},
},
request: {
url: VANTA_QUERY_ROUTE,
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
operation: 'vanta_get_test',
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
testId: params.testId,
}),
},
transformResponse: createVantaTransformResponse<VantaGetTestResponse>('Failed to get Vanta test'),
outputs: {
test: {
type: 'json',
description: 'The requested test',
properties: VANTA_TEST_OUTPUT_PROPERTIES,
},
},
}
+64
View File
@@ -0,0 +1,64 @@
import type { ToolConfig } from '@/tools/types'
import { VANTA_VENDOR_OUTPUT_PROPERTIES } from '@/tools/vanta/outputs'
import type { VantaGetVendorParams, VantaGetVendorResponse } from '@/tools/vanta/types'
import { createVantaTransformResponse, VANTA_QUERY_ROUTE } from '@/tools/vanta/utils'
export const vantaGetVendorTool: ToolConfig<VantaGetVendorParams, VantaGetVendorResponse> = {
id: 'vanta_get_vendor',
name: 'Vanta Get Vendor',
description:
'Get a Vanta vendor by ID, including risk levels, contract details, and authentication info',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
vendorId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique ID of the vendor',
},
},
request: {
url: VANTA_QUERY_ROUTE,
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
operation: 'vanta_get_vendor',
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
vendorId: params.vendorId,
}),
},
transformResponse: createVantaTransformResponse<VantaGetVendorResponse>(
'Failed to get Vanta vendor'
),
outputs: {
vendor: {
type: 'json',
description: 'The requested vendor',
properties: VANTA_VENDOR_OUTPUT_PROPERTIES,
},
},
}
@@ -0,0 +1,70 @@
import type { ToolConfig } from '@/tools/types'
import { VANTA_VULNERABLE_ASSET_OUTPUT_PROPERTIES } from '@/tools/vanta/outputs'
import type {
VantaGetVulnerableAssetParams,
VantaGetVulnerableAssetResponse,
} from '@/tools/vanta/types'
import { createVantaTransformResponse, VANTA_QUERY_ROUTE } from '@/tools/vanta/utils'
export const vantaGetVulnerableAssetTool: ToolConfig<
VantaGetVulnerableAssetParams,
VantaGetVulnerableAssetResponse
> = {
id: 'vanta_get_vulnerable_asset',
name: 'Vanta Get Vulnerable Asset',
description:
'Get a vulnerable asset in Vanta by ID, including the scanners reporting it and per-scanner asset details',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
vulnerableAssetId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique ID of the vulnerable asset',
},
},
request: {
url: VANTA_QUERY_ROUTE,
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
operation: 'vanta_get_vulnerable_asset',
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
vulnerableAssetId: params.vulnerableAssetId,
}),
},
transformResponse: createVantaTransformResponse<VantaGetVulnerableAssetResponse>(
'Failed to get Vanta vulnerable asset'
),
outputs: {
asset: {
type: 'json',
description: 'The requested vulnerable asset',
properties: VANTA_VULNERABLE_ASSET_OUTPUT_PROPERTIES,
},
},
}
+30
View File
@@ -0,0 +1,30 @@
export { vantaDownloadDocumentFileTool } from './download_document_file'
export { vantaGetControlTool } from './get_control'
export { vantaGetDocumentTool } from './get_document'
export { vantaGetFrameworkTool } from './get_framework'
export { vantaGetPersonTool } from './get_person'
export { vantaGetPolicyTool } from './get_policy'
export { vantaGetRiskScenarioTool } from './get_risk_scenario'
export { vantaGetTestTool } from './get_test'
export { vantaGetVendorTool } from './get_vendor'
export { vantaGetVulnerableAssetTool } from './get_vulnerable_asset'
export { vantaListControlDocumentsTool } from './list_control_documents'
export { vantaListControlTestsTool } from './list_control_tests'
export { vantaListControlsTool } from './list_controls'
export { vantaListDocumentUploadsTool } from './list_document_uploads'
export { vantaListDocumentsTool } from './list_documents'
export { vantaListFrameworkControlsTool } from './list_framework_controls'
export { vantaListFrameworksTool } from './list_frameworks'
export { vantaListMonitoredComputersTool } from './list_monitored_computers'
export { vantaListPeopleTool } from './list_people'
export { vantaListPoliciesTool } from './list_policies'
export { vantaListRiskScenariosTool } from './list_risk_scenarios'
export { vantaListTestEntitiesTool } from './list_test_entities'
export { vantaListTestsTool } from './list_tests'
export { vantaListVendorsTool } from './list_vendors'
export { vantaListVulnerabilitiesTool } from './list_vulnerabilities'
export { vantaListVulnerabilityRemediationsTool } from './list_vulnerability_remediations'
export { vantaListVulnerableAssetsTool } from './list_vulnerable_assets'
export { vantaSubmitDocumentTool } from './submit_document'
export * from './types'
export { vantaUploadDocumentFileTool } from './upload_document_file'
@@ -0,0 +1,94 @@
import type { ToolConfig } from '@/tools/types'
import {
VANTA_DOCUMENT_OUTPUT_PROPERTIES,
VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
} from '@/tools/vanta/outputs'
import type {
VantaListControlDocumentsParams,
VantaListDocumentsResponse,
} from '@/tools/vanta/types'
import { createVantaTransformResponse, VANTA_QUERY_ROUTE } from '@/tools/vanta/utils'
export const vantaListControlDocumentsTool: ToolConfig<
VantaListControlDocumentsParams,
VantaListDocumentsResponse
> = {
id: 'vanta_list_control_documents',
name: 'Vanta List Control Documents',
description: 'List the evidence documents mapped to a specific Vanta control',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
controlId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique ID of the control',
},
pageSize: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of items per page (1-100, default 10)',
},
pageCursor: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Pagination cursor: pass the endCursor from the previous response to fetch the next page',
},
},
request: {
url: VANTA_QUERY_ROUTE,
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
operation: 'vanta_list_control_documents',
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
controlId: params.controlId,
pageSize: params.pageSize,
pageCursor: params.pageCursor,
}),
},
transformResponse: createVantaTransformResponse<VantaListDocumentsResponse>(
'Failed to list Vanta control documents'
),
outputs: {
documents: {
type: 'array',
description: 'Documents mapped to the control',
items: { type: 'object', properties: VANTA_DOCUMENT_OUTPUT_PROPERTIES },
},
pageInfo: {
type: 'json',
description:
'Cursor pagination info for the returned page; pass endCursor as pageCursor to fetch the next page',
optional: true,
properties: VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
},
},
}
@@ -0,0 +1,91 @@
import type { ToolConfig } from '@/tools/types'
import {
VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
VANTA_TEST_OUTPUT_PROPERTIES,
} from '@/tools/vanta/outputs'
import type { VantaListControlTestsParams, VantaListTestsResponse } from '@/tools/vanta/types'
import { createVantaTransformResponse, VANTA_QUERY_ROUTE } from '@/tools/vanta/utils'
export const vantaListControlTestsTool: ToolConfig<
VantaListControlTestsParams,
VantaListTestsResponse
> = {
id: 'vanta_list_control_tests',
name: 'Vanta List Control Tests',
description: 'List the automated tests mapped to a specific Vanta control',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
controlId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique ID of the control',
},
pageSize: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of items per page (1-100, default 10)',
},
pageCursor: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Pagination cursor: pass the endCursor from the previous response to fetch the next page',
},
},
request: {
url: VANTA_QUERY_ROUTE,
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
operation: 'vanta_list_control_tests',
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
controlId: params.controlId,
pageSize: params.pageSize,
pageCursor: params.pageCursor,
}),
},
transformResponse: createVantaTransformResponse<VantaListTestsResponse>(
'Failed to list Vanta control tests'
),
outputs: {
tests: {
type: 'array',
description: 'Tests mapped to the control',
items: { type: 'object', properties: VANTA_TEST_OUTPUT_PROPERTIES },
},
pageInfo: {
type: 'json',
description:
'Cursor pagination info for the returned page; pass endCursor as pageCursor to fetch the next page',
optional: true,
properties: VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
},
},
}
+89
View File
@@ -0,0 +1,89 @@
import type { ToolConfig } from '@/tools/types'
import {
VANTA_CONTROL_OUTPUT_PROPERTIES,
VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
} from '@/tools/vanta/outputs'
import type { VantaListControlsParams, VantaListControlsResponse } from '@/tools/vanta/types'
import { createVantaTransformResponse, VANTA_QUERY_ROUTE } from '@/tools/vanta/utils'
export const vantaListControlsTool: ToolConfig<VantaListControlsParams, VantaListControlsResponse> =
{
id: 'vanta_list_controls',
name: 'Vanta List Controls',
description: 'List the security controls in a Vanta account, optionally filtered by framework',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
frameworkMatchesAny: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated framework IDs to filter controls by (e.g., soc2,iso27001)',
},
pageSize: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of items per page (1-100, default 10)',
},
pageCursor: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Pagination cursor: pass the endCursor from the previous response to fetch the next page',
},
},
request: {
url: VANTA_QUERY_ROUTE,
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
operation: 'vanta_list_controls',
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
frameworkMatchesAny: params.frameworkMatchesAny,
pageSize: params.pageSize,
pageCursor: params.pageCursor,
}),
},
transformResponse: createVantaTransformResponse<VantaListControlsResponse>(
'Failed to list Vanta controls'
),
outputs: {
controls: {
type: 'array',
description: 'Controls matching the filters',
items: { type: 'object', properties: VANTA_CONTROL_OUTPUT_PROPERTIES },
},
pageInfo: {
type: 'json',
description:
'Cursor pagination info for the returned page; pass endCursor as pageCursor to fetch the next page',
optional: true,
properties: VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
},
},
}
@@ -0,0 +1,94 @@
import type { ToolConfig } from '@/tools/types'
import {
VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
VANTA_UPLOADED_FILE_OUTPUT_PROPERTIES,
} from '@/tools/vanta/outputs'
import type {
VantaListDocumentUploadsParams,
VantaListDocumentUploadsResponse,
} from '@/tools/vanta/types'
import { createVantaTransformResponse, VANTA_QUERY_ROUTE } from '@/tools/vanta/utils'
export const vantaListDocumentUploadsTool: ToolConfig<
VantaListDocumentUploadsParams,
VantaListDocumentUploadsResponse
> = {
id: 'vanta_list_document_uploads',
name: 'Vanta List Document Uploads',
description: 'List the files uploaded to a specific Vanta evidence document',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
documentId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique ID of the document',
},
pageSize: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of items per page (1-100, default 10)',
},
pageCursor: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Pagination cursor: pass the endCursor from the previous response to fetch the next page',
},
},
request: {
url: VANTA_QUERY_ROUTE,
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
operation: 'vanta_list_document_uploads',
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
documentId: params.documentId,
pageSize: params.pageSize,
pageCursor: params.pageCursor,
}),
},
transformResponse: createVantaTransformResponse<VantaListDocumentUploadsResponse>(
'Failed to list Vanta document uploads'
),
outputs: {
uploads: {
type: 'array',
description: 'Files uploaded to the document',
items: { type: 'object', properties: VANTA_UPLOADED_FILE_OUTPUT_PROPERTIES },
},
pageInfo: {
type: 'json',
description:
'Cursor pagination info for the returned page; pass endCursor as pageCursor to fetch the next page',
optional: true,
properties: VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
},
},
}
+100
View File
@@ -0,0 +1,100 @@
import type { ToolConfig } from '@/tools/types'
import {
VANTA_DOCUMENT_OUTPUT_PROPERTIES,
VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
} from '@/tools/vanta/outputs'
import type { VantaListDocumentsParams, VantaListDocumentsResponse } from '@/tools/vanta/types'
import { createVantaTransformResponse, VANTA_QUERY_ROUTE } from '@/tools/vanta/utils'
export const vantaListDocumentsTool: ToolConfig<
VantaListDocumentsParams,
VantaListDocumentsResponse
> = {
id: 'vanta_list_documents',
name: 'Vanta List Documents',
description:
'List the evidence documents in a Vanta account, optionally filtered by framework or document status',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
frameworkMatchesAny: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated framework IDs to filter documents by (e.g., soc2,iso27001)',
},
statusMatchesAny: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Comma-separated document statuses to filter by: "Needs document", "Needs update", "Not relevant", "OK"',
},
pageSize: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of items per page (1-100, default 10)',
},
pageCursor: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Pagination cursor: pass the endCursor from the previous response to fetch the next page',
},
},
request: {
url: VANTA_QUERY_ROUTE,
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
operation: 'vanta_list_documents',
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
frameworkMatchesAny: params.frameworkMatchesAny,
statusMatchesAny: params.statusMatchesAny,
pageSize: params.pageSize,
pageCursor: params.pageCursor,
}),
},
transformResponse: createVantaTransformResponse<VantaListDocumentsResponse>(
'Failed to list Vanta documents'
),
outputs: {
documents: {
type: 'array',
description: 'Documents matching the filters',
items: { type: 'object', properties: VANTA_DOCUMENT_OUTPUT_PROPERTIES },
},
pageInfo: {
type: 'json',
description:
'Cursor pagination info for the returned page; pass endCursor as pageCursor to fetch the next page',
optional: true,
properties: VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
},
},
}
@@ -0,0 +1,94 @@
import type { ToolConfig } from '@/tools/types'
import {
VANTA_CONTROL_OUTPUT_PROPERTIES,
VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
} from '@/tools/vanta/outputs'
import type {
VantaListControlsResponse,
VantaListFrameworkControlsParams,
} from '@/tools/vanta/types'
import { createVantaTransformResponse, VANTA_QUERY_ROUTE } from '@/tools/vanta/utils'
export const vantaListFrameworkControlsTool: ToolConfig<
VantaListFrameworkControlsParams,
VantaListControlsResponse
> = {
id: 'vanta_list_framework_controls',
name: 'Vanta List Framework Controls',
description: 'List the controls that belong to a specific Vanta compliance framework',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
frameworkId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique ID of the framework (e.g., soc2)',
},
pageSize: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of items per page (1-100, default 10)',
},
pageCursor: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Pagination cursor: pass the endCursor from the previous response to fetch the next page',
},
},
request: {
url: VANTA_QUERY_ROUTE,
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
operation: 'vanta_list_framework_controls',
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
frameworkId: params.frameworkId,
pageSize: params.pageSize,
pageCursor: params.pageCursor,
}),
},
transformResponse: createVantaTransformResponse<VantaListControlsResponse>(
'Failed to list Vanta framework controls'
),
outputs: {
controls: {
type: 'array',
description: 'Controls belonging to the framework',
items: { type: 'object', properties: VANTA_CONTROL_OUTPUT_PROPERTIES },
},
pageInfo: {
type: 'json',
description:
'Cursor pagination info for the returned page; pass endCursor as pageCursor to fetch the next page',
optional: true,
properties: VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
},
},
}
+85
View File
@@ -0,0 +1,85 @@
import type { ToolConfig } from '@/tools/types'
import {
VANTA_FRAMEWORK_OUTPUT_PROPERTIES,
VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
} from '@/tools/vanta/outputs'
import type { VantaListFrameworksParams, VantaListFrameworksResponse } from '@/tools/vanta/types'
import { createVantaTransformResponse, VANTA_QUERY_ROUTE } from '@/tools/vanta/utils'
export const vantaListFrameworksTool: ToolConfig<
VantaListFrameworksParams,
VantaListFrameworksResponse
> = {
id: 'vanta_list_frameworks',
name: 'Vanta List Frameworks',
description:
'List the compliance frameworks (e.g., SOC 2, ISO 27001) available in a Vanta account with completion counts',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
pageSize: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of items per page (1-100, default 10)',
},
pageCursor: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Pagination cursor: pass the endCursor from the previous response to fetch the next page',
},
},
request: {
url: VANTA_QUERY_ROUTE,
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
operation: 'vanta_list_frameworks',
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
pageSize: params.pageSize,
pageCursor: params.pageCursor,
}),
},
transformResponse: createVantaTransformResponse<VantaListFrameworksResponse>(
'Failed to list Vanta frameworks'
),
outputs: {
frameworks: {
type: 'array',
description: 'Frameworks in the Vanta account',
items: { type: 'object', properties: VANTA_FRAMEWORK_OUTPUT_PROPERTIES },
},
pageInfo: {
type: 'json',
description:
'Cursor pagination info for the returned page; pass endCursor as pageCursor to fetch the next page',
optional: true,
properties: VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
},
},
}
@@ -0,0 +1,96 @@
import type { ToolConfig } from '@/tools/types'
import {
VANTA_MONITORED_COMPUTER_OUTPUT_PROPERTIES,
VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
} from '@/tools/vanta/outputs'
import type {
VantaListMonitoredComputersParams,
VantaListMonitoredComputersResponse,
} from '@/tools/vanta/types'
import { createVantaTransformResponse, VANTA_QUERY_ROUTE } from '@/tools/vanta/utils'
export const vantaListMonitoredComputersTool: ToolConfig<
VantaListMonitoredComputersParams,
VantaListMonitoredComputersResponse
> = {
id: 'vanta_list_monitored_computers',
name: 'Vanta List Monitored Computers',
description:
'List the monitored computers in a Vanta account with screenlock, disk encryption, password manager, and antivirus check outcomes',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
complianceStatusFilterMatchesAny: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Comma-separated compliance issues to filter by: PWM_NOT_INSTALLED, HD_NOT_ENCRYPTED, AV_NOT_INSTALLED, SCREENLOCK_NOT_CONFIGURED, LAST_CHECK_OVER_14_DAYS',
},
pageSize: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of items per page (1-100, default 10)',
},
pageCursor: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Pagination cursor: pass the endCursor from the previous response to fetch the next page',
},
},
request: {
url: VANTA_QUERY_ROUTE,
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
operation: 'vanta_list_monitored_computers',
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
complianceStatusFilterMatchesAny: params.complianceStatusFilterMatchesAny,
pageSize: params.pageSize,
pageCursor: params.pageCursor,
}),
},
transformResponse: createVantaTransformResponse<VantaListMonitoredComputersResponse>(
'Failed to list Vanta monitored computers'
),
outputs: {
computers: {
type: 'array',
description: 'Monitored computers matching the filters',
items: { type: 'object', properties: VANTA_MONITORED_COMPUTER_OUTPUT_PROPERTIES },
},
pageInfo: {
type: 'json',
description:
'Cursor pagination info for the returned page; pass endCursor as pageCursor to fetch the next page',
optional: true,
properties: VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
},
},
}
+126
View File
@@ -0,0 +1,126 @@
import type { ToolConfig } from '@/tools/types'
import {
VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
VANTA_PERSON_OUTPUT_PROPERTIES,
} from '@/tools/vanta/outputs'
import type { VantaListPeopleParams, VantaListPeopleResponse } from '@/tools/vanta/types'
import { createVantaTransformResponse, VANTA_QUERY_ROUTE } from '@/tools/vanta/utils'
export const vantaListPeopleTool: ToolConfig<VantaListPeopleParams, VantaListPeopleResponse> = {
id: 'vanta_list_people',
name: 'Vanta List People',
description:
'List the people tracked in a Vanta account with employment status, group membership, and security task completion',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
emailAndNameFilter: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter people by email address or name',
},
employmentStatus: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by employment status: UPCOMING, CURRENT, ON_LEAVE, INACTIVE, or FORMER',
},
groupIdsMatchesAny: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated group IDs to filter people by',
},
tasksSummaryStatusMatchesAny: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Comma-separated task summary statuses to filter by: NONE, DUE_SOON, OVERDUE, COMPLETE, PAUSED, OFFBOARDING_DUE_SOON, OFFBOARDING_OVERDUE, OFFBOARDING_COMPLETE',
},
taskTypeMatchesAny: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Comma-separated task types to filter by: COMPLETE_TRAININGS, ACCEPT_POLICIES, COMPLETE_CUSTOM_TASKS, COMPLETE_CUSTOM_OFFBOARDING_TASKS, INSTALL_DEVICE_MONITORING, COMPLETE_BACKGROUND_CHECKS',
},
taskStatusMatchesAny: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated task statuses to filter by: COMPLETE, DUE_SOON, OVERDUE, NONE',
},
pageSize: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of items per page (1-100, default 10)',
},
pageCursor: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Pagination cursor: pass the endCursor from the previous response to fetch the next page',
},
},
request: {
url: VANTA_QUERY_ROUTE,
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
operation: 'vanta_list_people',
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
emailAndNameFilter: params.emailAndNameFilter,
employmentStatus: params.employmentStatus,
groupIdsMatchesAny: params.groupIdsMatchesAny,
tasksSummaryStatusMatchesAny: params.tasksSummaryStatusMatchesAny,
taskTypeMatchesAny: params.taskTypeMatchesAny,
taskStatusMatchesAny: params.taskStatusMatchesAny,
pageSize: params.pageSize,
pageCursor: params.pageCursor,
}),
},
transformResponse: createVantaTransformResponse<VantaListPeopleResponse>(
'Failed to list Vanta people'
),
outputs: {
people: {
type: 'array',
description: 'People matching the filters',
items: { type: 'object', properties: VANTA_PERSON_OUTPUT_PROPERTIES },
},
pageInfo: {
type: 'json',
description:
'Cursor pagination info for the returned page; pass endCursor as pageCursor to fetch the next page',
optional: true,
properties: VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
},
},
}
+83
View File
@@ -0,0 +1,83 @@
import type { ToolConfig } from '@/tools/types'
import {
VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
VANTA_POLICY_OUTPUT_PROPERTIES,
} from '@/tools/vanta/outputs'
import type { VantaListPoliciesParams, VantaListPoliciesResponse } from '@/tools/vanta/types'
import { createVantaTransformResponse, VANTA_QUERY_ROUTE } from '@/tools/vanta/utils'
export const vantaListPoliciesTool: ToolConfig<VantaListPoliciesParams, VantaListPoliciesResponse> =
{
id: 'vanta_list_policies',
name: 'Vanta List Policies',
description:
'List the security policies in a Vanta account with approval status and version info',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
pageSize: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of items per page (1-100, default 10)',
},
pageCursor: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Pagination cursor: pass the endCursor from the previous response to fetch the next page',
},
},
request: {
url: VANTA_QUERY_ROUTE,
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
operation: 'vanta_list_policies',
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
pageSize: params.pageSize,
pageCursor: params.pageCursor,
}),
},
transformResponse: createVantaTransformResponse<VantaListPoliciesResponse>(
'Failed to list Vanta policies'
),
outputs: {
policies: {
type: 'array',
description: 'Policies in the Vanta account',
items: { type: 'object', properties: VANTA_POLICY_OUTPUT_PROPERTIES },
},
pageInfo: {
type: 'json',
description:
'Cursor pagination info for the returned page; pass endCursor as pageCursor to fetch the next page',
optional: true,
properties: VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
},
},
}
+169
View File
@@ -0,0 +1,169 @@
import type { ToolConfig } from '@/tools/types'
import {
VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
VANTA_RISK_SCENARIO_OUTPUT_PROPERTIES,
} from '@/tools/vanta/outputs'
import type {
VantaListRiskScenariosParams,
VantaListRiskScenariosResponse,
} from '@/tools/vanta/types'
import { createVantaTransformResponse, VANTA_QUERY_ROUTE } from '@/tools/vanta/utils'
export const vantaListRiskScenariosTool: ToolConfig<
VantaListRiskScenariosParams,
VantaListRiskScenariosResponse
> = {
id: 'vanta_list_risk_scenarios',
name: 'Vanta List Risk Scenarios',
description:
'List the risk scenarios in a Vanta risk register with likelihood/impact scores, treatment decisions, and review status',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
searchString: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Search string to filter risk scenarios',
},
includeIgnored: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Include ignored risk scenarios',
},
type: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by scenario type: "Risk Scenario" or "Enterprise Risk"',
},
ownerMatchesAny: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated owner emails to filter by',
},
categoryMatchesAny: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated risk categories to filter by',
},
ciaCategoryMatchesAny: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Comma-separated CIA categories to filter by: Confidentiality, Integrity, Availability',
},
treatmentTypeMatchesAny: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated treatments to filter by: Mitigate, Transfer, Avoid, Accept',
},
inherentScoreGroupMatchesAny: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Comma-separated inherent score groups to filter by: "Very low", Low, Med, High, Critical',
},
residualScoreGroupMatchesAny: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Comma-separated residual score groups to filter by: "Very low", Low, Med, High, Critical',
},
reviewStatusMatchesAny: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Comma-separated review statuses to filter by: APPROVED, DRAFT, NOT_REVIEWED, AWAITING_SUBMISSION, PENDING_APPROVAL, REQUESTED_CHANGES',
},
orderBy: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Field to order results by: description or createdAt',
},
pageSize: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of items per page (1-100, default 10)',
},
pageCursor: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Pagination cursor: pass the endCursor from the previous response to fetch the next page',
},
},
request: {
url: VANTA_QUERY_ROUTE,
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
operation: 'vanta_list_risk_scenarios',
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
searchString: params.searchString,
includeIgnored: params.includeIgnored,
type: params.type,
ownerMatchesAny: params.ownerMatchesAny,
categoryMatchesAny: params.categoryMatchesAny,
ciaCategoryMatchesAny: params.ciaCategoryMatchesAny,
treatmentTypeMatchesAny: params.treatmentTypeMatchesAny,
inherentScoreGroupMatchesAny: params.inherentScoreGroupMatchesAny,
residualScoreGroupMatchesAny: params.residualScoreGroupMatchesAny,
reviewStatusMatchesAny: params.reviewStatusMatchesAny,
orderBy: params.orderBy,
pageSize: params.pageSize,
pageCursor: params.pageCursor,
}),
},
transformResponse: createVantaTransformResponse<VantaListRiskScenariosResponse>(
'Failed to list Vanta risk scenarios'
),
outputs: {
riskScenarios: {
type: 'array',
description: 'Risk scenarios matching the filters',
items: { type: 'object', properties: VANTA_RISK_SCENARIO_OUTPUT_PROPERTIES },
},
pageInfo: {
type: 'json',
description:
'Cursor pagination info for the returned page; pass endCursor as pageCursor to fetch the next page',
optional: true,
properties: VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
},
},
}
+102
View File
@@ -0,0 +1,102 @@
import type { ToolConfig } from '@/tools/types'
import {
VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
VANTA_TEST_ENTITY_OUTPUT_PROPERTIES,
} from '@/tools/vanta/outputs'
import type {
VantaListTestEntitiesParams,
VantaListTestEntitiesResponse,
} from '@/tools/vanta/types'
import { createVantaTransformResponse, VANTA_QUERY_ROUTE } from '@/tools/vanta/utils'
export const vantaListTestEntitiesTool: ToolConfig<
VantaListTestEntitiesParams,
VantaListTestEntitiesResponse
> = {
id: 'vanta_list_test_entities',
name: 'Vanta List Test Entities',
description:
'List the failing or deactivated resource entities for a specific Vanta test, useful for finding exactly which resources need remediation',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
testId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique ID of the test (e.g., test-aws-cloudtrail-enabled)',
},
entityStatus: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter entities by status: FAILING or DEACTIVATED',
},
pageSize: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of items per page (1-100, default 10)',
},
pageCursor: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Pagination cursor: pass the endCursor from the previous response to fetch the next page',
},
},
request: {
url: VANTA_QUERY_ROUTE,
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
operation: 'vanta_list_test_entities',
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
testId: params.testId,
entityStatus: params.entityStatus,
pageSize: params.pageSize,
pageCursor: params.pageCursor,
}),
},
transformResponse: createVantaTransformResponse<VantaListTestEntitiesResponse>(
'Failed to list Vanta test entities'
),
outputs: {
entities: {
type: 'array',
description: 'Resource entities for the test',
items: { type: 'object', properties: VANTA_TEST_ENTITY_OUTPUT_PROPERTIES },
},
pageInfo: {
type: 'json',
description:
'Cursor pagination info for the returned page; pass endCursor as pageCursor to fetch the next page',
optional: true,
properties: VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
},
},
}
+133
View File
@@ -0,0 +1,133 @@
import type { ToolConfig } from '@/tools/types'
import {
VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
VANTA_TEST_OUTPUT_PROPERTIES,
} from '@/tools/vanta/outputs'
import type { VantaListTestsParams, VantaListTestsResponse } from '@/tools/vanta/types'
import { createVantaTransformResponse, VANTA_QUERY_ROUTE } from '@/tools/vanta/utils'
export const vantaListTestsTool: ToolConfig<VantaListTestsParams, VantaListTestsResponse> = {
id: 'vanta_list_tests',
name: 'Vanta List Tests',
description:
'List the automated compliance tests in a Vanta account, with filters for status, framework, integration, control, owner, and category',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
statusFilter: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Filter by test status: OK, DEACTIVATED, NEEDS_ATTENTION, IN_PROGRESS, INVALID, or NOT_APPLICABLE',
},
frameworkFilter: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by framework ID (e.g., soc2)',
},
integrationFilter: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by integration ID (e.g., aws)',
},
controlFilter: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by control ID',
},
ownerFilter: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by owner user ID',
},
categoryFilter: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Filter by test category (e.g., ACCOUNTS_ACCESS, COMPUTERS, INFRASTRUCTURE, POLICIES, VULNERABILITY_MANAGEMENT)',
},
isInRollout: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Filter by whether the test is in rollout',
},
pageSize: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of items per page (1-100, default 10)',
},
pageCursor: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Pagination cursor: pass the endCursor from the previous response to fetch the next page',
},
},
request: {
url: VANTA_QUERY_ROUTE,
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
operation: 'vanta_list_tests',
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
statusFilter: params.statusFilter,
frameworkFilter: params.frameworkFilter,
integrationFilter: params.integrationFilter,
controlFilter: params.controlFilter,
ownerFilter: params.ownerFilter,
categoryFilter: params.categoryFilter,
isInRollout: params.isInRollout,
pageSize: params.pageSize,
pageCursor: params.pageCursor,
}),
},
transformResponse: createVantaTransformResponse<VantaListTestsResponse>(
'Failed to list Vanta tests'
),
outputs: {
tests: {
type: 'array',
description: 'Tests matching the filters',
items: { type: 'object', properties: VANTA_TEST_OUTPUT_PROPERTIES },
},
pageInfo: {
type: 'json',
description:
'Cursor pagination info for the returned page; pass endCursor as pageCursor to fetch the next page',
optional: true,
properties: VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
},
},
}
+97
View File
@@ -0,0 +1,97 @@
import type { ToolConfig } from '@/tools/types'
import {
VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
VANTA_VENDOR_OUTPUT_PROPERTIES,
} from '@/tools/vanta/outputs'
import type { VantaListVendorsParams, VantaListVendorsResponse } from '@/tools/vanta/types'
import { createVantaTransformResponse, VANTA_QUERY_ROUTE } from '@/tools/vanta/utils'
export const vantaListVendorsTool: ToolConfig<VantaListVendorsParams, VantaListVendorsResponse> = {
id: 'vanta_list_vendors',
name: 'Vanta List Vendors',
description:
'List the vendors tracked in a Vanta account with risk levels, contract dates, and security review schedules',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
name: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter vendors by name',
},
statusMatchesAny: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Comma-separated vendor statuses to filter by: MANAGED, ARCHIVED, IN_PROCUREMENT',
},
pageSize: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of items per page (1-100, default 10)',
},
pageCursor: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Pagination cursor: pass the endCursor from the previous response to fetch the next page',
},
},
request: {
url: VANTA_QUERY_ROUTE,
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
operation: 'vanta_list_vendors',
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
name: params.name,
statusMatchesAny: params.statusMatchesAny,
pageSize: params.pageSize,
pageCursor: params.pageCursor,
}),
},
transformResponse: createVantaTransformResponse<VantaListVendorsResponse>(
'Failed to list Vanta vendors'
),
outputs: {
vendors: {
type: 'array',
description: 'Vendors matching the filters',
items: { type: 'object', properties: VANTA_VENDOR_OUTPUT_PROPERTIES },
},
pageInfo: {
type: 'json',
description:
'Cursor pagination info for the returned page; pass endCursor as pageCursor to fetch the next page',
optional: true,
properties: VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
},
},
}
@@ -0,0 +1,165 @@
import type { ToolConfig } from '@/tools/types'
import {
VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
VANTA_VULNERABILITY_OUTPUT_PROPERTIES,
} from '@/tools/vanta/outputs'
import type {
VantaListVulnerabilitiesParams,
VantaListVulnerabilitiesResponse,
} from '@/tools/vanta/types'
import { createVantaTransformResponse, VANTA_QUERY_ROUTE } from '@/tools/vanta/utils'
export const vantaListVulnerabilitiesTool: ToolConfig<
VantaListVulnerabilitiesParams,
VantaListVulnerabilitiesResponse
> = {
id: 'vanta_list_vulnerabilities',
name: 'Vanta List Vulnerabilities',
description:
'List the vulnerabilities detected across a Vanta account with filters for severity, fixability, SLA deadlines, package, and integration',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
q: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Search query for vulnerabilities',
},
severity: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by severity: LOW, MEDIUM, HIGH, or CRITICAL',
},
isFixAvailable: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Filter by whether a fix is available',
},
isDeactivated: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Filter by whether vulnerability monitoring is deactivated',
},
includeVulnerabilitiesWithoutSlas: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Include vulnerabilities that have no SLA deadline',
},
packageIdentifier: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by the affected package identifier',
},
externalVulnerabilityId: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by external vulnerability ID (e.g., a CVE identifier)',
},
integrationId: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by the integration that detected the vulnerability',
},
vulnerableAssetId: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by the vulnerable asset ID',
},
slaDeadlineAfterDate: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Only include vulnerabilities with an SLA deadline after this ISO 8601 date',
},
slaDeadlineBeforeDate: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Only include vulnerabilities with an SLA deadline before this ISO 8601 date',
},
pageSize: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of items per page (1-100, default 10)',
},
pageCursor: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Pagination cursor: pass the endCursor from the previous response to fetch the next page',
},
},
request: {
url: VANTA_QUERY_ROUTE,
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
operation: 'vanta_list_vulnerabilities',
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
q: params.q,
severity: params.severity,
isFixAvailable: params.isFixAvailable,
isDeactivated: params.isDeactivated,
includeVulnerabilitiesWithoutSlas: params.includeVulnerabilitiesWithoutSlas,
packageIdentifier: params.packageIdentifier,
externalVulnerabilityId: params.externalVulnerabilityId,
integrationId: params.integrationId,
vulnerableAssetId: params.vulnerableAssetId,
slaDeadlineAfterDate: params.slaDeadlineAfterDate,
slaDeadlineBeforeDate: params.slaDeadlineBeforeDate,
pageSize: params.pageSize,
pageCursor: params.pageCursor,
}),
},
transformResponse: createVantaTransformResponse<VantaListVulnerabilitiesResponse>(
'Failed to list Vanta vulnerabilities'
),
outputs: {
vulnerabilities: {
type: 'array',
description: 'Vulnerabilities matching the filters',
items: { type: 'object', properties: VANTA_VULNERABILITY_OUTPUT_PROPERTIES },
},
pageInfo: {
type: 'json',
description:
'Cursor pagination info for the returned page; pass endCursor as pageCursor to fetch the next page',
optional: true,
properties: VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
},
},
}
@@ -0,0 +1,123 @@
import type { ToolConfig } from '@/tools/types'
import {
VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
VANTA_VULNERABILITY_REMEDIATION_OUTPUT_PROPERTIES,
} from '@/tools/vanta/outputs'
import type {
VantaListVulnerabilityRemediationsParams,
VantaListVulnerabilityRemediationsResponse,
} from '@/tools/vanta/types'
import { createVantaTransformResponse, VANTA_QUERY_ROUTE } from '@/tools/vanta/utils'
export const vantaListVulnerabilityRemediationsTool: ToolConfig<
VantaListVulnerabilityRemediationsParams,
VantaListVulnerabilityRemediationsResponse
> = {
id: 'vanta_list_vulnerability_remediations',
name: 'Vanta List Vulnerability Remediations',
description:
'List remediated vulnerabilities in a Vanta account with detection, SLA deadline, and remediation dates',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
integrationId: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by the integration that detected the vulnerability',
},
severity: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by severity: LOW, MEDIUM, HIGH, or CRITICAL',
},
isRemediatedOnTime: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Filter by whether the vulnerability was remediated before its SLA deadline',
},
remediatedAfterDate: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Only include remediations completed after this ISO 8601 date',
},
remediatedBeforeDate: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Only include remediations completed before this ISO 8601 date',
},
pageSize: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of items per page (1-100, default 10)',
},
pageCursor: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Pagination cursor: pass the endCursor from the previous response to fetch the next page',
},
},
request: {
url: VANTA_QUERY_ROUTE,
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
operation: 'vanta_list_vulnerability_remediations',
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
integrationId: params.integrationId,
severity: params.severity,
isRemediatedOnTime: params.isRemediatedOnTime,
remediatedAfterDate: params.remediatedAfterDate,
remediatedBeforeDate: params.remediatedBeforeDate,
pageSize: params.pageSize,
pageCursor: params.pageCursor,
}),
},
transformResponse: createVantaTransformResponse<VantaListVulnerabilityRemediationsResponse>(
'Failed to list Vanta vulnerability remediations'
),
outputs: {
remediations: {
type: 'array',
description: 'Vulnerability remediations matching the filters',
items: { type: 'object', properties: VANTA_VULNERABILITY_REMEDIATION_OUTPUT_PROPERTIES },
},
pageInfo: {
type: 'json',
description:
'Cursor pagination info for the returned page; pass endCursor as pageCursor to fetch the next page',
optional: true,
properties: VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
},
},
}
@@ -0,0 +1,117 @@
import type { ToolConfig } from '@/tools/types'
import {
VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
VANTA_VULNERABLE_ASSET_OUTPUT_PROPERTIES,
} from '@/tools/vanta/outputs'
import type {
VantaListVulnerableAssetsParams,
VantaListVulnerableAssetsResponse,
} from '@/tools/vanta/types'
import { createVantaTransformResponse, VANTA_QUERY_ROUTE } from '@/tools/vanta/utils'
export const vantaListVulnerableAssetsTool: ToolConfig<
VantaListVulnerableAssetsParams,
VantaListVulnerableAssetsResponse
> = {
id: 'vanta_list_vulnerable_assets',
name: 'Vanta List Vulnerable Assets',
description:
'List the assets associated with vulnerabilities in a Vanta account (servers, repositories, workstations, and more)',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
q: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Search query for vulnerable assets',
},
integrationId: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by the integration scanning the asset',
},
assetType: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Filter by asset type: SERVER, SERVERLESS_FUNCTION, CONTAINER, CONTAINER_REPOSITORY, CONTAINER_REPOSITORY_IMAGE, CODE_REPOSITORY, MANIFEST_FILE, WORKSTATION, or OTHER',
},
assetExternalAccountId: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by the external account ID the asset belongs to',
},
pageSize: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of items per page (1-100, default 10)',
},
pageCursor: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Pagination cursor: pass the endCursor from the previous response to fetch the next page',
},
},
request: {
url: VANTA_QUERY_ROUTE,
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
operation: 'vanta_list_vulnerable_assets',
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
q: params.q,
integrationId: params.integrationId,
assetType: params.assetType,
assetExternalAccountId: params.assetExternalAccountId,
pageSize: params.pageSize,
pageCursor: params.pageCursor,
}),
},
transformResponse: createVantaTransformResponse<VantaListVulnerableAssetsResponse>(
'Failed to list Vanta vulnerable assets'
),
outputs: {
assets: {
type: 'array',
description: 'Vulnerable assets matching the filters',
items: { type: 'object', properties: VANTA_VULNERABLE_ASSET_OUTPUT_PROPERTIES },
},
pageInfo: {
type: 'json',
description:
'Cursor pagination info for the returned page; pass endCursor as pageCursor to fetch the next page',
optional: true,
properties: VANTA_PAGE_INFO_OUTPUT_PROPERTIES,
},
},
}
+794
View File
@@ -0,0 +1,794 @@
import type { OutputProperty } from '@/tools/types'
export const VANTA_PAGE_INFO_OUTPUT_PROPERTIES: Record<string, OutputProperty> = {
startCursor: {
type: 'string',
description: 'Cursor pointing to the start of the current page',
optional: true,
},
endCursor: {
type: 'string',
description:
'Cursor pointing to the end of the current page; pass as pageCursor to fetch the next page',
optional: true,
},
hasNextPage: { type: 'boolean', description: 'Whether another page exists after this one' },
hasPreviousPage: { type: 'boolean', description: 'Whether a page exists before this one' },
}
const VANTA_OWNER_OUTPUT_PROPERTIES: Record<string, OutputProperty> = {
id: { type: 'string', description: 'Unique ID of the owner', optional: true },
displayName: { type: 'string', description: 'Display name of the owner', optional: true },
emailAddress: { type: 'string', description: 'Email address of the owner', optional: true },
}
const VANTA_CUSTOM_FIELDS_OUTPUT: OutputProperty = {
type: 'array',
description: 'Custom field values configured in the Vanta instance',
items: {
type: 'object',
properties: {
label: { type: 'string', description: 'Custom field label', optional: true },
value: {
type: 'json',
description: 'Custom field value (string or list of strings)',
optional: true,
},
},
},
}
export const VANTA_FRAMEWORK_OUTPUT_PROPERTIES: Record<string, OutputProperty> = {
id: { type: 'string', description: "The framework's unique ID" },
displayName: { type: 'string', description: "The framework's display name" },
shorthandName: { type: 'string', description: "The short version of the framework's name" },
description: { type: 'string', description: "The framework's description" },
numControlsCompleted: {
type: 'number',
description: 'Number of completed controls in the framework',
},
numControlsTotal: { type: 'number', description: 'Total number of controls in the framework' },
numDocumentsPassing: {
type: 'number',
description: 'Number of passing documents in the framework',
},
numDocumentsTotal: { type: 'number', description: 'Total number of documents in the framework' },
numTestsPassing: { type: 'number', description: 'Number of passing tests in the framework' },
numTestsTotal: { type: 'number', description: 'Total number of tests in the framework' },
}
export const VANTA_FRAMEWORK_DETAIL_OUTPUT_PROPERTIES: Record<string, OutputProperty> = {
...VANTA_FRAMEWORK_OUTPUT_PROPERTIES,
requirementCategories: {
type: 'array',
description:
"The framework's requirement categories, each with requirements and mapped controls",
items: {
type: 'object',
properties: {
id: { type: 'string', description: 'Requirement category ID' },
name: { type: 'string', description: 'Requirement category name' },
shorthand: {
type: 'string',
description: 'Requirement category short name',
optional: true,
},
requirements: {
type: 'array',
description: 'Requirements in this category, each listing its mapped controls',
},
},
},
},
}
export const VANTA_CONTROL_OUTPUT_PROPERTIES: Record<string, OutputProperty> = {
id: { type: 'string', description: "The control's unique ID" },
externalId: { type: 'string', description: "The control's external ID", optional: true },
name: { type: 'string', description: "The control's name" },
description: { type: 'string', description: "The control's description" },
source: { type: 'string', description: 'The control source, either "Vanta" or "Custom"' },
domains: {
type: 'array',
description: 'Security domains the control belongs to',
items: { type: 'string' },
},
owner: {
type: 'json',
description: "The control's owner",
optional: true,
properties: VANTA_OWNER_OUTPUT_PROPERTIES,
},
role: { type: 'string', description: "The control's GDPR role, if applicable", optional: true },
customFields: VANTA_CUSTOM_FIELDS_OUTPUT,
creationDate: {
type: 'string',
description: 'When the control was created (null for Vanta library controls)',
optional: true,
},
modificationDate: {
type: 'string',
description: 'When the control was last modified (null for Vanta library controls)',
optional: true,
},
}
export const VANTA_CONTROL_DETAIL_OUTPUT_PROPERTIES: Record<string, OutputProperty> = {
...VANTA_CONTROL_OUTPUT_PROPERTIES,
note: { type: 'string', description: 'A user-created note for the control', optional: true },
status: {
type: 'string',
description: 'Control status (NO_EVIDENCE_MAPPED, NOT_STARTED, IN_PROGRESS, or COMPLETED)',
optional: true,
},
numDocumentsPassing: {
type: 'number',
description: 'Number of passing documents linked to the control',
optional: true,
},
numDocumentsTotal: {
type: 'number',
description: 'Total number of documents linked to the control',
optional: true,
},
numTestsPassing: {
type: 'number',
description: 'Number of passing tests linked to the control',
optional: true,
},
numTestsTotal: {
type: 'number',
description: 'Total number of tests linked to the control',
optional: true,
},
}
export const VANTA_TEST_OUTPUT_PROPERTIES: Record<string, OutputProperty> = {
id: { type: 'string', description: "The test's unique ID" },
name: { type: 'string', description: "The test's name" },
description: { type: 'string', description: "The test's description" },
failureDescription: { type: 'string', description: "The test's failure description" },
remediationDescription: { type: 'string', description: "The test's remediation description" },
category: { type: 'string', description: "The test's category" },
status: {
type: 'string',
description:
'Test run status (OK, DEACTIVATED, NEEDS_ATTENTION, IN_PROGRESS, INVALID, or NOT_APPLICABLE)',
},
integrations: {
type: 'array',
description: "The test's third-party integration dependencies",
items: { type: 'string' },
},
lastTestRunDate: { type: 'string', description: 'Timestamp of the last test run' },
latestFlipDate: {
type: 'string',
description: 'Most recent date the test flipped status',
optional: true,
},
version: {
type: 'json',
description: "The test's version",
optional: true,
properties: {
major: { type: 'number', description: 'Major version number' },
minor: { type: 'number', description: 'Minor version number' },
},
},
deactivatedStatusInfo: {
type: 'json',
description: "The test's deactivation status",
optional: true,
properties: {
isDeactivated: { type: 'boolean', description: 'Whether the test is deactivated' },
deactivatedReason: { type: 'string', description: 'Reason for deactivation', optional: true },
lastUpdatedDate: {
type: 'string',
description: 'Date of the last deactivation status update',
optional: true,
},
},
},
remediationStatusInfo: {
type: 'json',
description: "The test's remediation status",
optional: true,
properties: {
status: { type: 'string', description: 'Remediation status' },
soonestRemediateByDate: {
type: 'string',
description: 'Soonest remediate-by date',
optional: true,
},
itemCount: { type: 'number', description: 'Number of items needing remediation' },
},
},
owner: {
type: 'json',
description: "The test's owner",
optional: true,
properties: VANTA_OWNER_OUTPUT_PROPERTIES,
},
}
export const VANTA_TEST_ENTITY_OUTPUT_PROPERTIES: Record<string, OutputProperty> = {
id: { type: 'string', description: 'Identifier of the entity' },
entityStatus: { type: 'string', description: 'Entity status (FAILING or DEACTIVATED)' },
displayName: { type: 'string', description: 'Display name of the entity' },
responseType: { type: 'string', description: 'Response type of the entity' },
deactivatedReason: { type: 'string', description: 'Reason for deactivation', optional: true },
createdDate: { type: 'string', description: 'Date the entity was first detected' },
lastUpdatedDate: { type: 'string', description: 'Date of the last update to the entity' },
}
export const VANTA_DOCUMENT_OUTPUT_PROPERTIES: Record<string, OutputProperty> = {
id: { type: 'string', description: "The document's unique ID" },
title: { type: 'string', description: "The document's title" },
description: { type: 'string', description: "The document's description" },
category: { type: 'string', description: "The document's category" },
ownerId: { type: 'string', description: "User ID of the document's owner", optional: true },
isSensitive: { type: 'boolean', description: 'Whether the document is sensitive' },
uploadStatus: {
type: 'string',
description: 'Document status ("Needs document", "Needs update", "Not relevant", or "OK")',
},
uploadStatusDate: {
type: 'string',
description: 'Date the upload status last changed',
optional: true,
},
url: { type: 'string', description: 'URL to view the document within Vanta', optional: true },
}
export const VANTA_DOCUMENT_DETAIL_OUTPUT_PROPERTIES: Record<string, OutputProperty> = {
...VANTA_DOCUMENT_OUTPUT_PROPERTIES,
note: { type: 'string', description: 'A user note for the document', optional: true },
nextRenewalDate: {
type: 'string',
description: 'When the document needs to be renewed',
optional: true,
},
renewalCadence: {
type: 'string',
description: 'How often the document must be renewed',
optional: true,
},
reminderWindow: {
type: 'string',
description: 'Reminder window ahead of the renewal date (P0D, P1D, P1W, P1M, or P3M)',
optional: true,
},
subscribers: {
type: 'array',
description: 'Emails subscribed to the document',
items: { type: 'string' },
},
deactivatedStatus: {
type: 'json',
description: "The document's deactivation status",
optional: true,
properties: {
isDeactivated: { type: 'boolean', description: 'Whether the document is deactivated' },
reason: {
type: 'string',
description: 'Reason the document was deactivated',
optional: true,
},
creationDate: { type: 'string', description: 'Date the document was deactivated' },
expiration: { type: 'string', description: 'Date the deactivation expires', optional: true },
},
},
}
export const VANTA_UPLOADED_FILE_OUTPUT_PROPERTIES: Record<string, OutputProperty> = {
id: { type: 'string', description: 'Unique ID of the uploaded file' },
fileName: { type: 'string', description: 'File name of the upload', optional: true },
title: { type: 'string', description: 'Title of the upload' },
description: { type: 'string', description: 'Description of the upload', optional: true },
mimeType: { type: 'string', description: 'MIME type of the uploaded file' },
uploadedBy: {
type: 'json',
description: 'Actor who uploaded the file (a user or an application)',
optional: true,
properties: {
id: { type: 'string', description: 'Actor ID' },
type: { type: 'string', description: 'Actor type (USER or APPLICATION)' },
},
},
creationDate: { type: 'string', description: 'Date the file was uploaded' },
updatedDate: { type: 'string', description: 'Date the file was last updated' },
deletionDate: {
type: 'string',
description: 'Date the file was deleted (null if not deleted)',
optional: true,
},
effectiveDate: { type: 'string', description: "The file's effective date", optional: true },
url: { type: 'string', description: "The file's URL" },
}
export const VANTA_PERSON_OUTPUT_PROPERTIES: Record<string, OutputProperty> = {
id: { type: 'string', description: "The person's unique ID" },
userId: {
type: 'string',
description: 'ID of the associated Vanta user account, if one exists',
optional: true,
},
emailAddress: { type: 'string', description: "The person's email address" },
name: {
type: 'json',
description: "The person's name",
optional: true,
properties: {
first: { type: 'string', description: 'First (given) name', optional: true },
last: { type: 'string', description: 'Last (family) name', optional: true },
display: { type: 'string', description: 'Display name used in Vanta' },
},
},
employment: {
type: 'json',
description: "The person's employment information",
optional: true,
properties: {
status: {
type: 'string',
description: 'Employment status (UPCOMING, CURRENT, ON_LEAVE, INACTIVE, or FORMER)',
},
startDate: { type: 'string', description: 'Employment start date' },
endDate: { type: 'string', description: 'Employment end date, if present', optional: true },
jobTitle: { type: 'string', description: 'Job title', optional: true },
},
},
leaveInfo: {
type: 'json',
description: "The person's active or upcoming leave, if any",
optional: true,
properties: {
status: { type: 'string', description: 'Leave status (ACTIVE or UPCOMING)' },
startDate: { type: 'string', description: 'Start of the leave' },
endDate: {
type: 'string',
description: 'End of the leave (null implies indefinite leave)',
optional: true,
},
},
},
groupIds: {
type: 'array',
description: 'IDs of the groups the person belongs to',
items: { type: 'string' },
},
tasksSummary: {
type: 'json',
description: "Aggregated status of the person's tasks",
optional: true,
properties: {
status: {
type: 'string',
description:
'Overall task status (e.g., NONE, DUE_SOON, OVERDUE, COMPLETE, PAUSED, or an OFFBOARDING_* variant)',
},
dueDate: {
type: 'string',
description: "Due date of the person's earliest-due task",
optional: true,
},
completionDate: {
type: 'string',
description: "Date the person's tasks were completed",
optional: true,
},
},
},
}
export const VANTA_POLICY_OUTPUT_PROPERTIES: Record<string, OutputProperty> = {
id: { type: 'string', description: "The policy's unique ID" },
name: { type: 'string', description: "The policy's name" },
description: { type: 'string', description: "The policy's description" },
status: { type: 'string', description: 'Policy status (OK or NEEDS_REMEDIATION)' },
approvedAtDate: {
type: 'string',
description: "The policy's most recent approval date, if applicable",
optional: true,
},
latestVersionStatus: {
type: 'string',
description:
"Status of the policy's latest version (NOT_STARTED, DRAFT, PENDING_APPROVAL, APPROVED, RENEW_SOON, or EXPIRED)",
},
latestApprovedVersion: {
type: 'json',
description: 'The latest approved version of the policy, if available',
optional: true,
properties: {
versionId: { type: 'string', description: 'ID of the latest approved version' },
documents: {
type: 'array',
description: 'Available policy document versions, organized by language',
},
},
},
}
export const VANTA_VENDOR_OUTPUT_PROPERTIES: Record<string, OutputProperty> = {
id: { type: 'string', description: "The vendor's unique ID" },
name: { type: 'string', description: "The vendor's display name" },
status: { type: 'string', description: 'Vendor status (MANAGED, ARCHIVED, or IN_PROCUREMENT)' },
websiteUrl: { type: 'string', description: "The vendor's website URL", optional: true },
category: {
type: 'string',
description: "Display name of the vendor's category",
optional: true,
},
servicesProvided: {
type: 'string',
description: 'Services provided by the vendor',
optional: true,
},
additionalNotes: {
type: 'string',
description: 'Additional notes about the vendor',
optional: true,
},
accountManagerName: {
type: 'string',
description: "The vendor's external account manager name",
optional: true,
},
accountManagerEmail: {
type: 'string',
description: "The vendor's external account manager email",
optional: true,
},
securityOwnerUserId: {
type: 'string',
description: "Vanta user ID of the vendor's security owner",
optional: true,
},
businessOwnerUserId: {
type: 'string',
description: "Vanta user ID of the vendor's business owner",
optional: true,
},
inherentRiskLevel: {
type: 'string',
description: 'Inherent risk level (CRITICAL, HIGH, MEDIUM, LOW, or UNSCORED)',
},
residualRiskLevel: {
type: 'string',
description: 'Residual risk level (CRITICAL, HIGH, MEDIUM, LOW, or UNSCORED)',
},
isRiskAutoScored: {
type: 'boolean',
description: "Whether the vendor's risk is automatically scored",
optional: true,
},
isVisibleToAuditors: {
type: 'boolean',
description: 'Whether auditors can view this vendor',
optional: true,
},
riskAttributeIds: {
type: 'array',
description: 'Risk attribute IDs assigned to the vendor',
items: { type: 'string' },
},
vendorHeadquarters: {
type: 'string',
description: "Country code of the vendor's headquarters",
optional: true,
},
contractStartDate: {
type: 'string',
description: 'Date the vendor contract began',
optional: true,
},
contractRenewalDate: {
type: 'string',
description: 'Date the vendor contract is up for renewal',
optional: true,
},
contractTerminationDate: {
type: 'string',
description: 'Date the vendor contract was terminated',
optional: true,
},
contractAmount: {
type: 'json',
description: 'Contract amount for the vendor',
optional: true,
properties: {
amount: { type: 'number', description: 'Amount of the contract' },
currency: { type: 'string', description: 'Currency of the contract' },
},
},
nextSecurityReviewDueDate: {
type: 'string',
description: 'Next due date for a security review',
optional: true,
},
lastSecurityReviewCompletionDate: {
type: 'string',
description: 'Most recent date a security review was completed',
optional: true,
},
authDetails: {
type: 'json',
description: "The vendor's authentication details",
optional: true,
properties: {
method: {
type: 'string',
description: 'Authentication method (e.g., SSO, OKTA, USERNAME_PASSWORD)',
optional: true,
},
passwordMFA: {
type: 'boolean',
description: 'Whether passwords require multi-factor authentication',
optional: true,
},
passwordMinimumLength: {
type: 'number',
description: 'Minimum password length',
optional: true,
},
passwordRequiresNumber: {
type: 'boolean',
description: 'Whether passwords require a number',
optional: true,
},
passwordRequiresSymbol: {
type: 'boolean',
description: 'Whether passwords require a symbol',
optional: true,
},
},
},
customFields: VANTA_CUSTOM_FIELDS_OUTPUT,
latestDecision: {
type: 'json',
description: "The vendor's latest decision (null when no decision has been made)",
optional: true,
properties: {
status: {
type: 'string',
description: 'Decision status (APPROVED, CONDITIONALLY_APPROVED, or NOT_APPROVED)',
},
lastUpdatedAt: { type: 'string', description: 'When the decision was last updated' },
},
},
linkedTaskTrackerTaskProcurementRequest: {
type: 'json',
description: 'Linked task tracker procurement request, if any',
optional: true,
properties: {
url: { type: 'string', description: 'URL of the procurement request' },
service: { type: 'string', description: 'Task tracker service' },
},
},
}
export const VANTA_MONITORED_COMPUTER_OUTPUT_PROPERTIES: Record<string, OutputProperty> = {
id: { type: 'string', description: 'Unique identifier of the monitored computer' },
integrationId: { type: 'string', description: 'Integration that reports this computer' },
lastCheckDate: {
type: 'string',
description: "Date of the computer's most recent report",
optional: true,
},
screenlock: {
type: 'string',
description: 'Screenlock check outcome (PASS, FAIL, IN_PROGRESS, or NA)',
},
diskEncryption: {
type: 'string',
description: 'Disk encryption check outcome (PASS, FAIL, IN_PROGRESS, or NA)',
},
passwordManager: {
type: 'string',
description: 'Password manager check outcome (PASS, FAIL, IN_PROGRESS, or NA)',
},
antivirusInstallation: {
type: 'string',
description: 'Antivirus check outcome (PASS, FAIL, IN_PROGRESS, or NA)',
},
operatingSystem: {
type: 'json',
description: "The computer's operating system",
optional: true,
properties: {
type: { type: 'string', description: 'Operating system type (macOS, linux, or windows)' },
version: { type: 'string', description: 'Operating system version', optional: true },
},
},
owner: {
type: 'json',
description: "The computer's owner",
optional: true,
properties: VANTA_OWNER_OUTPUT_PROPERTIES,
},
serialNumber: { type: 'string', description: 'Serial number of the computer', optional: true },
udid: { type: 'string', description: 'Universal device ID of the computer', optional: true },
}
export const VANTA_RISK_SCENARIO_OUTPUT_PROPERTIES: Record<string, OutputProperty> = {
riskId: { type: 'string', description: 'Unique user-specified ID of the risk scenario' },
description: { type: 'string', description: 'Description of the risk scenario' },
likelihood: {
type: 'number',
description: 'Likelihood score (defaults to a 1-5 range; null when unscored)',
optional: true,
},
impact: {
type: 'number',
description: 'Impact score (defaults to a 1-5 range; null when unscored)',
optional: true,
},
residualLikelihood: {
type: 'number',
description: 'Residual likelihood score after treatments',
optional: true,
},
residualImpact: {
type: 'number',
description: 'Residual impact score after treatments',
optional: true,
},
categories: {
type: 'array',
description: 'Categories this risk scenario belongs to',
items: { type: 'string' },
},
ciaCategories: {
type: 'array',
description: 'CIA categories (Confidentiality, Integrity, Availability)',
items: { type: 'string' },
},
treatment: {
type: 'string',
description: 'Risk treatment decision (Mitigate, Transfer, Avoid, or Accept)',
optional: true,
},
owner: {
type: 'string',
description: 'Email of the person responsible for this risk',
optional: true,
},
note: {
type: 'string',
description: 'Additional context about the risk scenario',
optional: true,
},
riskRegister: {
type: 'string',
description: 'Name of the associated risk register',
optional: true,
},
customFields: VANTA_CUSTOM_FIELDS_OUTPUT,
isArchived: { type: 'boolean', description: 'Whether the scenario is archived' },
reviewStatus: {
type: 'string',
description:
'Review status (APPROVED, DRAFT, NOT_REVIEWED, AWAITING_SUBMISSION, PENDING_APPROVAL, or REQUESTED_CHANGES)',
},
requiredApprovers: {
type: 'array',
description: 'Required approvers for this risk scenario',
items: { type: 'string' },
},
type: { type: 'string', description: 'Scenario type ("Risk Scenario" or "Enterprise Risk")' },
identificationDate: { type: 'string', description: 'Date this risk was identified' },
}
export const VANTA_VULNERABILITY_REMEDIATION_OUTPUT_PROPERTIES: Record<string, OutputProperty> = {
id: { type: 'string', description: 'Unique identifier of the remediation' },
vulnerabilityId: { type: 'string', description: 'ID of the remediated vulnerability' },
vulnerableAssetId: { type: 'string', description: 'ID of the vulnerable asset' },
severity: { type: 'string', description: 'Severity of the vulnerability' },
detectedDate: {
type: 'string',
description: 'Date the vulnerability was first detected',
optional: true,
},
slaDeadlineDate: { type: 'string', description: 'SLA deadline for remediation', optional: true },
remediationDate: {
type: 'string',
description: 'Date the vulnerability was remediated',
optional: true,
},
}
export const VANTA_VULNERABLE_ASSET_OUTPUT_PROPERTIES: Record<string, OutputProperty> = {
id: { type: 'string', description: 'Unique identifier of the vulnerable asset' },
name: { type: 'string', description: 'Display name of the vulnerable asset' },
assetType: {
type: 'string',
description:
'Asset type (e.g., SERVER, SERVERLESS_FUNCTION, CONTAINER_REPOSITORY, CODE_REPOSITORY, WORKSTATION)',
},
hasBeenScanned: { type: 'boolean', description: 'Whether the asset has been scanned' },
imageScanTag: {
type: 'string',
description:
'Container image tag that vulnerabilities are retrieved for (container repositories only)',
optional: true,
},
scanners: {
type: 'array',
description:
'Integrations scanning this asset, with per-scanner asset details (resource ID, hostnames, IPs, image metadata)',
},
}
export const VANTA_VULNERABILITY_OUTPUT_PROPERTIES: Record<string, OutputProperty> = {
id: { type: 'string', description: 'Unique identifier of the vulnerability' },
name: { type: 'string', description: 'Display name of the vulnerability' },
description: { type: 'string', description: 'Description of the vulnerability' },
severity: { type: 'string', description: 'Severity (LOW, MEDIUM, HIGH, or CRITICAL)' },
vulnerabilityType: {
type: 'string',
description: 'Vulnerability type (CONFIGURATION, COMMON, or GROUPED)',
},
integrationId: { type: 'string', description: 'Integration that scans this vulnerability' },
targetId: { type: 'string', description: 'ID of the resource the vulnerability was found on' },
packageIdentifier: {
type: 'string',
description: 'Identifier of the affected package (COMMON and GROUPED vulnerabilities only)',
optional: true,
},
cvssSeverityScore: { type: 'number', description: 'CVSS severity score', optional: true },
scannerScore: { type: 'number', description: 'Scanner score', optional: true },
isFixable: { type: 'boolean', description: 'Whether the vulnerability is fixable' },
fixedVersion: {
type: 'string',
description: 'Package version that remediates the vulnerability',
optional: true,
},
remediateByDate: {
type: 'string',
description: 'SLA date by which the vulnerability should be remediated',
optional: true,
},
firstDetectedDate: { type: 'string', description: 'Date first detected by Vanta' },
sourceDetectedDate: {
type: 'string',
description: 'Date first detected by the source',
optional: true,
},
lastDetectedDate: { type: 'string', description: 'Date last detected', optional: true },
scanSource: {
type: 'string',
description: 'Scanning tool that detected the vulnerability',
optional: true,
},
externalURL: { type: 'string', description: 'External URL for the vulnerability' },
relatedVulns: {
type: 'array',
description: 'Related vulnerabilities (GROUPED vulnerabilities only)',
items: { type: 'string' },
},
relatedUrls: {
type: 'array',
description: 'Related URLs',
items: { type: 'string' },
},
deactivateMetadata: {
type: 'json',
description: 'Deactivation metadata, if the vulnerability was deactivated',
optional: true,
properties: {
isVulnDeactivatedIndefinitely: {
type: 'boolean',
description: 'Whether deactivated indefinitely',
},
deactivatedUntilDate: {
type: 'string',
description: 'Date the vulnerability will be reactivated',
optional: true,
},
deactivationReason: { type: 'string', description: 'Reason for deactivation' },
deactivatedOnDate: { type: 'string', description: 'Date the vulnerability was deactivated' },
deactivatedBy: { type: 'string', description: 'User who deactivated the vulnerability' },
},
},
}
+63
View File
@@ -0,0 +1,63 @@
import type { ToolConfig } from '@/tools/types'
import type { VantaSubmitDocumentParams, VantaSubmitDocumentResponse } from '@/tools/vanta/types'
import { createVantaTransformResponse, VANTA_QUERY_ROUTE } from '@/tools/vanta/utils'
export const vantaSubmitDocumentTool: ToolConfig<
VantaSubmitDocumentParams,
VantaSubmitDocumentResponse
> = {
id: 'vanta_submit_document',
name: 'Vanta Submit Document',
description:
'Submit a Vanta document collection for review so uploaded evidence becomes visible to auditors. Requires credentials with write access.',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
documentId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique ID of the document to submit',
},
},
request: {
url: VANTA_QUERY_ROUTE,
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
operation: 'vanta_submit_document',
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
documentId: params.documentId,
}),
},
transformResponse: createVantaTransformResponse<VantaSubmitDocumentResponse>(
'Failed to submit Vanta document'
),
outputs: {
documentId: { type: 'string', description: 'ID of the submitted document' },
submitted: { type: 'boolean', description: 'Whether the document collection was submitted' },
},
}
+780
View File
@@ -0,0 +1,780 @@
import type { ToolResponse } from '@/tools/types'
export type VantaRegion = 'us' | 'gov'
export interface VantaBaseParams {
clientId: string
clientSecret: string
region?: VantaRegion
}
export interface VantaPaginationParams {
pageSize?: number
pageCursor?: string
}
export interface VantaListFrameworksParams extends VantaBaseParams, VantaPaginationParams {}
export interface VantaGetFrameworkParams extends VantaBaseParams {
frameworkId: string
}
export interface VantaListFrameworkControlsParams extends VantaBaseParams, VantaPaginationParams {
frameworkId: string
}
export interface VantaListControlsParams extends VantaBaseParams, VantaPaginationParams {
frameworkMatchesAny?: string
}
export interface VantaGetControlParams extends VantaBaseParams {
controlId: string
}
export interface VantaListControlTestsParams extends VantaBaseParams, VantaPaginationParams {
controlId: string
}
export interface VantaListControlDocumentsParams extends VantaBaseParams, VantaPaginationParams {
controlId: string
}
export interface VantaListTestsParams extends VantaBaseParams, VantaPaginationParams {
statusFilter?: string
categoryFilter?: string
frameworkFilter?: string
integrationFilter?: string
controlFilter?: string
ownerFilter?: string
isInRollout?: boolean
}
export interface VantaGetTestParams extends VantaBaseParams {
testId: string
}
export interface VantaListTestEntitiesParams extends VantaBaseParams, VantaPaginationParams {
testId: string
entityStatus?: string
}
export interface VantaListDocumentsParams extends VantaBaseParams, VantaPaginationParams {
frameworkMatchesAny?: string
statusMatchesAny?: string
}
export interface VantaGetDocumentParams extends VantaBaseParams {
documentId: string
}
export interface VantaListDocumentUploadsParams extends VantaBaseParams, VantaPaginationParams {
documentId: string
}
export interface VantaUploadDocumentFileParams extends VantaBaseParams {
documentId: string
file?: unknown
fileContent?: string
fileName?: string
mimeType?: string
description?: string
effectiveAtDate?: string
}
export interface VantaDownloadDocumentFileParams extends VantaBaseParams {
documentId: string
uploadedFileId: string
}
export interface VantaSubmitDocumentParams extends VantaBaseParams {
documentId: string
}
export interface VantaListPeopleParams extends VantaBaseParams, VantaPaginationParams {
emailAndNameFilter?: string
employmentStatus?: string
groupIdsMatchesAny?: string
tasksSummaryStatusMatchesAny?: string
taskTypeMatchesAny?: string
taskStatusMatchesAny?: string
}
export interface VantaGetPersonParams extends VantaBaseParams {
personId: string
}
export interface VantaListPoliciesParams extends VantaBaseParams, VantaPaginationParams {}
export interface VantaGetPolicyParams extends VantaBaseParams {
policyId: string
}
export interface VantaListMonitoredComputersParams extends VantaBaseParams, VantaPaginationParams {
complianceStatusFilterMatchesAny?: string
}
export interface VantaListRiskScenariosParams extends VantaBaseParams, VantaPaginationParams {
searchString?: string
includeIgnored?: boolean
type?: string
ownerMatchesAny?: string
categoryMatchesAny?: string
ciaCategoryMatchesAny?: string
treatmentTypeMatchesAny?: string
inherentScoreGroupMatchesAny?: string
residualScoreGroupMatchesAny?: string
reviewStatusMatchesAny?: string
orderBy?: string
}
export interface VantaGetRiskScenarioParams extends VantaBaseParams {
riskScenarioId: string
}
export interface VantaListVulnerabilityRemediationsParams
extends VantaBaseParams,
VantaPaginationParams {
integrationId?: string
severity?: string
isRemediatedOnTime?: boolean
remediatedAfterDate?: string
remediatedBeforeDate?: string
}
export interface VantaListVulnerableAssetsParams extends VantaBaseParams, VantaPaginationParams {
q?: string
integrationId?: string
assetType?: string
assetExternalAccountId?: string
}
export interface VantaGetVulnerableAssetParams extends VantaBaseParams {
vulnerableAssetId: string
}
export interface VantaListVendorsParams extends VantaBaseParams, VantaPaginationParams {
name?: string
statusMatchesAny?: string
}
export interface VantaGetVendorParams extends VantaBaseParams {
vendorId: string
}
export interface VantaListVulnerabilitiesParams extends VantaBaseParams, VantaPaginationParams {
q?: string
severity?: string
isFixAvailable?: boolean
isDeactivated?: boolean
includeVulnerabilitiesWithoutSlas?: boolean
packageIdentifier?: string
externalVulnerabilityId?: string
integrationId?: string
vulnerableAssetId?: string
slaDeadlineAfterDate?: string
slaDeadlineBeforeDate?: string
}
export interface VantaPageInfo {
startCursor: string | null
endCursor: string | null
hasNextPage: boolean
hasPreviousPage: boolean
}
export interface VantaOwner {
id: string | null
displayName: string | null
emailAddress: string | null
}
export interface VantaCustomField {
label: string | null
value: string | string[] | null
}
export interface VantaFramework {
id: string | null
displayName: string | null
shorthandName: string | null
description: string | null
numControlsCompleted: number | null
numControlsTotal: number | null
numDocumentsPassing: number | null
numDocumentsTotal: number | null
numTestsPassing: number | null
numTestsTotal: number | null
}
export interface VantaFrameworkRequirementControl {
id: string | null
externalId: string | null
name: string | null
description: string | null
}
export interface VantaFrameworkRequirement {
id: string | null
name: string | null
shorthand: string | null
description: string | null
controls: VantaFrameworkRequirementControl[]
}
export interface VantaFrameworkRequirementCategory {
id: string | null
name: string | null
shorthand: string | null
requirements: VantaFrameworkRequirement[]
}
export interface VantaFrameworkDetail extends VantaFramework {
requirementCategories: VantaFrameworkRequirementCategory[]
}
export interface VantaControl {
id: string | null
externalId: string | null
name: string | null
description: string | null
source: string | null
domains: string[]
owner: VantaOwner | null
role: string | null
customFields: VantaCustomField[]
creationDate: string | null
modificationDate: string | null
}
export interface VantaControlDetail extends VantaControl {
note: string | null
status: string | null
numDocumentsPassing: number | null
numDocumentsTotal: number | null
numTestsPassing: number | null
numTestsTotal: number | null
}
export interface VantaTestVersion {
major: number | null
minor: number | null
}
export interface VantaTestDeactivatedStatusInfo {
isDeactivated: boolean | null
deactivatedReason: string | null
lastUpdatedDate: string | null
}
export interface VantaTestRemediationStatusInfo {
status: string | null
soonestRemediateByDate: string | null
itemCount: number | null
}
export interface VantaTest {
id: string | null
name: string | null
description: string | null
failureDescription: string | null
remediationDescription: string | null
category: string | null
status: string | null
integrations: string[]
lastTestRunDate: string | null
latestFlipDate: string | null
version: VantaTestVersion | null
deactivatedStatusInfo: VantaTestDeactivatedStatusInfo | null
remediationStatusInfo: VantaTestRemediationStatusInfo | null
owner: VantaOwner | null
}
export interface VantaTestEntity {
id: string | null
entityStatus: string | null
displayName: string | null
responseType: string | null
deactivatedReason: string | null
createdDate: string | null
lastUpdatedDate: string | null
}
export interface VantaDocument {
id: string | null
title: string | null
description: string | null
category: string | null
ownerId: string | null
isSensitive: boolean | null
uploadStatus: string | null
uploadStatusDate: string | null
url: string | null
}
export interface VantaDocumentDeactivatedStatus {
isDeactivated: boolean | null
reason: string | null
creationDate: string | null
expiration: string | null
}
export interface VantaDocumentDetail extends VantaDocument {
note: string | null
nextRenewalDate: string | null
renewalCadence: string | null
reminderWindow: string | null
subscribers: string[]
deactivatedStatus: VantaDocumentDeactivatedStatus | null
}
export interface VantaUploadedByActor {
id: string | null
type: string | null
}
export interface VantaUploadedFile {
id: string | null
fileName: string | null
title: string | null
description: string | null
mimeType: string | null
uploadedBy: VantaUploadedByActor | null
creationDate: string | null
updatedDate: string | null
deletionDate: string | null
effectiveDate: string | null
url: string | null
}
export interface VantaPersonName {
first: string | null
last: string | null
display: string | null
}
export interface VantaPersonEmployment {
status: string | null
startDate: string | null
endDate: string | null
jobTitle: string | null
}
export interface VantaPersonLeaveInfo {
status: string | null
startDate: string | null
endDate: string | null
}
export interface VantaPersonTasksSummary {
status: string | null
dueDate: string | null
completionDate: string | null
}
export interface VantaPerson {
id: string | null
userId: string | null
emailAddress: string | null
name: VantaPersonName | null
employment: VantaPersonEmployment | null
leaveInfo: VantaPersonLeaveInfo | null
groupIds: string[]
tasksSummary: VantaPersonTasksSummary | null
}
export interface VantaPolicyDocument {
language: string | null
slugId: string | null
url: string | null
}
export interface VantaPolicyLatestApprovedVersion {
versionId: string | null
documents: VantaPolicyDocument[]
}
export interface VantaPolicy {
id: string | null
name: string | null
description: string | null
status: string | null
approvedAtDate: string | null
latestVersionStatus: string | null
latestApprovedVersion: VantaPolicyLatestApprovedVersion | null
}
export interface VantaVendorAuthDetails {
method: string | null
passwordMFA: boolean | null
passwordMinimumLength: number | null
passwordRequiresNumber: boolean | null
passwordRequiresSymbol: boolean | null
}
export interface VantaVendorContractAmount {
amount: number | null
currency: string | null
}
export interface VantaVendorDecision {
status: string | null
lastUpdatedAt: string | null
}
export interface VantaVendorProcurementRequest {
url: string | null
service: string | null
}
export interface VantaVendor {
id: string | null
name: string | null
status: string | null
websiteUrl: string | null
category: string | null
servicesProvided: string | null
additionalNotes: string | null
accountManagerName: string | null
accountManagerEmail: string | null
securityOwnerUserId: string | null
businessOwnerUserId: string | null
inherentRiskLevel: string | null
residualRiskLevel: string | null
isRiskAutoScored: boolean | null
isVisibleToAuditors: boolean | null
riskAttributeIds: string[]
vendorHeadquarters: string | null
contractStartDate: string | null
contractRenewalDate: string | null
contractTerminationDate: string | null
contractAmount: VantaVendorContractAmount | null
nextSecurityReviewDueDate: string | null
lastSecurityReviewCompletionDate: string | null
authDetails: VantaVendorAuthDetails | null
customFields: VantaCustomField[]
latestDecision: VantaVendorDecision | null
linkedTaskTrackerTaskProcurementRequest: VantaVendorProcurementRequest | null
}
export interface VantaVulnerabilityDeactivateMetadata {
isVulnDeactivatedIndefinitely: boolean | null
deactivatedUntilDate: string | null
deactivationReason: string | null
deactivatedOnDate: string | null
deactivatedBy: string | null
}
export interface VantaVulnerability {
id: string | null
name: string | null
description: string | null
severity: string | null
vulnerabilityType: string | null
integrationId: string | null
targetId: string | null
packageIdentifier: string | null
cvssSeverityScore: number | null
scannerScore: number | null
isFixable: boolean | null
fixedVersion: string | null
remediateByDate: string | null
firstDetectedDate: string | null
sourceDetectedDate: string | null
lastDetectedDate: string | null
scanSource: string | null
externalURL: string | null
relatedVulns: string[]
relatedUrls: string[]
deactivateMetadata: VantaVulnerabilityDeactivateMetadata | null
}
export interface VantaOperatingSystem {
type: string | null
version: string | null
}
export interface VantaMonitoredComputer {
id: string | null
integrationId: string | null
lastCheckDate: string | null
screenlock: string | null
diskEncryption: string | null
passwordManager: string | null
antivirusInstallation: string | null
operatingSystem: VantaOperatingSystem | null
owner: VantaOwner | null
serialNumber: string | null
udid: string | null
}
export interface VantaRiskScenario {
riskId: string | null
description: string | null
likelihood: number | null
impact: number | null
residualLikelihood: number | null
residualImpact: number | null
categories: string[]
ciaCategories: string[]
treatment: string | null
owner: string | null
note: string | null
riskRegister: string | null
customFields: VantaCustomField[]
isArchived: boolean | null
reviewStatus: string | null
requiredApprovers: string[]
type: string | null
identificationDate: string | null
}
export interface VantaVulnerabilityRemediation {
id: string | null
vulnerabilityId: string | null
vulnerableAssetId: string | null
severity: string | null
detectedDate: string | null
slaDeadlineDate: string | null
remediationDate: string | null
}
export interface VantaAssetTag {
key: string | null
value: string | null
}
export interface VantaVulnerableAssetScanner {
resourceId: string | null
integrationId: string | null
targetId: string | null
imageDigest: string | null
imagePushedAtDate: string | null
imageTags: string[]
assetTags: VantaAssetTag[]
parentAccountOrOrganization: string | null
biosUuid: string | null
ipv4s: string[]
ipv6s: string[]
macAddresses: string[]
hostnames: string[]
fqdns: string[]
operatingSystems: string[]
}
export interface VantaVulnerableAsset {
id: string | null
name: string | null
assetType: string | null
hasBeenScanned: boolean | null
imageScanTag: string | null
scanners: VantaVulnerableAssetScanner[]
}
export interface VantaDownloadedFile {
name: string
mimeType: string
data: string
size: number
}
export interface VantaListFrameworksResponse extends ToolResponse {
output: {
frameworks: VantaFramework[]
pageInfo: VantaPageInfo | null
}
}
export interface VantaGetFrameworkResponse extends ToolResponse {
output: {
framework: VantaFrameworkDetail
}
}
export interface VantaListControlsResponse extends ToolResponse {
output: {
controls: VantaControl[]
pageInfo: VantaPageInfo | null
}
}
export interface VantaGetControlResponse extends ToolResponse {
output: {
control: VantaControlDetail
}
}
export interface VantaListTestsResponse extends ToolResponse {
output: {
tests: VantaTest[]
pageInfo: VantaPageInfo | null
}
}
export interface VantaGetTestResponse extends ToolResponse {
output: {
test: VantaTest
}
}
export interface VantaListTestEntitiesResponse extends ToolResponse {
output: {
entities: VantaTestEntity[]
pageInfo: VantaPageInfo | null
}
}
export interface VantaListDocumentsResponse extends ToolResponse {
output: {
documents: VantaDocument[]
pageInfo: VantaPageInfo | null
}
}
export interface VantaGetDocumentResponse extends ToolResponse {
output: {
document: VantaDocumentDetail
}
}
export interface VantaListDocumentUploadsResponse extends ToolResponse {
output: {
uploads: VantaUploadedFile[]
pageInfo: VantaPageInfo | null
}
}
export interface VantaUploadDocumentFileResponse extends ToolResponse {
output: {
upload: VantaUploadedFile
}
}
export interface VantaDownloadDocumentFileResponse extends ToolResponse {
output: {
file: VantaDownloadedFile
name: string
mimeType: string
size: number
}
}
export interface VantaSubmitDocumentResponse extends ToolResponse {
output: {
documentId: string
submitted: boolean
}
}
export interface VantaGetPersonResponse extends ToolResponse {
output: {
person: VantaPerson
}
}
export interface VantaGetPolicyResponse extends ToolResponse {
output: {
policy: VantaPolicy
}
}
export interface VantaListMonitoredComputersResponse extends ToolResponse {
output: {
computers: VantaMonitoredComputer[]
pageInfo: VantaPageInfo | null
}
}
export interface VantaListRiskScenariosResponse extends ToolResponse {
output: {
riskScenarios: VantaRiskScenario[]
pageInfo: VantaPageInfo | null
}
}
export interface VantaGetRiskScenarioResponse extends ToolResponse {
output: {
riskScenario: VantaRiskScenario
}
}
export interface VantaListVulnerabilityRemediationsResponse extends ToolResponse {
output: {
remediations: VantaVulnerabilityRemediation[]
pageInfo: VantaPageInfo | null
}
}
export interface VantaListVulnerableAssetsResponse extends ToolResponse {
output: {
assets: VantaVulnerableAsset[]
pageInfo: VantaPageInfo | null
}
}
export interface VantaGetVulnerableAssetResponse extends ToolResponse {
output: {
asset: VantaVulnerableAsset
}
}
export interface VantaListPeopleResponse extends ToolResponse {
output: {
people: VantaPerson[]
pageInfo: VantaPageInfo | null
}
}
export interface VantaListPoliciesResponse extends ToolResponse {
output: {
policies: VantaPolicy[]
pageInfo: VantaPageInfo | null
}
}
export interface VantaListVendorsResponse extends ToolResponse {
output: {
vendors: VantaVendor[]
pageInfo: VantaPageInfo | null
}
}
export interface VantaGetVendorResponse extends ToolResponse {
output: {
vendor: VantaVendor
}
}
export interface VantaListVulnerabilitiesResponse extends ToolResponse {
output: {
vulnerabilities: VantaVulnerability[]
pageInfo: VantaPageInfo | null
}
}
export type VantaResponse =
| VantaListFrameworksResponse
| VantaGetFrameworkResponse
| VantaListControlsResponse
| VantaGetControlResponse
| VantaListTestsResponse
| VantaGetTestResponse
| VantaListTestEntitiesResponse
| VantaListDocumentsResponse
| VantaGetDocumentResponse
| VantaListDocumentUploadsResponse
| VantaUploadDocumentFileResponse
| VantaDownloadDocumentFileResponse
| VantaSubmitDocumentResponse
| VantaListPeopleResponse
| VantaGetPersonResponse
| VantaListPoliciesResponse
| VantaGetPolicyResponse
| VantaListVendorsResponse
| VantaGetVendorResponse
| VantaListMonitoredComputersResponse
| VantaListVulnerabilitiesResponse
| VantaListVulnerabilityRemediationsResponse
| VantaListVulnerableAssetsResponse
| VantaGetVulnerableAssetResponse
| VantaListRiskScenariosResponse
| VantaGetRiskScenarioResponse
@@ -0,0 +1,112 @@
import type { ToolConfig } from '@/tools/types'
import { VANTA_UPLOADED_FILE_OUTPUT_PROPERTIES } from '@/tools/vanta/outputs'
import type {
VantaUploadDocumentFileParams,
VantaUploadDocumentFileResponse,
} from '@/tools/vanta/types'
import { createVantaTransformResponse } from '@/tools/vanta/utils'
export const vantaUploadDocumentFileTool: ToolConfig<
VantaUploadDocumentFileParams,
VantaUploadDocumentFileResponse
> = {
id: 'vanta_upload_document_file',
name: 'Vanta Upload Document File',
description:
'Upload an evidence file to a Vanta document. Requires credentials with the vanta-api.documents:upload scope.',
version: '1.0.0',
params: {
clientId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client ID',
},
clientSecret: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Vanta OAuth application client secret',
},
region: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Vanta API region: "us" (api.vanta.com, default) or "gov" (api.vanta-gov.com)',
},
documentId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique ID of the document to attach the file to',
},
file: {
type: 'file',
required: false,
visibility: 'user-or-llm',
description: 'The evidence file to upload',
},
fileContent: {
type: 'string',
required: false,
visibility: 'hidden',
description: 'Base64-encoded file content (alternative to file)',
},
fileName: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Optional file name override',
},
mimeType: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'MIME type of the file (e.g., application/pdf); used when uploading base64 content, since uploaded files already carry their own type',
},
description: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Description of the uploaded evidence (e.g., "Q3 access review evidence")',
},
effectiveAtDate: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'ISO 8601 date indicating when the document is effective from',
},
},
request: {
url: '/api/tools/vanta/upload',
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
body: (params) => ({
clientId: params.clientId,
clientSecret: params.clientSecret,
region: params.region,
documentId: params.documentId,
file: params.file,
fileContent: params.fileContent,
fileName: params.fileName,
mimeType: params.mimeType,
description: params.description,
effectiveAtDate: params.effectiveAtDate,
}),
},
transformResponse: createVantaTransformResponse<VantaUploadDocumentFileResponse>(
'Failed to upload file to Vanta document'
),
outputs: {
upload: {
type: 'json',
description: 'Metadata of the uploaded file',
properties: VANTA_UPLOADED_FILE_OUTPUT_PROPERTIES,
},
},
}
+804
View File
@@ -0,0 +1,804 @@
import { isRecordLike } from '@sim/utils/object'
import type {
VantaControl,
VantaControlDetail,
VantaCustomField,
VantaDocument,
VantaDocumentDetail,
VantaFramework,
VantaFrameworkDetail,
VantaFrameworkRequirement,
VantaFrameworkRequirementCategory,
VantaFrameworkRequirementControl,
VantaMonitoredComputer,
VantaOwner,
VantaPageInfo,
VantaPerson,
VantaPolicy,
VantaPolicyDocument,
VantaRegion,
VantaRiskScenario,
VantaTest,
VantaTestEntity,
VantaUploadedFile,
VantaVendor,
VantaVulnerability,
VantaVulnerabilityRemediation,
VantaVulnerableAsset,
VantaVulnerableAssetScanner,
} from '@/tools/vanta/types'
export const VANTA_API_BASE_URLS: Record<VantaRegion, string> = {
us: 'https://api.vanta.com',
gov: 'https://api.vanta-gov.com',
}
/** Read-only scope used by every query and download operation. */
export const VANTA_READ_SCOPE = 'vanta-api.all:read'
/** Read-write scope used by write operations that do not upload files. */
export const VANTA_WRITE_SCOPE = 'vanta-api.all:read vanta-api.all:write'
/**
* Scope string for document evidence uploads, taken verbatim from Vanta's
* "Upload a document" guide (the upload scope cannot be requested alone).
*/
export const VANTA_DOCUMENT_UPLOAD_SCOPE =
'vanta-api.all:read vanta-api.all:write vanta-api.documents:upload'
export function getVantaBaseUrl(region: VantaRegion | undefined): string {
return VANTA_API_BASE_URLS[region ?? 'us']
}
export const VANTA_QUERY_ROUTE = '/api/tools/vanta/query'
/**
* Builds the standard transformResponse for Vanta tools, which call internal
* API routes that return `{ success, output }` JSON or `{ success: false,
* error }` on failure.
*/
export function createVantaTransformResponse<R extends { success: boolean; output: unknown }>(
fallbackError: string
) {
return async (response: Response): Promise<R> => {
const data = await response.json()
if (!response.ok || data.success === false) {
throw new Error(data.error || fallbackError)
}
return { success: true, output: data.output } as R
}
}
type JsonRecord = Record<string, unknown>
/**
* Coerces an unknown single-resource response body to a record so the
* normalizers can run on it; non-object bodies normalize to all-null fields.
*/
export function asVantaRecord(value: unknown): JsonRecord {
return isRecordLike(value) ? value : {}
}
function getString(value: unknown): string | null {
return typeof value === 'string' ? value : null
}
function getNumber(value: unknown): number | null {
return typeof value === 'number' && Number.isFinite(value) ? value : null
}
function getBoolean(value: unknown): boolean | null {
return typeof value === 'boolean' ? value : null
}
function getStringArray(value: unknown): string[] {
if (!Array.isArray(value)) return []
return value.filter((entry): entry is string => typeof entry === 'string')
}
function getRecordArray(value: unknown): JsonRecord[] {
if (!Array.isArray(value)) return []
return value.filter(isRecordLike)
}
/**
* Extracts a human-readable error message from a Vanta API error body.
*/
export function extractVantaError(data: unknown, fallback: string): string {
if (!isRecordLike(data)) return fallback
if (isRecordLike(data.error)) {
const nested = getString(data.error.message) ?? getString(data.error.code)
if (nested) return nested
}
return (
getString(data.message) ??
getString(data.error_description) ??
getString(data.error) ??
fallback
)
}
export interface VantaTokenParams {
clientId: string
clientSecret: string
region?: VantaRegion
scope: string
}
interface VantaCachedToken {
token: string
expiresAt: number
}
/**
* In-memory token cache. Vanta only keeps one access token active per
* application — requesting a new token revokes the previous one — so reusing
* a cached token keeps concurrent tool executions with the same credentials
* from revoking each other's tokens mid-flight.
*/
const vantaTokenCache = new Map<string, VantaCachedToken>()
/**
* In-flight token exchanges, keyed like the cache. Concurrent callers that
* miss the cache join the same exchange instead of issuing competing ones
* that would revoke each other's tokens.
*/
const vantaTokenExchanges = new Map<string, Promise<string>>()
/** Evict cached tokens well before their one-hour expiry. */
const VANTA_TOKEN_EXPIRY_BUFFER_MS = 10 * 60 * 1000
/**
* Hard deadline on the token-endpoint exchange. The exchange promise is
* shared across concurrent callers, so a hung endpoint without this bound
* would wedge every joiner until the undici socket defaults (~5 min) gave up.
*/
const VANTA_TOKEN_EXCHANGE_TIMEOUT_MS = 15_000
/**
* Derives the cache key for a credential set. The client secret is included
* only as a SHA-256 digest so plaintext secrets never persist in the
* long-lived cache maps.
*/
async function vantaTokenCacheKey(params: VantaTokenParams): Promise<string> {
const digest = await crypto.subtle.digest(
'SHA-256',
new TextEncoder().encode(`${params.clientId}:${params.clientSecret}`)
)
const secretHash = Array.from(new Uint8Array(digest))
.map((byte) => byte.toString(16).padStart(2, '0'))
.join('')
return [params.region ?? 'us', params.scope, params.clientId, secretHash].join('|')
}
async function exchangeVantaToken(params: VantaTokenParams, cacheKey: string): Promise<string> {
const response = await fetch(`${getVantaBaseUrl(params.region)}/oauth/token`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
client_id: params.clientId,
client_secret: params.clientSecret,
scope: params.scope,
grant_type: 'client_credentials',
}),
cache: 'no-store',
signal: AbortSignal.timeout(VANTA_TOKEN_EXCHANGE_TIMEOUT_MS),
})
const data: unknown = await response.json().catch(() => null)
if (!response.ok) {
throw new Error(extractVantaError(data, 'Failed to authenticate with Vanta'))
}
if (!isRecordLike(data) || typeof data.access_token !== 'string') {
throw new Error('Vanta authentication did not return an access token')
}
const expiresInMs = (getNumber(data.expires_in) ?? 0) * 1000
if (expiresInMs > VANTA_TOKEN_EXPIRY_BUFFER_MS) {
vantaTokenCache.set(cacheKey, {
token: data.access_token,
expiresAt: Date.now() + expiresInMs - VANTA_TOKEN_EXPIRY_BUFFER_MS,
})
}
return data.access_token
}
/**
* Returns a bearer token for the Vanta API, exchanging OAuth client
* credentials and caching the result until shortly before expiry. Concurrent
* callers share a single in-flight exchange. Pass `forceRefresh` when a
* cached token has been revoked (e.g., by another process exchanging the
* same credentials); a force refresh still joins any exchange already in
* flight, since that exchange yields an equally fresh token.
*/
export async function getVantaAccessToken(
params: VantaTokenParams,
options?: { forceRefresh?: boolean }
): Promise<string> {
const cacheKey = await vantaTokenCacheKey(params)
if (!options?.forceRefresh) {
const cached = vantaTokenCache.get(cacheKey)
if (cached && cached.expiresAt > Date.now()) {
return cached.token
}
}
const inFlight = vantaTokenExchanges.get(cacheKey)
if (inFlight) {
return inFlight
}
vantaTokenCache.delete(cacheKey)
const exchange = exchangeVantaToken(params, cacheKey)
vantaTokenExchanges.set(cacheKey, exchange)
try {
return await exchange
} finally {
vantaTokenExchanges.delete(cacheKey)
}
}
/**
* Performs an authenticated Vanta API request. When the request comes back
* 401 — typically because another process exchanged the same credentials and
* revoked the cached token — it retries once with a freshly exchanged token.
*/
export async function fetchVantaWithAuth(
tokenParams: VantaTokenParams,
doFetch: (accessToken: string) => Promise<Response>
): Promise<Response> {
const accessToken = await getVantaAccessToken(tokenParams)
const response = await doFetch(accessToken)
if (response.status !== 401) {
return response
}
const freshToken = await getVantaAccessToken(tokenParams, { forceRefresh: true })
return doFetch(freshToken)
}
/**
* Builds a Vanta v1 API URL, appending only query parameters that have a
* value. Array values are appended as repeated parameters.
*/
export function buildVantaUrl(
baseUrl: string,
path: string,
query?: Record<string, string | number | boolean | string[] | null | undefined>
): string {
const url = new URL(`${baseUrl}/v1${path}`)
if (query) {
for (const [key, value] of Object.entries(query)) {
if (value == null || value === '') continue
if (Array.isArray(value)) {
for (const entry of value) {
url.searchParams.append(key, entry)
}
} else {
url.searchParams.set(key, String(value))
}
}
}
return url.toString()
}
/**
* Splits a comma-separated filter value into trimmed entries, returning
* undefined when no usable entries remain.
*/
export function splitVantaCommaList(value: string | null | undefined): string[] | undefined {
if (!value) return undefined
const entries = value
.split(',')
.map((entry) => entry.trim())
.filter(Boolean)
return entries.length > 0 ? entries : undefined
}
/**
* Unwraps the `{ results: { data, pageInfo } }` envelope that every Vanta
* list endpoint returns.
*/
export function getVantaListResults(data: unknown): {
data: JsonRecord[]
pageInfo: VantaPageInfo | null
} {
if (!isRecordLike(data) || !isRecordLike(data.results)) {
return { data: [], pageInfo: null }
}
return {
data: getRecordArray(data.results.data),
pageInfo: normalizeVantaPageInfo(data.results.pageInfo),
}
}
export function normalizeVantaPageInfo(value: unknown): VantaPageInfo | null {
if (!isRecordLike(value)) return null
return {
startCursor: getString(value.startCursor),
endCursor: getString(value.endCursor),
hasNextPage: getBoolean(value.hasNextPage) ?? false,
hasPreviousPage: getBoolean(value.hasPreviousPage) ?? false,
}
}
function normalizeVantaOwner(value: unknown): VantaOwner | null {
if (!isRecordLike(value)) return null
return {
id: getString(value.id),
displayName: getString(value.displayName),
emailAddress: getString(value.emailAddress),
}
}
function normalizeVantaCustomFields(value: unknown): VantaCustomField[] {
return getRecordArray(value).map((field) => ({
label: getString(field.label),
value: Array.isArray(field.value) ? getStringArray(field.value) : getString(field.value),
}))
}
export function normalizeVantaFramework(resource: JsonRecord): VantaFramework {
return {
id: getString(resource.id),
displayName: getString(resource.displayName),
shorthandName: getString(resource.shorthandName),
description: getString(resource.description),
numControlsCompleted: getNumber(resource.numControlsCompleted),
numControlsTotal: getNumber(resource.numControlsTotal),
numDocumentsPassing: getNumber(resource.numDocumentsPassing),
numDocumentsTotal: getNumber(resource.numDocumentsTotal),
numTestsPassing: getNumber(resource.numTestsPassing),
numTestsTotal: getNumber(resource.numTestsTotal),
}
}
function normalizeVantaFrameworkRequirementControl(
resource: JsonRecord
): VantaFrameworkRequirementControl {
return {
id: getString(resource.id),
externalId: getString(resource.externalId),
name: getString(resource.name),
description: getString(resource.description),
}
}
function normalizeVantaFrameworkRequirement(resource: JsonRecord): VantaFrameworkRequirement {
return {
id: getString(resource.id),
name: getString(resource.name),
shorthand: getString(resource.shorthand),
description: getString(resource.description),
controls: getRecordArray(resource.controls).map(normalizeVantaFrameworkRequirementControl),
}
}
function normalizeVantaFrameworkRequirementCategory(
resource: JsonRecord
): VantaFrameworkRequirementCategory {
return {
id: getString(resource.id),
name: getString(resource.name),
shorthand: getString(resource.shorthand),
requirements: getRecordArray(resource.requirements).map(normalizeVantaFrameworkRequirement),
}
}
export function normalizeVantaFrameworkDetail(resource: JsonRecord): VantaFrameworkDetail {
return {
...normalizeVantaFramework(resource),
requirementCategories: getRecordArray(resource.requirementCategories).map(
normalizeVantaFrameworkRequirementCategory
),
}
}
export function normalizeVantaControl(resource: JsonRecord): VantaControl {
return {
id: getString(resource.id),
externalId: getString(resource.externalId),
name: getString(resource.name),
description: getString(resource.description),
source: getString(resource.source),
domains: getStringArray(resource.domains),
owner: normalizeVantaOwner(resource.owner),
role: getString(resource.role),
customFields: normalizeVantaCustomFields(resource.customFields),
creationDate: getString(resource.creationDate),
modificationDate: getString(resource.modificationDate),
}
}
export function normalizeVantaControlDetail(resource: JsonRecord): VantaControlDetail {
return {
...normalizeVantaControl(resource),
note: getString(resource.note),
status: getString(resource.status),
numDocumentsPassing: getNumber(resource.numDocumentsPassing),
numDocumentsTotal: getNumber(resource.numDocumentsTotal),
numTestsPassing: getNumber(resource.numTestsPassing),
numTestsTotal: getNumber(resource.numTestsTotal),
}
}
export function normalizeVantaTest(resource: JsonRecord): VantaTest {
const version = isRecordLike(resource.version)
? { major: getNumber(resource.version.major), minor: getNumber(resource.version.minor) }
: null
const deactivatedStatusInfo = isRecordLike(resource.deactivatedStatusInfo)
? {
isDeactivated: getBoolean(resource.deactivatedStatusInfo.isDeactivated),
deactivatedReason: getString(resource.deactivatedStatusInfo.deactivatedReason),
lastUpdatedDate: getString(resource.deactivatedStatusInfo.lastUpdatedDate),
}
: null
const remediationStatusInfo = isRecordLike(resource.remediationStatusInfo)
? {
status: getString(resource.remediationStatusInfo.status),
soonestRemediateByDate: getString(resource.remediationStatusInfo.soonestRemediateByDate),
itemCount: getNumber(resource.remediationStatusInfo.itemCount),
}
: null
return {
id: getString(resource.id),
name: getString(resource.name),
description: getString(resource.description),
failureDescription: getString(resource.failureDescription),
remediationDescription: getString(resource.remediationDescription),
category: getString(resource.category),
status: getString(resource.status),
integrations: getStringArray(resource.integrations),
lastTestRunDate: getString(resource.lastTestRunDate),
latestFlipDate: getString(resource.latestFlipDate),
version,
deactivatedStatusInfo,
remediationStatusInfo,
owner: normalizeVantaOwner(resource.owner),
}
}
export function normalizeVantaTestEntity(resource: JsonRecord): VantaTestEntity {
return {
id: getString(resource.id),
entityStatus: getString(resource.entityStatus),
displayName: getString(resource.displayName),
responseType: getString(resource.responseType),
deactivatedReason: getString(resource.deactivatedReason),
createdDate: getString(resource.createdDate),
lastUpdatedDate: getString(resource.lastUpdatedDate),
}
}
export function normalizeVantaDocument(resource: JsonRecord): VantaDocument {
return {
id: getString(resource.id),
title: getString(resource.title),
description: getString(resource.description),
category: getString(resource.category),
ownerId: getString(resource.ownerId),
isSensitive: getBoolean(resource.isSensitive),
uploadStatus: getString(resource.uploadStatus),
uploadStatusDate: getString(resource.uploadStatusDate),
url: getString(resource.url),
}
}
export function normalizeVantaDocumentDetail(resource: JsonRecord): VantaDocumentDetail {
const deactivatedStatus = isRecordLike(resource.deactivatedStatus)
? {
isDeactivated: getBoolean(resource.deactivatedStatus.isDeactivated),
reason: getString(resource.deactivatedStatus.reason),
creationDate: getString(resource.deactivatedStatus.creationDate),
expiration: getString(resource.deactivatedStatus.expiration),
}
: null
return {
...normalizeVantaDocument(resource),
note: getString(resource.note),
nextRenewalDate: getString(resource.nextRenewalDate),
renewalCadence: getString(resource.renewalCadence),
reminderWindow: getString(resource.reminderWindow),
subscribers: getStringArray(resource.subscribers),
deactivatedStatus,
}
}
export function normalizeVantaUploadedFile(resource: JsonRecord): VantaUploadedFile {
const uploadedBy = isRecordLike(resource.uploadedBy)
? { id: getString(resource.uploadedBy.id), type: getString(resource.uploadedBy.type) }
: null
return {
id: getString(resource.id),
fileName: getString(resource.fileName),
title: getString(resource.title),
description: getString(resource.description),
mimeType: getString(resource.mimeType),
uploadedBy,
creationDate: getString(resource.creationDate),
updatedDate: getString(resource.updatedDate),
deletionDate: getString(resource.deletionDate),
effectiveDate: getString(resource.effectiveDate),
url: getString(resource.url),
}
}
export function normalizeVantaPerson(resource: JsonRecord): VantaPerson {
const name = isRecordLike(resource.name)
? {
first: getString(resource.name.first),
last: getString(resource.name.last),
display: getString(resource.name.display),
}
: null
const employment = isRecordLike(resource.employment)
? {
status: getString(resource.employment.status),
startDate: getString(resource.employment.startDate),
endDate: getString(resource.employment.endDate),
jobTitle: getString(resource.employment.jobTitle),
}
: null
const leaveInfo = isRecordLike(resource.leaveInfo)
? {
status: getString(resource.leaveInfo.status),
startDate: getString(resource.leaveInfo.startDate),
endDate: getString(resource.leaveInfo.endDate),
}
: null
const tasksSummary = isRecordLike(resource.tasksSummary)
? {
status: getString(resource.tasksSummary.status),
dueDate: getString(resource.tasksSummary.dueDate),
completionDate: getString(resource.tasksSummary.completionDate),
}
: null
return {
id: getString(resource.id),
userId: getString(resource.userId),
emailAddress: getString(resource.emailAddress),
name,
employment,
leaveInfo,
groupIds: getStringArray(resource.groupIds),
tasksSummary,
}
}
function normalizeVantaPolicyDocument(resource: JsonRecord): VantaPolicyDocument {
return {
language: getString(resource.language),
slugId: getString(resource.slugId),
url: getString(resource.url),
}
}
export function normalizeVantaPolicy(resource: JsonRecord): VantaPolicy {
const latestApprovedVersion = isRecordLike(resource.latestApprovedVersion)
? {
versionId: getString(resource.latestApprovedVersion.versionId),
documents: getRecordArray(resource.latestApprovedVersion.documents).map(
normalizeVantaPolicyDocument
),
}
: null
return {
id: getString(resource.id),
name: getString(resource.name),
description: getString(resource.description),
status: getString(resource.status),
approvedAtDate: getString(resource.approvedAtDate),
latestVersionStatus: isRecordLike(resource.latestVersion)
? getString(resource.latestVersion.status)
: null,
latestApprovedVersion,
}
}
export function normalizeVantaVendor(resource: JsonRecord): VantaVendor {
const authDetails = isRecordLike(resource.authDetails)
? {
method: getString(resource.authDetails.method),
passwordMFA: getBoolean(resource.authDetails.passwordMFA),
passwordMinimumLength: getNumber(resource.authDetails.passwordMinimumLength),
passwordRequiresNumber: getBoolean(resource.authDetails.passwordRequiresNumber),
passwordRequiresSymbol: getBoolean(resource.authDetails.passwordRequiresSymbol),
}
: null
const contractAmount = isRecordLike(resource.contractAmount)
? {
amount: getNumber(resource.contractAmount.amount),
currency: getString(resource.contractAmount.currency),
}
: null
const latestDecision = isRecordLike(resource.latestDecision)
? {
status: getString(resource.latestDecision.status),
lastUpdatedAt: getString(resource.latestDecision.lastUpdatedAt),
}
: null
const procurementRequest = isRecordLike(resource.linkedTaskTrackerTaskProcurementRequest)
? {
url: getString(resource.linkedTaskTrackerTaskProcurementRequest.url),
service: getString(resource.linkedTaskTrackerTaskProcurementRequest.service),
}
: null
return {
id: getString(resource.id),
name: getString(resource.name),
status: getString(resource.status),
websiteUrl: getString(resource.websiteUrl),
category: isRecordLike(resource.category) ? getString(resource.category.displayName) : null,
servicesProvided: getString(resource.servicesProvided),
additionalNotes: getString(resource.additionalNotes),
accountManagerName: getString(resource.accountManagerName),
accountManagerEmail: getString(resource.accountManagerEmail),
securityOwnerUserId: getString(resource.securityOwnerUserId),
businessOwnerUserId: getString(resource.businessOwnerUserId),
inherentRiskLevel: getString(resource.inherentRiskLevel),
residualRiskLevel: getString(resource.residualRiskLevel),
isRiskAutoScored: getBoolean(resource.isRiskAutoScored),
isVisibleToAuditors: getBoolean(resource.isVisibleToAuditors),
riskAttributeIds: getStringArray(resource.riskAttributeIds),
vendorHeadquarters: getString(resource.vendorHeadquarters),
contractStartDate: getString(resource.contractStartDate),
contractRenewalDate: getString(resource.contractRenewalDate),
contractTerminationDate: getString(resource.contractTerminationDate),
contractAmount,
nextSecurityReviewDueDate: getString(resource.nextSecurityReviewDueDate),
lastSecurityReviewCompletionDate: getString(resource.lastSecurityReviewCompletionDate),
authDetails,
customFields: normalizeVantaCustomFields(resource.customFields),
latestDecision,
linkedTaskTrackerTaskProcurementRequest: procurementRequest,
}
}
function getComputerStatusOutcome(value: unknown): string | null {
return isRecordLike(value) ? getString(value.outcome) : null
}
export function normalizeVantaMonitoredComputer(resource: JsonRecord): VantaMonitoredComputer {
const operatingSystem = isRecordLike(resource.operatingSystem)
? {
type: getString(resource.operatingSystem.type),
version: getString(resource.operatingSystem.version),
}
: null
return {
id: getString(resource.id),
integrationId: getString(resource.integrationId),
lastCheckDate: getString(resource.lastCheckDate),
screenlock: getComputerStatusOutcome(resource.screenlock),
diskEncryption: getComputerStatusOutcome(resource.diskEncryption),
passwordManager: getComputerStatusOutcome(resource.passwordManager),
antivirusInstallation: getComputerStatusOutcome(resource.antivirusInstallation),
operatingSystem,
owner: normalizeVantaOwner(resource.owner),
serialNumber: getString(resource.serialNumber),
udid: getString(resource.udid),
}
}
export function normalizeVantaRiskScenario(resource: JsonRecord): VantaRiskScenario {
return {
riskId: getString(resource.riskId),
description: getString(resource.description),
likelihood: getNumber(resource.likelihood),
impact: getNumber(resource.impact),
residualLikelihood: getNumber(resource.residualLikelihood),
residualImpact: getNumber(resource.residualImpact),
categories: getStringArray(resource.categories),
ciaCategories: getStringArray(resource.ciaCategories),
treatment: getString(resource.treatment),
owner: getString(resource.owner),
note: getString(resource.note),
riskRegister: getString(resource.riskRegister),
customFields: normalizeVantaCustomFields(resource.customFields),
isArchived: getBoolean(resource.isArchived),
reviewStatus: getString(resource.reviewStatus),
requiredApprovers: getStringArray(resource.requiredApprovers),
type: getString(resource.type),
identificationDate: getString(resource.identificationDate),
}
}
export function normalizeVantaVulnerabilityRemediation(
resource: JsonRecord
): VantaVulnerabilityRemediation {
return {
id: getString(resource.id),
vulnerabilityId: getString(resource.vulnerabilityId),
vulnerableAssetId: getString(resource.vulnerableAssetId),
severity: getString(resource.severity),
detectedDate: getString(resource.detectedDate),
slaDeadlineDate: getString(resource.slaDeadlineDate),
remediationDate: getString(resource.remediationDate),
}
}
function normalizeVantaVulnerableAssetScanner(resource: JsonRecord): VantaVulnerableAssetScanner {
return {
resourceId: getString(resource.resourceId),
integrationId: getString(resource.integrationId),
targetId: getString(resource.targetId),
imageDigest: getString(resource.imageDigest),
imagePushedAtDate: getString(resource.imagePushedAtDate),
imageTags: getStringArray(resource.imageTags),
assetTags: getRecordArray(resource.assetTags).map((tag) => ({
key: getString(tag.key),
value: getString(tag.value),
})),
parentAccountOrOrganization: getString(resource.parentAccountOrOrganization),
biosUuid: getString(resource.biosUuid),
ipv4s: getStringArray(resource.ipv4s),
ipv6s: getStringArray(resource.ipv6s),
macAddresses: getStringArray(resource.macAddresses),
hostnames: getStringArray(resource.hostnames),
fqdns: getStringArray(resource.fqdns),
operatingSystems: getStringArray(resource.operatingSystems),
}
}
export function normalizeVantaVulnerableAsset(resource: JsonRecord): VantaVulnerableAsset {
return {
id: getString(resource.id),
name: getString(resource.name),
assetType: getString(resource.assetType),
hasBeenScanned: getBoolean(resource.hasBeenScanned),
imageScanTag: getString(resource.imageScanTag),
scanners: getRecordArray(resource.scanners).map(normalizeVantaVulnerableAssetScanner),
}
}
export function normalizeVantaVulnerability(resource: JsonRecord): VantaVulnerability {
const deactivateMetadata = isRecordLike(resource.deactivateMetadata)
? {
isVulnDeactivatedIndefinitely: getBoolean(
resource.deactivateMetadata.isVulnDeactivatedIndefinitely
),
deactivatedUntilDate: getString(resource.deactivateMetadata.deactivatedUntilDate),
deactivationReason: getString(resource.deactivateMetadata.deactivationReason),
deactivatedOnDate: getString(resource.deactivateMetadata.deactivatedOnDate),
deactivatedBy: getString(resource.deactivateMetadata.deactivatedBy),
}
: null
return {
id: getString(resource.id),
name: getString(resource.name),
description: getString(resource.description),
severity: getString(resource.severity),
vulnerabilityType: getString(resource.vulnerabilityType),
integrationId: getString(resource.integrationId),
targetId: getString(resource.targetId),
packageIdentifier: getString(resource.packageIdentifier),
cvssSeverityScore: getNumber(resource.cvssSeverityScore),
scannerScore: getNumber(resource.scannerScore),
isFixable: getBoolean(resource.isFixable),
fixedVersion: getString(resource.fixedVersion),
remediateByDate: getString(resource.remediateByDate),
firstDetectedDate: getString(resource.firstDetectedDate),
sourceDetectedDate: getString(resource.sourceDetectedDate),
lastDetectedDate: getString(resource.lastDetectedDate),
scanSource: getString(resource.scanSource),
externalURL: getString(resource.externalURL),
relatedVulns: getStringArray(resource.relatedVulns),
relatedUrls: getStringArray(resource.relatedUrls),
deactivateMetadata,
}
}