Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
127 commits
Select commit Hold shift + click to select a range
4150c9f
feat(vmm): sweep netd interfaces by VM and keep removals recoverable
kvinwang Sep 14, 2026
0606026
fix(vmm): make netd interface cleanup converge without a restart
kvinwang Sep 14, 2026
2f4414d
fix(vmm): don't strand VMs on netd-less nodes and confirm manual bind…
kvinwang Sep 15, 2026
f0e3f78
fix(netd): read helper output while waiting and tighten binding teardown
kvinwang Sep 15, 2026
b4cad12
fix(netd): keep sweep and manual removal rules consistent
kvinwang Sep 15, 2026
a78b082
os/kernel: add TDX guest scaling knobs
kvinwang Sep 15, 2026
f950ff9
os: ship experimental tdx-guest-tune.sh helper
kvinwang Sep 15, 2026
e4ff854
docs: describe TDX guest scaling knobs and profiles
kvinwang Sep 15, 2026
38cb94b
os/kernel: stop accepting 4 MiB per allocation before watermarks are set
kvinwang Sep 15, 2026
2a3cc49
os/kernel: convert the TDX SWIOTLB buffer to shared after SMP bring-up
kvinwang Sep 15, 2026
50d4f06
docs: describe the large TDX guest boot-time fixes
kvinwang Sep 15, 2026
70fdc28
os/kernel: warn on SWIOTLB bounce before the default pool is shared
kvinwang Sep 15, 2026
6ff96df
Merge pull request #1220 from Dstack-TEE/feat/tdx-large-guest-boot
kvinwang Sep 15, 2026
cb7ea9b
Merge pull request #1214 from Dstack-TEE/feat/netd-lifecycle
kvinwang Sep 15, 2026
2eb9f7f
fix(vmm): sanitize GPUs via VFIO hot reset instead of sysfs SBR
Leechael Aug 14, 2026
cfbee85
feat(vmm): add sanitize-gpu subcommand for manual GPU reset
Leechael Aug 14, 2026
57de57c
refactor(vmm): use vfio-ioctls for GPU hot reset
kvinwang Aug 17, 2026
c975611
refactor(vmm): keep VFIO group handling encapsulated
kvinwang Aug 17, 2026
0055cc0
Merge pull request #1065 from Dstack-TEE/fix/gpu-sbr-vfio-ioctls
kvinwang Sep 15, 2026
42844e0
ci: publish release images to GHCR
kvinwang Sep 15, 2026
d697fbc
ci: harden GHCR release publishing
kvinwang Sep 15, 2026
4c6cabc
Merge pull request #1222 from Dstack-TEE/fix/ghcr-release-images
kvinwang Sep 15, 2026
0c6b751
ci: verify GHCR images are public
kvinwang Sep 15, 2026
455ff98
Merge pull request #1223 from Dstack-TEE/fix/ghcr-public-check
kvinwang Sep 15, 2026
bc760b2
ci: build KMS contracts from checked-out dependencies
kvinwang Sep 15, 2026
2da8d01
Merge pull request #1224 from Dstack-TEE/fix/kms-release-forge
kvinwang Sep 15, 2026
3b75a4c
feat(vmm): add a status filter to the console instance list
Leechael Sep 9, 2026
0f8d6b9
style(vmm): rustfmt the status-filter test imports
Leechael Sep 15, 2026
b7ed51b
Merge pull request #1193 from Dstack-TEE/feat/vmm-ui-status-filter
Leechael Sep 15, 2026
c11c410
fix(yocto): avoid preserving source groups during unpack
WimYedema Sep 15, 2026
fdfdfbd
fix(yocto): drop source owner as well during unpack staging
kvinwang Sep 16, 2026
dcce1f6
Merge pull request #1225 from WimYedema/fix/rsync-archive-group-next
kvinwang Sep 16, 2026
576b0d2
feat(os): export the guest kernel build tree for out-of-tree modules
kvinwang Sep 17, 2026
1581cc9
feat(os/image): publish the exported kernel build tree as a release a…
kvinwang Sep 17, 2026
fe8039a
feat(os/image): add the kernel module builder image
kvinwang Sep 17, 2026
dfb0e46
feat(os/mkosi): export the kernel build tree of the image it builds
kvinwang Sep 17, 2026
a508fa4
ci(mkosi): publish the kernel build tree and the builder image
kvinwang Sep 17, 2026
d970feb
docs: document building out-of-tree kernel modules for the guest OS
kvinwang Sep 17, 2026
cfd4e12
fix(os): validate kernel-devel archives and simplify builder workflow
kvinwang Sep 17, 2026
7e76996
refactor(os): simplify the kernel-devel export and builder image
kvinwang Sep 17, 2026
e2cf39a
Merge pull request #1226 from Dstack-TEE/feat/os-kernel-headers
kvinwang Sep 17, 2026
b94c6bf
fix(scripts): remove the installer's temporary checkout on exit
kvinwang Sep 17, 2026
73f61b6
fix(kms): sync auth backend bun lockfiles with package.json
kvinwang Sep 17, 2026
8c8c1a2
Merge pull request #1227 from Dstack-TEE/fix/install-script-temp-chec…
kvinwang Sep 18, 2026
6395721
Merge pull request #1228 from Dstack-TEE/fix/kms-auth-bun-lockfiles
kvinwang Sep 18, 2026
3f451c3
fix(os): normalize the kernel setup header to QEMU's layout, not zeros
kvinwang Sep 18, 2026
7727bd1
docs(os): correct stale wording about how the setup header is normalized
kvinwang Sep 18, 2026
b419782
fix(os): read XLF_CAN_BE_LOADED_ABOVE_4G as bit 1, not 0x40
kvinwang Sep 18, 2026
aa4e3d0
docs(os): state that one fixed header is written, not QEMU's logic
kvinwang Sep 19, 2026
2e4bf36
Merge pull request #1229 from Dstack-TEE/fix/ovmf-qemu-legacy-setup-h…
kvinwang Sep 19, 2026
a15f083
feat(vmm): add a host-side data disk preallocation option
kvinwang Sep 19, 2026
bea7451
fix(vmm): build the QEMU launch off the async executor
kvinwang Sep 19, 2026
46f3eb8
feat(vmm-cli): expose disk preallocation and storage_discard
kvinwang Sep 19, 2026
b6ea123
feat(vmm-ui): offer disk preallocation in the create dialog
kvinwang Sep 19, 2026
4e8048a
docs(vmm-cli): document --disk-prealloc and its discard requirement
kvinwang Sep 19, 2026
8215145
fix(vmm): publish the data disk atomically
kvinwang Sep 19, 2026
dda4c7c
fix(vmm): keep the launch lock for as long as the launch runs
kvinwang Sep 19, 2026
de1ce24
refactor(vmm): say what the preallocation rejection means for an update
kvinwang Sep 19, 2026
dace63c
docs(vmm): correct the preallocation defaults and migration wording
kvinwang Sep 19, 2026
030fbb2
Merge pull request #1230 from Dstack-TEE/feat/vmm-disk-prealloc
kvinwang Sep 19, 2026
4406f72
fix(guest-agent): reject a certificate validity bound it cannot repre…
kvinwang Sep 20, 2026
c06cb70
fix(dstack-mr): reject a zero-length TDVF guid table entry
kvinwang Sep 20, 2026
3a744e8
fix(dstack-mr): bound the TDVF section table to the firmware blob
kvinwang Sep 20, 2026
6201061
fix(dstack-mr): cap the work a TDVF section table can ask for
kvinwang Sep 20, 2026
fcfc7fb
fix(dstack-mr): bound the TD HOB witness range count
kvinwang Sep 20, 2026
58e1b17
fix(key-provider): refuse to provision a debug-mode TD
kvinwang Sep 20, 2026
3c0b0da
fix(guest-agent): gate the dashboard container table on the public flags
kvinwang Sep 20, 2026
c3423a1
fix(dstack-util): install a host registry mirror only for digest-pinn…
kvinwang Sep 20, 2026
be458a0
fix(dstack-util): refuse to classify orphans when compose uses include:
kvinwang Sep 20, 2026
195d1bf
fix(dstack-util): mount the host share nosuid, nodev and noexec
kvinwang Sep 20, 2026
c629021
fix(gateway): bound the SNI extractor's length-prefixed records
kvinwang Sep 20, 2026
2fc6e9b
test(gateway): pin what keeps the PROXY protocol reader in bounds
kvinwang Sep 20, 2026
b26de5f
fix(kms): quote an auth backend's response on a character boundary
kvinwang Sep 20, 2026
d608793
fix(sev-snp-qvl): an empty SNP report in a /verify body aborts the ve…
kvinwang Sep 20, 2026
ccd9663
feat(kms): gate Nitro Enclave key release behind an explicit opt-in
kvinwang Sep 21, 2026
97ecd79
docs: add app key compromise recovery guide
kvinwang Sep 21, 2026
8829c21
Merge pull request #1304 from kvinwang/docs/app-key-compromise-recovery
kvinwang Sep 21, 2026
21ae5d1
Merge pull request #1303 from Dstack-TEE/feat/nitro-enclave-key-release
kvinwang Sep 21, 2026
5b6e294
fix(attest): derive Nitro Enclave device_id from the EC2 instance id
kvinwang Sep 21, 2026
ccefe06
Merge pull request #1279 from Dstack-TEE/fix/attestation-parser-bounds
kvinwang Sep 22, 2026
a7a191e
fix(sdk): reject TLS keys in wallet adapters
kvinwang Sep 22, 2026
66772bc
fix(dstack-mr): constrain sev guest_features to the bits dstack launc…
kvinwang Sep 20, 2026
bd49e35
fix(tpm-qvl): check every quoted PCR against the attested bank
kvinwang Sep 20, 2026
206c4b3
fix(dstack-types): reject trailing bytes after a CBOR measurement doc…
kvinwang Sep 20, 2026
7d11e04
fix(dstack-types): require an explicit version in an mr_config document
kvinwang Sep 20, 2026
4272ff4
fix(dstack-mr): reject a duplicated dstack.rootfs_hash instead of res…
kvinwang Sep 20, 2026
0d65353
fix(dstack-types): version the AWS measurement document like its sibl…
kvinwang Sep 20, 2026
d56b4c0
refactor(dstack-attest): delete the unused sev_snp_mr_config accessor
kvinwang Sep 20, 2026
27b106f
refactor(sev-snp-qvl): rename parse_amd_snp_report to say it verifies…
kvinwang Sep 20, 2026
856bab4
Merge pull request #1283 from Dstack-TEE/fix/sdk-tls-key-scalar
kvinwang Sep 22, 2026
27dd0f6
Drop registry mirror and dashboard changes from this PR
kvinwang Sep 22, 2026
708e74e
fix(key-provider): mirror dcap-qvl's TD attribute policy
kvinwang Sep 22, 2026
a269b54
Merge pull request #1242 from Dstack-TEE/fix/key-provider-debug-td
kvinwang Sep 22, 2026
4ccfbbe
docs(gateway): clarify PROXY parser safety invariant
kvinwang Sep 22, 2026
19243b8
refactor(verifier): address review nits
kvinwang Sep 22, 2026
4b8c1d6
Merge pull request #1278 from Dstack-TEE/fix/network-parser-bounds
kvinwang Sep 22, 2026
94d1e25
Merge pull request #1254 from Dstack-TEE/fix/guest-exposure-surfaces
kvinwang Sep 22, 2026
08f3ae8
fix(kms): refuse to auto-bootstrap over existing root keys
kvinwang Sep 20, 2026
2198600
Merge pull request #1305 from Dstack-TEE/fix/kms-auto-bootstrap-root-…
kvinwang Sep 22, 2026
0a835f2
Merge pull request #1275 from Dstack-TEE/fix/verifier-input-canonical…
kvinwang Sep 22, 2026
3abd232
Merge pull request #1302 from Dstack-TEE/fix/nitro-enclave-device-id
kvinwang Sep 22, 2026
80b09ca
fix(dstack-mr): reject overflowing TD HOB varints
kvinwang Sep 22, 2026
5a6aed6
fix(ra-tls): satisfy formatting checks
kvinwang Sep 22, 2026
804c2bc
Merge pull request #1236 from Dstack-TEE/fix/dstack-mr-tdvf-bounds
kvinwang Sep 22, 2026
f2f7b52
test: simplify certificate validity coverage
kvinwang Sep 22, 2026
721df1b
Merge pull request #1232 from Dstack-TEE/fix/cert-validity-overflow
kvinwang Sep 22, 2026
23ed35a
fix(kms): bound compose_hash and instance_id before the policy backend
kvinwang Sep 20, 2026
817294d
fix(kms): coalesce identical in-flight auth api calls
kvinwang Sep 20, 2026
85ea777
fix(kms): let a bootstrap interrupted by a crash be redone
kvinwang Sep 22, 2026
81173da
refactor(kms): trim identity width checks and tests
kvinwang Sep 22, 2026
1436738
Merge pull request #1309 from Dstack-TEE/fix/kms-partial-bootstrap
kvinwang Sep 22, 2026
884402f
Merge pull request #1310 from Dstack-TEE/fix/kms-identity-widths
kvinwang Sep 22, 2026
cf13397
refactor(kms): replace InFlight with short-lived moka caches
kvinwang Sep 22, 2026
f00ceaf
Merge pull request #1311 from Dstack-TEE/fix/kms-auth-api-inflight
kvinwang Sep 22, 2026
37f6ee7
fix(kms): scope the onboarding os_image_hash fallback to legacy certi…
kvinwang Sep 22, 2026
46da2bd
fix(kms): read each auth-eth decision from a single block
kvinwang Sep 22, 2026
d99c337
Merge pull request #1314 from Dstack-TEE/fix/auth-eth-chain-pinning
kvinwang Sep 22, 2026
a6c492f
docs(kms): note that requireTcbUpToDate does not gate AWS NitroTPM
kvinwang Sep 22, 2026
12ea288
Merge pull request #1313 from Dstack-TEE/fix/kms-onboard-image-fallback
kvinwang Sep 22, 2026
7e41e75
Merge pull request #1316 from Dstack-TEE/docs/kms-nitro-tpm-tcb-vacuous
kvinwang Sep 22, 2026
793626d
fix(dstack-util): bound host-shared copy by bytes read, not a prior stat
kvinwang Sep 22, 2026
2d0c31b
Merge pull request #1317 from Dstack-TEE/fix/host-shared-copy-bound
kvinwang Sep 22, 2026
f124caf
fix(attest): require /dev/nsm before selecting the Nitro Enclave variant
kvinwang Sep 22, 2026
d9de891
Merge pull request #1285 from Dstack-TEE/fix/host-app-boundary
kvinwang Sep 22, 2026
e125bbd
chore: sync upstream dstack and validate alpha fork
lalalune Sep 22, 2026
2983887
fix: publish fork releases in repository owner namespace
lalalune Sep 22, 2026
80c0003
test: exercise real verifier one-shot rejection in CI
lalalune Sep 22, 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
36 changes: 34 additions & 2 deletions .github/workflows/docker-build-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,27 @@ name: Docker Build Check
# does.
on:
push:
branches: [ next, 'release/**' ]
branches: [ alpha, next, 'release/**' ]
paths:
- 'dstack/**'
- 'rust-toolchain.toml'
- '.github/workflows/docker-build-check.yml'
- '.github/workflows/kms-release.yml'
- '.github/workflows/gateway-release.yml'
- '.github/workflows/verifier-release.yml'
- '.github/workflows/local-key-provider-release.yml'
- '.github/workflows/mkosi-build.yml'
pull_request:
branches: [ next, 'release/**' ]
branches: [ alpha, next, 'release/**' ]
paths:
- 'dstack/**'
- 'rust-toolchain.toml'
- '.github/workflows/docker-build-check.yml'
- '.github/workflows/kms-release.yml'
- '.github/workflows/gateway-release.yml'
- '.github/workflows/verifier-release.yml'
- '.github/workflows/local-key-provider-release.yml'
- '.github/workflows/mkosi-build.yml'

