Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
58 changes: 44 additions & 14 deletions .github/workflows/msi-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:
wix --version
wix extension add --global WixToolset.Util.wixext/4.0.5

- name: Build Windows .exe
- name: Build Windows .exes (agent + launcher)
shell: pwsh
run: |
$env:GOOS = "windows"
Expand All @@ -64,7 +64,11 @@ jobs:
go build -trimpath -ldflags "-s -w" `
-o "$PWD\dmg-smoke.exe" `
./cmd/stepsecurity-dev-machine-guard
Get-Item "$PWD\dmg-smoke.exe" | Select-Object Name, Length
go build -trimpath -ldflags "-s -w -H windowsgui" `
-o "$PWD\dmg-smoke-task.exe" `
./cmd/stepsecurity-dev-machine-guard-task
Get-Item "$PWD\dmg-smoke.exe", "$PWD\dmg-smoke-task.exe" |
Select-Object Name, Length

- name: Build MSI
shell: pwsh
Expand All @@ -83,6 +87,7 @@ jobs:
-d Arch=x64 `
-d "Version=$version" `
-d "BinaryPath=$PWD\dmg-smoke.exe" `
-d "LauncherPath=$PWD\dmg-smoke-task.exe" `
-out "dist\dmg-smoke.msi"
Get-Item "dist\dmg-smoke.msi" | Select-Object Name, Length

Expand Down Expand Up @@ -112,18 +117,28 @@ jobs:
- name: Verify install artifacts
shell: pwsh
run: |
$bin = "C:\Program Files\StepSecurity\stepsecurity-dev-machine-guard.exe"
$cfg = "C:\ProgramData\StepSecurity\config.json"
$task = "StepSecurity Dev Machine Guard"
$bin = "C:\Program Files\StepSecurity\stepsecurity-dev-machine-guard.exe"
$launcher = "C:\Program Files\StepSecurity\stepsecurity-dev-machine-guard-task.exe"
$cfg = "C:\ProgramData\StepSecurity\config.json"
$task = "StepSecurity Dev Machine Guard"

$checks = @()

# 1. Binary on disk
# 1a. Agent binary on disk
if (Test-Path $bin) {
Write-Host "[OK] Binary present at $bin"
Write-Host "[OK] Agent present at $bin"
$checks += $true
} else {
Write-Host "::error::Binary missing: $bin"
Write-Host "::error::Agent missing: $bin"
$checks += $false
}

# 1b. Launcher binary on disk
if (Test-Path $launcher) {
Write-Host "[OK] Launcher present at $launcher"
$checks += $true
} else {
Write-Host "::error::Launcher missing: $launcher"
$checks += $false
}

Expand Down Expand Up @@ -160,7 +175,8 @@ jobs:
$checks += $false
}

# 4. Scheduled task registered and runs as INTERACTIVE
# 4. Scheduled task registered, runs as INTERACTIVE, and its
# action points at the launcher (not the agent directly).
$taskInfo = schtasks /query /tn $task /v /fo LIST 2>&1
if ($LASTEXITCODE -eq 0) {
$runAs = ($taskInfo | Select-String -Pattern '^\s*Run As User:').ToString()
Expand All @@ -171,6 +187,15 @@ jobs:
Write-Host "::error::Run As User wrong: $runAs"
$checks += $false
}

