首页
/ Trivy 贡献指南:为现有云服务商(Provider)新增 Service 支持(以 AWS CodeBuild 为例)

Trivy 贡献指南:为现有云服务商(Provider)新增 Service 支持(以 AWS CodeBuild 为例)

2026-09-05 10:15:24作者:尤辰城Agatha

本文为 Trivy IaC 检查体系贡献者指南的一部分,讲解如何为已有的云服务商(如 AWS)新增一个 Service(云服务)支持。读完本文,你将掌握:如何在 Provider 目录中定义承载扫描目标的数据结构(struct)、如何利用 iacTypes 包装类型保留资源的文件/行号元数据、如何编写 Terraform/CloudFormation 等 IaaS 到该结构的 Adapter,以及如何用 mage 命令自动生成并校验 Rego Schema。

什么是 Service,为什么需要新增

在 Trivy 的 IaC 误配置检查体系中,"service" 指的是云服务商(cloud provider)提供的一项服务,例如 AWS 的 RDS、S3、CodeBuild 等。所有已支持的服务定义都位于 pkg/iac/providers 目录中。

当你要为某个云服务写 Rego 检查(checks)时,首先要确认该 provider 下是否已经有目标 service;如果没有,就需要按本文的流程为其添加支持。这一步是后续编写内置检查(如 builtin.aws.rds.aws0176 这类规则)的前提——检查的 input 就是这些 service 结构体经 JSON 序列化后的 Schema。新增一个 service 需要两件事:

  1. 一个数据结构(struct):用于存放待扫描资源的属性信息;
  2. 一个或多个 Adapter:把各类扫描目标(Terraform、CloudFormation、Ansible 等)的原始输入转换成上述数据结构。

前置条件:确认服务尚未被支持

开始之前,请先检查 pkg/iac/providers 下目标 provider 的 struct 中是否已经包含你要添加的 service。以 AWS 为例,pkg/iac/providers/aws/aws.go 定义了 AWS 聚合结构,其中每个字段对应一个已支持的服务:

type AWS struct {
	Meta           Meta
	AccessAnalyzer accessanalyzer.AccessAnalyzer
	APIGateway     apigateway.APIGateway
	Athena         athena.Athena
	Cloudfront     cloudfront.Cloudfront
	CloudTrail     cloudtrail.CloudTrail
	CloudWatch     cloudwatch.CloudWatch
	CodeBuild      codebuild.CodeBuild
	Config         config.Config
	// ... 还有 DocumentDB、DynamoDB、EC2、ECR、ECS、EKS、IAM、KMS、
	// Lambda、RDS、Redshift、S3、SAM、SNS、SQS、SSM、WorkSpaces 等
}

从源码结构看,AWS struct 的字段命名基本就是各 service 的包名(如 CodeBuild codebuild.CodeBuildRDS rds.RDS)。如果你的目标服务不在其中,就可以继续下面的流程。

步骤一:在 provider 目录下创建 service 的数据结构

以给 AWS 添加 CodeBuild 服务为例。第一步是在 provider 目录下为新服务创建独立的子目录和文件,即 pkg/iac/providers/aws/codebuild/codebuild.go

被扫描的输入是用户配置并希望检测误配置的 CodeBuild 资源,因此需要定义一个顶层 struct 来承载它:

type CodeBuild struct {
	Projects []Project
}

CodeBuild 服务管理的是 Project 资源,因此再定义 Project struct 保存每个 Project 的属性;而 Project 又管理 ArtifactSettings

type Project struct {
	Metadata                  iacTypes.Metadata
	ArtifactSettings          ArtifactSettings
	SecondaryArtifactSettings []ArtifactSettings
}

type ArtifactSettings struct {
	Metadata          iacTypes.Metadata
	EncryptionEnabled iacTypes.BoolValue
}

以上正是仓库中 codebuild.go 的完整定义。其中有两个值得深入理解的 Trivy 约定:

1. 每个资源都内嵌 iacTypes.Metadata

iacTypes.Metadata 被嵌入到所有 Trivy 资源类型中,为每个资源提供一套统一的元数据,包括该资源定义所在的文件路径、行号以及资源名称(定义见 pkg/iac/types/metadata.go)。这保证了扫描报告能够精确指回 IaC 源码中的具体位置。

2. 用 iacTypes 包装类型代替裸的 string/bool

例如 ArtifactSettings 中,Project 可以有名称、也可以可选地开启加密,但这里没有直接使用 stringbool,而是使用 Trivy 类型 iacTypes.MetadataiacTypes.BoolValue。这些类型(如 pkg/iac/types/bool.gopkg/iac/types/string.go)对原始值进行包装,并额外携带"这个值是否由用户显式设置""值定义在哪个文件的哪一行"等元数据。

