Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
b012273
build-app-cli cache: fail-closed image.json digest-pin validator
aram356 Aug 27, 2026
3b5436b
Merge branch 'main' into feature/build-app-cli-cache
aram356 Aug 27, 2026
55dcf07
Move build-caching spec to docs/superpowers/specs (superpowers conven…
aram356 Aug 28, 2026
aac4448
Timestamp the build-caching spec filename to match the superpowers co…
aram356 Aug 28, 2026
599ffef
check-image-pin: reject non-string repository/tag/digest (jq -r coerc…
aram356 Aug 28, 2026
9f7526b
build-caching spec v6.15 + plan: address the v6.14 review's findings
aram356 Aug 28, 2026
e040db4
check-image-pin: require the canonical EdgeZero GHCR repository
aram356 Aug 28, 2026
3e1ae38
build-caching spec v6.16 + plan: address the v6.15 review's contract …
aram356 Aug 28, 2026
3f81105
build-caching spec v6.17 + plan: address the v6.16 review's contract …
aram356 Aug 29, 2026
4cda752
docs: finalize build caching design and plan
aram356 Aug 31, 2026
2ea8c2d
docs: harden build caching release contracts
aram356 Aug 31, 2026
97b2eec
docs: finalize build cache design and plans
aram356 Sep 4, 2026
dbef380
docs: close build cache design review gaps
aram356 Sep 4, 2026
9a778ea
docs: fix cache runner identity contracts
aram356 Sep 5, 2026
6743379
docs: harden cache workflow guard contracts
aram356 Sep 6, 2026
b358974
ci: enforce exact action versions and documentation release gates
aram356 Sep 6, 2026
8f68476
feat: add canonical provenance JSON protocol and schema
aram356 Sep 6, 2026
30b87db
docs: reconcile caching contracts and consolidate deployment docs
aram356 Sep 7, 2026
76ecccb
docs: close build cache v6.31 contracts
aram356 Sep 8, 2026
b32efbc
fix(ci): align documentation gate with v6.31
aram356 Sep 8, 2026
c8cfefc
Merge branch 'main' of github.com:stackpop/edgezero into feature/buil…
aram356 Sep 8, 2026
147f797
docs: refresh v6.31 verification evidence
aram356 Sep 8, 2026
7d78da8
docs: record hosted selector qualification
aram356 Sep 8, 2026
7ed2600
docs: correct release qualification order
aram356 Sep 8, 2026
b6167a7
feat: add provenance archive protocol
aram356 Sep 8, 2026
3d0984c
feat: add ELF provenance validation
aram356 Sep 8, 2026
525a18d
feat: add provenance validator CLI
aram356 Sep 8, 2026
785a6c0
feat: validate build container pin records
aram356 Sep 8, 2026
fa810a1
feat: add verified build container source
aram356 Sep 8, 2026
786ef5e
feat: verify build container images
aram356 Sep 8, 2026
ee7336e
feat: qualify build image runtime
aram356 Sep 9, 2026
82c6696
feat(actions): add protected build container gate
aram356 Sep 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
**
!.dockerignore
!.tool-versions
!.github/
!.github/actions/
!.github/actions/deploy-fastly/
!.github/actions/deploy-fastly/versions.json
!.github/docker/
!.github/docker/build-app-cli/
!.github/docker/build-app-cli/Dockerfile
!.github/docker/build-app-cli/fixtures/
!.github/docker/build-app-cli/fixtures/gnu-smoke.rs
!.github/docker/build-app-cli/fixtures/provenance/
!.github/docker/build-app-cli/fixtures/provenance/**
!.github/docker/build-app-cli/fixtures/wasm-smoke.rs
!.github/docker/build-app-cli/image-context-paths.txt
!.github/docker/build-app-cli/provenance.schema.json
!.github/docker/build-app-cli/verify-toolchain.sh
!.github/tools/
!.github/tools/edgezero-provenance-validator/
!.github/tools/edgezero-provenance-validator/**
108 changes: 108 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/.dockerignore @stackpop/edgezero-build-container-gate-reviewers
/.github/CODEOWNERS @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-core/tests/assert-build-container-app-token.test.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-core/tests/assert-build-container-completion.test.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-core/tests/assert-build-container-context.test.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-core/tests/assert-build-container-dispatch-context.test.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-core/tests/build-container-workflows.test.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-core/tests/check-action-pins.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-core/tests/check-build-container-publisher.test.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-core/tests/check-doc-action-pins.mjs @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-core/tests/check-doc-action-pins.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-core/tests/check-doc-action-pins.test.mjs @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-core/tests/check-image-pin.test.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-core/tests/classify-build-container-change.test.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-core/tests/install-actionlint.test.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-core/tests/install-yq.test.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-core/tests/release-approval-gate.test.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-core/tests/run-actionlint.test.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-core/tests/run-build-container-gate.test.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-core/tests/run.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-core/tests/select-build-container-range.test.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-core/tests/stage-build-context.test.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-core/tests/update-image-pin-pr.test.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-core/tests/verify-build-container-publication.test.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-core/tests/verify-gate-rotation-lock.test.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-core/tests/verify-published-image.test.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-core/tests/verify-release-prerequisites.test.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-core/tests/verify-toolchain.test.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-core/tests/write-image-release-record.test.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-core/tests/write-publisher-prerequisite.test.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/actions/deploy-fastly/versions.json @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/Dockerfile @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/assert-build-container-app-token.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/assert-build-container-completion.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/assert-build-container-context.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/assert-build-container-dispatch-context.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/check-build-container-publisher.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/check-image-pin.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/classify-build-container-change.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/gnu-smoke.rs @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/invalid/archive-base256.tar @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/invalid/archive-checksum.tar @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/invalid/archive-duplicate.tar @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/invalid/archive-embedded-nul.tar @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/invalid/archive-end-block.tar @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/invalid/archive-extra-end-block.tar @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/invalid/archive-extra.tar @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/invalid/archive-gnu.tar @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/invalid/archive-header.tar @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/invalid/archive-link.tar @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/invalid/archive-max-size.tar @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/invalid/archive-octal-digit.tar @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/invalid/archive-octal-padding.tar @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/invalid/archive-order.tar @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/invalid/archive-padding.tar @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/invalid/archive-pax.tar @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/invalid/archive-size-limit.tar @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/invalid/archive-size.tar @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/invalid/archive-sparse.tar @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/invalid/archive-special.tar @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/invalid/archive-trailing.tar @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/invalid/archive-traversal.tar @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/invalid/elf-malformed/app-cli @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/invalid/expected-duplicate.json @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/invalid/meta-missing-interpreter.json @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/valid/archive.tar @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/valid/dynamic-meta.json @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/valid/elf-static/app-cli @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/valid/expected.json @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/provenance/valid/static-meta.json @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/fixtures/wasm-smoke.rs @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/gate-paths.txt @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/image-context-paths.txt @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/provenance.schema.json @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/release-approval-gate.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/run-build-container-gate.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/select-build-container-range.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/stage-build-context.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/update-image-pin-pr.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/verify-build-container-publication.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/verify-gate-rotation-lock.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/verify-published-image.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/verify-release-prerequisites.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/verify-toolchain.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/write-image-release-record.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/docker/build-app-cli/write-publisher-prerequisite.sh @stackpop/edgezero-build-container-gate-reviewers
/.github/tools/edgezero-provenance-validator/Cargo.lock @stackpop/edgezero-build-container-gate-reviewers
/.github/tools/edgezero-provenance-validator/Cargo.toml @stackpop/edgezero-build-container-gate-reviewers
/.github/tools/edgezero-provenance-validator/src/archive.rs @stackpop/edgezero-build-container-gate-reviewers
/.github/tools/edgezero-provenance-validator/src/command.rs @stackpop/edgezero-build-container-gate-reviewers
/.github/tools/edgezero-provenance-validator/src/elf.rs @stackpop/edgezero-build-container-gate-reviewers
/.github/tools/edgezero-provenance-validator/src/extract.rs @stackpop/edgezero-build-container-gate-reviewers
/.github/tools/edgezero-provenance-validator/src/json_contract.rs @stackpop/edgezero-build-container-gate-reviewers
/.github/tools/edgezero-provenance-validator/src/lib.rs @stackpop/edgezero-build-container-gate-reviewers
/.github/tools/edgezero-provenance-validator/src/main.rs @stackpop/edgezero-build-container-gate-reviewers
/.github/tools/edgezero-provenance-validator/src/orchestration.rs @stackpop/edgezero-build-container-gate-reviewers
/.github/tools/edgezero-provenance-validator/src/self_test.rs @stackpop/edgezero-build-container-gate-reviewers
/.github/tools/edgezero-provenance-validator/tests/cli.rs @stackpop/edgezero-build-container-gate-reviewers
/.github/workflows/build-container-ci.yml @stackpop/edgezero-build-container-gate-reviewers
/.github/workflows/publish-build-container.yml @stackpop/edgezero-build-container-gate-reviewers
/.github/workflows/rotate-build-container-gate.yml @stackpop/edgezero-build-container-gate-reviewers
/.github/zizmor.yml @stackpop/edgezero-build-container-gate-reviewers
/.tool-versions @stackpop/edgezero-build-container-gate-reviewers
/docs/package-lock.json @stackpop/edgezero-build-container-gate-reviewers
/docs/package.json @stackpop/edgezero-build-container-gate-reviewers
/scripts/install-actionlint.sh @stackpop/edgezero-build-container-gate-reviewers
/scripts/install-yq.sh @stackpop/edgezero-build-container-gate-reviewers
/scripts/run-actionlint.sh @stackpop/edgezero-build-container-gate-reviewers
2 changes: 1 addition & 1 deletion .github/actions/build-app-cli/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ runs:
# step's note): a custom provider secret should be scoped to the one step that
# needs it, never to job-level `env:` shared with the build.
- name: Upload CLI artifact
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v7.0.1
env:
FASTLY_API_TOKEN: ""
FASTLY_SERVICE_ID: ""
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/config-push-fastly/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ runs:
run: exec "$GITHUB_ACTION_PATH/scripts/validate.sh"

- name: Download CLI artifact
uses: actions/download-artifact@v8
uses: actions/download-artifact@v8.0.1
with:
name: ${{ inputs['app-cli-artifact'] }}
path: ${{ steps.ws.outputs.root }}/cli-download
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#!/usr/bin/env bash
set -euo pipefail

DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
ASSERT="$DIR/../../../docker/build-app-cli/assert-build-container-app-token.sh"
WORK=$(mktemp -d)
WORK=$(cd -- "$WORK" && pwd -P)
trap 'rm -rf "$WORK"' EXIT
FAKE_BIN="$WORK/bin"
mkdir -p "$FAKE_BIN"

cat >"$FAKE_BIN/curl" <<'SH'
#!/usr/bin/env bash
set -euo pipefail
fixture=$(cd -- "$(dirname -- "$0")" && pwd)
[[ "$LC_ALL" == C ]]
[[ -z "${GITHUB_TOKEN+x}${GH_TOKEN+x}${HTTPS_PROXY+x}${HTTP_PROXY+x}${ALL_PROXY+x}${HOME+x}${XDG_CONFIG_HOME+x}${CURL_HOME+x}" ]]
printf '%s\n' "$@" >"$fixture/args"
cat >"$fixture/config"
cat "$fixture/reply"
SH
chmod 0755 "$FAKE_BIN/curl"

pass=0
fail=0

write_reply() {
local full_name=${1:-stackpop/edgezero} status=${2:-200}
local version=${3:-2026-03-10} media=${4:-application/json}
jq -cn --arg full_name "$full_name" \
'{id:123456789,full_name:$full_name,private:false,visibility:"public"}' >"$FAKE_BIN/body"
{
cat "$FAKE_BIN/body"
printf '\n%s\n%s\n%s' "$status" "$version" "$media"
} >"$FAKE_BIN/reply"
}

run_assert() {
PATH="$FAKE_BIN:$PATH" \
EDGEZERO_APP_TOKEN="${TOKEN:-fixture-token}" \
EDGEZERO_INSTALLATION_ID="${INSTALLATION_ID:-12345}" \
EDGEZERO_EXPECTED_INSTALLATION_ID="${EXPECTED_INSTALLATION_ID:-12345}" \
bash "$ASSERT"
}

assert_pass() {
local description=$1
if run_assert >"$WORK/stdout" 2>"$WORK/stderr" &&
[[ ! -s "$WORK/stdout" && ! -s "$WORK/stderr" ]]; then
printf ' \033[32mok\033[0m %s\n' "$description"
pass=$((pass + 1))
else
cat "$WORK/stdout" "$WORK/stderr" >&2
printf ' \033[31mFAIL\033[0m %s\n' "$description" >&2
fail=$((fail + 1))
fi
}

assert_fail() {
local description=$1
if run_assert >"$WORK/stdout" 2>"$WORK/stderr"; then
printf ' \033[31mFAIL\033[0m %s\n' "$description" >&2
fail=$((fail + 1))
elif [[ -s "$WORK/stdout" ]]; then
cat "$WORK/stdout" >&2
printf ' \033[31mFAIL\033[0m %s emitted stdout\n' "$description" >&2
fail=$((fail + 1))
else
printf ' \033[32mok\033[0m %s\n' "$description"
pass=$((pass + 1))
fi
}

echo '== protected publisher App token probe =='
write_reply
assert_pass 'exact installation token can read only the expected repository identity'
if grep -qF 'Authorization: Bearer fixture-token' "$FAKE_BIN/config" &&
! grep -qF 'fixture-token' "$FAKE_BIN/args"; then
printf ' \033[32mok\033[0m token is passed through config stdin and never argv\n'
pass=$((pass + 1))
else
printf ' \033[31mFAIL\033[0m token is passed through config stdin and never argv\n' >&2
fail=$((fail + 1))
fi
if awk 'previous == "--connect-timeout" && $0 == "10" { found = 1 } { previous = $0 } END { exit !found }' \
"$FAKE_BIN/args"; then
printf ' \033[32mok\033[0m API probe fixes the connection timeout at 10 seconds\n'
pass=$((pass + 1))
else
printf ' \033[31mFAIL\033[0m API probe fixes the connection timeout at 10 seconds\n' >&2
fail=$((fail + 1))
fi

INSTALLATION_ID=12346
assert_fail 'action installation output must equal protected environment value'
unset INSTALLATION_ID
EXPECTED_INSTALLATION_ID=012345
assert_fail 'installation IDs must be canonical positive integers'
unset EXPECTED_INSTALLATION_ID
TOKEN=$'bad\ntoken'
assert_fail 'line-breaking token is rejected'
unset TOKEN

write_reply other/repository
assert_fail 'repository substitution is rejected'
write_reply stackpop/edgezero 302
assert_fail 'redirect response is rejected'
write_reply stackpop/edgezero 200 2022-11-28
assert_fail 'wrong selected API version is rejected'
write_reply stackpop/edgezero 200 2026-03-10 text/json
assert_fail 'wrong response media type is rejected'

if ((fail)); then
printf '\n%d passed, %d failed\n' "$pass" "$fail" >&2
exit 1
fi
printf '\n%d passed, %d failed\n' "$pass" "$fail"
Loading
Loading