1
1
const { sigstore } = require ( 'sigstore' )
2
+ const ci = require ( 'ci-info' )
3
+ const { env } = process
2
4
3
5
const INTOTO_PAYLOAD_TYPE = 'application/vnd.in-toto+json'
4
6
const INTOTO_STATEMENT_TYPE = 'https://in-toto.io/Statement/v0.1'
5
7
const SLSA_PREDICATE_TYPE = 'https://slsa.dev/provenance/v0.2'
6
8
7
- const BUILDER_ID = 'https://github.com/actions/runner'
8
- const BUILD_TYPE_PREFIX = 'https://github.com/npm/cli/gha'
9
- const BUILD_TYPE_VERSION = 'v2'
9
+ const GITHUB_BUILDER_ID = 'https://github.com/actions/runner'
10
+ const GITHUB_BUILD_TYPE_PREFIX = 'https://github.com/npm/cli/gha'
11
+ const GITHUB_BUILD_TYPE_VERSION = 'v2'
10
12
11
13
const generateProvenance = async ( subject , opts ) => {
12
- const { env } = process
14
+ var provenance
15
+ switch ( true ) {
16
+ case ci . GITHUB_ACTIONS :
17
+ provenance = githubProvenance ( subject )
18
+ break
19
+ case ci . GITLAB :
20
+ provenance = gitlabProvenance ( subject )
21
+ break
22
+ default :
23
+ throw Object . assign (
24
+ new Error ( 'Unsupported provenance type ' + ci . name ) ,
25
+ { code : 'EUSAGE' }
26
+ )
27
+ }
28
+ return sigstore . attest ( provenance , INTOTO_PAYLOAD_TYPE , opts )
29
+ }
30
+
31
+ const githubProvenance = ( subject ) => {
13
32
/* istanbul ignore next - not covering missing env var case */
14
33
const [ workflowPath ] = ( env . GITHUB_WORKFLOW_REF || '' )
15
34
. replace ( env . GITHUB_REPOSITORY + '/' , '' )
@@ -19,8 +38,8 @@ const generateProvenance = async (subject, opts) => {
19
38
subject,
20
39
predicateType : SLSA_PREDICATE_TYPE ,
21
40
predicate : {
22
- buildType : `${ BUILD_TYPE_PREFIX } /${ BUILD_TYPE_VERSION } ` ,
23
- builder : { id : BUILDER_ID } ,
41
+ buildType : `${ GITHUB_BUILD_TYPE_PREFIX } /${ GITHUB_BUILD_TYPE_VERSION } ` ,
42
+ builder : { id : GITHUB_BUILDER_ID } ,
24
43
invocation : {
25
44
configSource : {
26
45
uri : `git+${ env . GITHUB_SERVER_URL } /${ env . GITHUB_REPOSITORY } @${ env . GITHUB_REF } ` ,
@@ -63,7 +82,142 @@ const generateProvenance = async (subject, opts) => {
63
82
} ,
64
83
}
65
84
66
- return sigstore . attest ( Buffer . from ( JSON . stringify ( payload ) ) , INTOTO_PAYLOAD_TYPE , opts )
85
+ return Buffer . from ( JSON . stringify ( payload ) )
86
+ }
87
+
88
+ const GITLAB_BUILD_TYPE_PREFIX = 'https://github.com/npm/cli/gitlab'
89
+ const GITLAB_BUILD_TYPE_VERSION = 'v1alpha1'
90
+
91
+ const gitlabProvenance = ( subject , opts ) => {
92
+ // TODO: pull values from authenticated JWT rather than environment variables.
93
+ const payload = {
94
+ _type : INTOTO_STATEMENT_TYPE ,
95
+ subject,
96
+ predicateType : SLSA_PREDICATE_TYPE ,
97
+ predicate : {
98
+ buildType : `${ GITLAB_BUILD_TYPE_PREFIX } /${ GITLAB_BUILD_TYPE_VERSION } ` ,
99
+ builder : { id : `${ env . CI_PROJECT_URL } /-/runners/${ env . CI_RUNNER_ID } ` } ,
100
+ invocation : {
101
+ configSource : {
102
+ uri : `git+${ env . CI_PROJECT_URL } @${ env . CI_BUILD_REF } ` ,
103
+ digest : {
104
+ sha1 : env . CI_COMMIT_SHA ,
105
+ } ,
106
+ entryPoint : env . CI_JOB_NAME ,
107
+ } ,
108
+ parameters : {
109
+ CI : env . CI ,
110
+ CI_API_GRAPHQL_URL : env . CI_API_GRAPHQL_URL ,
111
+ CI_API_V4_URL : env . CI_API_V4_URL ,
112
+ CI_BUILD_BEFORE_SHA : env . CI_BUILD_BEFORE_SHA ,
113
+ CI_BUILD_ID : env . CI_BUILD_ID ,
114
+ CI_BUILD_NAME : env . CI_BUILD_NAME ,
115
+ CI_BUILD_REF : env . CI_BUILD_REF ,
116
+ CI_BUILD_REF_NAME : env . CI_BUILD_REF_NAME ,
117
+ CI_BUILD_REF_SLUG : env . CI_BUILD_REF_SLUG ,
118
+ CI_BUILD_STAGE : env . CI_BUILD_STAGE ,
119
+ CI_COMMIT_AUTHOR : env . CI_COMMIT_AUTHOR ,
120
+ CI_COMMIT_BEFORE_SHA : env . CI_COMMIT_BEFORE_SHA ,
121
+ CI_COMMIT_BRANCH : env . CI_COMMIT_BRANCH ,
122
+ CI_COMMIT_DESCRIPTION : env . CI_COMMIT_DESCRIPTION ,
123
+ CI_COMMIT_MESSAGE : env . CI_COMMIT_MESSAGE ,
124
+ CI_COMMIT_REF_NAME : env . CI_COMMIT_REF_NAME ,
125
+ CI_COMMIT_REF_PROTECTED : env . CI_COMMIT_REF_PROTECTED ,
126
+ CI_COMMIT_REF_SLUG : env . CI_COMMIT_REF_SLUG ,
127
+ CI_COMMIT_SHA : env . CI_COMMIT_SHA ,
128
+ CI_COMMIT_SHORT_SHA : env . CI_COMMIT_SHORT_SHA ,
129
+ CI_COMMIT_TIMESTAMP : env . CI_COMMIT_TIMESTAMP ,
130
+ CI_COMMIT_TITLE : env . CI_COMMIT_TITLE ,
131
+ CI_CONFIG_PATH : env . CI_CONFIG_PATH ,
132
+ CI_DEFAULT_BRANCH : env . CI_DEFAULT_BRANCH ,
133
+ CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX :
134
+ env . CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX ,
135
+ CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX : env . CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX ,
136
+ CI_DEPENDENCY_PROXY_SERVER : env . CI_DEPENDENCY_PROXY_SERVER ,
137
+ CI_DEPENDENCY_PROXY_USER : env . CI_DEPENDENCY_PROXY_USER ,
138
+ CI_JOB_ID : env . CI_JOB_ID ,
139
+ CI_JOB_NAME : env . CI_JOB_NAME ,
140
+ CI_JOB_NAME_SLUG : env . CI_JOB_NAME_SLUG ,
141
+ CI_JOB_STAGE : env . CI_JOB_STAGE ,
142
+ CI_JOB_STARTED_AT : env . CI_JOB_STARTED_AT ,
143
+ CI_JOB_URL : env . CI_JOB_URL ,
144
+ CI_NODE_TOTAL : env . CI_NODE_TOTAL ,
145
+ CI_PAGES_DOMAIN : env . CI_PAGES_DOMAIN ,
146
+ CI_PAGES_URL : env . CI_PAGES_URL ,
147
+ CI_PIPELINE_CREATED_AT : env . CI_PIPELINE_CREATED_AT ,
148
+ CI_PIPELINE_ID : env . CI_PIPELINE_ID ,
149
+ CI_PIPELINE_IID : env . CI_PIPELINE_IID ,
150
+ CI_PIPELINE_SOURCE : env . CI_PIPELINE_SOURCE ,
151
+ CI_PIPELINE_URL : env . CI_PIPELINE_URL ,
152
+ CI_PROJECT_CLASSIFICATION_LABEL : env . CI_PROJECT_CLASSIFICATION_LABEL ,
153
+ CI_PROJECT_DESCRIPTION : env . CI_PROJECT_DESCRIPTION ,
154
+ CI_PROJECT_ID : env . CI_PROJECT_ID ,
155
+ CI_PROJECT_NAME : env . CI_PROJECT_NAME ,
156
+ CI_PROJECT_NAMESPACE : env . CI_PROJECT_NAMESPACE ,
157
+ CI_PROJECT_NAMESPACE_ID : env . CI_PROJECT_NAMESPACE_ID ,
158
+ CI_PROJECT_PATH : env . CI_PROJECT_PATH ,
159
+ CI_PROJECT_PATH_SLUG : env . CI_PROJECT_PATH_SLUG ,
160
+ CI_PROJECT_REPOSITORY_LANGUAGES : env . CI_PROJECT_REPOSITORY_LANGUAGES ,
161
+ CI_PROJECT_ROOT_NAMESPACE : env . CI_PROJECT_ROOT_NAMESPACE ,
162
+ CI_PROJECT_TITLE : env . CI_PROJECT_TITLE ,
163
+ CI_PROJECT_URL : env . CI_PROJECT_URL ,
164
+ CI_PROJECT_VISIBILITY : env . CI_PROJECT_VISIBILITY ,
165
+ CI_REGISTRY : env . CI_REGISTRY ,
166
+ CI_REGISTRY_IMAGE : env . CI_REGISTRY_IMAGE ,
167
+ CI_REGISTRY_USER : env . CI_REGISTRY_USER ,
168
+ CI_REPOSITORY_URL : env . CI_REPOSITORY_URL ,
169
+ CI_RUNNER_DESCRIPTION : env . CI_RUNNER_DESCRIPTION ,
170
+ CI_RUNNER_ID : env . CI_RUNNER_ID ,
171
+ CI_RUNNER_TAGS : env . CI_RUNNER_TAGS ,
172
+ CI_SERVER_HOST : env . CI_SERVER_HOST ,
173
+ CI_SERVER_NAME : env . CI_SERVER_NAME ,
174
+ CI_SERVER_PORT : env . CI_SERVER_PORT ,
175
+ CI_SERVER_PROTOCOL : env . CI_SERVER_PROTOCOL ,
176
+ CI_SERVER_REVISION : env . CI_SERVER_REVISION ,
177
+ CI_SERVER_SHELL_SSH_HOST : env . CI_SERVER_SHELL_SSH_HOST ,
178
+ CI_SERVER_SHELL_SSH_PORT : env . CI_SERVER_SHELL_SSH_PORT ,
179
+ CI_SERVER_URL : env . CI_SERVER_URL ,
180
+ CI_SERVER_VERSION : env . CI_SERVER_VERSION ,
181
+ CI_SERVER_VERSION_MAJOR : env . CI_SERVER_VERSION_MAJOR ,
182
+ CI_SERVER_VERSION_MINOR : env . CI_SERVER_VERSION_MINOR ,
183
+ CI_SERVER_VERSION_PATCH : env . CI_SERVER_VERSION_PATCH ,
184
+ CI_TEMPLATE_REGISTRY_HOST : env . CI_TEMPLATE_REGISTRY_HOST ,
185
+ GITLAB_CI : env . GITLAB_CI ,
186
+ GITLAB_FEATURES : env . GITLAB_FEATURES ,
187
+ GITLAB_USER_EMAIL : env . GITLAB_USER_EMAIL ,
188
+ GITLAB_USER_ID : env . GITLAB_USER_ID ,
189
+ GITLAB_USER_LOGIN : env . GITLAB_USER_LOGIN ,
190
+ GITLAB_USER_NAME : env . GITLAB_USER_NAME ,
191
+ RUNNER_GENERATE_ARTIFACTS_METADATA : env . RUNNER_GENERATE_ARTIFACTS_METADATA ,
192
+ } ,
193
+ environment : {
194
+ name : env . CI_RUNNER_DESCRIPTION ,
195
+ architecture : env . CI_RUNNER_EXECUTABLE_ARCH ,
196
+ job : {
197
+ id : env . CI_JOB_ID ,
198
+ } ,
199
+ } ,
200
+ } ,
201
+ metadata : {
202
+ buildInvocationId : `${ env . CI_JOB_URL } ` ,
203
+ completeness : {
204
+ parameters : true ,
205
+ environment : true ,
206
+ materials : false ,
207
+ } ,
208
+ reproducible : false ,
209
+ } ,
210
+ materials : [
211
+ {
212
+ uri : `git+${ env . CI_PROJECT_URL } @${ env . CI_BUILD_REF } ` ,
213
+ digest : {
214
+ sha1 : env . CI_COMMIT_SHA ,
215
+ } ,
216
+ } ,
217
+ ] ,
218
+ } ,
219
+ }
220
+ return Buffer . from ( JSON . stringify ( payload ) )
67
221
}
68
222
69
223
module . exports = {
0 commit comments