这一点在实际 Adapter 中体现得非常清楚。看 pkg/iac/adapters/terraform/aws/codebuild/adapt.go

project := codebuild.Project{
	Metadata: resource.GetMetadata(),
	ArtifactSettings: codebuild.ArtifactSettings{
		Metadata:          resource.GetMetadata(),
		EncryptionEnabled: types.BoolDefault(true, resource.GetMetadata()),
	},
	// ...
}

artifacts 块显式设置了 encryption_disabled = true 时,Adapter 会写入 types.Bool(false, ...)(有明确来源);而未显式设置时则回退为 types.BoolDefault(true, ...)(默认值)。从源码结构看,Rego 检查可以据此区分"用户明确关闭了加密"和"默认行为",从而减少误报。编写新的 service struct 时,建议参考 pkg/iac/providers 目录下的其他 provider 与 service,保持同样的命名与结构风格。

把新 service 注册到 provider struct

最后,在 provider 的聚合 struct 中引用你的新 service。对 AWS 而言,就是在 pkg/iac/providers/aws/aws.go 中添加字段并引入对应包:

type AWS struct {
	...
	CodeBuild codebuild.CodeBuild
	...
}

步骤二:更新各 IaaS 的 Adapters

新增 service 后,需要更新所有会填充该 provider struct 的 adapter(位于 pkg/iac/adapters 目录)。以"为 Terraform 添加 CodeBuild 支持"为例,需要新增 pkg/iac/adapters/terraform/aws/codebuild/adapt.go,其核心调用链为:

func Adapt(modules terraform.Modules) codebuild.CodeBuild {
	return codebuild.CodeBuild{
		Projects: adaptProjects(modules),
	}
}

func adaptProjects(modules terraform.Modules) []codebuild.Project {
	var projects []codebuild.Project
	for _, module := range modules {
		for _, resource := range module.GetResourcesByType("aws_codebuild_project") {
			projects = append(projects, adaptProject(resource))
		}
	}
	return projects
}

Adapter 的工作模式是:遍历所有 Terraform module,按资源类型名(如 aws_codebuild_project)取出资源块,再逐字段映射到 service struct,并附带 GetMetadata() 记录文件/行号信息。

编写 Adapter 时请注意:

  • 对照官方 IaC 资源的文档来理解各字段的语义。例如 CodeBuild 应参考 Terraform AWS Provider 中 aws_codebuild_project 资源文档的字段定义(如 artifacts 块的 typeencryption_disabled 等);
  • 为每个 Adapter 编写测试:仓库中同目录下的 adapt_test.go 就是配套测试,覆盖了 artifacts 块存在/缺失、secondary_artifacts 等多个输入场景;
  • 如果该 provider 同时支持 CloudFormation、Ansible 等输入源,对应地也要更新 pkg/iac/adapters 下相应输入源(如 cloudformation/aws/...)的 adapter。

步骤三:生成并校验 Rego Schema

service 添加到 provider 后,还需要把它纳入 provider 的 Schema——Rego 检查正是通过 # METADATA 中的 schemas: input: schema["aws"] 将输入映射到具体的 provider/service 对象(详见 docs/community/contribute/checks/overview.md)。

这一过程已通过 mage 命令自动化。在 Trivy 仓库根目录执行:

mage schema:generate
mage schema:verify

从源码看,这两个目标最终会执行 magefiles/schema.go 中的逻辑(由 magefile.go-tags=mage_schema 构建方式驱动):

  • schema:generate 调用 schemas.Build() 基于 Go 结构反射构建出完整的 IaC Schema,将其 JSON 序列化后写入 pkg/iac/rego/schemas/cloud.json
  • schema:verify 则重新构建 Schema 并与已提交的 cloud.json 逐字节比对,若不一致会提示 schema is out of date: please run 'mage schema:generate' and commit the changes

因此完整的贡献流程是:定义 service struct → 注册到 provider → 编写各输入源的 Adapter 与测试 → mage schema:generate → 提交时运行 mage schema:verify 确保 Schema 已同步

小结

为 Trivy 现有 provider 添加新 service 的三步走:

步骤 关键产物 参考路径
1. 定义数据结构 service struct + iacTypes.Metadata/BoolValue 等包装类型,并注册进 provider struct pkg/iac/providers/aws/codebuild/codebuild.gopkg/iac/providers/aws/aws.go
2. 编写 Adapter 将 Terraform/CloudFormation 等资源块映射为 service struct,配套测试 pkg/iac/adapters/terraform/aws/codebuild/adapt.go
3. 生成 Schema mage schema:generate / mage schema:verify 维护 pkg/iac/rego/schemas/cloud.json magefiles/schema.go

完成以上步骤后,该 service 即可作为 Rego 检查的输入,供社区在 docs/community/contribute/checks/overview.md 所述的流程中编写具体的安全规则。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
528
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
982
503
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384