env:
DSTACK_REV: ${{ github.event.pull_request.head.sha || github.sha }}
Expand All @@ -52,6 +56,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Install workflow contract parser
run: python3 -m pip install PyYAML==6.0.3
- name: Test release build orchestration
run: python3 -m unittest discover -s dstack/build/shared/tests -v

Expand Down Expand Up @@ -187,6 +193,32 @@ jobs:
DSTACK_REV=${{ env.DSTACK_REV }}
DSTACK_SRC_URL=${{ env.DSTACK_SRC_URL }}

- name: Verify offline one-shot rejection contract
run: |
python3 - <<'PYTEST'
import json
import pathlib
import subprocess
import tempfile

with tempfile.TemporaryDirectory() as directory:
request = pathlib.Path(directory) / "invalid.json"
request.write_text(json.dumps({"attestation": "00"}))
result = subprocess.run(
["docker", "run", "--rm", "--network=none",
"-v", f"{directory}:/evidence", "dstack-verifier-check:latest",
"--config", "/etc/dstack/dstack-verifier.toml",
"--verify", "/evidence/invalid.json"],
capture_output=True, text=True, timeout=30,
)
assert result.returncode == 1, (result.returncode, result.stderr)
response = json.loads(result.stdout)
assert response["is_valid"] is False, response
assert isinstance(response["details"], dict), response
assert response["reason"], response
print("Real verifier CLI rejects malformed attestation with one JSON response")
PYTEST

