You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: config.md
+48-6Lines changed: 48 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -25,19 +25,61 @@ Changing it means creating a new derived image, instead of changing the existing
25
25
26
26
### Layer DiffID
27
27
28
-
A layer DiffID is a SHA256 digest over the layer's uncompressed tar archive and serialized in the descriptor digest format, e.g., `sha256:a9561eb1b190625c9adb5a9513e72c4dedafc1cb2d4c5236c9a6957ec7dfd5a9`.
28
+
A layer DiffID is the digest over the layer's uncompressed tar archive and serialized in the descriptor digest format, e.g., `sha256:a9561eb1b190625c9adb5a9513e72c4dedafc1cb2d4c5236c9a6957ec7dfd5a9`.
29
29
Layers must be packed and unpacked reproducibly to avoid changing the layer DiffID, for example by using tar-split to save the tar headers.
30
30
31
31
NOTE: Do not confuse DiffIDs with [layer digests](manifest.md#image-manifest-property-descriptions), often referenced in the manifest, which are digests over compressed or uncompressed content.
32
32
33
33
### Layer ChainID
34
34
35
35
For convenience, it is sometimes useful to refer to a stack of layers with a single identifier.
36
-
This is called a `ChainID`.
37
-
For a single layer (or the layer at the bottom of a stack), the
For this, we define the binary `|` operation to be the result of applying the right operand to the left operand.
50
+
For example, given base layer `A` and a changeset `B`, we refer to the result of applying `B` to `A` as `A|B`.
51
+
52
+
Above, we define the `ChainID` for a single layer (`L₀`) as equivalent to the `DiffID` for that layer.
53
+
Otherwise, the `ChainID` for `L₀|...|Lₙ₋₁|Lₙ` is defined as recursion `Digest(ChainID(L₀|...|Lₙ₋₁) + " " + DiffID(Lₙ))`.
54
+
55
+
#### Explanation
56
+
57
+
Let's say we have layers A, B, C, ordered from bottom to top, where A is the base and C is the top.
58
+
Defining `|` as a binary application operator, the root filesystem may be `A|B|C`.
59
+
While it is implied that `C` is only useful when applied to `A|B`, the identifier `C` is insufficient to identify this result, as we'd have the equality `C = A|B|C`, which isn't true.
60
+
61
+
The main issue is when we have two definitions of `C`, `C = C` and `C = A|B|C`. If this is true (with some handwaving), `C = x|C` where `x = any application` must be true.
62
+
This means that if an attacker can define `x`, relying on `C` provides no guarantee that the layers were applied in any order.
63
+
64
+
The `ChainID` addresses this problem by being defined as a compound hash.
65
+
__We differentiate the changeset `C`, from the order dependent application `A|B|C` by saying that the resulting rootfs is identified by ChainID(A|B|C), which can be calculated by `ImageConfig.rootfs`.__
66
+
67
+
Let's expand the definition of `ChainID(A|B|C)` to explore its internal structure:
Hopefully, the above is illustrative of the _actual_ contents of the `ChainID`.
82
+
Most importantly, we can easily see that `ChainID(C) != ChainID(A|B|C)`, otherwise, `ChainID(C) = DiffID(C)`, which is the base case, could not be true.
0 commit comments