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

ci: sgx ci/cd #631

Open
wants to merge 19 commits into
base: dev
Choose a base branch
from
43 changes: 43 additions & 0 deletions .github/scripts/gramine.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#/bin/sh
# this is to be ran in a docker container via an github action that has gramine set-up already e.g.,
# notaryserverbuilds.azurecr.io/builder/gramine
# with sgx hardware:
# ./gramine.sh sgx
#
# without:
# ./gramine.sh
##

if [ -z "$1" ]
then
run='gramine-direct notary-server &'

else
run='gramine-sgx notary-server &'
fi



curl https://sh.rustup.rs -sSf | sh -s -- -y
. "$HOME/.cargo/env"
apt install libssl-dev

gramine-sgx-gen-private-key
SGX=1 make
gramine-sgx-sign -m notary-server.manifest -o notary-server.sgx
mr_enclave=$(gramine-sgx-sigstruct-view --verbose --output-format=json notary-server.sig |jq .mr_enclave)
echo "mrenclave=$mr_enclave" >> "$GITHUB_OUTPUT"
echo "#### sgx mrenclave" | tee >> $GITHUB_STEP_SUMMARY
echo "\`\`\`${mr_enclave}\`\`\`" | tee >> $GITHUB_STEP_SUMMARY
eval "$run"
sleep 5

if [ "$1" ]; then
curl 127.0.0.1:7047/info
else
quote=$(curl 127.0.0.1:7047/info | jq .quote.rawQuote)
echo $quote
echo "quote=$quote" >> $GITHUB_OUTPUT
echo "#### 🔒 signed quote ${quote}" | tee >> $GITHUB_STEP_SUMMARY
echo "${quote}" | tee >> $GITHUB_STEP_SUMMARY
fi
9 changes: 8 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,11 @@ jobs:
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: lcov.info
fail_ci_if_error: true
fail_ci_if_error: true
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
trigger-deployment:
trigger-tee-deployment:

Copy link
Member

@yuroitaki yuroitaki Oct 22, 2024

Choose a reason for hiding this comment

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

wouldn't this deployment run everytime a PR is raised? as the trigger condition in this ci.yml is

on:
  push:
    branches:
      - dev
    tags:
      - "[v]?[0-9]+.[0-9]+.[0-9]+*"
  pull_request:
     ...

Copy link
Member

Choose a reason for hiding this comment

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

We can add this to the trigger-tee-deployment job:

    # only for dev branch and tags
    if: github.event_name == 'push' && (startsWith(github.ref, 'refs/tags/') || github.ref == 'refs/heads/dev')

trigger-deployment:
# doing this here due to feedback @ https://github.com/tlsnotary/tlsn/pull/631#issuecomment-2415806267
needs: tests-integration
uses: ./.github/workflows/tee-cd.yml
with:
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
# what this is supposed to do -> $ref is the tag: e.g., v0.1.0-alpha.7; pass the $ref string to the cd script and update reverse proxy / deploy
# pass the $ref string to the cd script and update reverse proxy / deploy
# $ref is the tag: e.g., v0.1.0-alpha.7

# what this is supposed to do -> $ref is the tag: e.g., v0.1.0-alpha.7; pass the $ref string to the cd script and update reverse proxy / deploy
ref: ${{ github.ref_name }}
156 changes: 156 additions & 0 deletions .github/workflows/tee-cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
name: azure-tee-release

permissions:
contents: read
id-token: write
attestations: write

on:
workflow_dispatch:
inputs:
ref:
description: 'git branch'
required: false
default: 'dev'
type: string

#on:
# release:
# types: [published]
# branches:
# - 'releases/**'
Comment on lines +17 to +21
Copy link
Member

Choose a reason for hiding this comment

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

remove or activate?


env:
GIT_COMMIT_HASH: ${{ github.event.pull_request.head.sha || github.sha }}
GIT_COMMIT_TIMESTAMP: ${{ github.event.repository.updated_at}}
Copy link
Member

Choose a reason for hiding this comment

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