- name: Verify pinned packages (runtime)
run: |
dstack/build/shared/verify-pinned-packages.sh dstack-verifier-check:latest \
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/gateway-cluster-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ name: Gateway cluster tests
# this replaces could not do.
on:
push:
branches: [ next, 'release/**' ]
branches: [ alpha, next, 'release/**' ]
paths:
- 'dstack/gateway/**'
- 'dstack/cert-client/**'
Expand All @@ -24,7 +24,7 @@ on:
- 'dstack/crates/mock-attestation/**'
- '.github/workflows/gateway-cluster-tests.yml'
pull_request:
branches: [ next, 'release/**' ]
branches: [ alpha, next, 'release/**' ]
paths:
- 'dstack/gateway/**'
- 'dstack/cert-client/**'
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/gateway-e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ name: Gateway e2e tests
# cluster mTLS path that a harness with the checks switched off cannot reach.
on:
push:
branches: [ next, 'release/**' ]
branches: [ alpha, next, 'release/**' ]
paths:
- 'dstack/gateway/**'
- 'dstack/cert-client/**'
Expand All @@ -27,7 +27,7 @@ on:
- 'tools/mock-cf-dns/**'
- '.github/workflows/gateway-e2e-tests.yml'
pull_request:
branches: [ next, 'release/**' ]
branches: [ alpha, next, 'release/**' ]
paths:
- 'dstack/gateway/**'
- 'dstack/cert-client/**'
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/gateway-proxy-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ name: Gateway proxy tests
# anything else was using TLS.
on:
push:
branches: [ next, 'release/**' ]
branches: [ alpha, next, 'release/**' ]
paths:
- 'dstack/gateway/**'
- 'dstack/vendor/ktls/**'
Expand All @@ -28,7 +28,7 @@ on:
- 'sdk/simulator/**'
- '.github/workflows/gateway-proxy-tests.yml'
pull_request:
branches: [ next, 'release/**' ]
branches: [ alpha, next, 'release/**' ]
paths:
- 'dstack/gateway/**'
- 'dstack/vendor/ktls/**'
Expand Down
38 changes: 27 additions & 11 deletions .github/workflows/gateway-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,22 @@ jobs:

