Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 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
2 changes: 1 addition & 1 deletion .commitlintrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ extends:
# feat(docker): add versioned Node stage
# fix: correct TruffleHog tag format
# docs: update pinning strategy guidance
# chore(deps): bump Trivy to 0.69.3
# chore(deps): bump TruffleHog to 3.93.8
# ci: add commit-lint workflow

rules:
Expand Down
11 changes: 6 additions & 5 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,13 @@ updates:
cooldown:
default-days: 7

# Main Dockerfile — tracks aquasec/trivy, trufflesecurity/trufflehog,
# ghcr.io/astral-sh/uv, and the python base image.
# Main Dockerfile — tracks trufflesecurity/trufflehog, ghcr.io/astral-sh/uv,
# and the python base image.
# NOTE: OPENGREP_VERSION is not trackable via Dependabot (no Docker image);
# update it manually in the Dockerfile ARG.
# NOTE: trivy is deliberately NOT tracked here — it comes from Socket's own
# build (ghcr.io/socketdev/trivy, digest-pinned) and is updated by that
# release process, never bumped independently.
- package-ecosystem: "docker"
directory: "/"
schedule:
Expand All @@ -56,7 +59,6 @@ updates:
- dependency-name: "python"
- dependency-name: "ghcr.io/astral-sh/uv"
- dependency-name: "trufflesecurity/trufflehog"
- dependency-name: "aquasec/trivy"
groups:
docker-main-minor-patch:
patterns:
Expand All @@ -74,7 +76,7 @@ updates:
- "docker"
commit-message:
prefix: "chore"
include: "scope" # → chore(deps): bump trivy from 0.69.2 to 0.69.3
include: "scope" # → chore(deps): bump trufflehog from 3.93.7 to 3.93.8
cooldown:
default-days: 7

Expand All @@ -89,7 +91,6 @@ updates:
- dependency-name: "golang"
- dependency-name: "securego/gosec"
- dependency-name: "trufflesecurity/trufflehog"
- dependency-name: "aquasec/trivy"
groups:
docker-app-tests-minor-patch:
patterns:
Expand Down
11 changes: 9 additions & 2 deletions .github/workflows/_docker-pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ on:
jobs:
pipeline:
runs-on: ${{ inputs.runs_on }}
# Push mode binds the `publish` environment so the environment-scoped
# Docker Hub secrets resolve (callers use `secrets: inherit`). Test mode
# (push: false) binds no environment — PR branches would violate the
# environment's deployment policy.
environment: ${{ inputs.push && 'publish' || '' }}
timeout-minutes: 60

steps:
Expand All @@ -95,9 +100,11 @@ jobs:
- name: 🔨 Set up Docker Buildx
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0

# GHCR login runs before the build — needed to pull ghcr.io/astral-sh/uv.
# GHCR login runs before the build in EVERY mode (not just push): the
# trivy build stage pulls the private ghcr.io/socketdev/trivy image, so
# unauthenticated PR builds would fail at FROM. Callers must grant
# `packages: read`.
- name: Login to GHCR
if: inputs.push
uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4.5.1
with:
registry: ghcr.io
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/commit-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,6 @@ jobs:
echo " feat(docker): Add versioned Node stage"
echo " fix: Correct TruffleHog tag format"
echo " docs: Update pinning strategy guidance"
echo " chore(deps): Bump Trivy to 0.69.3"
echo " chore(deps): Bump TruffleHog to 3.93.8"
exit 1
fi
4 changes: 3 additions & 1 deletion .github/workflows/dependency-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -281,10 +281,12 @@ jobs:
uses: ./.github/workflows/_docker-pipeline.yml
permissions:
contents: read
packages: read # pull the private Socket-built trivy base image
with:
name: socket-basics-app-tests
dockerfile: app_tests/Dockerfile
context: .
# app_tests/ is its own build context (its pyproject/uv.lock, fixture apps).
context: app_tests
check_set: app-tests
push: false

Expand Down
44 changes: 29 additions & 15 deletions .github/workflows/publish-docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ name: publish-docker
# registry, distinguished by tag suffix: 2.0.0 (main), 2.0.0-heavy (heavy).
# See docs/github-action.md → "Pinning strategies" for the full rationale.
#
# Required repository secrets:
# DOCKERHUB_USERNAME — Docker Hub account name
# Required secrets — scoped to the `publish` environment (deployment policy:
# branch `main` + tags `v*`), not repo-level:
# DOCKERHUB_USERNAME — Docker Hub account name (also the registry namespace)
# DOCKERHUB_TOKEN — Docker Hub access token (read/write)
# Publishing jobs bind `environment: publish` to resolve them; the reusable
# pipeline binds it only in push mode (see _docker-pipeline.yml).

