Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add proposal cosign integration #172

Merged
merged 6 commits into from
Mar 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added proposals/images/accessory/accessory_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added proposals/images/accessory/accessory_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added proposals/images/accessory/accessory_3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added proposals/images/cosign/accessory_cosign.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added proposals/images/cosign/build_reference.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
247 changes: 247 additions & 0 deletions proposals/new/accessory.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
Proposal: Add abstract definition accessory

Author: Yan Wang

## Abstract

Beside to store an artifact into registry, there are requirements on storing secure chain artifacts, like Software Bill of Materials (SBoM) and signatures to provide rich rich functionality of an artifact.

The proposal is to introduce an abstract definition -- accessory -- to enable Harbor to extend the capabilities for storing artifact with additional stuff.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tianon you as a native speaker, do you think the term accessory is correct here or would you use a better suited term?

I would like to critically question the "term", as it will stick on forever and generation of Harbor developers and users would need lookup the manual and the code just to understand what it means.

IMHO an artifact artifact attachment or attachment would be a better suited term because:

  1. It is a common and well know term for an object that can be (optionally) attached to another object. It is known to many user and developers from email, documents and files.
  2. A good word that denotes the common use correctly will save thousand hours of time for many many users and developers.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm certainly not an expert, but I am "native" so I'll do my best! 😇

I'll start by saying I find it a little amusing that "attachment" is the very word I've been using to describe this feature to colleagues. 😅 🙈

To be clear, I think "accessory" is ok, but I do agree that "attachment" would be a better word for what this is.

An "accessory" is usually something that's only useful or thought about in the context of the thing it's connected to (for example, jewelry is commonly called an "accessory" because something like a necklace is not terribly useful in isolation). Another way to put that is that it "enhances" the thing it's connected to ("accessory to a crime" for example -- someone who helped the crime be committed but wasn't the person who did the crime directly), and this is the usage that makes me OK with this as a term for this feature.

Conversely, "attachment" only implies a connection between the things, not necessarily that the attached thing improves the thing it's attached to in any way - the attached item is (more) often useful/meaningful in isolation too.

(IMO the word "attachment" is also more closely related to the word "reference" that the OCI is working with/around than "accessory" is.)

So I guess my conclusion would be that if we expect this feature to grow beyond just things like signatures or SBOMs that "enhance" the thing they're attached to, then yes, "attachment" is a better term for it, but if we don't want this feature to grow into more use cases we haven't thought of yet (where there might be a softer relationship between the OCI artifact and the attachment), then "accessory" is probably fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks @Vad1mo and @tianon, firstly, we'd like to extend the accessory into more cases, like SBoM, Nydus(converted images).

I know the OCI or Oras community uses the attachement to describe the linkage of subject manifest and its things. IMO, in Harbor, I'd like to use different term to descirbe, we can say, the same thing to avoid confusion. A typical example is label, in Harbor we have this term to help user to filter artifact. However, in docker community, labels are an key-value pair.

And since we've reached the RC stage and all the source code has been merged, we have to draw an conclusion soon.


## Motivation

Artifact Security has become a primary concern, user wants to store the signature, SBoMs to meet their security policy.

## Solution

To provide these capabilities, the abstract definition will provide a specification for storing and discovering an accessory, including the ability to store references between types, enabling a graph of objects.

## Definition

Accessory: Independent, but linked to an existing subject artifact, which enabling the extendibility of an OCI artifact.

* N:1 accessories, enabling multiple accessories to be linked to a single artifact.

![Accessory](../images/accessory/accessory_1.png)

* The operation of an accessory is on top of distribution v2 API.

* For the exposure, based on the subject artifact, user has to use the subject digest to discover accessory. Refer to the API.

* [To Be Discussed]The accessory is stored as individual, untagged artifact in Harbor. These Untagged artifacts are not subject to GC if they have a subject reference to an existing artifact.

The biggest challenge for Harbor is to add the new accessory lookup API's, and adjust GC to support accessory.

### Life Cycle Management

Reference: Add an artifact to Harbor, referencing existing content.

**Hard Reference** : The accessory is tied to the subject manifest.

**Soft Reference** : The accessory is not tied to the subject manifest.

The type of linkage of accessory and its subject. This should be discussed.

* By Tag: If the accessory doesn't have a tag, it's hard reference. Otherwise, it's soft.
![Accessory](../images/accessory/accessory_3.png)

* By Type: If the accessory is a kind of signature, it's hard reference. However, SBoM is soft.
![Accessory](../images/accessory/accessory_2.png)

Bases on the linkage, Harbor treats the accessory as either a standalone artifact or an extra stuff of a subject artifact.

**Deletion**
1. Soft Reference: If the linkage is Soft Reference, when the subject artifact is removed, the linkage will be removed as well, the accessory becomes an individual artifact.
2. Hard Reference: If the linkage is Hard Reference, the accessory will be removed together with the subject artifact.

**Garbage Collection**
1. Soft Reference: If the linkage is Soft Reference, Harbor treats the accessory as normal artifact and will not set it as the GC candidate.
2. Hard Reference: If the linkage is Hard Reference, Harbor treats the accessory as an extra stuff of the subject artifact. It means, it being tied to the subject artifact and will be GCed whenever the subject artifact is marked and deleted.

### DB scheme

