snyk/snyk-ls
GitHub: snyk/snyk-ls
Snyk 官方的语言服务器实现,通过 LSP 协议为 IDE 提供实时的开源漏洞、代码安全、IaC 风险和密钥泄露检测后端服务。
Stars: 79 | Forks: 15
# Snyk Language Server (Snyk-LS)
[](https://github.com/snyk/snyk-ls/actions/workflows/build.yaml)
[](https://github.com/snyk/snyk-ls/actions/workflows/release.yaml)
[](CODE_OF_CONDUCT.md)
## 支持的功能
该语言服务器遵循
[Language Server Protocol](https://microsoft.github.io/language-server-protocol/specifications/specification-current/)
并集成了 Snyk Open Source、Snyk Infrastructure as Code、Snyk Code 和 Snyk Secrets。对于 Open Source 和 IaC,它使用 Snyk CLI 作为数据提供者;Snyk Code 使用 Snyk Code API;Secrets 扫描在适用时使用 CLI。
目前,该语言服务器支持以下操作:
- 如果文档是当前文件夹集的一部分,则在打开文档时向客户端发送诊断信息。
- 在启动时开始文件夹扫描并发送诊断信息。
- 根据命令开始所有文件夹的工作区扫描。
- 缓存诊断信息,直到保存或触发新的工作区扫描。
- 保存文档时使缓存失效并重新获取已保存文档的诊断信息。
- 提供范围计算,以在其文件中正确高亮显示 Snyk Open Source 问题。
- 提供带有诊断详细信息和后续链接的格式化悬停提示
- 向客户端报告后台作业的进度
- 向客户端发送通知和日志消息
- 需要时进行身份验证,使用 OAuth2 或 Token 身份验证,并在必要时打开网页
- 如果在打开网页时遇到问题,将身份验证 URL 复制到剪贴板
- 如果找不到或未配置 Snyk CLI,则自动下载到 XDG_DATA_HOME
- 根据传输的设置选择性激活产品
- 扫描错误将作为诊断信息报告给 Language Server Client
- Code Lenses 用于在编辑器内导航 Snyk Code 数据流
- 用于编辑器内命令的 Code Actions,例如打开浏览器、执行快速修复或打开 Snyk Learn 课程
针对发现的诊断
### 已实现的操作
### Language Server Protocol 支持
#### 请求
- initialize
- exit
- textDocument/codeAction
- textDocument/codeLens
- textDocument/didClose
- textDocument/didSave
- textDocument/hover
- textDocument/inlineValue
- shutdown
- workspace/didChangeWorkspaceFolders
- workspace/didChangeConfiguration
- workspace/executeCommand
- window/workDoneProgress/create (从服务器 -> 客户端)
- window/showMessageRequest
- window/showDocument
#### 通知
- $/progress
- $/cancelRequest
- textDocument/publishDiagnostics
- params: `types.PublishDiagnosticsParams`
- 示例: Snyk Open Source
{
"uri": "file:///path/to/file",
"diagnostics": [
{
"range": {
"start": { "line": 1, "character": 0 },
"end": { "line": 2, "character": 0 },
},
"severity": 1,
"code": "S100",
"source": "Snyk",
"message": "Message",
"tags": ["security"],
"data": {
"id": "123",
"issueType": "vulnerability",
"packageName": "packageName",
"packageVersion": "packageVersion",
"issue": "issue",
"additionalData": {
"ruleId": "ruleId",
"identifiers": {
"cwe": ["cwe"],
"cve": ["cve"]
},
"description": "description",
"language": "language",
"packageManager": "packageManager",
"packageName": "packageName"
}
}
}
]
}
- 示例: Snyk Code
{
"uri": "file:///path/to/file",
"diagnostics": [
{
"range": {
"start": { "line": 1, "character": 0 },
"end": { "line": 2, "character": 0 },
},
"severity": 1,
"code": "S100",
"source": "Snyk",
"message": "Message",
"tags": ["security"],
"data": {
"id": "123",
"filePath": "filePath",
"range": {
"start": { "line": 1, "character": 0 },
"end": { "line": 2, "character": 0 },
},
"additionalData": {
"message": "message",
"rule": "rule",
"ruleId": "ruleId",
"dataFlow": [
{
"filePath": "filePath",
"range": {
"start": { "line": 1, "character": 0 },
"end": { "line": 2, "character": 0 },
},
}
],
"cwe": "cwe",
"isSecurityType": true
}
}
}
]
}
- window/logMessage
- window/showMessage
### Language Server Protocol 的自定义扩展(服务器 -> 客户端)
- SDKs 回调,用于从客户端检索已配置的 SDKs
- 方法:`workspace/snyk.sdks`
- 参数:`types.WorkspaceFolder`
- 示例:
[{
"type": "java", // 或 python 或 go
"path": "/path/to/sdk" // Java 对应 JAVA_HOME,Go 对应 GOROOT,Python 对应 Python 可执行文件
}]
- 配置通知(协议 v25+)
- 方法:`$/snyk.configuration`
- 参数:`types.LspConfigurationParam`
- 注意:统一的基于映射的协议 — 全局设置 + 每个文件夹的设置,每个设置包含 value、source、origin 和 lock 状态
- 示例:
{
"settings": {
"api_endpoint": { "value": "https://api.snyk.io", "source": "global" },
"snyk_oss_enabled": { "value": true, "source": "ldx-sync", "originScope": "organization" },
"proxy_http": { "value": "http://proxy:8080", "source": "ldx-sync-locked", "originScope": "tenant", "isLocked": true }
},
"folderConfigs": [
{
"folderPath": "/path/to/project",
"settings": {
"base_branch": { "value": "main", "source": "folder" },
"preferred_org": { "value": "org-id", "source": "folder" },
"snyk_code_enabled": { "value": false, "source": "ldx-sync-locked", "originScope": "group", "isLocked": true },
"enabled_severities": { "value": ["critical", "high"], "source": "ldx-sync", "originScope": "organization" }
}
}
]
}
- IDE→LS 使用 `changed: true` 表示 PATCH 语义:`{"snyk_oss_enabled": {"value": true, "changed": true}}`
- 自定义发布诊断通知
- 方法:`$/snyk.publishDiagnostics316`
- 参数:`types.PublishDiagnosticsParams`
- 注意:textDocument/publishDiagnostics 的别名
- 身份验证通知
- 方法:`$/snyk.hasAuthenticated`
- 参数:`types.AuthenticationParams`
- 示例:
{
"token": "the snyk token", // 这可以是一个 oauth2.Token 字符串或传统令牌
"apiUrl": "https://api.snyk.io"
}
- 请参阅 https://pkg.go.dev/golang.org/x/oauth2@v0.6.0#Token 了解有关 oauth 令牌的更多详细信息。
- CLI 路径通知
- 方法:`$/snyk.isAvailableCli`
- 参数:`types.SnykIsAvailableCli`
- 示例:
{
"cliPath": "/a/path/to/cli-executable"
}
- 受信任文件夹通知
- 方法:`$/snyk.addTrustedFolders`
- 参数:`types.SnykTrustedFoldersParams`
- 示例:
{
"trustedFolders": ["/a/path/to/trust"]
}
- 扫描通知
- 方法:`$/snyk.scan`
- 参数:`types.ScanParams`
- 示例:成功扫描
{
"status": "success", // 可能的值:"error", "inProgress", "success"
"product": "code", // 可能的值:"code", "oss", "iac", "secrets"
"folderPath": "/a/path/to/folder",
}
- 示例:扫描失败并带有错误
{
"status": "error",
"product": "code",
"folderPath": "/a/path/to/folder",
"presentableError": {
"cliError": {
"code": "CLI_ERROR_CODE",
"error": "An error occurred"
},
"showNotification": true,
"treeNodeSuffixError": "(failed)"
}
}
- 摘要面板状态通知
- 方法:`$/snyk.scanSummary`
- 参数:`types.ScanSummary`
- 示例:
{
"scanSummary": " Summary "
}
- 注册 MCP 通知
- 方法:`$/snyk.registerMcp`
- 参数:`types.SnykRegisterMcpParams`
- 示例:
{
"command": "/path/to/cli",
"args": [ "mcp", "-t", "stdio" ],
"env": {
"ENV1": "value1",
"ENV2": "value2"
}
}
### 命令
- `NavigateToRangeCommand` 导航客户端到给定的范围
- command: `snyk.navigateToRange`
- args: `path`, `Range`
- `WorkspaceScanCommand` 触发所有工作区文件夹的扫描
- command: `snyk.workspace.scan`
- args: 空
- `WorkspaceFolderScanCommand` 触发给定工作区文件夹的扫描
- command: `snyk.workspaceFolder.scan`
- args: `path`
- `OpenBrowserCommand` 在默认浏览器中打开给定的 URL
- command: `snyk.openBrowser`
- args: `URL`
- `LoginCommand` 触发登录过程
- command: `snyk.login`
- args: 可选 `[authMethod, endpoint, insecure]` — 例如 `["oauth", "https://api.snyk.io", false]`(参见配置 HTML bridge);省略的参数将使用当前设置
- `CopyAuthLinkCommand` 将身份验证 URL 复制到剪贴板
- command: `snyk.copyAuthLink`
- args: 空
- `LogoutCommand` 触发登出过程
- command: `snyk.logout`
- args: 空
- `TrustWorkspaceFoldersCommand` 检查受信任的工作区文件夹,并在必要时请求信任
- command: `snyk.trustWorkspaceFolders`
- args: 空
- `OpenLearnLesson` 在 Snyk Learn 网站上打开给定的课程
- command: `snyk.openLearnLesson`
- args:
- `rule string`
- `ecosystem string`
- `cwes string` (以逗号分隔),例如 `CWE-79,CWE-89`
- `cves string` (以逗号分隔),例如 `CVE-2018-11776,CVE-2018-11784`
- `issueType int`
PackageHealth Type = 0
CodeSecurityVulnerability = 1
LicenceIssue = 2
DependencyVulnerability = 3
InfrastructureIssue = 4
- `GetLearnSession` 返回 Snyk Learn 网站上的给定课程
- command: `snyk.getLearnLesson`
- args:
- `rule string`
- `ecosystem string`
- `cwes string` (以逗号分隔),例如 `CWE-79,CWE-89`
- `cves string` (以逗号分隔),例如 `CVE-2018-11776,CVE-2018-11784`
- `issueType int`
PackageHealth Type = 0
CodeSecurityVulnerability = 1
LicenceIssue = 2
DependencyVulnerability = 3
InfrastructureIssue = 4
- result: 课程 JSON
{
"lessonId": "123",
"datePublished": "2022-01-01",
"author": "John Doe",
"title": "Introduction to Golang",
"subtitle": "A beginner's guide to Golang",
"seoKeywords": ["Golang", "Programming", "Beginner"],
"seoTitle": "Learn Golang",
"cves": ["CVE-2022-1234", "CVE-2022-5678"],
"cwes": ["CWE-123", "CWE-456"],
"description": "This lesson provides an introduction to Golang for beginners"ecosystem": "Programming",
"rules": ["Rule 1", "Rule 2", "Rule 3"],
"slug": "golang-intro",
"published": true,
"url": "https://example.com/golang-intro",
"source": "Example.com",
"img": "https://example.com/images/golang-intro.png"
}
- `SettingsSastEnabled` 触发 API 调用以检查 Snyk Code 是否已启用
- command: `snyk.getSettingsSastEnabled`
- args: 空
- 返回 `*sast_contract.SastResponse`,如果发生错误则返回错误和 false
- `GetActiveUser` 触发 API 调用以获取当前登录的活动用户,如果未登录则返回错误
- command: `snyk.getActiveUser`
- args: 空
- 返回活动用户及其组织和组,如果未登录则返回错误。
{
"id": "123",
"username": "johndoe",
"orgs": [
{
"name": "org1",
"id": "org1_id",
"group": {
"name": "group1",
"id": "group1_id"
}
}
],
}
- `Code Fix Command` 触发自动修复并应用第一个建议的更改
- command: `snyk.code.fix`
- args:
- `codeActionId` string
- `AffectedFilePath` string
- `range` Range
- 如果不成功则返回错误
- `Code Fix Diffs` 允许检索自动修复建议的差异
- command: `snyk.code.fixDiffs`
- args:
- issueID string (UUID)
- 返回建议数组:
[{
"fixId": "123",
"unifiedDiffsPerFile": {
"path/to/file": "diff"
}
}]
- Diff 示例:
--- /var/folders/vn/77lwfy3974g7vykcm5lr6mkh0000gn/T/Test_SmokeWorkspaceScanOssAndCode952013010/001/1
+++ /var/folders/vn/77lwfy3974g7vykcm5lr6mkh0000gn/T/Test_SmokeWorkspaceScanOssAndCode952013010/001/1-fixed
@@ -32,7 +32,8 @@
test('should set success to OK upon success', function() {
// GIVEN
- comp.password = comp.confirmPassword = 'myPassword';
+ comp.password = process.env.TEST_PASSWORD;
+ comp.confirmPassword = process.env.TEST_PASSWORD;
// WHEN
comp.changePassword();
- `Code Fix Apply Edit Command` 触发自动修复并应用第一个建议的更改
- command: `snyk.code.fixApplyEdit`
- args:
- `fixId` string
- 返回一个 WorkspaceEdit:
- `Feature Flag Status Command` 触发 API 调用以检查功能标志是否已启用
- command: `snyk.getFeatureFlagStatus`
- args:
- `featureFlagType` string
- 返回一个包含功能标志状态和可选用户消息的对象
{
"ok": true, // 指示功能是否启用的布尔值 (true 或 false)
"userMessage": "Optional message to the user" // 如果 'ok' 为 false 则存在
}
- `Clear Cache` 清除持久化缓存或内存缓存,或两者都清除。
- command: `snyk.clearCache`
- args:
- `folderUri` string,
- `cacheType` `persisted` 或 `inMemory`
- `Generate Issue Description` 以 HTML 格式生成问题描述。
- command: `snyk.generateIssueDescription`
- args:
- `issueId` string
- `Configuration Dialog` 打开包含所有 Snyk 设置的配置对话框。
- command: `snyk.workspace.configuration`
- args: 空
- 返回:包含配置对话框的 HTML 字符串
- 示例:
Snyk Configuration
...
- 有关完整的集成详细信息,请参阅[配置对话框集成指南](docs/configuration-dialog.md)。
- `Connectivity Check` 执行全面的连接诊断,包括网络检查、代理检测、身份验证和组织访问。
- command: `snyk.diagnostics.checkConnectivity`
- args: 空
- 返回:字符串(无 ANSI 颜色的格式化连接检查结果)
- 执行的检查:
- 到所有 Snyk 端点的网络连接
- 代理配置检测(包括 Kerberos 环境变量)
- 身份验证状态
- 组织访问权限
- `Directory Diagnostics` 对 Snyk 使用的目录执行目录诊断,检查存在性、可写性和 CLI 二进制文件。
- command: `snyk.diagnostics.checkDirectories`
- args: 要检查的附加目录的可选数组
[
{
"pathWanted": "/path/to/check",
"purpose": "Description of the directory purpose",
"mayContainCLI": true // 该目录是否可能包含 CLI 二进制文件
}
]
- 返回:字符串(无 ANSI 颜色的格式化目录诊断结果)
- 执行的检查:
- 当前用户信息
- 默认 Snyk 目录位置(CLI 下载、配置存储、缓存)
- LS 设置中配置的 CLI 路径
- 客户端传递的附加目录
- 对于每个目录:
- 存在性检查(如果不存在,则查找最近的现有父目录)
- 写入权限
- 找到的 Snyk CLI 二进制文件(针对可能包含 CLI 的目录)
## 安装说明
### 下载
发布工作流存储生成的可执行文件,以便可以[在这里](https://github.com/snyk/snyk-ls/releases/tag/latest)下载。只需选择您想要其构建产物的发布版本,并下载附加到其上的 zip 文件。目前,为 Windows、macOS 和 Linux 生成了可执行文件。
可以使用[此](getLanguageServer.sh) bash 脚本检索当前发布的二进制文件,请记住[协议版本](.goreleaser.yaml)是下载链接的一部分,并且可能会更改以强制插件/语言服务器同步。有关更多信息,请参阅 [CONTRIBUTING.md](CONTRIBUTING.md)。
### 从源代码构建
- 安装 [CONTRIBUTING.md](CONTRIBUTING.md) 中列出的 Go 版本(当前为 Go 1.26.x),如有需要请设置 `GOPATH` 和 `GOROOT`
- 进入此代码库的根目录
- 执行 `go get ./...` 以下载所有依赖项
- 执行 `make build && make install` 以生成 `snyk-ls` 二进制文件
## 配置
### Snyk LSP 命令行标志
`-c ` 允许指定一个要在所有其他配置之前加载的配置文件
`-f ` 允许指定日志文件而不是记录到控制台
`-l ` 允许指定日志级别(`trace`、`debug`、`info`、`warn`、`error`、`fatal`)。默认日志级别为 `info`。这可以通过设置环境变量 `SNYK_DEBUG_LEVEL` 来覆盖,例如 `export SNYK_DEBUG_LEVEL=debug`
`-licenses`(独立运行时)显示 Language Server 使用的[许可证](https://github.com/snyk/snyk-ls/tree/main/licenses)\
`--licenses`(在 Snyk CLI 中运行时)
`-o ` 允许指定问题的输出格式(`md` 或 `html`)
`-v ` 打印 Language Server 的版本
#### 配置
#### LSP 初始化选项 (协议 v25+)
作为 [Initialize 消息](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#initialize) 的一部分,
`initializationOptions` 被反序列化为 `types.InitializationOptions`(`internal/types/lsp.go`)。
**机器设置** 使用 **pflag 规范名称** 作为映射键,每个值是一个 `ConfigSetting`(`value`、可选的 `changed` 等)。只有带有 `changed: true` 的条目才会在初始化时应用(IDE 默认值不得覆盖 LDX-sync 或 GAF 默认值)。
**仅初始化元数据**(相同的 JSON 对象,顶级字段):`requiredProtocolVersion`、`deviceId`、`integrationName`、`integrationVersion`、`osPlatform`、`osArch`、`runtimeName`、`runtimeVersion`、`hoverVerbosity`、`outputFormat`、`path`、`trustedFolders`。
示例结构:
```
{
"requiredProtocolVersion": "25",
"integrationName": "VISUAL_STUDIO_CODE",
"integrationVersion": "1.0.0",
"deviceId": "00000000-0000-0000-0000-000000000000",
"path": "/usr/local/bin",
"trustedFolders": ["/safe/project"],
"settings": {
"snyk_oss_enabled": { "value": true, "changed": true },
"snyk_code_enabled": { "value": true, "changed": true },
"snyk_iac_enabled": { "value": true, "changed": true },
"api_endpoint": { "value": "https://api.snyk.io", "changed": true },
"organization": { "value": "org-slug-or-uuid", "changed": true },
"token": { "value": "secret-token", "changed": true },
"proxy_insecure": { "value": false, "changed": true },
"authentication_method": { "value": "oauth", "changed": true },
"scan_automatic": { "value": true, "changed": true },
"enabled_severities": {
"value": { "critical": true, "high": true, "medium": true, "low": true },
"changed": true
},
"issue_view_open_issues": { "value": true, "changed": true },
"issue_view_ignored_issues": { "value": false, "changed": true },
"scan_net_new": { "value": false, "changed": true },
"risk_score_threshold": { "value": 400, "changed": true },
"cli_path": { "value": "/path/to/snyk", "changed": true },
"automatic_download": { "value": true, "changed": true },
"binary_base_url": { "value": "https://downloads.snyk.io", "changed": true },
"cli_release_channel": { "value": "stable", "changed": true }
},
"folderConfigs": [
{
"folderPath": "/path/to/workspace",
"settings": {
"base_branch": { "value": "main", "changed": true },
"preferred_org": { "value": "org-id", "changed": true },
"org_set_by_user": { "value": true, "changed": true }
}
}
]
}
```
已注册的标志名称和优先级规则记录在 [docs/configuration.md](docs/configuration.md) 中。
**运行时更新** 使用带有相同负载信封的 `workspace/didChangeConfiguration`:LSP `settings` 是一个 `LspConfigurationParam`,其字段为 `settings`(映射)、`folderConfigs` 和可选的 `trustedFolders` — 请参阅 `internal/types/lsp.go` 中的 `types.DidChangeConfigurationParams`。
#### 工作区信任
作为检查代码库漏洞的一部分,Snyk 可能会在您的计算机上自动执行代码以获取用于分析的额外数据。例如,这包括调用包管理器(例如 pip、gradle、maven、yarn、npm 等)以获取 Snyk Open Source 的依赖项信息。在具有恶意配置的不受信任的代码上调用这些程序可能会使您的系统面临恶意代码执行和漏洞利用的风险。
为了防止在不信任的文件夹上使用语言服务器,我们的语言服务器在针对这些文件夹运行扫描之前会请求文件夹信任。如有疑问,请勿授予权限。
信任功能默认启用。当一个文件夹受信任时,其所有子文件夹也将受信任。在文件夹受信任后,Snyk Language Server 会通过自定义的 `$/snyk.addTrustedFolders` 通知通知 Language Server Client,其中包含当前受信任文件夹路径的列表。基于此,客户端随后可以实现逻辑以拦截此通知,并将决定和信任持久化保存在 IDE 或编辑器存储机制中。
可以通过在初始化选项中将 `enableTrustedFoldersFeature` 设置为 `false` 来禁用信任对话框。这将禁用所有信任提示和检查。
可以通过在 `initializationOptions` 中将 `trustedFolders` 设置为路径数组来提供一组初始的受信任文件夹。这些文件夹在启动时将受到信任,并且不会提示用户信任它们。
#### 环境变量
Snyk LS 和 Snyk CLI 支持并需要某些环境变量才能运行:
1. `HTTP_PROXY`、`HTTPS_PROXY` 和 `NO_PROXY` 用于定义要使用的 http 代理
2. `JAVA_HOME` 用于通过 Snyk CLI 分析基于 Java JVM 的项目
3. `PATH` 用于在分析 Maven 项目时查找 maven、查找 python 等
#### 自动配置
要自动将这些变量添加到环境中,Snyk LS 会搜索以下文件,其顺序决定了优先级。如果可执行文件不是从已配置的环境中调用的(例如通过 `zsh -i -c 'snyk-ls'`),您也可以使用 `-c` 命令行标志指定配置文件来设置上述变量。Snyk LS 按给定的优先级和顺序读取以下文件,不会覆盖已加载的变量。
```
given config file via -c flag
/.snyk.env
$HOME/.snyk.env
```
任何包含 `VARIABLENAME=VARIABLEVALUE` 格式环境变量的行,如果尚未存在,都会自动添加到环境中。这遵循 `dotenv` 格式。对于 `.profile`、`.zshrc` 等文件,如果变量是直接导出的,例如通过 `export VARIABLENAME=VARIABLEVALUE`,则不会被加载。导出语句必须单独拆分并在单独的行中,例如
```
VARIABLENAME=VARIABLEVALUE
export VARIABLENAME
```
PATH 变量的处理方式与所有其他变量不同,因为它是文件和环境中找到的所有 PATH 变量的聚合。此外,当前工作目录 `.` 会自动添加到路径中,因此通过 LSP 客户端将 Snyk CLI 下载到当前工作目录将使 Language Server 能够找到 Snyk CLI。
除了通过配置文件配置变量外,Snyk LS 还会在 Linux 和 macOS 上将以下目录添加到路径中:
- /bin
- $HOME/bin
- /usr/local/bin
- $JAVA_HOME/bin
如果未设置 JAVA_HOME,它会首先在路径中自动搜索 Java 可执行文件,然后在以下目录中搜索,并将其父目录的父目录添加为 JAVA_HOME。将递归搜索以下目录:
- /usr/lib
- /usr/java
- /opt
- /Library
- $HOME/.sdkman
- C:\Program Files
- C:\Program Files (x86)
同样的目录也会被搜索 Maven 可执行文件,并将其父目录添加到路径中。
#### Snyk CLI
要查找自动管理的 Snyk CLI,
会自动扫描 [XDG Data Home](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html#variables)
和 `PATH` 路径以查找依赖操作系统的文件,例如 macOS 上的 `snyk-macos`,Linux 上的 `snyk-linux` 和 Windows 上的 `snyk-win.exe`,找到它的第一个路径会被添加到环境中。
稍后它将用于所有依赖 CLI 的功能。
#### 全局设置环境变量
如果您希望环境变量在系统范围内可用,您需要将变量添加到 `/etc/environment` 或在 macOS 上添加到 `/etc/launchd.conf`,或者在 shell 脚本中通过 `launchctl` 设置它们。前两个位置会被 snyk lsp 自动读取。在 Windows 上,可以通过 UI 为用户或系统范围定义用户变量。在像 `~/.profile` 这样的文件中,它看起来像这样:
```
SNYK_TOKEN=
DEEPROXY_API_URL=https://deeproxy.snyk.io/
# 导出变量,但请确保 export 不与变量定义在同一行
export SNYK_TOKEN
export DEEPROXY_API_URL
```
#### Snyk 身份验证
Snyk LS 身份验证流程会自动进行,除非在配置中被禁用,其过程如下。当 Snyk Language Server 启动时,它会:
- 如果端点是 snykgov.io 端点,或者 authenticationMethod 设置为 `oauth`,它将通过 OAuth2 进行身份验证。这将打开一个浏览器窗口。
- 如果身份验证方法不是 `oauth`,它会尝试使用 Snyk CLI token 身份验证来检索 token。
- 如果 CLI 也未经过身份验证,它会打开一个浏览器窗口进行身份验证
- 如果在打开浏览器窗口时遇到问题,可以将身份验证 URL 复制到剪贴板(通过实现 `snyk.copyAuthLink`)。_请注意,Linux/Unix 用户需要安装 `xsel` 或 `xclip` 才能使用此功能。_
在 Web 浏览器中成功进行身份验证后,Snyk Language Server 会自动检索 Snyk 身份验证凭据,并将其用于后续请求。
## 运行测试
```
go test ./...
```
如果您在运行 pact 时遇到任何问题,请扩展您的 PATH 环境变量。
例如:
```
PATH=$PATH:$PWD/.bin/pact/bin make test
```
输出应如下所示(它针对 Snyk Code API 运行并使用真实的 CLI):
```
? github.com/snyk/snyk-ls [no test files]
ok github.com/snyk/snyk-ls/code 24.201s
ok github.com/snyk/snyk-ls/diagnostics 26.590s
ok github.com/snyk/snyk-ls/iac 25.780s
? github.com/snyk/snyk-ls/lsp [no test files]
ok github.com/snyk/snyk-ls/oss 22.427s
ok github.com/snyk/snyk-ls/server 48.558s
ok github.com/snyk/snyk-ls/util 9.562s
```
## 在本地测试 Github Action
您可以使用 [act](https://github.com/nektos/act) 在本地测试 github actions。
### 安装 act 及前置条件
```
brew install act
# 如果您没有 docker desktop,可以使用 minikube(一个单节点 kubernetes 发行版)
brew install --cask virtualbox # you need to enable the virtualbox extension in macOS settings
brew install minikube
minikube start
eval $(minikube docker-env) # gives you a fully functional docker environment
```
### 运行 act
```
act --secret SNYK_TOKEN=$SNYK_TOKEN --secret DEEPROXY_API_URL=$DEEPROXY_API_URL
```
标签:DevSecOps, EVTX分析, Go语言, IaC安全, IDE插件, Language Server Protocol, LSP, OAuth2认证, SAST, secrets扫描, Snyk, VS Code, WebSocket, 上游代理, 代码安全, 依赖分析, 后台扫描, 基础设施即代码安全, 安全合规, 开发安全, 批量测试, 日志审计, 漏洞枚举, 盲注攻击, 程序破解, 网络代理, 诊断提示, 语言服务器, 跨平台工具, 集成开发环境, 静态应用安全测试