on:
push:
Expand Down Expand Up @@ -149,7 +152,10 @@ jobs:
check_set: heavy
arch: arm64
runs_on: ubuntu-24.04-arm
uses: ./.github/workflows/_docker-pipeline.yml
# zizmor: ignore[secrets-inherit] — required: environment-scoped secrets
# cannot be passed via an explicit workflow-call mapping (they only resolve
# on the environment-bound job inside the called same-repo workflow).
uses: ./.github/workflows/_docker-pipeline.yml # zizmor: ignore[secrets-inherit]
with:
name: ${{ matrix.image }}
dockerfile: ${{ matrix.dockerfile }}
Expand All @@ -164,20 +170,25 @@ jobs:
push: true
version: ${{ needs.resolve-version.outputs.version }}
ref: ${{ needs.resolve-version.outputs.ref }}
secrets:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
# Environment secrets can't be passed from a workflow-call job (no
# `environment:` allowed here); inherit lets the reusable workflow's
# environment-bound job resolve them itself.
secrets: inherit

# ── Job 3: Merge per-arch digests into a multi-arch manifest list ──────────
# Floating major version tags (v2 → latest v2.x.y) are intentionally omitted.
# Mutable tags are structurally equivalent to :latest and inappropriate for a
# security tool. Users should pin to an exact version and use Dependabot.
# Tags: exact immutable version (X.Y.Z / X.Y.Z-heavy) plus the floating
# `latest` / `latest-heavy` convenience aliases. Version tags are immutable
# registry-side (Docker Hub immutable-tag rule: ^\d+\.\d+\.\d+(-heavy)?$);
# `latest` deliberately floats. Consumers needing reproducibility should pin
# the exact version or digest (docs/github-action.md → "Pinning strategies").
# Floating MAJOR tags (v2 → latest v2.x.y) remain intentionally omitted.
merge-manifests:
name: merge-manifests (${{ matrix.variant }})
needs: [resolve-version, build-test-push]
permissions:
contents: read
packages: write
environment: publish # Docker Hub secrets are environment-scoped
runs-on: ubuntu-latest
strategy:
fail-fast: false
Expand Down Expand Up @@ -221,16 +232,19 @@ jobs:
images: |
ghcr.io/socketdev/socket-basics
${{ secrets.DOCKERHUB_USERNAME }}/socket-basics
# Disable the automatic :latest tag — metadata-action adds it by default
# for semver tag pushes. Mutable tags are inappropriate for a security tool.
# The variant suffix yields 2.2.0 for the main image, 2.2.0-heavy for heavy.
# `latest` (and `latest-heavy` via the variant suffix) float to the
# newest release; exact version tags stay immutable registry-side.
# The variant suffix yields X.Y.Z for the main image, X.Y.Z-heavy for heavy.
flavor: |
latest=false
latest=true
Comment thread
cursor[bot] marked this conversation as resolved.
suffix=${{ matrix.tag_suffix }}
tags: |
# Tag push (v2.0.0) → exact immutable version tag only.
# Tag push (vX.Y.Z) → exact immutable version tag + latest alias.
type=semver,pattern={{version}}
# workflow_dispatch re-publish → use the version input directly
# workflow_dispatch re-publish → use the version input directly.
# NOTE: re-pushing an already-published version tag is rejected by
# the registry's immutable-tag rule — dispatch mode is for recovery
# when tags never landed (it also repoints `latest`).
type=raw,value=${{ needs.resolve-version.outputs.version }},enable=${{ github.event_name == 'workflow_dispatch' }}

- name: 🧬 Create multi-arch manifest list
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/smoke-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ on:

permissions:
contents: read
packages: read # pull the private Socket-built trivy base image