# Manual runs rebuild an existing release tag, not the selected branch.
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
with:
ref: ${{ github.event_name == 'workflow_dispatch' && env.RELEASE_TAG || github.sha }}

- name: Log in to Docker Hub
uses: docker/login-action@v3
- name: Normalise registry owner
run: echo "OWNER_LC=${GITHUB_REPOSITORY_OWNER,,}" >> "$GITHUB_ENV"

- name: Log in to GitHub Container Registry
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3

- name: Resolve the revision to build
run: echo "GIT_REV=$(git rev-parse HEAD)" >> "$GITHUB_ENV"
Expand All @@ -71,7 +75,7 @@ jobs:
METADATA_FILE: ${{ runner.temp }}/build-metadata.json
GIT_REV: ${{ env.GIT_REV }}
IMAGE_VERSION: ${{ env.VERSION }}
IMAGE_NAME: ${{ vars.DOCKERHUB_ORG }}/dstack-gateway:${{ env.VERSION }}
IMAGE_NAME: ghcr.io/${{ env.OWNER_LC }}/dstack-gateway:${{ env.VERSION }}
IMAGE_SOURCE_URL: ${{ github.server_url }}/${{ github.repository }}
DSTACK_SRC_URL: ${{ github.server_url }}/${{ github.repository }}.git
run: |
Expand All @@ -84,23 +88,35 @@ jobs:
fi
echo "digest=$digest" >> "$GITHUB_OUTPUT"

