WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content
Open
37 changes: 33 additions & 4 deletions .github/workflows/build-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ on:
branches:
- main
- release-*

jobs:
BUILD_PACKAGE:
env:
BUILD_PACKAGE: true
runs-on:
- oracle-vm-24cpu-96gb-x86-64
permissions:
id-token: write
contents: read
steps:
- name: Configure AWS credentials
uses: aws-actions/[email protected]
Expand All @@ -40,6 +42,8 @@ jobs:
- uses: actions/checkout@v5
with:
path: src/github.com/goharbor/harbor
- name: Install Cosign
uses: sigstore/[email protected]
- name: Build Base Image
if: |
contains(steps.changed-files.outputs.modified, 'Dockerfile.base') ||
Expand Down Expand Up @@ -87,6 +91,7 @@ jobs:
else
build_base_params=" BUILD_BASE=true PULL_BASE_FROM_DOCKERHUB=true PUSHBASEIMAGE=true REGISTRYUSER=\"${{ secrets.DOCKER_HUB_USERNAME }}\" REGISTRYPASSWORD=\"${{ secrets.DOCKER_HUB_PASSWORD }}\""
fi

sudo make package_offline GOBUILDTAGS="include_oss include_gcs" BASEIMAGETAG=${Harbor_Build_Base_Tag} VERSIONTAG=${Harbor_Assets_Version} PKGVERSIONTAG=${Harbor_Package_Version} TRIVYFLAG=true EXPORTERFLAG=true HTTPPROXY= ${build_base_params}
sudo make package_online GOBUILDTAGS="include_oss include_gcs" BASEIMAGETAG=${Harbor_Build_Base_Tag} VERSIONTAG=${Harbor_Assets_Version} PKGVERSIONTAG=${Harbor_Package_Version} TRIVYFLAG=true EXPORTERFLAG=true HTTPPROXY= ${build_base_params}
harbor_offline_build_bundle=$(basename harbor-offline-installer-*.tgz)
Expand All @@ -99,8 +104,32 @@ jobs:
cp ${harbor_online_build_bundle} harbor-online-installer-latest.tgz
uploader ${harbor_offline_build_bundle} $harbor_target_bucket
uploader ${harbor_online_build_bundle} $harbor_target_bucket
uploader harbor-offline-installer-latest.tgz $harbor_target_bucket
uploader harbor-online-installer-latest.tgz $harbor_target_bucket
echo "BUILD_BUNDLE=$harbor_offline_build_bundle" >> $GITHUB_ENV

echo "harbor_target_bucket=$harbor_target_bucket" >> $GITHUB_ENV

publishImage $target_branch $Harbor_Assets_Version "${{ secrets.DOCKER_HUB_USERNAME }}" "${{ secrets.DOCKER_HUB_PASSWORD }}"
- name: Sign Offline Installer with Cosign
run: |
cd src/github.com/goharbor/harbor
harbor_offline_build_bundle=$(ls harbor-offline-installer-*.tgz | head -n 1)
echo "Signing: $harbor_offline_build_bundle"
cosign sign-blob --yes --bundle=${harbor_offline_build_bundle}.bundle $harbor_offline_build_bundle

- name: Sign Online Installer with Cosign
run: |
cd src/github.com/goharbor/harbor
harbor_online_build_bundle=$(ls harbor-online-installer-*.tgz | head -n 1)
echo "Signing: $harbor_online_build_bundle"
cosign sign-blob --yes --bundle=${harbor_online_build_bundle}.bundle $harbor_online_build_bundle

- name: Upload Bundle Files to S3
run: |
cd src/github.com/goharbor/harbor
source tests/ci/build_util.sh
harbor_offline_bundle=$(ls harbor-offline-installer-*.tgz.bundle | head -n 1)
harbor_online_bundle=$(ls harbor-online-installer-*.tgz.bundle | head -n 1)
uploader ${harbor_offline_bundle} ${{ env.harbor_target_bucket }}
uploader ${harbor_online_bundle} ${{ env.harbor_target_bucket }}
uploader harbor-offline-installer-latest.tgz ${{ env.harbor_target_bucket }}
uploader harbor-online-installer-latest.tgz ${{ env.harbor_target_bucket }}

16 changes: 15 additions & 1 deletion .github/workflows/publish_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ on:
jobs:
release:
runs-on: oracle-vm-24cpu-96gb-x86-64
permissions:
contents: write
steps:
- uses: actions/checkout@v5
- name: Setup env
Expand Down Expand Up @@ -39,13 +41,22 @@ jobs:
src_online_package=harbor-online-installer-${{ env.BASE_TAG }}-${{ env.BUILD_NO }}.tgz
dst_offline_package=harbor-offline-installer-${{ env.CUR_TAG }}.tgz
dst_online_package=harbor-online-installer-${{ env.CUR_TAG }}.tgz
src_offline_bundle=${src_offline_package}.bundle
src_online_bundle=${src_online_package}.bundle
dst_offline_bundle=${dst_offline_package}.bundle
dst_online_bundle=${dst_online_package}.bundle