concurrency:
group: smoke-test-${{ github.ref }}
Expand Down
24 changes: 16 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
# ─── Global version pins (single source of truth) ────────────────────────────
# Dependabot tracks all ARGs below via the FROM lines that reference them.
# To override at build time: docker build --build-arg TRIVY_VERSION=0.70.0 .
# To override at build time: docker build --build-arg TRUFFLEHOG_VERSION=3.93.8 .
#
# Dependabot-trackable (each has a corresponding FROM <image>:<ARG> stage):
ARG PYTHON_VERSION=3.12
ARG TRUFFLEHOG_VERSION=3.93.8
ARG TRIVY_VERSION=0.69.3
ARG UV_VERSION=0.10.11
ARG TRUFFLEHOG_VERSION=3.96.0
ARG UV_VERSION=0.12.1
#
# NOT Dependabot-trackable (no official Docker image with a stable binary path):
ARG OPENGREP_VERSION=v1.16.5
ARG OPENGREP_VERSION=v1.26.0
#
# NOT Dependabot-trackable — Socket-built Trivy, rebuilt from unmodified upstream
# source and published by Socket's own release pipeline. Pinned by digest; both
# ARGs are updated together by that release process, never bumped independently.
# Building requires pull access to the registry; contributors without it can
# override, e.g.: docker build --build-arg TRIVY_IMAGE=aquasec/trivy:0.73.0 .
# TRIVY_VERSION feeds the image label — keep it in sync with the TRIVY_IMAGE tag.
ARG TRIVY_VERSION=0.73.0
ARG TRIVY_IMAGE=ghcr.io/socketdev/trivy:0.73.0@sha256:e3d9d5f10250cb73b0ea9446ae1191c0f2da2f5e6173eac08a840b1812f02e0b

# ─── Stage: trivy (Dependabot-trackable) ──────────────────────────────────────
# FROM aquasec/trivy:${TRIVY_VERSION} AS trivy
# ─── Stage: trivy (Socket-built redistribution) ───────────────────────────────
FROM ${TRIVY_IMAGE} AS trivy

# ─── Stage: trufflehog (Dependabot-trackable) ─────────────────────────────────
FROM trufflesecurity/trufflehog:${TRUFFLEHOG_VERSION} AS trufflehog
Expand Down Expand Up @@ -42,7 +50,7 @@ WORKDIR /socket-basics
COPY --from=uv /uv /uvx /bin/

# Binary tools from immutable build stages
# COPY --from=trivy /usr/local/bin/trivy /usr/local/bin/trivy
COPY --from=trivy /usr/local/bin/trivy /usr/local/bin/trivy
COPY --from=trufflehog /usr/bin/trufflehog /usr/local/bin/trufflehog
COPY --from=opengrep-installer /root/.opengrep /root/.opengrep

Expand Down
14 changes: 8 additions & 6 deletions Dockerfile.heavy
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# Heavy POC image: socket-basics plus a pinned stable Python Socket CLI.
ARG PYTHON_VERSION=3.12
ARG TRUFFLEHOG_VERSION=3.93.8
ARG TRIVY_VERSION=0.69.3
ARG UV_VERSION=0.10.11
ARG OPENGREP_VERSION=v1.16.5
ARG SOCKET_CLI_VERSION=2.5.0
ARG TRUFFLEHOG_VERSION=3.96.0
ARG UV_VERSION=0.12.1
ARG OPENGREP_VERSION=v1.26.0
ARG SOCKET_CLI_VERSION=2.5.8
# Socket-built Trivy, pinned by digest — see the note in ./Dockerfile.
ARG TRIVY_IMAGE=ghcr.io/socketdev/trivy:0.73.0@sha256:e3d9d5f10250cb73b0ea9446ae1191c0f2da2f5e6173eac08a840b1812f02e0b

# FROM aquasec/trivy:${TRIVY_VERSION} AS trivy
FROM ${TRIVY_IMAGE} AS trivy
FROM trufflesecurity/trufflehog:${TRUFFLEHOG_VERSION} AS trufflehog
FROM ghcr.io/astral-sh/uv:${UV_VERSION} AS uv

Expand All @@ -24,6 +25,7 @@ FROM python:${PYTHON_VERSION}-slim AS runtime
WORKDIR /socket-basics

COPY --from=uv /uv /uvx /bin/
COPY --from=trivy /usr/local/bin/trivy /usr/local/bin/trivy
COPY --from=trufflehog /usr/bin/trufflehog /usr/local/bin/trufflehog
COPY --from=opengrep-installer /root/.opengrep /root/.opengrep

Expand Down
25 changes: 11 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,20 +65,17 @@ jobs:

Socket Basics can also run locally or in other CI/CD environments:

> [!IMPORTANT]
> The supported pre-built GitHub Action and Docker image paths currently ship
> _without_ Trivy while we evaluate the safest way to bundle it with Basics
> again.
> If you need Trivy in the meantime, use the native/manual path and pin to
> `v0.69.3` or Docker tag `0.69.3`.
> [Aqua's official incident summary](https://www.aquasec.com/blog/trivy-supply-chain-attack-what-you-need-to-know/)
> lists the known-safe Trivy binary range as `v0.69.2` to `v0.69.3`; we
> standardize on the latest known-safe version.
> Do not use `v0.69.4`, and audit any cached Docker Hub images for `0.69.5` and
> `0.69.6`.
> [!NOTE]
> Trivy-backed scanning is bundled in the pre-built GitHub Action and Docker
> images again. Socket Basics ships a **Socket-built distribution of Trivy** —
> rebuilt from unmodified upstream source by Socket's own release pipeline and
> pinned by digest in the [Dockerfile](Dockerfile) — rather than pulling
> upstream-published binaries or images.
> If you install Trivy natively instead, never use versions `0.69.4`, `0.69.5`,
> or `0.69.6` ([Aqua's incident summary](https://www.aquasec.com/blog/trivy-supply-chain-attack-what-you-need-to-know/)),
> and audit any cached Docker Hub images for those tags.
> See [Local Installation](docs/local-installation.md#trivy-container-scanning)
> for the detailed version guidance, installation options, and the
> corresponding Aqua action versions.
> for installation options.

- **[Pre-Commit Hook](docs/pre-commit-hook.md)** — Catch issues before they're committed
- **[Local Docker Installation](docs/local-install-docker.md)** — Run in Docker with no tool installation required
Expand All @@ -89,7 +86,7 @@ Socket Basics can also run locally or in other CI/CD environments:
**Built-in Security Scanners:**
- 🔍 **SAST** — Static analysis for 15+ languages (Python, JavaScript, Go, Java, Ruby, C#, and more)
- 🔐 **Secret Scanning** — Detect leaked credentials and API keys with TruffleHog
- 🐳 **Container Scanning** — Trivy-backed image and Dockerfile scanning for native installs
- 🐳 **Container Scanning** — Trivy-backed image and Dockerfile scanning
- 📦 **Dependency Analysis** — Socket Tier 1 reachability analysis for supply chain security

**Enterprise Features** (requires [Socket Enterprise](https://socket.dev/enterprise)):
Expand Down
9 changes: 4 additions & 5 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ runs:
INPUT_SWIFT_DISABLED_RULES: ${{ inputs.swift_disabled_rules }}
INPUT_SWIFT_ENABLED_RULES: ${{ inputs.swift_enabled_rules }}
INPUT_SWIFT_SAST_ENABLED: ${{ inputs.swift_sast_enabled }}
# Trivy-backed scanning is temporarily disabled in the pre-built GitHub Action image.
INPUT_TRIVY_DISABLED_RULES: ${{ inputs.trivy_disabled_rules }}
INPUT_TRIVY_IMAGE_SCANNING_DISABLED: ${{ inputs.trivy_image_scanning_disabled }}
INPUT_TRIVY_NOTIFICATION_METHOD: ${{ inputs.trivy_notification_method }}
Expand Down Expand Up @@ -412,19 +411,19 @@ inputs:
required: false
default: "false"
trivy_disabled_rules:
description: "Comma-separated list of Trivy rules to disable. Trivy-backed scanning is temporarily unavailable in the pre-built GitHub Action image."
description: "Comma-separated list of Trivy rules to disable."
required: false
default: ""
trivy_image_scanning_disabled:
description: "Disable Trivy image scanning. Trivy-backed scanning is temporarily unavailable in the pre-built GitHub Action image."
description: "Disable Trivy image scanning."
required: false
default: "false"
trivy_notification_method:
description: "Notification method for Trivy (e.g., console, slack). Trivy-backed scanning is temporarily unavailable in the pre-built GitHub Action image."
description: "Notification method for Trivy (e.g., console, slack)."
required: false
default: ""
trivy_vuln_enabled:
description: "Enable Trivy vulnerability scanning for all supported language ecosystems. Trivy-backed scanning is temporarily unavailable in the pre-built GitHub Action image."
description: "Enable Trivy vulnerability scanning for all supported language ecosystems."
required: false
default: "false"
trufflehog_exclude_dir:
Expand Down
Loading