- name: Verify anonymous pull access
env:
IMAGE_DIGEST: ${{ steps.build-and-push.outputs.digest }}
run: |
token=$(curl -fsSL \
"https://ghcr.io/token?scope=repository:${OWNER_LC}/dstack-gateway:pull" \
| jq -er .token)
curl -fsSL -o /dev/null \
-H "Authorization: Bearer $token" \
-H "Accept: application/vnd.oci.image.manifest.v1+json" \
"https://ghcr.io/v2/${OWNER_LC}/dstack-gateway/manifests/$IMAGE_DIGEST"

- name: Generate artifact attestation
uses: actions/attest-build-provenance@v1
uses: actions/attest-build-provenance@92c65d2898f1f53cfdc910b962cecff86e7f8fcc # v1
with:
subject-name: "docker.io/${{ vars.DOCKERHUB_ORG }}/dstack-gateway"
subject-name: "ghcr.io/${{ env.OWNER_LC }}/dstack-gateway"
subject-digest: ${{ steps.build-and-push.outputs.digest }}
push-to-registry: true

- name: GitHub Release
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2
with:
tag_name: ${{ env.RELEASE_TAG }}
target_commitish: ${{ env.GIT_REV }}
name: "Gateway Release v${{ env.VERSION }}"
body: |
## Docker Image Information

