sha256:4d33c433227359e0c8718df12d9f232978f4c1be76baf854740bb8fe3e2132cf
Last pushed
1 day by sbx
Type
Sandbox Kit
Manifest digest
sha256:4d33c433227359e0c8718df12d9f232978f4c1be76baf854740bb8fe3e2132cf
schemaVersion: "3"
displayName: Snyk Evo ADS
description: Installs Snyk AgentScan, Agent Guard, and/or Snyk Studio, selected via SNYK_COMPONENTS, directly from their public release channels
sourceUrl: https://github.com/docker/sbx-kits-contrib/tree/main/snyk-evo-ads
version: 1.0.0
licenses:
- Apache-2.0
kind: mixin
requires:
- deb/coreutils
- deb/util-linux
capabilities:
- type: com.docker.sandbox/network-policy@1
config:
install:
allow:
- '**.snyk.io'
- registry.npmjs.org
- github.com
- release-assets.githubusercontent.com
runtime:
allow:
- '**.snyk.io'
- type: com.docker.sandbox/lifecycle@1
config:
install:
- command: |
set -eu
# Docker sources this file before nvm in new agent shells.
touch /etc/sandbox-persistent.sh
if ! grep -qxF 'unset NPM_CONFIG_PREFIX' /etc/sandbox-persistent.sh; then
printf '\nunset NPM_CONFIG_PREFIX\n' >> /etc/sandbox-persistent.sh
fi
description: Prevent npm prefix conflicts with nvm
user: "0"
- command: |
set -e
found=0
for src in /home/agent/corp-ca/*.crt; do
[ -e "$src" ] || continue
install -m 0644 "$src" "/usr/local/share/ca-certificates/$(basename "$src")"
echo "corp-ca: staged $(basename "$src")"
found=$((found + 1))
done
if [ "$found" = 0 ]; then
echo "corp-ca: WARNING no .crt files found under /home/agent/corp-ca/." >&2
echo "corp-ca: continuing without a corporate root CA. If outbound TLS is" >&2
echo "corp-ca: intercepted, the Snyk downloads below will fail with curl" >&2
echo "corp-ca: exit 60/77 — that is your signal to ship the cert at" >&2
echo "corp-ca: files/home/corp-ca/<name>.crt (PEM content, .crt extension)." >&2
exit 0
fi
command -v update-ca-certificates >/dev/null 2>&1 || {
echo "corp-ca: update-ca-certificates not found; install the ca-certificates package on the base image" >&2
exit 1
}
update-ca-certificates
echo "corp-ca: installed $found certificate(s) into the system trust store"
description: Install corporate root CA certificate(s) into the system trust store
user: "0"
- command: |
# Diagnostic only; network policy may block the probe.
if curl -fsS -I --max-time 20 -o /dev/null https://github.com/ 2>/dev/null; then
echo "corp-ca: outbound TLS verified"
else
rc=$?
echo "corp-ca: outbound TLS probe failed (curl exit $rc)" >&2
echo "corp-ca: 60/77 => TLS trust problem: ship the ROOT CA in PEM form." >&2
echo "corp-ca: 6/7 => egress blocked, not a cert problem. Under org" >&2
echo "corp-ca: governance, kit allow rules are IGNORED." >&2
echo "corp-ca: diagnose with: openssl s_client -connect github.com:443 -showcerts" >&2
fi
description: Verify the trust store accepts an intercepted TLS connection
env:
- HTTP_PROXY
- HTTPS_PROXY
- NO_PROXY
user: "1000"
- command: |
set -eu
COMPONENTS_OUTPUT="$(sh "$HOME/.snyk-kit/resolve-components.sh")" || exit 1
eval "$COMPONENTS_OUTPUT"
echo "snyk-ads: components scan=$scan guard=$guard studio=$studio (auth_mode=$auth_mode)"
if [ "$auth_mode" = none ]; then
echo "snyk-ads: no SNYK_TOKEN or SNYK_ADS_PUSH_KEY supplied; binaries install, but scan/guard hooks stay inactive until a credential is set and the sandbox is recreated."
fi
description: Resolve requested Snyk components
env:
- SNYK_COMPONENTS
- SNYK_TOKEN
- SNYK_ADS_PUSH_KEY
user: "1000"
- command: |
set -eu
unset NPM_CONFIG_PREFIX
COMPONENTS_OUTPUT="$(sh "$HOME/.snyk-kit/resolve-components.sh")" || exit 1
eval "$COMPONENTS_OUTPUT"
if [ "$scan" != 1 ] && [ "$guard" != 1 ]; then
echo "snyk-ads: scan and guard not requested; skipping AgentScan install."
exit 0
fi
# Installs unconditionally: the binary is public and needs no
# credential. Only guard install below needs one.
sh "$HOME/.snyk-kit/install-agent-scan.sh"
if [ "$guard" = 1 ]; then
if [ "$auth_mode" != enterprise ]; then
echo "snyk-ads: guard requested but SNYK_ADS_PUSH_KEY is not set; skipping Guard hook installation. Set SNYK_ADS_PUSH_KEY and recreate the sandbox to enable Guard."
exit 0
fi
# Docker sbx provides these identity variables at runtime.
: "${SANDBOX_NAME:?SANDBOX_NAME is required}"
: "${SANDBOX_ID:?SANDBOX_ID is required}"
MACHINE_ID="docker-sbx:${SANDBOX_NAME}:${SANDBOX_ID}"
echo "snyk-ads: installing Guard hooks under machine id ${MACHINE_ID}"
# "all" installs hooks for whichever of claude/cursor/codex is
# actually present, skipping the rest with a warning.
set -- guard install all
if [ -n "${SNYK_API:-}" ]; then
echo "snyk-ads: using Snyk API base ${SNYK_API}"
set -- "$@" --url "$SNYK_API"
fi
set +e
PUSH_KEY="$SNYK_ADS_PUSH_KEY" TENANT_ID="${SNYK_TENANT_ID:-}" MACHINE_ID="$MACHINE_ID" \
"$HOME/.local/share/snyk-agent-scan/agent-scan" "$@"
rc=$?
set -e
if [ "$rc" != 0 ]; then
if [ -n "${SNYK_API:-}" ]; then
echo "snyk-ads: ERROR guard install failed (exit $rc) against SNYK_API=${SNYK_API}. Guard install sends a test event to \${SNYK_API}/hidden/agent-monitor/hooks/<client> after copying hooks; a 404 there means that host doesn't serve Guard's backend routes for this push key/tenant, not a kit or network-policy problem. Verify SNYK_API points at a full Snyk API deployment with Guard enabled, and that SNYK_ADS_PUSH_KEY is valid for it." >&2
else
echo "snyk-ads: ERROR guard install failed (exit $rc)." >&2
fi
exit "$rc"
fi
fi
description: Install AgentScan and/or Guard
env:
- SNYK_COMPONENTS
- SNYK_TOKEN
- SNYK_ADS_PUSH_KEY
- SNYK_TENANT_ID
- SNYK_API
- SANDBOX_NAME
- SANDBOX_ID
- HTTP_PROXY
- HTTPS_PROXY
- NO_PROXY
user: "1000"
- command: |
set -eu
unset NPM_CONFIG_PREFIX
COMPONENTS_OUTPUT="$(sh "$HOME/.snyk-kit/resolve-components.sh")" || exit 1
eval "$COMPONENTS_OUTPUT"
if [ "$studio" != 1 ]; then
echo "snyk-ads: studio not requested; skipping."
exit 0
fi
sh "$HOME/.snyk-kit/install-studio.sh"
description: Install Snyk Studio
env:
- SNYK_COMPONENTS
- SNYK_TOKEN
- SNYK_ADS_PUSH_KEY
- HTTP_PROXY
- HTTPS_PROXY
- NO_PROXY
- NODE_EXTRA_CA_CERTS
user: "1000"
startup:
- background: true
command:
- bash
- -lc
- |
LOGDIR="$HOME/.snyk"
LOG="$LOGDIR/agent-scan-startup.log"
mkdir -p "$LOGDIR"
exec >>"$LOG" 2>&1
echo "===== $(date -Is) startup ====="
# Hold the lock between scans to prevent duplicate workers.
exec 9>"$LOGDIR/agent-scan.lock"
if ! flock -n 9; then
echo "agent-scan: SKIP inventory worker already running."
exit 0
fi
COMPONENTS_OUTPUT="$(sh "$HOME/.snyk-kit/resolve-components.sh" 2>/dev/null)" || {
echo "agent-scan: SKIP component resolution failed (malformed SNYK_COMPONENTS)."
exit 0
}
eval "$COMPONENTS_OUTPUT"
if [ "$scan" != 1 ]; then
echo "agent-scan: SKIP scan not requested (SNYK_COMPONENTS)."
exit 0
fi
if [ "$auth_mode" = none ]; then
echo "agent-scan: SKIP no SNYK_TOKEN or SNYK_ADS_PUSH_KEY supplied."
exit 0
fi
SCAN="$HOME/.local/share/snyk-agent-scan/agent-scan"
if [ ! -x "$SCAN" ]; then
echo "agent-scan: SKIP scan binary not found; rerun standalone installation."
exit 0
fi
echo "agent-scan: using $SCAN"
# The help subcommand reports the version without scanning.
if SCAN_HELP="$(NO_COLOR=1 timeout 15 "$SCAN" help 2>/dev/null)" &&
[[ "$SCAN_HELP" =~ Snyk\ Agent\ Scan\ v([0-9]+)\.([0-9]+)\.([0-9]+)([^[:space:]]*) ]]; then
SCAN_VERSION="${BASH_REMATCH[1]}.${BASH_REMATCH[2]}.${BASH_REMATCH[3]}${BASH_REMATCH[4]}"
SCAN_MAJOR=$((10#${BASH_REMATCH[1]}))
SCAN_MINOR=$((10#${BASH_REMATCH[2]}))
SCAN_PATCH=$((10#${BASH_REMATCH[3]}))
echo "agent-scan: version $SCAN_VERSION"
if (( SCAN_MAJOR == 0 && SCAN_MINOR < 6 )) ||
{ (( SCAN_MAJOR == 0 && SCAN_MINOR == 6 && SCAN_PATCH == 0 )) &&
[[ -n "${BASH_REMATCH[4]}" && "${BASH_REMATCH[4]}" != +* ]]; }; then
echo "agent-scan: WARNING version $SCAN_VERSION is older than 0.6.0; upgrade to 0.6.0 or later. Continuing scan."
fi
else
echo "agent-scan: WARNING could not determine whether AgentScan is 0.6.0 or later. Continuing scan."
fi
MACHINE_ID="docker-sbx:${SANDBOX_NAME}:${SANDBOX_ID}"
echo "agent-scan: machine id $MACHINE_ID"
SCAN_ARGS=(scan --machine-id "$MACHINE_ID")
if [ "$auth_mode" = enterprise ]; then
SCAN_ARGS+=(--push-key "$SNYK_ADS_PUSH_KEY")
fi
if [ -n "${SNYK_API:-}" ]; then
echo "agent-scan: using Snyk API base ${SNYK_API}"
SCAN_ARGS+=(--analysis-url "${SNYK_API}/hidden/mcp-scan/analysis-machine?version=2026-07-10")
fi
# Wait 15 minutes after each attempt; scans run sequentially.
while true; do
echo "agent-scan: starting $(date -Is)"
"$SCAN" "${SCAN_ARGS[@]}" \
|| echo "agent-scan: exited non-zero (rc=$?) — retrying after 15 minutes"
echo "agent-scan: done $(date -Is); next scan in 15 minutes"
sleep 900 || break
done
exit 0
description: Upload Snyk agent-scan inventory every 15 minutes
env:
- SNYK_COMPONENTS
- SNYK_TOKEN
- SNYK_ADS_PUSH_KEY
- SNYK_API
- SANDBOX_NAME
- SANDBOX_ID
- HTTP_PROXY
- HTTPS_PROXY
- NO_PROXY
user: "1000"
- type: com.docker.sandbox/agent-context@1
config:
contentFile: /usr/share/sandbox/kit/snyk-evo-ads/snyk-evo-ads-context.md