-
Notifications
You must be signed in to change notification settings - Fork 408
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'develop' into improv/event_handler_api_gateway_strip_pr…
…efixes
- Loading branch information
Showing
181 changed files
with
6,112 additions
and
3,644 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -62,6 +62,7 @@ body: | |
- "3.8" | ||
- "3.9" | ||
- "3.10" | ||
- "3.11" | ||
validations: | ||
required: true | ||
- type: dropdown | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,6 +29,7 @@ body: | |
- "3.8" | ||
- "3.9" | ||
- "3.10" | ||
- "3.11" | ||
validations: | ||
required: true | ||
- type: input | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
name: "Restore sealed source code" | ||
description: "Restore sealed source code and confirm integrity hash" | ||
|
||
# PROCESS | ||
# | ||
# 1. Exports artifact name using Prefix + GitHub Run ID (unique for each release trigger) | ||
# 2. Compress entire source code as tarball OR given files | ||
# 3. Create and export integrity hash for tarball | ||
# 4. Upload artifact | ||
# 5. Remove archive | ||
|
||
# USAGE | ||
# | ||
# - name: Seal and upload | ||
# id: seal_source_code | ||
# uses: ./.github/actions/seal | ||
# with: | ||
# artifact_name_prefix: "source" | ||
# | ||
# - name: Restore sealed source code | ||
# uses: ./.github/actions/seal-restore | ||
# with: | ||
# integrity_hash: ${{ needs.seal_source_code.outputs.integrity_hash }} | ||
# artifact_name: ${{ needs.seal_source_code.outputs.artifact_name }} | ||
|
||
# NOTES | ||
# | ||
# To be used together with .github/actions/seal | ||
|
||
inputs: | ||
integrity_hash: | ||
description: "Integrity hash to verify" | ||
required: true | ||
artifact_name: | ||
description: "Sealed artifact name to restore" | ||
required: true | ||
|
||
runs: | ||
using: "composite" | ||
steps: | ||
- id: adjust-path | ||
run: echo "${{ github.action_path }}" >> $GITHUB_PATH | ||
shell: bash | ||
|
||
- name: Download artifacts | ||
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 | ||
with: | ||
name: ${{ inputs.artifact_name }} | ||
path: . | ||
|
||
- id: integrity_hash | ||
name: Create integrity hash for downloaded artifact | ||
run: | | ||
HASH=$(sha256sum "${ARTIFACT_NAME}.tar" | awk '{print $1}') | ||
echo "current_hash=${HASH}" >> "$GITHUB_OUTPUT" | ||
env: | ||
ARTIFACT_NAME: ${{ inputs.artifact_name }} | ||
shell: bash | ||
|
||
- id: verify_hash | ||
name: Verify sealed artifact integrity hash | ||
run: test "${CURRENT_HASH}" = "${PROVIDED_HASH}" || exit 1 | ||
env: | ||
ARTIFACT_NAME: ${{ inputs.artifact_name }} | ||
PROVIDED_HASH: ${{ inputs.integrity_hash }} | ||
CURRENT_HASH: ${{ steps.integrity_hash.outputs.current_hash }} | ||
shell: bash | ||
|
||
# Restore and overwrite tarball in current directory | ||
- id: overwrite | ||
name: Extract tarball | ||
run: tar -xvf "${ARTIFACT_NAME}".tar | ||
env: | ||
ARTIFACT_NAME: ${{ inputs.artifact_name }} | ||
shell: bash | ||
|
||
- name: Remove archive | ||
run: rm -f "${ARTIFACT_NAME}.tar" | ||
env: | ||
ARTIFACT_NAME: ${{ inputs.artifact_name }} | ||
shell: bash |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
name: "Seal and hash source code" | ||
description: "Seal and export source code as a tarball artifact along with its integrity hash" | ||
|
||
# PROCESS | ||
# | ||
# 1. Exports artifact name using Prefix + GitHub Run ID (unique for each release trigger) | ||
# 2. Compress entire source code as tarball OR given files | ||
# 3. Create and export integrity hash for tarball | ||
# 4. Upload artifact | ||
# 5. Remove archive | ||
|
||
# USAGE | ||
# | ||
# - name: Seal and upload | ||
# id: seal_source_code | ||
# uses: ./.github/actions/seal | ||
# with: | ||
# artifact_name_prefix: "source" | ||
|
||
inputs: | ||
files: | ||
description: "Files to seal separated by space" | ||
required: false | ||
artifact_name_prefix: | ||
description: "Prefix to use when exporting artifact" | ||
required: true | ||
|
||
outputs: | ||
integrity_hash: | ||
description: "Source code integrity hash" | ||
value: ${{ steps.integrity_hash.outputs.integrity_hash }} | ||
artifact_name: | ||
description: "Artifact name containTemporary branch created with staged changed" | ||
value: ${{ steps.export_artifact_name.outputs.artifact_name }} | ||
|
||
runs: | ||
using: "composite" | ||
steps: | ||
- id: adjust-path | ||
run: echo "${{ github.action_path }}" >> $GITHUB_PATH | ||
shell: bash | ||
|
||
- id: export_artifact_name | ||
name: Export final artifact name | ||
run: echo "artifact_name=${ARTIFACT_PREFIX}-${GITHUB_RUN_ID}" >> "$GITHUB_OUTPUT" | ||
env: | ||
GITHUB_RUN_ID: ${{ github.run_id }} | ||
ARTIFACT_PREFIX: ${{ inputs.artifact_name_prefix }} | ||
shell: bash | ||
|
||
# By default, create a tarball of the current directory minus .git | ||
# otherwise it breaks GH Actions when restoring it | ||
- id: compress_all | ||
if: ${{ !inputs.files }} | ||
name: Create tarball for entire source | ||
run: tar --exclude-vcs -cvf "${ARTIFACT_NAME}".tar * | ||
env: | ||
ARTIFACT_NAME: ${{ steps.export_artifact_name.outputs.artifact_name }} | ||
shell: bash | ||
|
||
# If a list of files are given, then create a tarball for those only | ||
- id: compress_selected_files | ||
if: ${{ inputs.files }} | ||
name: Create tarball for selected files | ||
run: tar --exclude-vcs -cvf "${ARTIFACT_NAME}".tar "${FILES}" | ||
env: | ||
FILES: ${{ inputs.files }} | ||
ARTIFACT_NAME: ${{ steps.export_artifact_name.outputs.artifact_name }} | ||
shell: bash | ||
|
||
- id: integrity_hash | ||
name: Create and export integrity hash for tarball | ||
run: | | ||
HASH=$(sha256sum "${ARTIFACT_NAME}.tar" | awk '{print $1}') | ||
echo "integrity_hash=${HASH}" >> "$GITHUB_OUTPUT" | ||
env: | ||
ARTIFACT_NAME: ${{ steps.export_artifact_name.outputs.artifact_name }} | ||
shell: bash | ||
|
||
- name: Upload artifacts | ||
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 | ||
with: | ||
if-no-files-found: error | ||
name: ${{ steps.export_artifact_name.outputs.artifact_name }} | ||
path: ${{ steps.export_artifact_name.outputs.artifact_name }}.tar | ||
retention-days: 1 | ||
|
||
- name: Remove archive | ||
run: rm -f "${ARTEFACT_NAME}.tar" | ||
env: | ||
ARTIFACT_NAME: ${{ steps.export_artifact_name.outputs.artifact_name }} | ||
shell: bash |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
name: "Upload provenance attestation to release" | ||
description: "Download and upload newly generated provenance attestation to latest release." | ||
|
||
# PROCESS | ||
# | ||
# 1. Downloads provenance attestation artifact generated earlier in the release pipeline | ||
# 2. Updates latest GitHub draft release pointing to newly git release tag | ||
# 3. Uploads provenance attestation file to latest GitHub draft release | ||
|
||
# USAGE | ||
# | ||
# - name: Upload provenance | ||
# id: upload-provenance | ||
# uses: ./.github/actions/upload-release-provenance | ||
# with: | ||
# release_version: ${{ needs.seal.outputs.RELEASE_VERSION }} | ||
# provenance_name: ${{needs.provenance.outputs.provenance-name}} | ||
# github_token: ${{ secrets.GITHUB_TOKEN }} | ||
|
||
# NOTES | ||
# | ||
# There are no outputs. | ||
# | ||
|
||
inputs: | ||
provenance_name: | ||
description: "Provenance artifact name to download" | ||
required: true | ||
release_version: | ||
description: "Release version (e.g., 2.20.0)" | ||
required: true | ||
github_token: | ||
description: "GitHub token for GitHub CLI" | ||
required: true | ||
|
||
runs: | ||
using: "composite" | ||
steps: | ||
- id: adjust-path | ||
run: echo "${{ github.action_path }}" >> $GITHUB_PATH | ||
shell: bash | ||
|
||
- id: download-provenance | ||
name: Download newly generated provenance | ||
uses: actions/download-artifact@9782bd6a9848b53b110e712e20e42d89988822b7 # v3.0.1 | ||
with: | ||
name: ${{ inputs.provenance_name }} | ||
|
||
- id: sync-release-tag | ||
name: Update draft release tag to release commit tag | ||
run: | | ||
CURRENT_DRAFT_RELEASE=$(gh release list | awk '{ if ($2 == "Draft") print $1}') | ||
gh release edit "${CURRENT_DRAFT_RELEASE}" --tag v"${RELEASE_VERSION}" | ||
env: | ||
RELEASE_VERSION: ${{ inputs.release_version }} | ||
GH_TOKEN: ${{ inputs.github_token }} | ||
shell: bash | ||
|
||
- id: upload-provenance | ||
name: Upload provenance to release tag | ||
# clobber flag means overwrite release asset if available (eventual consistency, retried failed steps) | ||
run: gh release upload --clobber v"${RELEASE_VERSION}" "${PROVENANCE_FILE}" | ||
env: | ||
RELEASE_VERSION: ${{ inputs.release_version }} | ||
PROVENANCE_FILE: ${{ inputs.provenance_name }} | ||
GH_TOKEN: ${{ inputs.github_token }} | ||
shell: bash |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
#!/bin/bash | ||
set -uo pipefail # prevent accessing unset env vars, prevent masking pipeline errors to the next command | ||
|
||
#docs | ||
#title :verify_provenance.sh | ||
#description :This script will download and verify a signed Powertools for AWS Lambda (Python) release build with SLSA Verifier | ||
#author :@heitorlessa | ||
#date :July 1st 2023 | ||
#version :0.1 | ||
#usage :bash verify_provenance.sh {release version} | ||
#notes :Meant to use in GitHub Actions or locally (MacOS, Linux, WSL). | ||
#os_version :Ubuntu 22.04.2 LTS | ||
#============================================================================== | ||
|
||
# Check if RELEASE_VERSION is provided as a command line argument | ||
if [[ $# -eq 1 ]]; then | ||
export readonly RELEASE_VERSION="$1" | ||
else | ||
echo "ERROR: Please provider Powertools release version as a command line argument." | ||
echo "Example: bash verify_provenance.sh 2.20.0" | ||
exit 1 | ||
fi | ||
|
||
export readonly ARCHITECTURE=$(uname -m | sed 's/x86_64/amd64/g') # arm64, x86_64 ->amd64 | ||
export readonly OS_NAME=$(uname -s | tr '[:upper:]' '[:lower:]') # darwin, linux | ||
export readonly SLSA_VERIFIER_VERSION="2.3.0" | ||
export readonly SLSA_VERIFIER_CHECKSUM_FILE="SHA256SUM.md" | ||
export readonly SLSA_VERIFIER_BINARY="./slsa-verifier-${OS_NAME}-${ARCHITECTURE}" | ||
|
||
export readonly RELEASE_BINARY="aws_lambda_powertools-${RELEASE_VERSION}-py3-none-any.whl" | ||
export readonly ORG="aws-powertools" | ||
export readonly REPO="powertools-lambda-python" | ||
export readonly PROVENANCE_FILE="multiple.intoto.jsonl" | ||
|
||
export readonly FILES=("${SLSA_VERIFIER_BINARY}" "${SLSA_VERIFIER_CHECKSUM_FILE}" "${PROVENANCE_FILE}" "${RELEASE_BINARY}") | ||
|
||
function debug() { | ||
TIMESTAMP=$(date -u "+%FT%TZ") # 2023-05-10T07:53:59Z | ||
echo ""${TIMESTAMP}" DEBUG - [*] $1" | ||
} | ||
|
||
function error() { | ||
cleanup | ||
TIMESTAMP=$(date -u "+%FT%TZ") # 2023-05-10T07:53:59Z | ||
echo ""${TIMESTAMP}" ERROR - [!] $1" | ||
echo ""${TIMESTAMP}" ERROR - [!] exiting" | ||
exit 1 | ||
} | ||
|
||
function download_slsa_verifier() { | ||
readonly SLSA_URL="https://github.com/slsa-framework/slsa-verifier/releases/download/v${SLSA_VERIFIER_VERSION}/slsa-verifier-${OS_NAME}-${ARCHITECTURE}" | ||
# debug "Downloading SLSA Verifier for - Binary: slsa-verifier-${OS_NAME}-${ARCHITECTURE}" | ||
debug "Downloading SLSA Verifier binary: ${SLSA_URL}" | ||
curl \ | ||
--location \ | ||
--fail \ | ||
--silent \ | ||
-O "${SLSA_URL}" || error "Failed to download SLSA Verifier binary" | ||
|
||
readonly SLSA_CHECKSUM_URL="https://raw.githubusercontent.com/slsa-framework/slsa-verifier/f59b55ef2190581d40fc1a5f3b7a51cab2f4a652/${SLSA_VERIFIER_CHECKSUM_FILE}" | ||
debug "Downloading SLSA Verifier checksums" | ||
curl \ | ||
--location \ | ||
--fail \ | ||
--silent \ | ||
-O "${SLSA_CHECKSUM_URL}" || error "Failed to download SLSA Verifier binary checksum file" | ||
|
||
debug "Verifying SLSA Verifier binary integrity" | ||
CURRENT_HASH=$(sha256sum "${SLSA_VERIFIER_BINARY}" | awk '{print $1}') | ||
if [[ $(grep "${CURRENT_HASH}" "${SLSA_VERIFIER_CHECKSUM_FILE}") ]]; then | ||
debug "SLSA Verifier binary integrity confirmed" | ||
chmod +x "${SLSA_VERIFIER_BINARY}" | ||
else | ||
error "Failed integrity check for SLSA Verifier binary: ${SLSA_VERIFIER_BINARY}" | ||
fi | ||
} | ||
|
||
function download_provenance() { | ||
readonly PROVENANCE_URL="https://github.com/${ORG}/${REPO}/releases/download/v${RELEASE_VERSION}/${PROVENANCE_FILE}" | ||
debug "Downloading attestation: ${PROVENANCE_URL}" | ||
|
||
curl \ | ||
--location \ | ||
--fail \ | ||
--silent \ | ||
-O ${PROVENANCE_URL} || error "Failed to download provenance. Does the release already exist?" | ||
} | ||
|
||
function download_release_artifact() { | ||
debug "Downloading ${RELEASE_VERSION} release from PyPi" | ||
python -m pip download \ | ||
--only-binary=:all: \ | ||
--no-deps \ | ||
--quiet \ | ||
aws-lambda-powertools=="${RELEASE_VERSION}" | ||
} | ||
|
||
function verify_provenance() { | ||
debug "Verifying attestation with slsa-verifier" | ||
"${SLSA_VERIFIER_BINARY}" verify-artifact \ | ||
--provenance-path "${PROVENANCE_FILE}" \ | ||
--source-uri github.com/${ORG}/${REPO} \ | ||
${RELEASE_BINARY} | ||
} | ||
|
||
function cleanup() { | ||
debug "Cleaning up previously downloaded files" | ||
rm -f "${SLSA_VERIFIER_BINARY}" | ||
rm -f "${SLSA_VERIFIER_CHECKSUM_FILE}" | ||
rm -f "${PROVENANCE_FILE}" | ||
rm -f "${RELEASE_BINARY}" | ||
echo "${FILES[@]}" | xargs -n1 echo "Removed file: " | ||
} | ||
|
||
function main() { | ||
download_slsa_verifier | ||
download_provenance | ||
download_release_artifact | ||
verify_provenance | ||
cleanup | ||
} | ||
|
||
main | ||
|
||
# Lessons learned | ||
# | ||
# 1. If source doesn't match provenance | ||
# | ||
# FAILED: SLSA verification failed: source used to generate the binary does not match provenance: expected source 'awslabs/aws-lambda-powertools-python', got 'heitorlessa/aws-lambda-powertools-test' | ||
# | ||
# 2. Avoid building deps during download in Test registry endpoints | ||
# | ||
# FAILED: Could not find a version that satisfies the requirement poetry-core>=1.3.2 (from versions: 1.2.0) | ||
# |
Oops, something went wrong.