**Image**: `docker.io/${{ vars.DOCKERHUB_ORG }}/dstack-gateway:${{ env.VERSION }}`
**Image**: `ghcr.io/${{ env.OWNER_LC }}/dstack-gateway:${{ env.VERSION }}`

**Digest (SHA256)**: `${{ steps.build-and-push.outputs.digest }}`

Expand Down
41 changes: 28 additions & 13 deletions .github/workflows/kms-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:

# Manual runs rebuild an existing release tag, not the selected branch.
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
with:
ref: ${{ github.event_name == 'workflow_dispatch' && env.RELEASE_TAG || github.sha }}

Expand All @@ -56,14 +56,18 @@ jobs:
dstack/kms/auth-eth/lib/openzeppelin-contracts-upgradeable \
dstack/kms/auth-eth/lib/openzeppelin-foundry-upgrades

- name: Log in to Docker Hub
uses: docker/login-action@v3
- name: Normalise registry owner
run: echo "OWNER_LC=${GITHUB_REPOSITORY_OWNER,,}" >> "$GITHUB_ENV"

- name: Log in to GitHub Container Registry
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3

- name: Resolve the revision to build
run: echo "GIT_REV=$(git rev-parse HEAD)" >> "$GITHUB_ENV"
Expand All @@ -78,7 +82,7 @@ jobs:
METADATA_FILE: ${{ runner.temp }}/build-metadata.json
GIT_REV: ${{ env.GIT_REV }}
IMAGE_VERSION: ${{ env.VERSION }}
IMAGE_NAME: ${{ vars.DOCKERHUB_ORG }}/dstack-kms:${{ env.VERSION }}
IMAGE_NAME: ghcr.io/${{ env.OWNER_LC }}/dstack-kms:${{ env.VERSION }}
IMAGE_SOURCE_URL: ${{ github.server_url }}/${{ github.repository }}
DSTACK_SRC_URL: ${{ github.server_url }}/${{ github.repository }}.git
run: |
Expand All @@ -91,24 +95,35 @@ jobs:
fi
echo "digest=$digest" >> "$GITHUB_OUTPUT"

- name: Verify anonymous pull access
env:
IMAGE_DIGEST: ${{ steps.build-and-push.outputs.digest }}
run: |
token=$(curl -fsSL \
"https://ghcr.io/token?scope=repository:${OWNER_LC}/dstack-kms:pull" \
| jq -er .token)
curl -fsSL -o /dev/null \
-H "Authorization: Bearer $token" \
-H "Accept: application/vnd.oci.image.manifest.v1+json" \
"https://ghcr.io/v2/${OWNER_LC}/dstack-kms/manifests/$IMAGE_DIGEST"

- name: Generate artifact attestation
uses: actions/attest-build-provenance@v1
uses: actions/attest-build-provenance@92c65d2898f1f53cfdc910b962cecff86e7f8fcc # v1
with:
subject-name: "docker.io/${{ vars.DOCKERHUB_ORG }}/dstack-kms"
subject-name: "ghcr.io/${{ env.OWNER_LC }}/dstack-kms"
subject-digest: ${{ steps.build-and-push.outputs.digest }}
push-to-registry: true

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
uses: foundry-rs/foundry-toolchain@908c540300062bd5a7e473851cdb4282204cee09 # v1

- name: Compile contracts with Foundry
run: |
cd dstack/kms/auth-eth
forge install
forge build

