requirements.md 16.7 KB
Newer Older
1
# Requirements
2

3
4
5
6
7
8
9
Table of Contents:

*   [Definitions](#definitions)
*   [Source Requirements](#source-requirements)
*   [Build Requirements](#build-requirements)
*   [Provenance Requirements](#provenance-requirements)
*   [Common Requirements](#common-requirements)
10
11
12
13

_Reminder: The definitions below are not yet finalized and subject to change,
particularly SLSA 3-4._

14
15
16
This document enumerates all of the detailed requirements for an artifact to
meet SLSA. For a broader overview, including basic terminology and threat model,
see the [main page](README.md).
17
18
19
20
21
22
23
24
25
26
27
28

## Definitions

<a id="immutable-reference"></a>**Immutable reference:** An identifier that is
guaranteed to always point to the same, immutable artifact. This MUST allow the
consumer to locate the artifact and SHOULD include a cryptographic hash of the
artifact's contents to ensure integrity. Examples: git URL + branch/tag/ref \+
commit ID; cloud storage bucket ID + SHA-256 hash; Subversion URL (no hash).

[immutable reference]: #immutable-reference
[immutable references]: #immutable-reference

29
30
31
**Platform:** Infrastructure or service that hosts the source, build, or
distribution of software. Examples: GitHub, Google Cloud Build, Travis CI,
[Mozilla's self-hosted Mercurial server](https://hg.mozilla.org).
32

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
**Provenance**: Metadata about how an artifact was produced.

**Revision:** An immutable, coherent state of a source. In Git, for example, a
revision is a commit in the history reachable from a specific branch in a
specific repository. Different revisions within one repo MAY have different
levels. Example: the most recent revision on a branch meets SLSA 4 but very old
historical revisions before the cutoff do not.

**Trusted persons:** Set of persons who are granted the authority to maintain a
software project. For example, https://github.com/MarkLodato/dotfiles has just
one trusted person (MarkLodato), while https://hg.mozilla.org/mozilla-central
has a set of trusted persons with write access to the mozilla-central
repository.

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be
interpreted as described in [RFC 2119](https://www.rfc-editor.org/rfc/rfc2119).

## Source requirements

53
54
55
56
57
<table>
<tr><th>Requirement<th>Description<th>L1<th>L2<th>L3<th>L4
<tr id="version-controlled">
<td>Version Controlled
<td>
58

59
60
Every change to the source is tracked in a version control system that meets the
following requirements:
61

62
63
64
65
66
-   **[Change History]** There exists a record of the history of changes
    that went into the revision. Each change must contain: the identities of
    the uploader and reviewers (if any), timestamps of the reviews (if any)
    and submission, the change description / justification, the content of
    the change, and the parent revisions.
67

68
69
70
-   **\[Immutable Reference]** There exists a way to indefinitely reference
    this particular, immutable revision. In git, this is the {repo URL +
    branch/tag/ref + commit ID}.
71
72
73
74
75
76
77
78
79

Most popular version control system meet this requirement, such as git,
Mercurial, Subversion, or Perforce.

NOTE: This does NOT require that the code, uploader/reviewer identities, or
change history be made public. Rather, some organization must attest to the fact
that these requirements are met, and it is up to the consumer whether this
attestation is sufficient.

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
<td> <td><td><td>
<tr id="verified-history">
<td>Verified History
<td>

Every change in the revision's history has at least one strongly authenticated
actor identities (author, uploader, reviewer, etc.) and timestamp. It must be
clear which identities were verified, and those identities must use [two-step
verification](https://www.google.com/landing/2step/) or similar. (Exceptions
noted below.)

-   **[First-Parent History]** In the case of a non-linear version control
    system, where a revision can have more than one parent, only the "first
    parent history" is in scope. In other words, when a feature branch is merged
    back into the main branch, only the merge itself is in scope.
-   **[Historical Cutoff]** There is some TBD exception to allow existing
    projects to meet SLSA 3/4 even if historical revisions were present in the
    history. Current thinking is that this could be either last N months or a
    platform attestation guaranteeing that future changes in the next N months
    will meet the requirements.

<td> <td> <td><td>
<tr id="retained-indefinitely">
<td>Retained Indefinitely
<td>

The revision and its change history are preserved indefinitely and cannot be
deleted, except when subject to an established and transparent policy for
obliteration, such as a legal or policy requirement.

-   **[Immutable History]** It must not be possible for persons to delete or
    modify the history, even with multi-party approval, except by trusted
    platform admins with two-party approval following the obliterate policy.
-   **[Limited Retention for SLSA 2]** At SLSA 2 (but not 3), it is acceptable
    for the retention to be limited to 18 months, as attested by the source
    control platform.
    -   Example: If a commit is made on 2020-04-05 and then a retention
        attestation is generated on 2021-01-01, the commit must be retained
        until at least 2022-07-01.

<td> <td> <td>18 mo.<td>
<tr id="two-person-reviewed">
<td>Two-Person Reviewed
<td>

Every change in the revision's history was agreed to by two trusted persons
prior to submission, and both of these trusted persons were strongly
authenticated. (Exceptions from [Verified History](#verified-history) apply here
as well.)

-   The following combinations are acceptable:
    -   Uploader and reviewer are two different trusted persons.
    -   Two different reviewers are trusted persons.
-   **[Different Persons]** The platform ensures that no person can use
    alternate identities to bypass the two-person review requirement.
    -   Example: if a person uploads with identity X then reviews with alias Y,
        the platform understands that this is the same person and does not
        consider the review requirement satisfied.
-   **[Informed Review]** The reviewer is able and encouraged to make an
    informed decision about what they're approving. The reviewer should be
    presented with a full, meaningful content diff between the proposed revision
    and the previously reviewed revision. For example, it is not sufficient to
    just indicate that file changed without showing the contents.
-   **[Context-specific Approvals]** Approvals are for a specific context, such
    as a repo + branch in git. Moving fully reviewed content from one context to
    another still requires review. (Exact definition of "context" depends on the
    project, and this does not preclude well-understood automatic or reviewless
    merges, such as cutting a release branch.)
    -   Git example: If a fully reviewed commit in one repo is merged into a
        different repo, or a commit in one branch is merged into a different
        branch, then the merge still requires review.

<td> <td> <td> <td>
</table>
154
155

## Build Requirements
156
157
158
159

Requirements on build process:

<table>
160
161
162
163
<tr><th>Requirement<th>Description<th>L1<th>L2<th>L3<th>L4
<tr id="scripted-build">
<td>Scripted Build
<td>
164

165
166
All build steps were fully defined in some sort of "build script". The
only manual command, if any, was to invoke the build script.
167

168
Examples:
169

170
171
*   Build script is Makefile, invoked via `make all`.
*   Build script is .github/workflows/build.yaml, invoked by GitHub Actions.
172

173
174
175
176
<td><td><td><td>
<tr id="build-service">
<td>Build Service
<td>
177

178
179
All build steps ran using some build service, not on a developer's
workstation.
180

181
Examples: GitHub Actions, Google Cloud Build, Travis CI.
182

183
184
185
186
<td> <td><td><td>
<tr id="ephemeral-environment">
<td>Ephemeral Environment
<td>
187

188
189
190
The build service ensured that the build steps ran in an ephemeral environment,
such as a container or VM, provisioned solely for this build, and not reused
from a prior build.
191

192
193
194
195
<td> <td> <td><td>
<tr id="isolated">
<td>Isolated
<td>
196

197
198
The build service ensured that the build steps ran in an isolated environment
free of influence from other build instances, whether prior or concurrent.
199

200
*   It MUST NOT be possible for a build to access any secrets of the build
201
    service, such as the provenance signing key.
202
*   It MUST NOT be possible for two builds that overlap in time to
203
    influence one another.
204
*   It MUST NOT be possible for one build to persist or influence the
205
    build environment of a subsequent build.
206
*   Build caches, if used, MUST be purely content-addressable to prevent
207
208
    tampering.

209
210
211
212
<td> <td> <td><td>
<tr id="parameterless">
<td>Parameterless
<td>
213

214
215
216
The build output cannot be affected by user parameters other than the build
entry point and the top-level source location. In other words, the build is
fully defined through the build script and nothing else.
217

218
Examples:
219

220
*   GitHub Actions
221
    [workflow_dispatch](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#workflow_dispatch) `inputs` MUST be empty.
222
*   Google Cloud Build
223
224
225
226
    [user-defined substitutions](https://cloud.google.com/build/docs/configuring-builds/substitute-variable-values)
    MUST be empty. (Default substitutions, whose values are defined by the
    server, are acceptable.)

227
228
229
230
<td> <td> <td> <td>
<tr id="hermetic">
<td>Hermetic
<td>
231

232
233
234
All transitive build steps, sources, and dependencies were fully declared up
front with [immutable references], and the build steps ran with no network
access.
235

236
The user-defined build script:
237

238
*   MUST declare all dependencies, including sources and other build steps,
239
240
241
242
    using [immutable references] in a format that the build service understands.

  The build service:

243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
*   MUST fetch all artifacts in a trusted control plane.
*   MUST disallow mutable references.
*   MUST verify the integrity of each artifact.
    *   If the [immutable reference] includes a cryptographic hash, the service
        MUST verify the hash and reject the fetch if the verification fails.
    *   Otherwise, the service MUST fetch the artifact over a channel that
        ensures transport integrity, such as TLS or code signing.
*   MUST prevent network access while running the build steps.
    *   This requirement is "best effort." It SHOULD deter a reasonable team
        from having a non-hermetic build, but it need not stop a determined
        adversary. For example, using a container to prevent network access is
        sufficient.

<td> <td> <td> <td>
<tr id="reproducible">
<td>Reproducible
<td>

Re-running the build steps with identical input artifacts results in bit-for-bit
identical output. Builds that cannot meet this MUST provide a justification why
the build cannot be made reproducible.

"○" means that this requirement is "best effort". The user-provided build script
SHOULD declare whether the build is intended to be reproducible or a
justification why not. The build service MAY blindly propagate this intent
without verifying reproducibility. A consumer MAY reject the build if it does
not reproduce.

<td> <td> <td> <td>
272
273
</table>

274
## Provenance Requirements
275
276
277
278

Requirements on the process by which provenance is generated and consumed:

<table>
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
<tr><th>Requirement<th>Description<th>L1<th>L2<th>L3<th>L4
<tr id="available">
<td>Available
<td>

The provenance is available to the consumer in a format that the consumer
accepts. The format SHOULD be
[in-toto provenance](https://github.com/in-toto/attestation/blob/main/spec/predicates/provenance.md),
but another format MAY be used if both producer and consumer agree and it meets
all the other requirements.

<td><td><td><td>
<tr id="authenticated">
<td>Authenticated
<td>

The provenance's authenticity and integrity can be verified by the consumer.
This SHOULD be through a digital signature from a private key accessible only to
297
the service generating the provenance.
298
299
300

<td> <td><td><td>
<tr id="service-generated">
Tom Hennen's avatar
Tom Hennen committed
301
<td>Build Service Reported
302
303
<td>

Tom Hennen's avatar
Tom Hennen committed
304
305
The provenance was populated with data reported by the build service, not by user-provided tooling
running within the service.
306
307
308
309
310
311
312
313
314

<td> <td><td><td>
<tr id="non-falsifiable">
<td>Non-Falsifiable
<td>

Provenance cannot be falsified by the build service's users.

*   The provenance signing key MUST be stored in a secure key management system
315
    accessible only to the build service account.
316
*   The provenance signing key MUST NOT be accessible to the environment running
317
    the user-defined build steps.
318
*   Every field in the provenance MUST be generated or verified by the build
319
320
321
    service in a trusted control plane. The user-controlled build steps MUST
    NOT be able to inject or alter the contents, except as noted below.

322
323
The following provenance fields MAY be generated by the user-controlled build
steps without the build service verifying their correctness:
324

325
326
327
328
329
*   The output artifact hash from [Identifies Artifact](#identifies-artifact).
    *   Reasoning: This only allows a "bad" build to falsely claim that it
        produced a "good" artifact. This is not a security problem because the
        consumer MUST accept only "good" builds and reject "bad" builds.
*   The "reproducible" boolean and justification from
330
331
332
    [Reproducible](#reproducible).


333
334
335
336
<td> <td> <td><td>
<tr id="dependencies-complete">
<td>Dependencies Complete
<td>
337

338
339
340
Provenance records all build dependencies that were available while running the
build steps. This includes the initial state of the machine, VM, or container of
the build worker.
341

342
343
*   MUST include all user-specified build steps, sources, dependencies.
*   SHOULD include all service-provided artifacts.
344

345
<td> <td> <td> <td>
346
347
348
349
350
</table>

Requirements on the contents of the provenance:

<table>
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
<tr><th>Requirement<th>Description<th>L1<th>L2<th>L3<th>L4
<tr id="identifies-artifact">
<td>Identifies Artifact
<td>

The provenance identifies the output artifact via a cryptographic hash. The
RECOMMENDED algorithm is SHA-256 for cross-system compatibility. If another
algorithm is used, it SHOULD be resistant to collisions and second preimages.

<td><td><td><td>
<tr id="identifies-builder">
<td>Identifies Builder
<td>

The provenance identifies the entity that performed the build and generated the
provenance. This represents the entity that the consumer must trust. Examples:
"GitHub Actions with a GitHub-hosted worker", "jdoe@example.com's machine".

<td><td><td><td>
<tr id="identifies-source">
<td>Identifies Source
<td>

The provenance identifies the source containing the top-level build script, via
an [immutable reference]. Example: git URL + branch/tag/ref + commit ID.

<td><td><td><td>
<tr id="identifies-entry-point">
<td>Identifies Entry Point
<td>

The provenance identifies the "entry point" or command that was used to invoke
the build script. Example: `make all`.

<td><td><td><td>
<tr id="includes-all-params">
<td>Includes All Build Parameters
<td>

The provenance includes all build parameters under a user's control. See
[Parameterless](#parameterless) for details. (At L3, the parameters must be
listed; at L4, they must be empty.)

<td> <td> <td><td>
<tr id="includes-all-deps">
<td>Includes All Transitive Dependencies
<td>

The provenance includes all transitive dependencies listed in
[Dependencies Complete](#dependencies-complete).

<td> <td> <td> <td>
<tr id="includes-reproducible-info">
<td>Includes Reproducible Info
<td>

The provenance includes a boolean indicating whether build is intended to be
reproducible and, if so, all information necessary to reproduce the build. See
[Reproducible](#reproducible) for more details.

<td> <td> <td> <td>
<tr id="includes-metadata">
<td>Includes Metadata
<td>

The provenance includes metadata to aid debugging and investigations. This
SHOULD at least include start and end timestamps and a permalink to debug logs.

"○" = RECOMMENDED.

<td><td><td><td>
422
</table>
423
424
425
426
427
428

## Common requirements

Common requirements for every trusted system involved in the supply chain
(source, build, distribution, etc.)

429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
**TODO: Expand this section. Currently it is under-specified.**

<table>
<tr><th>Requirement<th>Description<th>L1<th>L2<th>L3<th>L4
<tr id="security">
<td>Security
<td>

The system meets some TBD baseline security standard to prevent compromise.
(Patching, vulnerability scanning, user isolation, transport security, secure
boot, machine identity, etc. Perhaps
[NIST 800-53](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-53r5.pdf)
or a subset thereof.)

<td> <td> <td> <td>
<tr id="access">
<td>Access
<td>

All physical and remote access must be rare, logged, and gated behind
multi-party approval.

<td> <td> <td> <td>
<tr id="superusers">
<td>Superusers
<td>
455

456
457
Only a small number of platform admins may override the guarantees listed here.
Doing so MUST require approval of a second platform admin.
458

459
460
<td> <td> <td> <td>
</table>