does github.event.repository.updated_at always refer to the timestamp of the head commit? It seems like the timestamp ll also be updated if someone updates e.g. the description of the repo (https://github.com/orgs/community/discussions/24442)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

  • help me understand how you are using the timestamp value downstream
  • how would this workflow get triggered in a way where the timestamp value was wrong?
    • is someone updating the description not a relevant timestamp update?

Copy link
Member

Choose a reason for hiding this comment

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

The timestamp ll be returned as part of the /info endpoint:

{
    "version": "0.1.0-alpha.7",
    "publicKey": "-----BEGIN PUBLIC KEY----- ...",
    "gitCommitHash": "99e02fb388c2e791d03c3426bd0411395bfaf453",
    "gitCommitTimestamp": "2024-10-14T20:23:19+02:00"
}

It's just an extra metadata to let end user know 'when' the code running in the server was last updated, as it's the timestamp of "gitCommitHash", the head commit.

So ya it shouldn't be the timestamp when someone updates the repo description / create a wiki page some time after the head commit is committed.

REGISTRY: notaryserverbuilds.azurecr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
update-reverse-proxy:
Copy link
Member

Choose a reason for hiding this comment

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

can we add a check to ensure that these cd steps only run after the ci integration test passes, i.e. https://github.com/tlsnotary/tlsn/blob/main/.github/workflows/cd-server.yml#L47-L56

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

  • the trigger is on release publish, so implicity the ci step would have ran ? Or is there something im missing?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

  • going to refactor this to be a core part of cd, needs more testing

  • initially this was built as a sidecar deployment, hence the trigger being post-release.

permissions:
contents: write
environment: tee
runs-on: [self-hosted, linux]
outputs:
teeport: ${{ steps.portbump.outputs.newport}}
deploy: ${{ steps.portbump.outputs.deploy}}
steps:
- name: checkout repository
uses: actions/checkout@v4
- name: update caddyfile
id: portbump
env:
RELEASE_TAG: ${{ github.event.release.tag_name || inputs.ref }}
Copy link
Member

Choose a reason for hiding this comment

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

since we do tag push to trigger release, instead of github.event.release.tag_name, it should be $GITHUB_REF_NAME

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

  • why does github.event.release.tag_name not suffice here?

run: |
echo "tag: $RELEASE_TAG"
NEXT_PORT=$(bash cd-scripts/tee/azure/updateproxy.sh 'cd-scripts/tee/azure/Caddyfile' $RELEASE_TAG)
echo "newport=$NEXT_PORT" >> $GITHUB_OUTPUT
echo "new deploy port: $NEXT_PORT 🚀" >> $GITHUB_STEP_SUMMARY
chmod +r -R cd-scripts/tee/azure/
- name: Deploy updated Caddyfile to server
if: ${{ steps.portbump.outputs.deploy == 'new' }}
yuroitaki marked this conversation as resolved.
Show resolved Hide resolved
uses: appleboy/[email protected]
with:
host: ${{ secrets.AZURE_TEE_PROD_HOST }}
username: ${{ secrets.AZURE_PROD_TEE_USERNAME }}
key: ${{ secrets.AZURE_TEE_PROD_KEY }}
source: "cd-scripts/tee/azure/Caddyfile"
target: "~/"
- name: Reload Caddy on server
if: ${{ steps.portbump.outputs.deploy == 'new' }}
uses: appleboy/[email protected]
with:
host: ${{ secrets.AZURE_TEE_PROD_HOST }}
username: ${{ secrets.AZURE_PROD_TEE_USERNAME }}
key: ${{ secrets.AZURE_TEE_PROD_KEY }}
script: |
sudo cp ~/cd-scripts/tee/azure/Caddyfile /etc/caddy/Caddyfile
sudo systemctl reload caddy
build-measure:
environment: tee
runs-on: [self-hosted, linux]
needs: [ update-reverse-proxy ]
container:
image: notaryserverbuilds.azurecr.io/prod/gramine
credentials:
username: notaryserverbuilds
password: ${{ secrets.AZURE_CR_BUILDS_PW }}
env:
GIT_COMMIT_HASH: ${{ github.event.pull_request.head.sha || github.sha }}
volumes:
- /var/run/aesmd/aesm.socket:/var/run/aesmd/aesm.socket
options: "--device /dev/sgx_enclave"
steps:
- name: get code
uses: actions/checkout@v4
- name: sccache
if: github.event_name != 'release'
# && github.event_name != 'workflow_dispatch'
uses: mozilla-actions/[email protected]
- name: set rust env for scc
if: github.event_name != 'release'
# && github.event_name != 'workflow_dispatch'
run: |
echo "SCCACHE_GHA_ENABLED=true" >> $GITHUB_ENV
echo "RUSTC_WRAPPER=sccache" >> $GITHUB_ENV
- name: reverse proxy port
run: echo "${{needs.update-reverse-proxy.outputs.teeport}}" | tee >> $GITHUB_STEP_SUMMARY
- name: get hardware measurement
working-directory: ${{ github.workspace }}/crates/notary/server/tee
run: |
chmod +x ../../../../.github/scripts/gramine.sh && ../../../../.github/scripts/gramine.sh sgx
artifact-deploy:
environment: tee
runs-on: [self-hosted, linux]
needs: [ build-measure, update-reverse-proxy ]
steps:
- name: auth to registry
uses: docker/login-action@v3
with:
registry: notaryserverbuilds.azurecr.io
username: notaryserverbuilds
password: ${{ secrets.AZURE_CR_BUILDS_PW }}
- name: get code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
Copy link
Member

Choose a reason for hiding this comment

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

No need to add directory of dockerfile here? context argument?

- name: Get Git commit timestamps
run: echo "TIMESTAMP=$(git log -1 --pretty=%ct)" >> $GITHUB_ENV
- name: Build and push
id: deploypush
uses: docker/build-push-action@v6
with:
provenance: mode=max
no-cache: true
context: ${{ github.workspace }}/crates/notary/server/tee
push: true
tags: notaryserverbuilds.azurecr.io/prod/notary-sgx:${{ env.GIT_COMMIT_HASH }}
labels: ${{needs.update-reverse-proxy.outputs.teeport}}
env:
# reproducible builds: https://github.com/moby/buildkit/blob/master/docs/build-repro.md#source_date_epoch
SOURCE_DATE_EPOCH: ${{ env.TIMESTAMP }}
- name: Generate SBOM
uses: anchore/sbom-action@v0
with:
image: notaryserverbuilds.azurecr.io/prod/notary-sgx:${{ env.GIT_COMMIT_HASH }}
format: 'cyclonedx-json'
output-file: 'sbom.cyclonedx.json'
# attestation section ::
# https://docs.docker.com/build/ci/github-actions/attestations/
- name: Attest
uses: actions/attest-build-provenance@v1
with:
subject-name: notaryserverbuilds.azurecr.io/prod/notary-sgx
subject-digest: ${{ steps.deploypush.outputs.digest }}
push-to-registry: true
-
name: run
run: |
if [[ ${{ needs.update-reverse-proxy.outputs.deploy }} == 'new' ]]; then
docker run --device /dev/sgx_enclave --device /dev/sgx_provision --volume=/var/run/aesmd/aesm.socket:/var/run/aesmd/aesm.socket -p ${{needs.update-reverse-proxy.outputs.teeport}}:7047 notaryserverbuilds.azurecr.io/prod/notary-sgx:${{ env.GIT_COMMIT_HASH }} &
else
old=$(docker ps --filter "name=${{needs.update-reverse-proxy.outputs.teeport}}")
docker rm -f $old
docker run --name ${{needs.update-reverse-proxy.outputs.teeport}} --device /dev/sgx_enclave --device /dev/sgx_provision --volume=/var/run/aesmd/aesm.socket:/var/run/aesmd/aesm.socket -p ${{needs.update-reverse-proxy.outputs.teeport}}:7047 notaryserverbuilds.azurecr.io/prod/notary-sgx:${{ env.GIT_COMMIT_HASH }} &
fi
41 changes: 41 additions & 0 deletions .github/workflows/tee-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: tee-build

on:
push:
branches: [ "dev" ]
pull_request:
branches: [ "dev" ]

concurrency:
group: ${{ github.head_ref || github.run_id }}
cancel-in-progress: true

jobs:
build-measure-emulated:
environment: tee
runs-on: [self-hosted, linux]
container:
image: notaryserverbuilds.azurecr.io/prod/gramine
credentials:
username: notaryserverbuilds
password: ${{ secrets.AZURE_CR_BUILDS_PW }}
env:
GIT_COMMIT_HASH: ${{ github.event.pull_request.head.sha || github.sha }}
steps:
- name: get code
uses: actions/checkout@v4
- name: sccache
if: github.event_name != 'release'
Copy link
Member

Choose a reason for hiding this comment

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

tlsn release workflow is triggered by a push of the new version tag to GH upstream, so the event_name should be push instead, together with an extra tag check, i.e. if [ "${{ github.event_name }}" = "push" ] && [[ "${{ github.ref }}" = "refs/tags/"* ]]

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

the spirit of this line is to make sure caching is off if the event that triggered the workflow is 'release'. are you suggesting that this does not work?

# && github.event_name != 'workflow_dispatch'
uses: mozilla-actions/[email protected]
- name: set rust env for scc
if: github.event_name != 'release'
# && github.event_name != 'workflow_dispatch'
run: |
echo "SCCACHE_GHA_ENABLED=true" >> $GITHUB_ENV
echo "RUSTC_WRAPPER=sccache" >> $GITHUB_ENV

- name: get emulated measurement (call gramine.sh without the sgx arg)
working-directory: ${{ github.workspace }}/crates/notary/server/tee
run: |
bash .github/scripts/gramine.sh
90 changes: 90 additions & 0 deletions cd-scripts/tee/azure/Caddyfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#
# global block =>
# email is for acme
# # # #

{
key_type p256
heeckhau marked this conversation as resolved.
Show resolved Hide resolved
email [email protected] # for acme
servers {
metrics
}
log {
output stdout
format console {
time_format common_log
time_local
}
level DEBUG
}
}

#
# server block, acme turned on (default when using dns)
# reverse proxy with fail_duration + lb will try upstreams sequentially (fallback)
# e.g. => `reverse_proxy :4000 :5000 10.10.10.10:1000 tlsnotary.org:443`
# will always deliver to :4000 if its up, but if :4000 is down for more than 4s it trys the next one
# # # #

notary.codes {
handle_path /v0.1.0-alpha.8* {
reverse_proxy :4002 :3333 {
lb_try_duration 4s
fail_duration 10s
lb_policy header X-Upstream {
fallback first
}
}
}
handle_path /v0.1.0-alpha.7* {
reverse_proxy :4002 :3333 {
lb_try_duration 4s
fail_duration 10s
lb_policy header X-Upstream {
fallback first
}
}
}
handle_path /v0.1.0-alpha.6* {
reverse_proxy :4001 :3333 {
lb_try_duration 4s
fail_duration 10s
lb_policy header X-Upstream {
fallback first
}
}
}

handle_path /nightly* {
reverse_proxy :3333 {
lb_try_duration 4s
fail_duration 10s
lb_policy header X-Upstream {
fallback first
}
}
}

handle_path /proxy* {
reverse_proxy :55688 proxy.notary.codes:443 {
lb_try_duration 4s
fail_duration 10s
lb_policy header X-Upstream {
fallback first
}
}
}

handle {
root * /srv
file_server
}

handle_errors {
@404 {
expression {http.error.status_code} == 404
}
rewrite @404 /index.html
file_server
}
}
7 changes: 7 additions & 0 deletions cd-scripts/tee/azure/prometheus.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
global:
scrape_interval: 15s

scrape_configs:
- job_name: caddy
static_configs:
- targets: ['localhost:2019']
Loading
Loading