- name: GitHub Release
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2
with:
tag_name: ${{ env.RELEASE_TAG }}
target_commitish: ${{ env.GIT_REV }}
Expand All @@ -119,7 +134,7 @@ jobs:
body: |
## Docker Image Information

**Image**: `docker.io/${{ vars.DOCKERHUB_ORG }}/dstack-kms:${{ env.VERSION }}`
**Image**: `ghcr.io/${{ env.OWNER_LC }}/dstack-kms:${{ env.VERSION }}`

**Digest (SHA256)**: `${{ steps.build-and-push.outputs.digest }}`

Expand Down
59 changes: 44 additions & 15 deletions .github/workflows/local-key-provider-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,48 +25,76 @@ jobs:
build-and-release:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v7

- name: Parse version from tag
- name: Parse and check version
env:
DISPATCH_VERSION: ${{ inputs.version }}
run: |
if [[ "$GITHUB_REF" == refs/tags/local-key-provider-v* ]]; then
VERSION=${GITHUB_REF#refs/tags/local-key-provider-v}
else
if [ "$GITHUB_EVENT_NAME" = workflow_dispatch ]; then
VERSION=$DISPATCH_VERSION
else
case "$GITHUB_REF" in
refs/tags/local-key-provider-v*) VERSION=${GITHUB_REF#refs/tags/local-key-provider-v} ;;
*) echo "Expected a local-key-provider-v* tag" >&2; exit 1 ;;
esac
fi
if [[ ! "$VERSION" =~ ^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$ ]]; then
echo "Version must be a valid Docker tag" >&2
exit 1
fi
echo "VERSION=$VERSION" >> "$GITHUB_ENV"
echo "Parsed version: $VERSION"
echo "RELEASE_TAG=local-key-provider-v$VERSION" >> "$GITHUB_ENV"

# Manual runs rebuild an existing release tag, not the selected branch.
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
ref: ${{ github.event_name == 'workflow_dispatch' && env.RELEASE_TAG || github.sha }}

# ghcr.io requires a lowercase owner; the org is mixed-case.
- name: Normalise registry owner
run: echo "OWNER_LC=${GITHUB_REPOSITORY_OWNER,,}" >> "$GITHUB_ENV"

- name: Log in to GitHub Container Registry
uses: docker/login-action@v4
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4

- name: Resolve the revision to build
run: echo "GIT_REV=$(git rev-parse HEAD)" >> "$GITHUB_ENV"

- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@v7
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7
with:
context: dstack
file: dstack/local-key-provider/build/Dockerfile.key-provider
push: true
tags: ghcr.io/${{ env.OWNER_LC }}/local-key-provider:${{ env.VERSION }}
labels: |
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
org.opencontainers.image.revision=${{ env.GIT_REV }}
org.opencontainers.image.version=${{ env.VERSION }}
platforms: linux/amd64
provenance: false

- name: Verify anonymous pull access
env:
IMAGE_DIGEST: ${{ steps.build-and-push.outputs.digest }}
run: |
token=$(curl -fsSL \
"https://ghcr.io/token?scope=repository:${OWNER_LC}/local-key-provider:pull" \
| jq -er .token)
curl -fsSL -o /dev/null \
-H "Authorization: Bearer $token" \
-H "Accept: application/vnd.oci.image.manifest.v1+json" \
"https://ghcr.io/v2/${OWNER_LC}/local-key-provider/manifests/$IMAGE_DIGEST"

- name: Generate artifact attestation
uses: actions/attest-build-provenance@v4
uses: actions/attest-build-provenance@8beda2b7ed98355c0e97c0a63bec38ae472e66c4 # v4
with:
subject-name: "ghcr.io/${{ env.OWNER_LC }}/local-key-provider"
subject-digest: ${{ steps.build-and-push.outputs.digest }}
Expand All @@ -91,10 +119,11 @@ jobs:
echo "MRSIGNER=$MRSIGNER" >> "$GITHUB_ENV"

- name: GitHub Release
uses: softprops/action-gh-release@v3
uses: softprops/action-gh-release@5113cdc90fd4d541c801c55356214017bf5ae34b # v3
with:
name: "Local Key Provider Release v${{ env.VERSION }}"
tag_name: local-key-provider-v${{ env.VERSION }}
tag_name: ${{ env.RELEASE_TAG }}
target_commitish: ${{ env.GIT_REV }}
files: local-key-provider.sig.json
body: |
## Docker Image Information
Expand Down
Loading
Loading