可信云原生软件供应链(Software Supply Chain) - Grafeas项目调研

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
简介: >> 99%的软件实现都是CRUD, 但有些CRUD还是能玩出花来的。 背景 Grafeas, 希腊语中Scribe(抄写员)的意思,是Google在2017年联合多家厂商发起的开源项目,希望可以定义一套统一的的方法来审计和管理软件供应链,具体的背景可以阅读「安全交付:GCP 的安全软件供应链」 如上图所示,所谓的软件供应链,可以大抵等同于从源码到发布物的整条流水线。感谢

>> 99%的软件实现都是CRUD, 但有些CRUD还是能玩出花来的。

背景

Grafeas, 希腊语中Scribe(抄写员)的意思,是Google在2017年联合多家厂商发起的开源项目,希望可以定义一套统一的的方法来审计和管理软件供应链,具体的背景可以阅读「安全交付:GCP 的安全软件供应链」

如上图所示,所谓的软件供应链,可以大抵等同于从源码到发布物的整条流水线。感谢区块链的科普,大家对于可信供应链的概念倒也不算陌生,一盒在超市里售卖的鸡蛋通过区块链可以回溯到下蛋的母鸡,然后孵出母鸡的蛋,然后找到下了那个蛋的母鸡,如此循环,一直到堆栈溢出...

言归正传,首先Grafeas不是区块链技术,官方称为「A Component Metadata API」。解释之前先描述一个实际例子, 笔者在Google的时候也维护着MySQL和PostgreSQL的分支以及其包含的一众第三方依赖,时不时的就会被系统分配到一个bug,说某个CVE影响到了当前代码仓库里的MySQL版本,要去修复。可以发现系统要做到这样的通知需要一些信息:

  • 代码仓库里的MySQL版本号
  • 针对当前MySQL的CVE信息
  • 以及当前MySQL的维护者

基本上各公司的安全扫描系统都会存类似信息,没什么太特别的,只是说每家都搞了一套自己的罢了,Google内部一套,JFrog一套,阿里也是自己一套,诸如此类。这时候,还是Google先站了出来,继续奉行标准先行,API先行的策略,推出了Grafeas想来统一一下这套数据模型。这个项目起于2017年, 3年过去了,还是不温不火的状态,Github星星数还没上千,当然这和软件供应链本身就是个小众领域也有关系。不过笔者相信软件供应链,尤其是可信安全这块接下来会受到越来越多的关注,有这么几个原因 :

  • 随着持续集成以及微服务成为主流,我们发布软件的频率极速上升。
  • 随着应用越来越复杂,以及开源的趋势,一个应用依赖了越来越多的三方依赖。
  • 随着应用基本功能的日趋完善同质化,诸如安全/合规类的特性会成为竞争关键点。

代码走读

模型和API

至于Grafeas这个项目,我个人还是比较看好的,主要是因为它的数据建模比较合理。Grafeas里最核心的两个概念叫做NoteOccurence, 其中Note记录了某种分析类型的具体实例,比如某一个具体的CVE就可以作为Vulnerability分析类型的一个实例。而Occurrence记录了针对某一个具体Note实例,在某个特定资源上发现的情况。拿之前MySQL的例子来说,如果MySQL某个版本曝出了某个CVE,这个CVE就是一个Note实例。而基于这个MySQL版本所打的镜像资源就会出现一个Occurrence,记录这个镜像有这么一个CVE。

目前Note的类型有这么些

oneof type {

   // A note describing a package vulnerability.

   grafeas.v1.VulnerabilityNote vulnerability = 10;

   // A note describing build provenance for a verifiable build.

   grafeas.v1.BuildNote build = 11;

   // A note describing a base image.

   grafeas.v1.ImageNote image = 12;

   // A note describing a package hosted by various package managers.

   grafeas.v1.PackageNote package = 13;

   // A note describing something that can be deployed.

   grafeas.v1.DeploymentNote deployment = 14;

   // A note describing the initial analysis of a resource.

   grafeas.v1.DiscoveryNote discovery = 15;

   // A note describing an attestation role.

   grafeas.v1.AttestationNote attestation = 16;

   // A note describing available package upgrades.

   grafeas.v1.UpgradeNote upgrade = 17;

 }

Occurence也有与之对应的

 // Required. Immutable. Describes the details of the note kind found on this

 // resource.

 oneof details {

   // Describes a security vulnerability.

   grafeas.v1.VulnerabilityOccurrence vulnerability = 8;

   // Describes a verifiable build.

   grafeas.v1.BuildOccurrence build = 9;

   // Describes how this resource derives from the basis in the associated

   // note.

   grafeas.v1.ImageOccurrence image = 10;

   // Describes the installation of a package on the linked resource.

   grafeas.v1.PackageOccurrence package = 11;

   // Describes the deployment of an artifact on a runtime.

   grafeas.v1.DeploymentOccurrence deployment = 12;

   // Describes when a resource was discovered.

   grafeas.v1.DiscoveryOccurrence discovery = 13;

   // Describes an attestation of an artifact.

   grafeas.v1.AttestationOccurrence attestation = 14;

   // Describes an available package upgrade on the linked resource.

   grafeas.v1.UpgradeOccurrence upgrade = 15;

 }

