-
Notifications
You must be signed in to change notification settings - Fork 0
Garnet privacy proxy #1
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
base: feature-button-i
Are you sure you want to change the base?
Changes from all commits
f4d246a
af8ac4a
fdbabc1
a93e248
adf5044
bdaa44a
c6c82ba
25eb5c2
9a6488d
b9885eb
a3a5b78
f5228c0
93ab3be
1d4d30d
a7cf0ae
db24a73
6b23951
795f169
bd1e22e
5db92c4
2d10dc1
21af429
a331145
ecec5a4
61b81e6
f48eba5
a88674e
f3b5fce
8b25fe4
03d698a
fcc78f0
effde70
714c7e7
117eabc
91c5b9f
71d9d1a
bda4ae1
3c2b4d3
ddd6b94
cfcf209
09e454d
e48fda0
f4fb719
834a8f8
e480afd
72dc280
8a44210
00d21a1
8fc2136
227ef95
5922765
299976f
0a8d70b
de3bd32
0205434
5abb6bb
0f4bdbf
0f1fe34
437fb22
b161bcc
bc2e680
2e1d066
9f5623c
d8d55aa
e9adc75
bc5e3d3
f685281
40f9076
6bd51f5
076cbfa
430be3d
d29a33b
10f363d
a0723e9
55d70f0
94d4239
f199a3d
bc828ed
5ffa6b5
a29753d
ee3f86b
e2767d2
e5b43b8
c430e52
0727f8a
eef251e
812d8a8
972c90c
76cb56f
8271022
0dc109e
05d4e53
0924290
e7d470f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,291 @@ | ||
| name: Build and Deploy Garnet | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| push: | ||
| tags: | ||
| - v* | ||
| branches: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. leave only main and staging. |
||
| - deploy/staging | ||
| - deploy/prod | ||
| - garnet-privacy-proxy | ||
| pull_request: | ||
| branches: | ||
| - garnet-privacy-proxy | ||
|
|
||
| jobs: | ||
|
|
||
| get-meta: | ||
| runs-on: ubuntu-latest | ||
| outputs: | ||
| version: ${{ steps.get_version.outputs.version }} | ||
| tag: ${{ steps.get_tag.outputs.name }} | ||
| revision: ${{ steps.get_revision.outputs.revision }} | ||
| proxy_changed: ${{ steps.changes.outputs.proxy }} | ||
| webui_changed: ${{ steps.changes.outputs.webui }} | ||
| steps: | ||
| - name: Checkout | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The workflow performs repository checkout using raw git clone commands with a PAT (GH_TOKEN) instead of using the official actions/checkout action. This bypasses GitHub Actions native authentication and security controls, increases token exposure risk in logs/process lists, loses shallow clone optimization, submodule handling, and provenance guarantees. and makes workflow maintenance harder. Remediation:
Use the built-in GITHUB_TOKEN unless cross-repo access is strictly required. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing pinned GitHub Actions versions : The workflow barely uses official actions and does not pin versions to commit SHAs. Use:
Prefer SHA-pinned actions in production:
Apply this to all third-party actions. |
||
| uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - name: Get version | ||
| id: get_version | ||
| run: | | ||
| if [[ "${GITHUB_REF}" == refs/tags/v* ]]; then | ||
| echo "version=${GITHUB_REF_NAME}" >> $GITHUB_OUTPUT | ||
| else | ||
| echo "version=$(cat version/VERSION).nightly" >> $GITHUB_OUTPUT | ||
| fi | ||
|
|
||
| - name: Get revision | ||
| id: get_revision | ||
| run: echo "revision=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT | ||
|
|
||
| - name: Get tag | ||
| id: get_tag | ||
| run: | | ||
| case "${GITHUB_REF}" in | ||
| refs/heads/deploy/staging) NAME=staging ;; | ||
| refs/heads/deploy/prod) NAME=prod ;; | ||
| refs/tags/v*) NAME=latest ;; | ||
| *) NAME="${FALLBACK}" ;; | ||
| esac | ||
| echo "name=${NAME}" >> $GITHUB_OUTPUT | ||
| env: | ||
| FALLBACK: ${{ steps.get_revision.outputs.revision }} | ||
|
|
||
| - name: Check changed files | ||
| id: changes | ||
| run: | | ||
| git diff --name-only ${{ github.event.before }} ${{ github.sha }} | grep '^backend/privacy_proxy/' \ | ||
| && echo "proxy=true" >> $GITHUB_OUTPUT \ | ||
| || echo "proxy=false" >> $GITHUB_OUTPUT | ||
| git diff --name-only ${{ github.event.before }} ${{ github.sha }} | grep -E '^src/|^backend/open_webui/' \ | ||
| && echo "webui=true" >> $GITHUB_OUTPUT \ | ||
| || echo "webui=false" >> $GITHUB_OUTPUT | ||
|
|
||
| build-proxy: | ||
| needs: get-meta | ||
| if: needs.get-meta.outputs.proxy_changed == 'true' | ||
| runs-on: ubuntu-latest | ||
| environment: production | ||
| permissions: | ||
| contents: read | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - name: Free disk space | ||
| run: | | ||
| sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache | ||
| df -h | ||
|
|
||
| - name: Set up Docker Buildx | ||
| run: | | ||
| docker buildx create --use --name garnet-builder | ||
| docker buildx inspect --bootstrap | ||
|
|
||
| - name: Login to Harbor | ||
| run: | | ||
| echo "${{ secrets.HARBOR_PASSWORD }}" | docker login harbor.enclaive.cloud \ | ||
| -u "${{ secrets.HARBOR_USERNAME }}" --password-stdin | ||
|
|
||
| - name: Build and push proxy image | ||
| id: build-proxy | ||
| run: | | ||
| DIGEST=$(docker buildx build \ | ||
| -f backend/privacy_proxy/Dockerfile \ | ||
| --build-arg PRODUCT_VERSION=${{ needs.get-meta.outputs.version }} \ | ||
| --build-arg PRODUCT_REVISION=${{ needs.get-meta.outputs.revision }} \ | ||
| --cache-from type=registry,ref=harbor.enclaive.cloud/garnetdemo/privacy-proxy:cache \ | ||
| --cache-to type=inline \ | ||
| --tag harbor.enclaive.cloud/garnetdemo/privacy-proxy:${{ needs.get-meta.outputs.tag }} \ | ||
| --tag harbor.enclaive.cloud/garnetdemo/privacy-proxy:${{ needs.get-meta.outputs.version }} \ | ||
| --tag harbor.enclaive.cloud/garnetdemo/privacy-proxy:${{ needs.get-meta.outputs.revision }} \ | ||
| --tag harbor.enclaive.cloud/garnetdemo/privacy-proxy:gh-run-${{ github.run_id }}-${{ github.run_attempt }}-${{ github.run_number }} \ | ||
| --push \ | ||
| --metadata-file /tmp/proxy-meta.json \ | ||
| backend/privacy_proxy/ && \ | ||
| cat /tmp/proxy-meta.json | python3 -c "import sys,json; print(json.load(sys.stdin)['containerimage.digest'])") | ||
| echo "digest=harbor.enclaive.cloud/garnetdemo/privacy-proxy@${DIGEST}" >> $GITHUB_OUTPUT | ||
|
|
||
| - name: Install cosign | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cosign installation without checksum verification: Issue:
Use official cosign installer : https://github.com/marketplace/actions/cosign-installer |
||
| uses: sigstore/cosign-installer@ba7bc0a3fef59531c69a25acd34668d6d3fe6f22 | ||
|
|
||
| - name: Sign proxy image | ||
| run: | | ||
| echo "${{ secrets.COSIGN_PRIVATE_KEY }}" > /tmp/cosign.key | ||
| chmod 600 /tmp/cosign.key | ||
| COSIGN_PASSWORD="" cosign sign --yes --key /tmp/cosign.key \ | ||
| ${{ steps.build-proxy.outputs.digest }} | ||
| rm /tmp/cosign.key | ||
|
|
||
| - name: Install Syft | ||
| run: | | ||
| curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh \ | ||
| | sh -s -- -b /usr/local/bin | ||
|
|
||
| - name: Generate SBOM + attest proxy | ||
| run: | | ||
| echo "${{ secrets.COSIGN_PRIVATE_KEY }}" > /tmp/cosign.key | ||
| chmod 600 /tmp/cosign.key | ||
| syft ${{ steps.build-proxy.outputs.digest }} -o spdx-json > /tmp/sbom-proxy.spdx.json | ||
| COSIGN_PASSWORD="" cosign attest --yes \ | ||
| --key /tmp/cosign.key \ | ||
| --type spdxjson \ | ||
| --predicate /tmp/sbom-proxy.spdx.json \ | ||
| ${{ steps.build-proxy.outputs.digest }} | ||
| rm /tmp/cosign.key | ||
|
|
||
| - name: Attest provenance proxy | ||
| run: | | ||
| echo "${{ secrets.COSIGN_PRIVATE_KEY }}" > /tmp/cosign.key | ||
| chmod 600 /tmp/cosign.key | ||
| cat > /tmp/provenance-proxy.json << EOF | ||
| { | ||
| "buildType": "https://github.com/enclaive/garnet", | ||
| "builder": {"id": "github-actions"}, | ||
| "invocation": { | ||
| "configSource": { | ||
| "uri": "git+https://github.com/enclaive/garnet", | ||
| "digest": {"sha1": "${{ github.sha }}"} | ||
| } | ||
| } | ||
| } | ||
| EOF | ||
| COSIGN_PASSWORD="" cosign attest --yes \ | ||
| --key /tmp/cosign.key \ | ||
| --type slsaprovenance \ | ||
| --predicate /tmp/provenance-proxy.json \ | ||
| ${{ steps.build-proxy.outputs.digest }} | ||
| rm /tmp/cosign.key | ||
|
|
||
| - name: Save SBOM + provenance to cVM | ||
| run: | | ||
| mkdir -p ~/.ssh | ||
| echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa | ||
| chmod 600 ~/.ssh/id_rsa | ||
| ssh-keyscan ${{ secrets.CVM_HOST }} >> ~/.ssh/known_hosts | ||
| ssh root@${{ secrets.CVM_HOST }} "mkdir -p /opt/garnet/sbom" | ||
| scp /tmp/sbom-proxy.spdx.json root@${{ secrets.CVM_HOST }}:/opt/garnet/sbom/sbom-proxy-${{ needs.get-meta.outputs.revision }}.spdx.json | ||
| scp /tmp/provenance-proxy.json root@${{ secrets.CVM_HOST }}:/opt/garnet/sbom/provenance-proxy-${{ needs.get-meta.outputs.revision }}.json | ||
|
|
||
| python-checks: | ||
| needs: [get-meta, build-proxy] | ||
| if: needs.get-meta.outputs.proxy_changed == 'true' | ||
| uses: ./.github/workflows/pythoncheck.yml | ||
| with: | ||
| image_tag: ${{ needs.get-meta.outputs.revision }} | ||
| secrets: | ||
| HARBOR_USERNAME: ${{ secrets.HARBOR_USERNAME }} | ||
| HARBOR_PASSWORD: ${{ secrets.HARBOR_PASSWORD }} | ||
|
|
||
| build-webui: | ||
| needs: get-meta | ||
| if: needs.get-meta.outputs.webui_changed == 'true' | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - name: Free disk space | ||
| run: | | ||
| sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache | ||
| df -h | ||
|
|
||
| - name: Set up Docker Buildx | ||
| run: | | ||
| docker buildx create --use --name garnet-builder | ||
| docker buildx inspect --bootstrap | ||
|
|
||
| - name: Login to Harbor | ||
| run: | | ||
| echo "${{ secrets.HARBOR_PASSWORD }}" | docker login harbor.enclaive.cloud \ | ||
| -u "${{ secrets.HARBOR_USERNAME }}" --password-stdin | ||
|
|
||
| - name: Build and push webui image | ||
| id: build-webui | ||
| run: | | ||
| DIGEST=$(docker buildx build \ | ||
| --build-arg PRODUCT_VERSION=${{ needs.get-meta.outputs.version }} \ | ||
| --build-arg PRODUCT_REVISION=${{ needs.get-meta.outputs.revision }} \ | ||
| --cache-from type=registry,ref=harbor.enclaive.cloud/garnetdemo/garnet-webui:cache \ | ||
| --cache-to type=registry,ref=harbor.enclaive.cloud/garnetdemo/garnet-webui:cache,mode=max \ | ||
| --tag harbor.enclaive.cloud/garnetdemo/garnet-webui:${{ needs.get-meta.outputs.tag }} \ | ||
| --tag harbor.enclaive.cloud/garnetdemo/garnet-webui:${{ needs.get-meta.outputs.version }} \ | ||
| --tag harbor.enclaive.cloud/garnetdemo/garnet-webui:${{ needs.get-meta.outputs.revision }} \ | ||
| --tag harbor.enclaive.cloud/garnetdemo/garnet-webui:gh-run-${{ github.run_id }}-${{ github.run_attempt }}-${{ github.run_number }} \ | ||
| --push \ | ||
| --metadata-file /tmp/webui-meta.json \ | ||
| . && \ | ||
| cat /tmp/webui-meta.json | python3 -c "import sys,json; print(json.load(sys.stdin)['containerimage.digest'])") | ||
| echo "digest=harbor.enclaive.cloud/garnetdemo/garnet-webui@${DIGEST}" >> $GITHUB_OUTPUT | ||
|
|
||
| - name: Install cosign | ||
| uses: sigstore/cosign-installer@ba7bc0a3fef59531c69a25acd34668d6d3fe6f22 | ||
|
|
||
| - name: Sign webui image | ||
| run: | | ||
| sleep 10 | ||
| echo "${{ secrets.COSIGN_PRIVATE_KEY }}" > /tmp/cosign.key | ||
| chmod 600 /tmp/cosign.key | ||
| COSIGN_PASSWORD="" cosign sign --yes --key /tmp/cosign.key \ | ||
| ${{ steps.build-webui.outputs.digest }} | ||
| rm /tmp/cosign.key | ||
|
|
||
| - name: Install Syft | ||
| run: | | ||
| curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh \ | ||
| | sh -s -- -b /usr/local/bin | ||
|
|
||
| - name: Generate SBOM + attest webui | ||
| run: | | ||
| echo "${{ secrets.COSIGN_PRIVATE_KEY }}" > /tmp/cosign.key | ||
| chmod 600 /tmp/cosign.key | ||
| syft ${{ steps.build-webui.outputs.digest }} -o spdx-json > /tmp/sbom-webui.spdx.json | ||
| COSIGN_PASSWORD="" cosign attest --yes \ | ||
| --key /tmp/cosign.key \ | ||
| --type spdxjson \ | ||
| --predicate /tmp/sbom-webui.spdx.json \ | ||
| ${{ steps.build-webui.outputs.digest }} | ||
| rm /tmp/cosign.key | ||
|
|
||
| - name: Attest provenance webui | ||
| run: | | ||
| echo "${{ secrets.COSIGN_PRIVATE_KEY }}" > /tmp/cosign.key | ||
| chmod 600 /tmp/cosign.key | ||
| cat > /tmp/provenance-webui.json << EOF | ||
| { | ||
| "buildType": "https://github.com/enclaive/garnet", | ||
| "builder": {"id": "github-actions"}, | ||
| "invocation": { | ||
| "configSource": { | ||
| "uri": "git+https://github.com/enclaive/garnet", | ||
| "digest": {"sha1": "${{ github.sha }}"} | ||
| } | ||
| } | ||
| } | ||
| EOF | ||
| COSIGN_PASSWORD="" cosign attest --yes \ | ||
| --key /tmp/cosign.key \ | ||
| --type slsaprovenance \ | ||
| --predicate /tmp/provenance-webui.json \ | ||
| ${{ steps.build-webui.outputs.digest }} | ||
| rm /tmp/cosign.key | ||
|
|
||
| - name: Save SBOM + provenance to cVM | ||
| run: | | ||
| mkdir -p ~/.ssh | ||
| echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa | ||
| chmod 600 ~/.ssh/id_rsa | ||
| ssh-keyscan ${{ secrets.CVM_HOST }} >> ~/.ssh/known_hosts | ||
| ssh root@${{ secrets.CVM_HOST }} "mkdir -p /opt/garnet/sbom" | ||
| scp /tmp/sbom-webui.spdx.json root@${{ secrets.CVM_HOST }}:/opt/garnet/sbom/sbom-webui-${{ needs.get-meta.outputs.revision }}.spdx.json | ||
| scp /tmp/provenance-webui.json root@${{ secrets.CVM_HOST }}:/opt/garnet/sbom/provenance-webui-${{ needs.get-meta.outputs.revision }}.json | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| name: Proxy Test Suite | ||
|
|
||
| on: | ||
| workflow_call: | ||
| secrets: | ||
| SSH_PRIVATE_KEY: | ||
| required: true | ||
| CVM_HOST: | ||
| required: true | ||
|
|
||
| jobs: | ||
| run-tests: | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| steps: | ||
| - name: Run proxy test suite | ||
| run: | | ||
| mkdir -p ~/.ssh | ||
| echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa | ||
| chmod 600 ~/.ssh/id_rsa | ||
| ssh-keyscan ${{ secrets.CVM_HOST }} >> ~/.ssh/known_hosts | ||
| ssh root@${{ secrets.CVM_HOST }} \ | ||
| "docker exec -w /service garnet-privacy-proxy-1 python3 app/test_proxy.py" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please remove any direct container execution tests on production host |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing SBOM generation and provenance attestation : Images are signed but no SBOM or SLSA provenance is generated.
Add : Syft SBOM generation or Cosign attestations