aws s3 cp s3://${{ secrets.HARBOR_RELEASE_BUILD }}/${{ env.BRANCH }}/${src_offline_package} s3://${{ secrets.HARBOR_RELEASE_BUILD }}/${{ env.BRANCH }}/${dst_offline_package}
aws s3 cp s3://${{ secrets.HARBOR_RELEASE_BUILD }}/${{ env.BRANCH }}/${src_online_package} s3://${{ secrets.HARBOR_RELEASE_BUILD }}/${{ env.BRANCH }}/${dst_online_package}
aws s3 cp s3://${{ secrets.HARBOR_RELEASE_BUILD }}/${{ env.BRANCH }}/${src_offline_bundle} s3://${{ secrets.HARBOR_RELEASE_BUILD }}/${{ env.BRANCH }}/${dst_offline_bundle}
aws s3 cp s3://${{ secrets.HARBOR_RELEASE_BUILD }}/${{ env.BRANCH }}/${src_online_bundle} s3://${{ secrets.HARBOR_RELEASE_BUILD }}/${{ env.BRANCH }}/${dst_online_bundle}

assets_path=$(pwd)/assets
source tools/release/release_utils.sh && getAssets ${{ secrets.HARBOR_RELEASE_BUILD }} ${{ env.BRANCH }} $dst_offline_package $dst_online_package ${{ env.PRERELEASE }} $assets_path
source tools/release/release_utils.sh && getAssets ${{ secrets.HARBOR_RELEASE_BUILD }} ${{ env.BRANCH }} $dst_offline_package $dst_online_package ${{ env.PRERELEASE }} $assets_path $dst_offline_bundle $dst_online_bundle
echo "OFFLINE_PACKAGE_PATH=$assets_path/$dst_offline_package" >> $GITHUB_ENV
echo "ONLINE_PACKAGE_PATH=$assets_path/$dst_online_package" >> $GITHUB_ENV
echo "OFFLINE_BUNDLE_PATH=$assets_path/$dst_offline_bundle" >> $GITHUB_ENV
echo "ONLINE_BUNDLE_PATH=$assets_path/$dst_online_bundle" >> $GITHUB_ENV
echo "MD5SUM_PATH=$assets_path/md5sum" >> $GITHUB_ENV
- name: Setup Docker
uses: docker-practice/actions-setup-docker@master
Expand All @@ -72,6 +83,7 @@ jobs:
body_path: ${{ env.RELEASE_NOTES_PATH }}
files: |
${{ env.OFFLINE_PACKAGE_PATH }}
${{ env.OFFLINE_BUNDLE_PATH }}
${{ env.MD5SUM_PATH }}
- name: GA Release
uses: softprops/action-gh-release@v2
Expand All @@ -80,5 +92,7 @@ jobs:
body_path: ${{ env.RELEASE_NOTES_PATH }}
files: |
${{ env.OFFLINE_PACKAGE_PATH }}
${{ env.OFFLINE_BUNDLE_PATH }}
${{ env.ONLINE_PACKAGE_PATH }}
${{ env.ONLINE_BUNDLE_PATH }}
${{ env.MD5SUM_PATH }}
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ For learning the architecture design of Harbor, check the document [Architecture
* Part 1: [New or changed APIs](https://editor.swagger.io/?url=https://raw.githubusercontent.com/goharbor/harbor/main/api/v2.0/swagger.yaml)

## Install & Run

**System requirements:**

**On a Linux host:** docker 20.10.10-ce+ and docker-compose 1.18.0+ .
Expand All @@ -61,6 +60,26 @@ Download binaries of **[Harbor release ](https://github.com/goharbor/harbor/rele
If you want to deploy Harbor on Kubernetes, please use the **[Harbor chart](https://github.com/goharbor/harbor-helm)**.

Refer to the **[documentation](https://goharbor.io/docs/)** for more details on how to use Harbor.
### Verifying Release Signatures
Starting with v2.15.0, Harbor release artifacts are cryptographically signed using Cosign to ensure authenticity and integrity.

Download the installers and signature bundles from the Harbor releases page.

#### Quick Verification
```bash
# Install Cosign (v2.0+)
brew install sigstore/tap/cosign

# Verify signature
cosign verify-blob \
--bundle harbor-offline-installer-v2.15.0.tgz.bundle \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
--certificate-identity-regexp '^https://github.com/goharbor/harbor/.github/workflows/build-package.yml@refs/(heads/main|tags/v.*)$' \
harbor-offline-installer-v2.15.0.tgz
```
- *Expected output:* Verified OK

- *Full verification guide:* [docs/signature-verification.md](docs/signature-verification.md)

## OCI Distribution Conformance Tests

Expand Down
109 changes: 109 additions & 0 deletions docs/signature-verification.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Harbor Release Signature Verification

> **Note:** Signature verification is available starting with Harbor v2.15.0. Earlier releases are not signed.

## Table of Contents
- [Overview](#overview)
- [Why Verify](#why-verify)
- [Prerequisites](#prerequisites)
- [Verification Steps](#verification-steps)
- [Troubleshooting](#troubleshooting)
- [What Gets Verified](#what-gets-verified)
- [Resources](#resources)

## Overview

Harbor release artifacts (installers) are cryptographically signed using [Cosign](https://docs.sigstore.dev/cosign/overview/) with keyless signing. This allows you to verify that downloads are authentic and unmodified.

## Why Verify

* Confirms the file came from Harbor's official build
* Detects any modifications or tampering
* Protects against malicious downloads

## Prerequisites

**Install Cosign (v2.0+):**
```bash
# macOS
brew install sigstore/tap/cosign

# Linux
curl -LO https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64
chmod +x cosign-linux-amd64
sudo mv cosign-linux-amd64 /usr/local/bin/cosign

# Windows (PowerShell)
Invoke-WebRequest -Uri "https://github.com/sigstore/cosign/releases/latest/download/cosign-windows-amd64.exe" -OutFile "cosign.exe"

# Verify installation
cosign version
```

## Verification Steps

### 1. Download Files
```bash
# Download installer and signature bundle (example v2.15.0)
wget https://github.com/goharbor/harbor/releases/download/v2.15.0/harbor-offline-installer-v2.15.0.tgz
wget https://github.com/goharbor/harbor/releases/download/v2.15.0/harbor-offline-installer-v2.15.0.tgz.bundle
```

### 2. Verify Signature
```bash
cosign verify-blob \
--bundle harbor-offline-installer-v2.15.0.tgz.bundle \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
--certificate-identity-regexp '^https://github.com/goharbor/harbor/.github/workflows/build-package.yml@refs/(heads/main|tags/v.*)$' \
harbor-offline-installer-v2.15.0.tgz
```

**Expected output:**
```
Verified OK
```

### 3. For Online Installer
```bash
wget https://github.com/goharbor/harbor/releases/download/v2.15.0/harbor-online-installer-v2.15.0.tgz
wget https://github.com/goharbor/harbor/releases/download/v2.15.0/harbor-online-installer-v2.15.0.tgz.bundle

cosign verify-blob \
--bundle harbor-online-installer-v2.15.0.tgz.bundle \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
--certificate-identity-regexp '^https://github.com/goharbor/harbor/.github/workflows/build-package.yml@refs/(heads/main|tags/v.*)$' \
harbor-online-installer-v2.15.0.tgz
```

## Troubleshooting

### Certificate identity doesn't match
**Cause:** Incorrect repository name in verification command
**Solution:** Ensure you're using `goharbor/harbor` in the `--certificate-identity-regexp` parameter

### Unable to find signature
**Cause:** Bundle file not in the same directory as the installer
**Solution:** Ensure both `.tgz` and `.tgz.bundle` files are in the current working directory

### Bad signature
**Cause:** Downloaded files are corrupted or incomplete
**Solution:** Re-download both the installer and bundle files from the official [Harbor releases page](https://github.com/goharbor/harbor/releases)

### Version not supported
**Cause:** Attempting to verify releases prior to v2.14.0
**Solution:** Signature verification is only available for Harbor v2.14.0 and later

## What Gets Verified

- **File authenticity** - Signed by official Harbor CI/CD workflow
- **File integrity** - No modifications since signing
- **Build provenance** - Logged in public Sigstore transparency log

## Resources

- [Cosign Documentation](https://docs.sigstore.dev/)
- [Harbor Releases](https://github.com/goharbor/harbor/releases)

---

**Applies to:** Harbor v2.15.0 and later
2 changes: 1 addition & 1 deletion make/pushimage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ fi

if [ "$PULL_BASE_FROM_DOCKERHUB" == "true" ];then
h2 "Remove local goharbor images"
DOCKER_RMI="docker rmi -f $(docker images | grep "${IMAGE%:*}" | awk '{print $3}') -f"
DOCKER_RMI="docker rmi -f $(docker images -q --filter reference="${IMAGE%:*}")"
info "$DOCKER_RMI"
DOCKER_RMI_OUTPUT=$($DOCKER_RMI)
if [ $? -ne 0 ];then
Expand Down
8 changes: 8 additions & 0 deletions tools/release/release_utils.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,22 @@ function getAssets {
local onlinePackage=$4
local prerelease=$5
local assetsPath=$6
local offlineBundle=$7
local onlineBundle=$8
mkdir $assetsPath && pushd $assetsPath
aws s3 cp s3://$bucket/$branch/$offlinePackage .
md5sum $offlinePackage > md5sum
if [ -n "$offlineBundle" ]; then
aws s3 cp s3://$bucket/$branch/$offlineBundle .
fi
# Pre-release does not handle online installer packages
if [ $prerelease = "false" ]
then
aws s3 cp s3://$bucket/$branch/$onlinePackage .
md5sum $onlinePackage >> md5sum
if [ -n "$onlineBundle" ]; then
aws s3 cp s3://$bucket/$branch/$onlineBundle .
fi
fi
popd
}
Expand Down