Occurrence中这样把资源和Note关联起来

 // Required. Immutable. A URI that represents the resource for which the

 // occurrence applies. For example,

 // `https://gcr.io/project/image@sha256:123abc` for a Docker image.

 string resource_uri = 2;

 // Required. Immutable. The analysis note associated with this occurrence, in

 // the form of `projects/[PROVIDER_ID]/notes/[NOTE_ID]`. This field can be

 // used as a filter in list requests.

 string note_name = 3;

 // Output only. This explicitly denotes which of the occurrence details are

 // specified. This field can be used as a filter in list requests.

 grafeas.v1.NoteKind kind = 4;

如果要继续探寻模型,寻着上面这些一路看下去就可以。目前的API版本是v1, 关键的数据模型相对于之前v1beta1增加了Upgrade这个类别,总体上模型比较稳定,体现了Google一贯在数据建模上的老道,这也来源于工程实践的积累。

除了最核心的建模之外,核心的Grafeas API设计也比较严谨,虽然只是普通的CRUD,但也是教科书般的grpc接口设计

  1. 命名的规范一致性,Get/List/Delete/Update/Create/BatchCreate, 其中Get/Delete/Update/Create针对单条操作用的是名词的单数形式,List/BatchCreate针对多条操作用的是复数形式。
  2. enum和anyof type的配对使用分别体现在Note以及Occurrence的枚举中。
  3. List接口采用page_token的形式。
  4. Update接口使用google.protobuf.FieldMask。

还有一个值得一提的是List请求里的filter字段,用的也是Google自己开源的Common Expression Language(CEL)。不过目前代码里还没有真正实现filter的功能,在storage这层是被无视掉的。

一些可改进点

整体的代码结构比较简单,虽然项目是2017年开始的,但是开发活跃度不是很高,主要还是几个Google Cloud的工程师在参与。

API

可以探讨的一个点是Grafeas服务本身是个monolithic service,包含了note和occurrence两个服务,comment中其实已经说:

// Analysis results are stored as a series of occurrences. An `Occurrence`

// contains information about a specific analysis instance on a resource. An

// occurrence refers to a `Note`. A note contains details describing the

// analysis and is generally stored in a separate project, called a `Provider`.

// Multiple occurrences can refer to the same note.

分离的话可以有更好的separation of concerns。还有在运行态,occurrence无论从调用频次还是重要性应该都高于note。比如在每次应用准入的时候,必然会调用occurrence接口校验应用镜像是否符合规范,显然如果occurrence服务这个时候挂了,要么应用无法启动,要么服务降级,暴露风险到线上。

功能

除了上文提到的filter,还有不少功能没有实现,比如看初始化grpcServer的地方,Auth, Filter, Logger均没有实现

 g := grafeas.API{

 Storage:           *db,

 Auth:              &grafeas.NoOpAuth{},

 Filter:            &grafeas.NoOpFilter{},

 Logger:            &grafeas.NoOpLogger{},

 EnforceValidation: true,

}

持久层

如前所示,持久层做了一层Storage接口的抽象,目前实现了基于内存的memstore, 基于BoltDB的embeddedstore, 以及基于PostgreSQL的pgsqlstore。从目前的代码看,storage的整体节奏有点问题,一方面embeddedstore如果选择sqlite的话,应该可以在写的时候做到和pgsqlstore更多的代码复用,抽象出更好的针对关系数据库的接口,方便对接mysql/oceanbase这些。另一方面,选择PostgreSQL,其实是不错的选择,但是没有利用上PostgreSQL的独特功能,可能有兼容性考虑,但还是有暴殄天物之感,例如:

  • 直接是把Note/Occurrenence序列化下存的, 没有使用PostgreSQL强大的JSON功能。然后使用了Text而不是二进制类型bytea。
  • 既然是存了个Blob, 相应的也就无法用到PostgreSQL的ENUM类型。
  • 也没有选择放在单独的schema里面,目前几张表名projects/notes/occurrences/operations还是容易引起名字冲突的。

当然因为模型比较简单,storage层对接个区块链应该也不是太难的问题。

扩展性

毕竟是Google的作品,还是带着Google的烙印,例如project应该就是源自Google Cloud的project概念,目前的deployment note也只支持Google Cloud的GKE和App Engine Flex。

整个项目在扩展性方面还没有太好的规划,比如没有引入any.proto以及配套的插件体系,使得在添加Note类型时需要直接修改核心代码。不过这个更可能是项目本身的克制,还在确定稳定的核心模型。另外还有一个核心扩展点在于提供Analysis的框架,帮助vendor可以更好把各种notes/occurrences集成进来。

集成

目前看到大厂里,Grafeas只集成进了Google Cloud自家的Container Analysis以及JFrog XRay里。像通过插件机制集成到Jenkins里,集成到Gitlab里还停留在Feature Request阶段。

总结