```yaml

CREATE TABLE artifact_accessory (
id SERIAL PRIMARY KEY NOT NULL,
/*
the artifact id of the accessory itself.
*/
artifact_id int,
/*
the subject artifact id of the accessory.
*/
subject_artifact_id int,
/*
the type of the accessory, like signature.cosign.
*/
type varchar(1024),
size int,
digest varchar(1024),
creation_time timestamp default CURRENT_TIMESTAMP,
FOREIGN KEY (artifact_id) REFERENCES artifact(id),
FOREIGN KEY (subject_artifact_id) REFERENCES artifact(id),
CONSTRAINT unique_artifact_accessory UNIQUE (artifact_id, subject_artifact_id)
);

```

### Accessory Interface

```go
type Reference string
type HardRef Reference
type SoftRef Reference

type Accessory Struct {
ID int64 `json:"id"`
ArtifactID int64 `json:"artifact_id"`
SubjectArtifactID int64 `json:"subject_artifact_id"`
Type string `json:"type"`
Size int64 `json:"size"`
Digest string `json:"digest"`
CreationTime time.Time `json:"creation_time"`
Ref Reference `json:"-"`
}

func (a Accessory) ReferenceType(ctx context.Context, artifact Artifact) Reference {
return a.Ref
}

type Signature Struct {
Accessory
}

type SBoM Struct {
Accessory
}

```


### Request Artifact Accessory

**List artifact**

1. You can use the `signature.cosign` in the accessories to determine whether an object is signed and to view information about the signature, and you can pull the signature with digest in the registry store,
2. [?]You cannot list the accessories directly via list artifact API.

```yaml

GET /api/v2.0/projects/library/repositories/hello-world/artifacts

{
...
"accessories":[
{
"artifact_id":1,
"subject_artifact_id":81,
"size": 1234,
"digest":"sha256:94788818ad901025c81f8696f3ee61619526b963b7dc36435ac284f4497aa7ca",
"type":"signature.example",
"icon":"sha256:0048162a053eef4d4ce3fe7518615bef084403614f8bca43b40ae2e762e11e06",
},
{
"artifact_id":2,
"subject_artifact_id":81,
"size": 1234,
"digest":"sha256:94788818ad901025c81f8696f3ee61619526b963b7dc36435ac284f4497aa7cb",
"type":"sbom.example",
"icon":"sha256:0048162a053eef4d4ce3fe7518615bef084403614f8bca43b40ae2e762e11e06",
}
],
...
}

```

**Request All Artifact Accessories**

```yaml
GET /api/v2.0/projects/library/repositories/hello-world/artifacts/accessories?n=<integer>

```

```yaml
GET /api/v2.0/projects/library/repositories/hello-world/artifacts/accessories?n=10&artifactType={artifactType}
```

Response

```yaml
200 OK
Link: <url>; rel="next"

{
"accessories": [
{
"id": "<int>",
"digest": "<string>",
"media_type": "<string>",
"manifest_media_type": "<string>",
"size": <integer>
},
...
]
}
```


**Delete an artifact**

User Stories outline the behavior:

1. If the top-level artifact is deleted, all the accessories that associate with the artifact are deleted unless it has tag.
2. The accessory can be deleted individually.

```rest
DELETE /api/v2.0/projects/library/repositories/hello-world/artifacts/sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792

HTTP/1.1 200 OK
Server: nginx
Date: Thu, 22 Jul 2021 07:32:22 GMT
Content-Length: 0
Connection: keep-alive
Vary: Cookie
X-Harbor-Csrf-Token: u7bGUcekdbuVAVHuVl9tfuCx5EmJjPMMnL2S5hnPUudZzmZ8EdFX8KhfAIL6Dherx6kX2mk2VrknNghn165ORg==
X-Request-Id: 8d70f12a-9f73-4fc9-9e81-3bed24926254
Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'none'
```

**Delete artifact signature(all)**

```rest
DELETE /api/v2.0/projects/library/repositories/hello-world/artifacts/sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792/accessory?type=signature.cosign

HTTP/1.1 200 OK
Server: nginx
Date: Thu, 22 Jul 2021 07:32:22 GMT
Content-Length: 0
Connection: keep-alive
Vary: Cookie
X-Harbor-Csrf-Token: u7bGUcekdbuVAVHuVl9tfuCx5EmJjPMMnL2S5hnPUudZzmZ8EdFX8KhfAIL6Dherx6kX2mk2VrknNghn165ORg==
X-Request-Id: 8d70f12a-9f73-4fc9-9e81-3bed24926254
Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'none'
```

**Delete artifact signature(specific)**

```rest
DELETE /api/v2.0/projects/library/repositories/hello-world/artifacts/sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792/accessory?type=signature.cosign&digtest=sha256:94788818ad901025c81f8696f3ee61619526b963b7dc36435ac284f4497aa7cb

HTTP/1.1 200 OK
Server: nginx
Date: Thu, 22 Jul 2021 07:32:22 GMT
Content-Length: 0
Connection: keep-alive
Vary: Cookie
X-Harbor-Csrf-Token: u7bGUcekdbuVAVHuVl9tfuCx5EmJjPMMnL2S5hnPUudZzmZ8EdFX8KhfAIL6Dherx6kX2mk2VrknNghn165ORg==
X-Request-Id: 8d70f12a-9f73-4fc9-9e81-3bed24926254
Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'none'
```
Loading