Skip to content

Commit 41d8470

Browse files
Ishaan Jaincursoragent
authored andcommitted
fix: make Checkov work on Intel Mac; harden tool install exits
Upstream Darwin Checkov zip is arm64 despite the X86_64 name — use pip on Intel Macs, fix arch assertions in macOS smoke, and exit non-zero when tool install/update fails. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 114b947 commit 41d8470

5 files changed

Lines changed: 90 additions & 34 deletions

File tree

.github/workflows/macos-local-smoke.yml

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -88,31 +88,37 @@ jobs:
8888
run: |
8989
set -euo pipefail
9090
TOOLS="${HOME}/.local/bin/accuknox"
91+
ARCH="${{ matrix.arch }}"
9192
ls -la "$TOOLS" "$TOOLS/sast" "$TOOLS/sq-sast/bin" || true
9293
93-
assert_arch () {
94+
assert_native_arch () {
9495
local bin="$1"
95-
local expect_x86="$2" # yes|no — whether this binary is expected x86_64
9696
echo "--- file $bin"
9797
file "$bin"
9898
test -x "$bin"
99-
if [[ "$expect_x86" == "yes" ]]; then
100-
file "$bin" | grep -Eiq 'x86_64|x86-64|Intel'
99+
if [[ "$ARCH" == "arm64" ]]; then
100+
file "$bin" | grep -Eiq 'arm64|aarch64'
101101
else
102-
if [[ "${{ matrix.arch }}" == "arm64" ]]; then
103-
file "$bin" | grep -Eiq 'arm64|aarch64'
104-
else
105-
file "$bin" | grep -Eiq 'x86_64|x86-64|Intel'
106-
fi
102+
file "$bin" | grep -Eiq 'x86_64|x86-64'
107103
fi
108104
}
109105
110-
# Checkov is Intel-only even on Apple Silicon (Rosetta).
111-
assert_arch "$TOOLS/iac" yes
112-
assert_arch "$TOOLS/sast/sast" no
113-
assert_arch "$TOOLS/secret" no
114-
assert_arch "$TOOLS/container" no
115-
assert_arch "$TOOLS/gitleaks" no
106+
# Checkov: Apple Silicon uses mislabeled standalone (arm64 Mach-O);
107+
# Intel Mac uses a pip-venv shell wrapper (script text).
108+
echo "--- iac"
109+
file "$TOOLS/iac"
110+
test -x "$TOOLS/iac"
111+
if [[ "$ARCH" == "arm64" ]]; then
112+
file "$TOOLS/iac" | grep -Eiq 'arm64|aarch64'
113+
else
114+
file "$TOOLS/iac" | grep -Eiq 'script|text|shell'
115+
test -x "$TOOLS/iac-venv/bin/checkov"
116+
fi
117+
118+
assert_native_arch "$TOOLS/sast/sast"
119+
assert_native_arch "$TOOLS/secret"
120+
assert_native_arch "$TOOLS/container"
121+
assert_native_arch "$TOOLS/gitleaks"
116122
test -x "$TOOLS/sq-sast/bin/sonar-scanner"
117123
test -d "$TOOLS/sast/rules"
118124

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ Notes:
8686

8787
- **Apple Silicon** = `arm64` / M-series; **Intel Mac** = `x86_64`. The CLI detects the CPU and installs the matching binary.
8888
- **Windows** local install currently targets **x64** upstream binaries (standard for these scanners).
89-
- **IaC (Checkov)** on Apple Silicon currently uses Checkov’s Intel build (needs [Rosetta 2](https://support.apple.com/en-us/102527)). Other Phase-1 tools use native arm64 or x86_64 builds.
89+
- **IaC (Checkov):** Apple Silicon uses Checkov’s Darwin standalone zip (the asset is named `X86_64` but the binary is arm64). Intel Mac installs Checkov via a dedicated pip venv (no usable x86_64 standalone zip). Other Phase-1 tools use native arm64 or x86_64 builds.
9090

9191
## Get Help
9292

aspm_cli/commands/tool_command.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,19 +49,22 @@ def execute(self, args):
4949
overwrite = args.mode == "update"
5050
action_message = {"install": "installed", "update": "updated"}
5151
action_message_present = {"install": "Installing", "update": "Updating"}
52+
failures = []
5253

5354
if validated.all:
5455
for tool in ALLOWED_TOOL_TYPES:
5556
spinner = Spinner(message=f"{action_message_present[args.mode]} tool for: {tool}")
5657
spinner.start()
57-
downloaded = downloader.download_tool(tool, overwrite) # <-- FIXED HERE
58+
downloaded = downloader.download_tool(tool, overwrite)
5859
spinner.stop()
5960
if downloaded:
6061
Logger.log_with_color(
6162
'INFO',
6263
f"{tool} {action_message[args.mode]} successfully.",
6364
Fore.GREEN
6465
)
66+
else:
67+
failures.append(tool)
6568
else:
6669
spinner = Spinner(message=f"{action_message_present[args.mode]} tool for: {validated.tooltype}")
6770
spinner.start()
@@ -72,4 +75,9 @@ def execute(self, args):
7275
'INFO',
7376
f"{validated.tooltype} {action_message[args.mode]} successfully.",
7477
Fore.GREEN
75-
)
78+
)
79+
else:
80+
failures.append(validated.tooltype)
81+
82+
if failures:
83+
sys.exit(1)

aspm_cli/tool/download.py

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import os
22
import platform
33
import shutil
4+
import subprocess
5+
import sys
46
import tarfile
57
import tempfile
68
import urllib.request
@@ -189,13 +191,51 @@ def _chmod_x(self, path: Path):
189191
path.chmod(path.stat().st_mode | 0o111)
190192

191193
def _install_darwin_iac(self, arch: str) -> bool:
192-
# Checkov currently publishes only darwin_X86_64; Apple Silicon runs it via Rosetta.
193-
zip_name = "checkov_darwin_X86_64.zip"
194-
if arch == "arm64":
194+
"""
195+
Install Checkov as ``iac``.
196+
197+
Bridgecrew's published ``checkov_darwin_X86_64.zip`` is mislabeled — the binary
198+
inside is arm64. Use that zip on Apple Silicon. On Intel macOS, install Checkov
199+
into a dedicated venv via pip (no usable x86_64 standalone zip).
200+
"""
201+
dest = self.install_dir / "iac"
202+
venv_dir = self.install_dir / "iac-venv"
203+
204+
if arch == "x86_64":
195205
Logger.get_logger().info(
196-
"Checkov has no native Apple Silicon binary; installing the Intel (x86_64) "
197-
"build (requires Rosetta 2 on M-series Macs)."
206+
"Checkov's published Darwin standalone zip is arm64-only; "
207+
f"installing Checkov {CHECKOV_VERSION} via pip for Intel Mac."
208+
)
209+
if venv_dir.exists():
210+
shutil.rmtree(venv_dir)
211+
subprocess.run([sys.executable, "-m", "venv", str(venv_dir)], check=True)
212+
pip = venv_dir / "bin" / "pip"
213+
subprocess.run(
214+
[str(pip), "install", "--upgrade", "pip"],
215+
check=True,
216+
capture_output=True,
217+
)
218+
subprocess.run(
219+
[str(pip), "install", f"checkov=={CHECKOV_VERSION}"],
220+
check=True,
221+
)
222+
checkov_bin = venv_dir / "bin" / "checkov"
223+
if not checkov_bin.exists():
224+
raise FileNotFoundError(f"checkov not found after pip install at {checkov_bin}")
225+
dest.write_text(
226+
"#!/bin/sh\n"
227+
f'exec "{checkov_bin}" "$@"\n',
228+
encoding="utf-8",
198229
)
230+
self._chmod_x(dest)
231+
return True
232+
233+
# Apple Silicon: use the mislabeled standalone zip (contains arm64 Mach-O).
234+
zip_name = "checkov_darwin_X86_64.zip"
235+
Logger.get_logger().info(
236+
"Installing Checkov Darwin standalone build "
237+
f"(asset name {zip_name}; binary is arm64)."
238+
)
199239
url = (
200240
f"https://github.com/bridgecrewio/checkov/releases/download/"
201241
f"{CHECKOV_VERSION}/{zip_name}"
@@ -205,15 +245,12 @@ def _install_darwin_iac(self, arch: str) -> bool:
205245
self._download_file(url, zip_path)
206246
with zipfile.ZipFile(zip_path, "r") as zf:
207247
zf.extractall(tmp)
208-
# Official zip lays out dist/checkov
209248
src = Path(tmp) / "dist" / "checkov"
210249
if not src.exists():
211-
# fallback: find any executable named checkov
212250
candidates = list(Path(tmp).rglob("checkov"))
213251
if not candidates:
214252
raise FileNotFoundError("checkov binary not found in archive")
215253
src = candidates[0]
216-
dest = self.install_dir / "iac"
217254
shutil.copy2(src, dest)
218255
self._chmod_x(dest)
219256
return True

utils/prepare-aspm-scanners-darwin.sh

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,19 @@ package_for_arch() {
2525
echo "=== Packaging Darwin ${ARCH} ==="
2626

2727
# --- iac (Checkov) ---
28-
# Upstream only ships darwin_X86_64; Apple Silicon uses Rosetta.
29-
curl -fsSL -o checkov.zip \
30-
"https://github.com/bridgecrewio/checkov/releases/download/${CHECKOV_VERSION}/checkov_darwin_X86_64.zip"
31-
unzip -o -q checkov.zip
32-
cp dist/checkov iac
33-
chmod +x iac
34-
tar -czf "${OUT_DIR}/iac-darwin-${ARCH}.tar.gz" iac
35-
echo "✅ iac-darwin-${ARCH}.tar.gz"
28+
# Upstream asset checkov_darwin_X86_64.zip is mislabeled and contains an arm64 Mach-O.
29+
# Only package it for arm64. Intel Mac local install uses pip (see ToolDownloader).
30+
if [[ "$ARCH" == "arm64" ]]; then
31+
curl -fsSL -o checkov.zip \
32+
"https://github.com/bridgecrewio/checkov/releases/download/${CHECKOV_VERSION}/checkov_darwin_X86_64.zip"
33+
unzip -o -q checkov.zip
34+
cp dist/checkov iac
35+
chmod +x iac
36+
tar -czf "${OUT_DIR}/iac-darwin-${ARCH}.tar.gz" iac
37+
echo "✅ iac-darwin-${ARCH}.tar.gz"
38+
else
39+
echo "⚠️ Skipping iac-darwin-${ARCH}.tar.gz (no usable Checkov standalone for Intel; CLI uses pip)"
40+
fi
3641

3742
# --- secret (TruffleHog) ---
3843
local HOG_ARCH="arm64"

0 commit comments

Comments
 (0)