总的来说Grafeas这个项目还有不少工作要做,但是对于最核心的部分,软件供应链建模以及相对应的API,项目设计得比较妥当,担得上「A Component Metadata API」这个称号。这个感觉类似于Google在CI/CD云原生领域的Tekton项目,同样是靠出色的建模脱颖而出。而且有意思的是这两个项目都出自Google,而不是垂直行业里的老大JFrog/Jenkins,反而是等Google推出后,JFrog/Jenkins不约而同地加入了Google的Grafeas/Tekton项目。

好了,单是把各种Notes和Occurrence存起来还只是可信软件供应链里的一部分,另一部分则是在于怎么样使用这些信息,比如作为软件部署时的准入规则,这就要说到随Grafeas应运而生的Kritis(希腊语Judge)项目了,下回分解。

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
15天前
|
供应链 安全 Cloud Native
阿里云容器服务助力企业构建云原生软件供应链安全
本文基于2024云栖大会演讲,探讨了软件供应链攻击的快速增长趋势及对企业安全的挑战。文中介绍了如何利用阿里云容器服务ACK、ACR和ASM构建云原生软件供应链安全,涵盖容器镜像的可信生产、管理和分发,以及服务网格ASM实现应用无感的零信任安全,确保企业在软件开发和部署过程中的安全性。
|
3月前
|
供应链 安全 Cloud Native
阿里云容器服务助力企业构建云原生软件供应链安全
针对软件供应链的攻击事件在以每年三位数的速度激增,其中三方或开源软件已经成为攻击者关注的重要目标,其攻击方式和技术也在不断演进。通过供应链的传播,一个底层软件包的漏洞的影响范围可以波及世界。企业亟需更加标准和完善的供应链风险洞察和防护机制。本文将结合最佳实践的形式,面向容器应用完整的生命周期展示如何基于容器服务ACK/ACR/ASM助力企业构建云原生软件供应链安全。
|
2月前
|
Cloud Native API C#
.NET云原生应用实践(一):从搭建项目框架结构开始
.NET云原生应用实践(一):从搭建项目框架结构开始
|
4月前
|
运维 Cloud Native Devops
云原生之旅:探索现代软件部署的未来之路
在数字化时代的浪潮下,云计算已不再是新鲜词汇,而云原生技术作为其进阶形态,正引领着软件开发和运维的全新变革。本文将深入浅出地解析云原生的核心概念、优势以及实践路径,旨在为读者揭示这一技术趋势如何重塑我们的数字世界,同时分享个人从传统IT向云原生转型的真实体验和所思所感。
|
3月前
|
Cloud Native API 持续交付
云原生技术:开启现代软件部署的新篇章
在数字化浪潮中,云计算已从简单的资源共享进化到支持复杂应用的平台。云原生技术作为这一演变的核心,不仅重塑了软件开发、部署的方式,还为业务敏捷性、可伸缩性和可靠性设定了新的标准。本文将探讨云原生的基本概念、核心技术及实践方法,揭示它如何引领企业走在数字化转型的前列。
|
4月前
|
运维 Cloud Native 安全
云原生之旅:探索现代软件部署的未来
在数字化转型的浪潮中,企业正寻求更高效、灵活的方式来部署和管理他们的应用程序。云原生技术,作为一种新兴的架构模式,提供了一种解决方案。本文将介绍云原生的基本概念,探讨它如何改变软件开发和运维的方式,并分析其在企业中的应用实例,最后讨论云原生面临的挑战及未来发展趋势。
57 2
|
4月前
|
敏捷开发 Cloud Native 云计算
云原生技术:推动现代软件发展的新引擎
【8月更文挑战第23天】在数字化浪潮的推动下,云原生技术正成为企业数字化转型和软件创新的关键力量。本文将深入探讨云原生技术的核心概念、优势及其在现代软件开发中的应用,旨在为读者提供对云原生技术的全面理解和认识。
|
5月前
|
存储 Kubernetes Cloud Native
云原生周刊:Score 成为 CNCF 沙箱项目
以下是内容的摘要,格式为Markdown: 开源项目: - [Trident]:NetApp维护的开源存储解决方案,支持容器化应用的持久化存储,兼容CSI接口。 - [Monokle]:Kubernetes YAML编辑器,简化配置创建、分析和部署。 - [Platform Aware Scheduling]:模块化策略驱动的Kubernetes调度器扩展,考虑平台特性。 - [cdebug]):容器和Pod故障排查工具,提供端口转发、文件系统导出等功能。
|
4月前
|
运维 Cloud Native API
云原生之旅:探索现代软件部署的未来
在数字化浪潮中,云原生技术如同一股清流,为软件开发与部署带来了革命性的变革。本文将深入浅出地探讨云原生概念的核心,揭示它如何优化资源利用、提升开发效率,并确保系统的可伸缩性与韧性。通过实际案例,我们一同见证云原生如何在企业中落地生根,助推创新和业务成长。
|
4月前
|
Cloud Native 持续交付 云计算
云原生之旅:探索现代软件部署的变革之路
在数字化浪潮中,云原生技术如同一艘航船,带领企业驶向灵活、高效的未来。本文将深入浅出地探讨云原生的核心理念、关键技术以及实践案例,揭示它如何重塑软件开发与运维的模式,为企业数字化转型提供动力。
55 0