Skip to content

Commit

Permalink
Merge pull request #16 from agrasth/RTDEV-52486
Browse files Browse the repository at this point in the history
Worker Sample Improvement
  • Loading branch information
yashprit-jfrog authored Jan 7, 2025
2 parents 72c0ea1 + d41089b commit b2bed64
Show file tree
Hide file tree
Showing 9 changed files with 369 additions and 26 deletions.
88 changes: 85 additions & 3 deletions samples/artifactory/AFTER_CREATE/check-image-signature/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,87 @@
# After Create
# Check Image Signature

In this use case want to demonstrate a signature validation scenario.
This worker demonstrates a signature validation scenario. After a Docker image has been uploaded, the worker verifies if the image is signed by checking for the presence of a signature file (e.g., `.sig` file generated by cosign). If the image is not signed, the worker removes it.

After a docker image has been uploaded, we check if its signature (for instance .sig file generated by cosign) is also present.
## Worker Functionality

### Workflow Overview
1. **Intercept the Creation of a Docker Image:**
- The worker identifies Docker manifests by checking if the uploaded file ends with `manifest.json`.

2. **Verify the Signature:**
- The worker checks if a signature file corresponding to the manifest exists.
- If the image is unsigned, it removes the image from the repository.

3. **Remove Unsigned Images:**
- If the image is unsigned, the worker deletes it from the repository.
- If only one version of the image exists, the entire image is removed.
- Otherwise, only the unsigned version is deleted.

## Responses

### Response Types

- **Signed Image:**
```json
{
"message": "proceed"
}
```

- **Unsigned Image:**
```json
{
"message": "Removing unsigned image test-docker-repo:your-image-name/1.0/manifest.json"
}
```

- **Error During Signature Check:**
```json
{
"message": "Unexpected error: Cannot read properties of undefined (reading 'sha256')"
}
```

- **Error While Checking Signature:**
```json
{
"message": "Error while checking signature: Error message"
}
```


### Key Methods

- **`isDockerManifest(data)`**
- Identifies Docker manifests by checking if the file ends with `manifest.json`.

- **`isSigned(context, data)`**
- Verifies if the image is signed by checking for the presence of a signature file for the manifest.

- **`deleteImage(context, data)`**
- Removes the image from the repository if it is unsigned.

- **`findDeployedVersions(context, repoKey, repoName, limit)`**
- Finds versions of the image deployed in the repository.

- **`extractRepoInfos(data)`**
- Extracts repository information such as repository key, repository name, and version from the uploaded data.

- **`getImageSha256(context, data)`**
- Retrieves the SHA-256 checksum of the Docker manifest.

- **`runAql(context, query)`**
- Runs an AQL (Artifactory Query Language) query to fetch details about artifacts.

- **`deleteArtifact(context, repoKey, repoName)`**
- Deletes the specified artifact from the repository.

## Use Case

This worker ensures that only signed Docker images are stored in the repository, enhancing the security and integrity of the artifacts.

## Notes