$action = ($taskInfo | Select-String -Pattern '^\s*Task To Run:').ToString()
if ($action -match 'stepsecurity-dev-machine-guard-task\.exe') {
Write-Host "[OK] Task action points at GUI launcher"
$checks += $true
} else {
Write-Host "::error::Task action does not point at launcher: $action"
$checks += $false
}
} else {
Write-Host "::error::schtasks /query failed: $taskInfo"
$checks += $false
Expand Down Expand Up @@ -199,12 +224,17 @@ jobs:
run: |
$task = "StepSecurity Dev Machine Guard"

# Binary should be gone
if (Test-Path "C:\Program Files\StepSecurity\stepsecurity-dev-machine-guard.exe") {
Write-Host "::error::Binary still present after uninstall"
exit 1
# Both binaries should be gone
foreach ($leftover in @(
"C:\Program Files\StepSecurity\stepsecurity-dev-machine-guard.exe",
"C:\Program Files\StepSecurity\stepsecurity-dev-machine-guard-task.exe"
)) {
if (Test-Path $leftover) {
Write-Host "::error::File still present after uninstall: $leftover"
exit 1
}
}
Write-Host "[OK] Binary removed"
Write-Host "[OK] Agent + launcher removed"

# Scheduled task should be gone. Capture the exit code into a
# local — PowerShell uses $LASTEXITCODE from the last native call
Expand Down
36 changes: 29 additions & 7 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,13 @@ jobs:
id: binaries
run: |
DARWIN=$(find dist -type f -name '*darwin_unnotarized' | head -1)
WIN_AMD64=$(find dist -type f -name '*.exe' -path '*windows_amd64*' | head -1)
WIN_ARM64=$(find dist -type f -name '*.exe' -path '*windows_arm64*' | head -1)
# Filter agent vs launcher (-task) explicitly — both ship as
# <name>-<version>-<os>_<arch>.exe so a bare *.exe glob would
# match either.
WIN_AMD64=$(find dist -type f -name 'stepsecurity-dev-machine-guard-*-windows_amd64.exe' ! -name '*-task-*' | head -1)
WIN_ARM64=$(find dist -type f -name 'stepsecurity-dev-machine-guard-*-windows_arm64.exe' ! -name '*-task-*' | head -1)
WIN_TASK_AMD64=$(find dist -type f -name 'stepsecurity-dev-machine-guard-task-*-windows_amd64.exe' | head -1)
WIN_TASK_ARM64=$(find dist -type f -name 'stepsecurity-dev-machine-guard-task-*-windows_arm64.exe' | head -1)
LINUX_AMD64=$(find dist -type f -name 'stepsecurity-dev-machine-guard' -path '*linux_amd64*' | head -1)
LINUX_ARM64=$(find dist -type f -name 'stepsecurity-dev-machine-guard' -path '*linux_arm64*' | head -1)

Expand All @@ -102,7 +107,7 @@ jobs:
RPM_AMD64=$(find dist -type f -name '*-amd64.rpm' | head -1)
RPM_ARM64=$(find dist -type f -name '*-arm64.rpm' | head -1)

for label in "darwin:${DARWIN}" "windows_amd64:${WIN_AMD64}" "windows_arm64:${WIN_ARM64}" "linux_amd64:${LINUX_AMD64}" "linux_arm64:${LINUX_ARM64}" "deb_amd64:${DEB_AMD64}" "deb_arm64:${DEB_ARM64}" "rpm_amd64:${RPM_AMD64}" "rpm_arm64:${RPM_ARM64}"; do
for label in "darwin:${DARWIN}" "windows_amd64:${WIN_AMD64}" "windows_arm64:${WIN_ARM64}" "windows_task_amd64:${WIN_TASK_AMD64}" "windows_task_arm64:${WIN_TASK_ARM64}" "linux_amd64:${LINUX_AMD64}" "linux_arm64:${LINUX_ARM64}" "deb_amd64:${DEB_AMD64}" "deb_arm64:${DEB_ARM64}" "rpm_amd64:${RPM_AMD64}" "rpm_arm64:${RPM_ARM64}"; do
name="${label%%:*}"
path="${label#*:}"
if [ -z "$path" ] || [ ! -f "$path" ]; then
Expand All @@ -115,6 +120,8 @@ jobs:
echo "darwin=$DARWIN" >> "$GITHUB_OUTPUT"
echo "win_amd64=$WIN_AMD64" >> "$GITHUB_OUTPUT"
echo "win_arm64=$WIN_ARM64" >> "$GITHUB_OUTPUT"
echo "win_task_amd64=$WIN_TASK_AMD64" >> "$GITHUB_OUTPUT"
echo "win_task_arm64=$WIN_TASK_ARM64" >> "$GITHUB_OUTPUT"
echo "linux_amd64=$LINUX_AMD64" >> "$GITHUB_OUTPUT"
echo "linux_arm64=$LINUX_ARM64" >> "$GITHUB_OUTPUT"
echo "deb_amd64=$DEB_AMD64" >> "$GITHUB_OUTPUT"
Expand Down Expand Up @@ -147,6 +154,10 @@ jobs:
"dist/stepsecurity-dev-machine-guard-windows_amd64.exe.bundle"
sign_with_retry "${{ steps.binaries.outputs.win_arm64 }}" \
"dist/stepsecurity-dev-machine-guard-windows_arm64.exe.bundle"
sign_with_retry "${{ steps.binaries.outputs.win_task_amd64 }}" \
"dist/stepsecurity-dev-machine-guard-task-windows_amd64.exe.bundle"
sign_with_retry "${{ steps.binaries.outputs.win_task_arm64 }}" \
"dist/stepsecurity-dev-machine-guard-task-windows_arm64.exe.bundle"
sign_with_retry "${{ steps.binaries.outputs.linux_amd64 }}" \
"dist/stepsecurity-dev-machine-guard-linux_amd64.bundle"
sign_with_retry "${{ steps.binaries.outputs.linux_arm64 }}" \
Expand All @@ -168,6 +179,8 @@ jobs:
dist/stepsecurity-dev-machine-guard-darwin_unnotarized.bundle \
dist/stepsecurity-dev-machine-guard-windows_amd64.exe.bundle \
dist/stepsecurity-dev-machine-guard-windows_arm64.exe.bundle \
dist/stepsecurity-dev-machine-guard-task-windows_amd64.exe.bundle \
dist/stepsecurity-dev-machine-guard-task-windows_arm64.exe.bundle \
dist/stepsecurity-dev-machine-guard-linux_amd64.bundle \
dist/stepsecurity-dev-machine-guard-linux_arm64.bundle \
"${{ steps.binaries.outputs.deb_amd64 }}.bundle" \
Expand All @@ -183,6 +196,8 @@ jobs:
${{ steps.binaries.outputs.darwin }}
${{ steps.binaries.outputs.win_amd64 }}
${{ steps.binaries.outputs.win_arm64 }}
${{ steps.binaries.outputs.win_task_amd64 }}
${{ steps.binaries.outputs.win_task_arm64 }}
${{ steps.binaries.outputs.linux_amd64 }}
${{ steps.binaries.outputs.linux_arm64 }}
${{ steps.binaries.outputs.deb_amd64 }}
Expand Down Expand Up @@ -240,10 +255,15 @@ jobs:
shell: pwsh
run: |
$version = "${{ needs.release.outputs.version }}"
$amd64 = Get-ChildItem dist -Filter "*-windows_amd64.exe" | Select-Object -First 1
$arm64 = Get-ChildItem dist -Filter "*-windows_arm64.exe" | Select-Object -First 1
if (-not $amd64 -or -not $arm64) {
Write-Error "Windows .exe assets missing under dist/"
# Both agent and launcher .exes share the *-windows_<arch>.exe
# suffix; filter on the -task- segment to tell them apart.
$amd64 = Get-ChildItem dist -Filter "stepsecurity-dev-machine-guard-*-windows_amd64.exe" | Where-Object Name -NotLike '*-task-*' | Select-Object -First 1
$arm64 = Get-ChildItem dist -Filter "stepsecurity-dev-machine-guard-*-windows_arm64.exe" | Where-Object Name -NotLike '*-task-*' | Select-Object -First 1
$taskAmd64 = Get-ChildItem dist -Filter "stepsecurity-dev-machine-guard-task-*-windows_amd64.exe" | Select-Object -First 1
$taskArm64 = Get-ChildItem dist -Filter "stepsecurity-dev-machine-guard-task-*-windows_arm64.exe" | Select-Object -First 1
if (-not $amd64 -or -not $arm64 -or -not $taskAmd64 -or -not $taskArm64) {
Write-Error "Windows .exe assets (agent + launcher, both arches) missing under dist/"
Get-ChildItem dist | Format-Table Name
exit 1
}

Expand All @@ -253,6 +273,7 @@ jobs:
-d Arch=x64 `
-d "Version=$version" `
-d "BinaryPath=$($amd64.FullName)" `
-d "LauncherPath=$($taskAmd64.FullName)" `
-out "dist/stepsecurity-dev-machine-guard-$version-x64.msi"

wix build packaging/windows/Product.wxs `
Expand All @@ -261,6 +282,7 @@ jobs:
-d Arch=arm64 `
-d "Version=$version" `
-d "BinaryPath=$($arm64.FullName)" `
-d "LauncherPath=$($taskArm64.FullName)" `
-out "dist/stepsecurity-dev-machine-guard-$version-arm64.msi"

Get-ChildItem dist -Filter "*.msi" | Format-Table Name, Length
Expand Down
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,9 @@ stepsecurity-dev-machine-guard-linux

# Temporary files
todo-remove/

# Agent runtime state. When the binary or its tests run from inside the
# repo (working dir = a subpkg, HOME pointing under it, etc.), it drops
# config.json, agent.error.log, ai-agent-hook-errors.jsonl, hooks-state.json
# and friends here. Never artifacts we want to track.
**/.stepsecurity/
30 changes: 30 additions & 0 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,29 @@ builds:
env:
- CGO_ENABLED=0

# GUI-subsystem launcher invoked by Windows Task Scheduler so the
# console-subsystem agent never gets a console window allocated.
# -H windowsgui flips the PE subsystem; otherwise identical config.
- id: stepsecurity-dev-machine-guard-task
main: ./cmd/stepsecurity-dev-machine-guard-task
binary: stepsecurity-dev-machine-guard-task
goos:
- windows
goarch:
- amd64
- arm64
mod_timestamp: "{{ .CommitTimestamp }}"
flags:
- -trimpath
ldflags:
- -s -w
- -H windowsgui
- -X github.com/step-security/dev-machine-guard/internal/buildinfo.GitCommit={{.FullCommit}}
- -X github.com/step-security/dev-machine-guard/internal/buildinfo.ReleaseTag={{.Tag}}
- -X github.com/step-security/dev-machine-guard/internal/buildinfo.ReleaseBranch={{.Branch}}
env:
- CGO_ENABLED=0

universal_binaries:
- id: universal
ids:
Expand All @@ -44,6 +67,13 @@ archives:
- binary
name_template: "stepsecurity-dev-machine-guard-{{ .Version }}-{{ .Os }}_{{ .Arch }}"
allow_different_binary_count: true
- id: windows-task
ids:
- stepsecurity-dev-machine-guard-task
formats:
- binary
name_template: "stepsecurity-dev-machine-guard-task-{{ .Version }}-{{ .Os }}_{{ .Arch }}"
allow_different_binary_count: true

nfpms:
- id: linux-packages
Expand Down
19 changes: 15 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,34 @@ LDFLAGS := -s -w \
-X $(MODULE)/internal/buildinfo.ReleaseTag=$(TAG) \
-X $(MODULE)/internal/buildinfo.ReleaseBranch=$(BRANCH)

.PHONY: build build-windows build-windows-arm64 build-linux deploy-windows test lint clean smoke build-msi-amd64 build-msi-arm64
.PHONY: build build-windows build-windows-task build-windows-arm64 build-windows-task-arm64 build-linux deploy-windows test lint clean smoke build-msi-amd64 build-msi-arm64

build:
go build -trimpath -ldflags "$(LDFLAGS)" -o $(BINARY) ./cmd/stepsecurity-dev-machine-guard

build-windows:
GOOS=windows GOARCH=amd64 go build -trimpath -ldflags "$(LDFLAGS)" -o $(BINARY).exe ./cmd/stepsecurity-dev-machine-guard

# GUI-subsystem launcher (see cmd/stepsecurity-dev-machine-guard-task).
# `-H windowsgui` flips the PE subsystem so Windows doesn't allocate
# a console when Task Scheduler launches it.
build-windows-task:
GOOS=windows GOARCH=amd64 go build -trimpath -ldflags "$(LDFLAGS) -H windowsgui" -o $(BINARY)-task.exe ./cmd/stepsecurity-dev-machine-guard-task

build-windows-arm64:
GOOS=windows GOARCH=arm64 go build -trimpath -ldflags "$(LDFLAGS)" -o $(BINARY)-arm64.exe ./cmd/stepsecurity-dev-machine-guard

build-windows-task-arm64:
GOOS=windows GOARCH=arm64 go build -trimpath -ldflags "$(LDFLAGS) -H windowsgui" -o $(BINARY)-task-arm64.exe ./cmd/stepsecurity-dev-machine-guard-task

build-linux:
GOOS=linux GOARCH=amd64 go build -trimpath -ldflags "$(LDFLAGS)" -o $(BINARY)-linux ./cmd/stepsecurity-dev-machine-guard

# MSI builds. Require WiX 4 on PATH: `dotnet tool install --global wix --version 4.0.5`.
# Output: dist/stepsecurity-dev-machine-guard-<version>-{x64,arm64}.msi
# Reads Version from internal/buildinfo so MajorUpgrade semantics line up
# with whatever the binary reports as `--version`.
build-msi-amd64: build-windows
build-msi-amd64: build-windows build-windows-task
mkdir -p dist
@wix extension list --global 2>/dev/null | grep -q "WixToolset.Util.wixext" || \
wix extension add --global WixToolset.Util.wixext/4.0.5
Expand All @@ -37,9 +46,10 @@ build-msi-amd64: build-windows
-d Arch=x64 \
-d Version=$(VERSION) \
-d BinaryPath=$(CURDIR)/$(BINARY).exe \
-d LauncherPath=$(CURDIR)/$(BINARY)-task.exe \
-out dist/stepsecurity-dev-machine-guard-$(VERSION)-x64.msi

build-msi-arm64: build-windows-arm64
build-msi-arm64: build-windows-arm64 build-windows-task-arm64
mkdir -p dist
@wix extension list --global 2>/dev/null | grep -q "WixToolset.Util.wixext" || \
wix extension add --global WixToolset.Util.wixext/4.0.5
Expand All @@ -49,6 +59,7 @@ build-msi-arm64: build-windows-arm64
-d Arch=arm64 \
-d Version=$(VERSION) \
-d BinaryPath=$(CURDIR)/$(BINARY)-arm64.exe \
-d LauncherPath=$(CURDIR)/$(BINARY)-task-arm64.exe \
-out dist/stepsecurity-dev-machine-guard-$(VERSION)-arm64.msi

deploy-windows:
Expand All @@ -61,7 +72,7 @@ lint:
golangci-lint run ./...

clean:
rm -f $(BINARY) $(BINARY).exe $(BINARY)-arm64.exe $(BINARY)-linux
rm -f $(BINARY) $(BINARY).exe $(BINARY)-task.exe $(BINARY)-arm64.exe $(BINARY)-task-arm64.exe $(BINARY)-linux
rm -rf dist/

smoke: build
Expand Down
Loading