- The worker assumes that the signature file is located in the `_uploads` directory and follows the naming convention `sha256-{manifestSha}.sig`.
- The worker uses AQL queries to identify existing versions and decide whether to delete the entire image or specific versions.
- Logs are added for troubleshooting and monitoring purposes.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "check-image-signature",
"description": "Run a script on AFTER_CREATE",
"version": "1.0.0",
"version": "1.0.1",
"scripts": {
"deploy": "jf worker deploy",
"undeploy": "jf worker rm \"check-image-signature\"",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,73 @@
# Block upload if the repoPath does not fit a given pattern
# Allow Upload by Pattern

This worker will block upload if the target path does not match a pattern. In this example the pattern is defined with a RegEx defined in the variable authorizedPathRegEx
## Overview

This worker script ensures that artifact uploads are allowed only if the target path matches a predefined pattern. This pattern is specified using a regular expression (`authorizedPathRegEx`). The script validates the repository path (`repoPath`) and blocks uploads that do not comply with the pattern.

## Functionality

- **Path Matching**: The worker validates repository paths against the regular expression:
```
/^org\/company\/(?:\w+.\/)+[\w\-\.]+\.(?:jar|war)$/
```
This regex allows paths that:
- Start with `org/company/`
- Contain subdirectories separated by `/`
- End with `.jar` or `.war`

- **Allowed Paths**: Examples of acceptable paths include:
- `org/company/src/app.jar`
- `org/company/package1/subPackage/webapp.war`

- **Blocked Paths**: Paths that do not match the pattern, such as `text.txt`, are disallowed.

## Response Examples

### When Path Matches the Pattern
```json
{
"status": 1,
"message": "RepoPath 'org/company/src/app.jar' is acceptable for the repository 'FIXTURE'",
"modifiedRepoPath": {
"key": "FIXTURE",
"path": "org/company/src/helloworld.jar",
"id": "FIXTURE:org/company/src/helloworld.jar"
}
}
```

### When Path Does Not Match the Pattern
```json
{
"status": 2,
"message": "RepoPath 'file.txt' does not match the regex /^org\\/company\\/(?:\\w+.\\/)+[\\w\\-\\.]+\\.(?:jar|war)$/ for the repository 'FIXTURE'",
"modifiedRepoPath": {
"key": "FIXTURE",
"path": "text.txt",
"id": "FIXTURE:text.txt"
}
}
```

## Error Handling

If an error occurs during the path validation process, the script logs the error and allows the upload with a warning:

```json
{
"status": 3,
"message": "An error occurred during the check. Proceed with warning.",
"modifiedRepoPath": {
"key": "FIXTURE",
"path": "example/path.txt",
"id": "FIXTURE:example/path.txt"
}
}
```

## Notes

1. **Custom Patterns**: Modify the `authorizedPathRegEx` variable to enforce different patterns based on project requirements.
2. **Security**: This script helps maintain a controlled upload environment by enforcing consistent repository paths.
3. **Error Logging**: All failed attempts are logged for auditing and debugging purposes.
4. **Extensions**: Although the current pattern focuses on `.jar` and `.war` files, it can be extended to support additional file types.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "allow-upload-by-pattern",
"description": "Run a script on BEFORE_UPLOAD",
"version": "1.0.0",
"version": "1.0.1",
"scripts": {
"deploy": "jf worker deploy",
"undeploy": "jf worker rm \"allow-upload-by-pattern\"",
Expand Down
102 changes: 97 additions & 5 deletions samples/artifactory/BEFORE_UPLOAD/check-project-repository/README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,101 @@
# Before Upload
# Worker: check-project-repository

This use case will look into the manifest for a **LABEL** named `org.jfrog.artifactory.projectKey`.
This worker is designed to intercept the upload of Docker image manifests and ensure that they target the correct project repository. It validates that the Docker image manifest contains a specific label (`org.jfrog.artifactory.projectKey`) and that the target repository is prefixed with the same project key.

This **LABEL** should contains the target _projectKey_.
## Use Case

Then the worker will check if the target repository belongs to the matching project.
### **LABEL Validation**
The worker inspects the Docker manifest for a **LABEL** named `org.jfrog.artifactory.projectKey`. This label should contain the target _projectKey_.

Meaning that the target repository should be prefixed by the _projectKey_.
### **Repository Validation**
The worker then verifies if the target repository belongs to the corresponding project by ensuring the repository name is prefixed with the _projectKey_.

### **Cleanup**
If the repository validation fails, the worker cleans up previously uploaded layers, ensuring no partial uploads are left in the repository.

## Responses
The worker can return the following responses:

### **1. Proceed**
Indicates that the upload is valid and should continue.

```json
{
"status": 1,
"message": "Proceed",
"modifiedRepoPath": {
"key": "test-docker-repo",
"path": "your-image-name/_uploads/af365c10-bca5-4091-bec1-f51670750f62.patch",
"id": "test-docker-repo:your-image-name/_uploads/af365c10-bca5-4091-bec1-f51670750f62.patch"
}
}
```

### **2. Not Targeting Project Repository**
Indicates that the upload does not target a project repository matching the project key.

```json
{
"status": 2,
"message": "Not targetting a project 'your-project-key' repository",
"modifiedRepoPath": {
"key": "test-docker-repo",
"path": "your-image-name/1.0/manifest.json",
"id": "test-docker-repo:your-image-name/1.0/manifest.json"
}
}
```

### **3. Project Key Missing**
Indicates that the `org.jfrog.artifactory.projectKey` label is missing from the Docker manifest.

```json
{
"status": 2,
"message": "The project key is missing. Please add the label org.jfrog.artifactory.projectKey to the manifest.",
"modifiedRepoPath": {
"key": "test-docker-repo",
"path": "your-image-name/1.0/manifest.json",
"id": "test-docker-repo:your-image-name/1.0/manifest.json"
}
}
```

### **4. Error**
Indicates an error occurred during the worker execution.

```json
{
"status": 3,
"message": "Error: Cannot read properties of undefined (reading 'docker.label.org.jfrog.artifactory.projectKey')",
"modifiedRepoPath": {
"key": "test-repo",
"path": "manifest.json",
"id": "test-repo:manifest.json"
}
}
```

### **5. Layers Cleanup**
If the repository validation fails, previously uploaded layers are cleaned up. The worker logs the cleanup process and ensures no unused layers are left.

## Worker Flow
1. **Intercepts Uploads**: The worker intercepts uploads for Docker manifests (files ending in `manifest.json`).
2. **Validates LABEL**: Checks for the presence of `org.jfrog.artifactory.projectKey` in the manifest.
3. **Validates Repository**: Confirms that the target repository is prefixed by the project key.
4. **Handles Failures**:
- Stops the upload if the repository is invalid.
- Cleans up previously uploaded layers if necessary.
5. **Logs and Returns**: Provides detailed responses for both success and failure cases.

## Implementation Notes
- The worker uses AQL queries to search for artifacts in Artifactory.
- Only intercepts Docker manifests; other layers are ignored.
- Cleanup ensures no orphaned layers remain after a failed validation.

## How to Use
1. Ensure the `org.jfrog.artifactory.projectKey` label is added to your Docker manifest during image build.
2. Push the image to a repository prefixed with the same project key.
3. The worker will validate the upload and proceed or stop based on the defined rules.

For more details, refer to the worker script or contact the platform administrator.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "redirect-to-project-repo",
"description": "Run a script on BEFORE_UPLOAD",
"version": "1.0.0",
"version": "1.0.1",
"scripts": {
"deploy": "jf worker deploy",
"undeploy": "jf worker rm \"redirect-to-project-repo\"",
Expand Down
Loading

0 comments on commit b2bed64

Please sign in to comment.