diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 356ba51..3e0beea 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -21,9 +21,9 @@ +- [ ] `pyproject.toml` `version:` field updated to new version +- [ ] `python3 scripts/sync_release_version.py --write` run after updating `pyproject.toml` - [ ] `socket_basics/version.py` updated to new version -- [ ] `pyproject.toml` `version:` field updated to match -- [ ] `action.yml` `image:` ref updated to `docker://ghcr.io/socketdev/socket-basics:` *(auto-updated by `publish-docker.yml` +- [ ] `socket_basics/__init__.py` updated to the same version +- [ ] `action.yml` `image:` ref updated to `docker://ghcr.io/socketdev/socket-basics:` - [ ] `CHANGELOG.md` `[Unreleased]` section reviewed - -> See [docs/releasing.md](../docs/releasing.md) for the full release process. diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 87fd378..6ee280f 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,6 +9,12 @@ updates: directory: "/" schedule: interval: "weekly" + open-pull-requests-limit: 5 + allow: + - dependency-name: "python" + - dependency-name: "ghcr.io/astral-sh/uv" + - dependency-name: "trufflesecurity/trufflehog" + - dependency-name: "aquasec/trivy" labels: - "dependencies" - "docker" @@ -23,6 +29,13 @@ updates: directory: "/app_tests" schedule: interval: "weekly" + open-pull-requests-limit: 2 + allow: + - dependency-name: "python" + - dependency-name: "golang" + - dependency-name: "securego/gosec" + - dependency-name: "trufflesecurity/trufflehog" + - dependency-name: "aquasec/trivy" labels: - "dependencies" - "docker" @@ -37,6 +50,14 @@ updates: directory: "/" schedule: interval: "weekly" + open-pull-requests-limit: 4 + groups: + github-actions-minor-patch: + patterns: + - "*" + update-types: + - "minor" + - "patch" labels: - "dependencies" - "github-actions" diff --git a/.github/workflows/_docker-pipeline.yml b/.github/workflows/_docker-pipeline.yml index 7caa21c..0fad966 100644 --- a/.github/workflows/_docker-pipeline.yml +++ b/.github/workflows/_docker-pipeline.yml @@ -66,6 +66,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - name: ๐Ÿ”จ Set up Docker Buildx uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 diff --git a/.github/workflows/dependabot-review.yml b/.github/workflows/dependabot-review.yml new file mode 100644 index 0000000..9163e8f --- /dev/null +++ b/.github/workflows/dependabot-review.yml @@ -0,0 +1,104 @@ +name: dependabot-review + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + +permissions: + contents: read + +concurrency: + group: dependabot-review-${{ github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + inspect: + if: github.event.pull_request.user.login == 'dependabot[bot]' + runs-on: ubuntu-latest + outputs: + root_docker_changed: ${{ steps.diff.outputs.root_docker_changed }} + app_tests_docker_changed: ${{ steps.diff.outputs.app_tests_docker_changed }} + workflow_or_action_changed: ${{ steps.diff.outputs.workflow_or_action_changed }} + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Inspect changed files + id: diff + env: + BASE_SHA: ${{ github.event.pull_request.base.sha }} + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + run: | + CHANGED_FILES="$(git diff --name-only "$BASE_SHA" "$HEAD_SHA")" + + echo "Changed files:" >> "$GITHUB_STEP_SUMMARY" + echo '```' >> "$GITHUB_STEP_SUMMARY" + printf '%s\n' "$CHANGED_FILES" >> "$GITHUB_STEP_SUMMARY" + echo '```' >> "$GITHUB_STEP_SUMMARY" + + has_file() { + local pattern="$1" + if printf '%s\n' "$CHANGED_FILES" | grep -Eq "$pattern"; then + echo "true" + else + echo "false" + fi + } + + echo "root_docker_changed=$(has_file '^Dockerfile$')" >> "$GITHUB_OUTPUT" + echo "app_tests_docker_changed=$(has_file '^app_tests/Dockerfile$')" >> "$GITHUB_OUTPUT" + echo "workflow_or_action_changed=$(has_file '^\\.github/workflows/|^action\\.yml$|^\\.github/dependabot\\.yml$')" >> "$GITHUB_OUTPUT" + + - name: Summarize review expectations + env: + PR_URL: ${{ github.event.pull_request.html_url }} + run: | + { + echo "## Dependabot Review Checklist" + echo "- PR: $PR_URL" + echo "- Confirm upstream release notes before merge" + echo "- Confirm Docker/toolchain changes match the files in this PR" + echo "- Do not treat a Dependabot PR as trusted solely because of the actor" + echo "- This workflow runs in pull_request context only; no publish secrets are exposed" + } >> "$GITHUB_STEP_SUMMARY" + + docker-smoke-main: + needs: inspect + if: github.event.pull_request.user.login == 'dependabot[bot]' && needs.inspect.outputs.root_docker_changed == 'true' + uses: ./.github/workflows/_docker-pipeline.yml + permissions: + contents: read + with: + name: socket-basics + dockerfile: Dockerfile + context: . + check_set: main + push: false + + docker-smoke-app-tests: + needs: inspect + if: github.event.pull_request.user.login == 'dependabot[bot]' && needs.inspect.outputs.app_tests_docker_changed == 'true' + uses: ./.github/workflows/_docker-pipeline.yml + permissions: + contents: read + with: + name: socket-basics-app-tests + dockerfile: app_tests/Dockerfile + context: . + check_set: app-tests + push: false + + workflow-notice: + needs: inspect + if: github.event.pull_request.user.login == 'dependabot[bot]' && needs.inspect.outputs.workflow_or_action_changed == 'true' + runs-on: ubuntu-latest + steps: + - name: Flag workflow-sensitive updates + run: | + { + echo "## Sensitive File Notice" + echo "This Dependabot PR changes workflow or action metadata files." + echo "Require explicit human review before merge." + } >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/publish-docker.yml b/.github/workflows/publish-docker.yml index 76a95c5..e997c06 100644 --- a/.github/workflows/publish-docker.yml +++ b/.github/workflows/publish-docker.yml @@ -42,6 +42,7 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref }} + persist-credentials: false - name: ๐Ÿท๏ธ Resolve version id: version @@ -97,6 +98,7 @@ jobs: with: ref: main fetch-depth: 0 + persist-credentials: false - name: ๐Ÿค– Generate socket-release-bot token id: bot @@ -129,25 +131,13 @@ jobs: --version "$VERSION" \ --date "$DATE" - - name: ๐Ÿ”€ Commit CHANGELOG + action.yml back to main + - name: ๐Ÿ”€ Commit CHANGELOG back to main env: BOT_TOKEN: ${{ steps.bot.outputs.token }} - REF_NAME: ${{ github.ref_name }} run: | git config user.name "socket-release-bot[bot]" git config user.email "socket-release-bot[bot]@users.noreply.github.com" git remote set-url origin "https://x-access-token:${BOT_TOKEN}@github.com/SocketDev/socket-basics.git" - - # Auto-update action.yml image ref to the new version. - # No-op if action.yml still uses `image: "Dockerfile"` (handles the - # chicken-and-egg on the initial v2.0.0 release). - if grep -q 'docker://ghcr.io/socketdev/socket-basics:' action.yml; then - sed -i "s|docker://ghcr.io/socketdev/socket-basics:[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*|docker://ghcr.io/socketdev/socket-basics:${VERSION}|" action.yml - echo "Updated action.yml image ref to ${VERSION}" - else - echo "action.yml not yet using pre-built image โ€” skipping version update" - fi - - git add CHANGELOG.md action.yml - git diff --cached --quiet || git commit -m "chore: release ${REF_NAME} โ€” update CHANGELOG and action.yml [skip ci]" + git add CHANGELOG.md + git diff --cached --quiet || git commit -m "chore: release ${github.ref_name} โ€” update CHANGELOG [skip ci]" git push origin HEAD:main diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index 561e6da..55052c5 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -45,34 +45,7 @@ jobs: run: | python -m pip install --upgrade pip pip install -e ".[dev]" - - name: ๐Ÿ”’ Assert version files in sync - run: | - V_PY=$(python -c "from socket_basics.version import __version__; print(__version__)") - V_TOML=$(python -c "import tomllib; print(tomllib.loads(open('pyproject.toml').read())['project']['version'])") - [ "$V_PY" = "$V_TOML" ] || (echo "Version mismatch: version.py=$V_PY pyproject.toml=$V_TOML" && exit 1) - echo "Version in sync: $V_PY" - - - name: ๐Ÿ”’ Assert action.yml image ref matches version (once switched to pre-built) - run: | - python3 - <<'EOF' - import re, sys, tomllib - from pathlib import Path - - action = Path("action.yml").read_text() - version = tomllib.loads(Path("pyproject.toml").read_text())["project"]["version"] - - match = re.search(r'image:\s*["\']docker://[^:]+:([^"\']+)["\']', action) - if not match: - print(f"SKIP: action.yml still uses Dockerfile โ€” check will activate once switched to pre-built image") - sys.exit(0) - - action_version = match.group(1) - if action_version != version: - print(f"FAIL: action.yml refs {action_version} but version is {version}") - print(f" Update action.yml image ref to docker://ghcr.io/socketdev/socket-basics:{version}") - sys.exit(1) - - print(f"OK: action.yml image ref matches version {version}") - EOF + - name: ๐Ÿ”’ Assert release version metadata is in sync + run: python3 scripts/sync_release_version.py --check - name: ๐Ÿงช Run tests run: pytest -q tests/ diff --git a/README.md b/README.md index edd4151..e4efe51 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,8 @@ jobs: socket_security_api_key: ${{ secrets.SOCKET_SECURITY_API_KEY }} ``` -> **Why pin to a SHA?** Socket Basics is a security tool โ€” its own supply-chain +> [!NOTE] +> Why pin to a SHA? Socket Basics is a security tool, so its own supply-chain > integrity matters. Version tags can be force-pushed or deleted; a commit SHA is > immutable. Dependabot manages the upgrade automatically so you still get updates > with a review gate. See [docs/github-action.md](docs/github-action.md#pinning-strategies) @@ -54,7 +55,7 @@ jobs: ### What You Get - โœ… **Zero Configuration Required** โ€” Configure scanning policies in the Socket Dashboard -- โœ… **All Scanners Included** โ€” SAST, secrets, containers, and dependency analysis +- โœ… **Unified Scanning** โ€” SAST, secrets, dependency analysis, and native container scanning support - โœ… **PR Comments** โ€” Automated security findings on pull requests - โœ… **Centralized Management** โ€” Update policies across all repos from one place @@ -64,6 +65,16 @@ jobs: Socket Basics can also run locally or in other CI/CD environments: +> [!NOTE] +> Container and Dockerfile scanning remain part of Socket Basics, but the current +> GitHub Action and pre-built image paths have Trivy-backed support temporarily +> disabled while we complete additional security review of the underlying scanner +> dependency path. If container or Dockerfile scanning is a near-term +> requirement, the [native installation path](docs/local-installation.md) remains +> available as a temporary workaround while the pre-built path is under +> additional review. Review the upstream install path and artifacts carefully +> before adopting it in production CI. + - **[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 - **[Local Installation](docs/local-installation.md)** โ€” Install security tools natively on your machine @@ -73,7 +84,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** โ€” Vulnerability scanning for Docker images and Dockerfiles with Trivy +- ๐Ÿณ **Container Scanning** โ€” Trivy-backed image and Dockerfile scanning for native installs - ๐Ÿ“ฆ **Dependency Analysis** โ€” Socket Tier 1 reachability analysis for supply chain security **Enterprise Features** (requires [Socket Enterprise](https://socket.dev/enterprise)): @@ -108,8 +119,7 @@ Every feature is customizable via GitHub Actions inputs, CLI flags, or environme - [PR Comment Guide](docs/github-pr-comment-guide.md) โ€” Detailed guide to PR comment customization - [Pre-Commit Hook Setup](docs/pre-commit-hook.md) โ€” Two installation methods (Docker vs native) - [Local Docker Installation](docs/local-install-docker.md) โ€” Run with Docker, no tools to install -- [Local Installation](docs/local-installation.md) โ€” Install Socket CLI, Trivy, and other tools natively -- [Releasing](docs/releasing.md) โ€” Maintainer guide: How to cut a release for Socket Basics +- [Local Installation](docs/local-installation.md) โ€” Install Socket CLI and other tools natively with version pinning guidance ### Configuration All configuration can be managed through: @@ -153,16 +163,18 @@ For GitHub Actions, see the [Quick Start](#-quick-start---github-actions) above ```bash # Pull the pre-built image (recommended โ€” no build step required) -docker pull socketdev/socket-basics:1.1.3 +docker pull ghcr.io/socketdev/socket-basics:2.0.2 # Run scan -docker run --rm -v "$PWD:/workspace" socketdev/socket-basics:1.1.3 \ +docker run --rm -v "$PWD:/workspace" ghcr.io/socketdev/socket-basics:2.0.2 \ --workspace /workspace \ --python-sast-enabled \ --secret-scanning-enabled \ --console-tabular-enabled ``` +The pre-built image is versioned and intended to be pinned exactly. Avoid floating tags like `:latest` in CI. + ๐Ÿ“– **[View Docker Installation Guide](docs/local-install-docker.md)** ### CLI @@ -175,12 +187,12 @@ socket-basics --python --secrets --containers --verbose ## ๐Ÿ”ง Requirements -**For GitHub Actions & Docker:** No installation needed โ€” all tools are bundled in the container. +**For GitHub Actions & Docker:** No local installation needed for the supported bundled scanners. **For Local Installation:** - Python 3.10+ - [Socket CLI](https://docs.socket.dev/docs/cli) (for dependency analysis) -- [Trivy](https://github.com/aquasecurity/trivy) (for container scanning) +- [Trivy](https://github.com/aquasecurity/trivy) (for native container scanning) - [OpenGrep/Semgrep](https://semgrep.dev/) (for SAST) - [TruffleHog](https://github.com/trufflesecurity/trufflehog) (for secret scanning) @@ -258,7 +270,6 @@ We welcome contributions! To add new features: 2. **New Notifiers:** Implement under `socket_basics/core/notification/` 3. **Configuration:** Add entries to `socket_basics/connectors.yaml` or `socket_basics/notifications.yaml` 4. **Testing:** See [Testing](#-testing) section below -5. **Releasing:** See [docs/releasing.md](docs/releasing.md) for the maintainer release process ## ๐Ÿงช Testing diff --git a/action.yml b/action.yml index dcbbfc4..75fedea 100644 --- a/action.yml +++ b/action.yml @@ -76,6 +76,7 @@ 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 }} @@ -383,19 +384,19 @@ inputs: required: false default: "false" trivy_disabled_rules: - description: "Comma-separated list of Trivy rules to disable" + description: "Comma-separated list of Trivy rules to disable. Trivy-backed scanning is temporarily unavailable in the pre-built GitHub Action image." required: false default: "" trivy_image_scanning_disabled: - description: "Disable Trivy image scanning" + description: "Disable Trivy image scanning. Trivy-backed scanning is temporarily unavailable in the pre-built GitHub Action image." required: false default: "false" trivy_notification_method: - description: "Notification method for Trivy (e.g., console, slack)" + description: "Notification method for Trivy (e.g., console, slack). Trivy-backed scanning is temporarily unavailable in the pre-built GitHub Action image." required: false default: "" trivy_vuln_enabled: - description: "Enable Trivy vulnerability scanning for all supported language ecosystems" + description: "Enable Trivy vulnerability scanning for all supported language ecosystems. Trivy-backed scanning is temporarily unavailable in the pre-built GitHub Action image." required: false default: "false" trufflehog_exclude_dir: diff --git a/docs/github-action.md b/docs/github-action.md index 3297c12..78d4b75 100644 --- a/docs/github-action.md +++ b/docs/github-action.md @@ -5,7 +5,7 @@ Complete guide to integrating Socket Basics into your GitHub Actions workflows f ## Table of Contents - [Quick Start](#quick-start) -- [Performance and Caching](#performance-and-caching) *(maintainers: see [releasing.md](releasing.md))* +- [Performance and Caching](#performance-and-caching) - [Basic Configuration](#basic-configuration) - [Enterprise Features](#enterprise-features) - [Advanced Workflows](#advanced-workflows) @@ -57,10 +57,10 @@ With just your `SOCKET_SECURITY_API_KEY`, all scanning configurations are manage ### How the action is currently built -When you reference `uses: SocketDev/socket-basics@v2.0.2`, GitHub Actions builds the -`Dockerfile` from source at the start of every workflow run. As of `1.1.3` the -Dockerfile uses a **multi-stage build** with BuildKit cache mounts, which provides -two categories of improvement: +When you reference `uses: SocketDev/socket-basics@v2.0.2`, GitHub Actions pulls the +pre-built image referenced by [`action.yml`](../action.yml). The historical multi-stage +Docker build still matters for maintainers because it determines what lands in the +published image: | Improvement | Benefit | |-------------|---------| @@ -69,27 +69,23 @@ two categories of improvement: | `--mount=type=cache` for apt / uv / npm | Faster repeated builds locally and on self-hosted runners with a persistent cache | **On standard GitHub-hosted runners** (ephemeral, no persistent Docker cache between -jobs), the multi-stage improvement is most visible when the same runner picks up a -cached layer โ€” typically within a workflow run or when GitHub's runner image itself -includes the base layers. Cold runs still download and run all tool-install steps. +jobs), users mainly benefit from pulling a ready-made image instead of rebuilding +Socket Basics from source in every workflow run. ### Pre-built image Starting with v2, the action pulls a pre-built image from GHCR rather than -building from source on every run. Pinning to a specific version tag (e.g. `@v2.0.0`) +building from source on every run. Pinning to a specific version tag (e.g. `@v2.0.2`) means the action starts in seconds โ€” the image is built, integration-tested, and published before the release tag is ever created. -> **Maintainers:** see [releasing.md](releasing.md) for the publish-before-tag -> release process and the PR checklist. - ### If you're running socket-basics outside of the GitHub Action If you run socket-basics in other CI systems (Jenkins, GitLab, CircleCI, etc.) or as a standalone `docker run`, pull the pre-built image directly: ```bash -docker pull ghcr.io/socketdev/socket-basics:1.1.3 +docker pull ghcr.io/socketdev/socket-basics:2.0.2 ``` See [Local Docker Installation](local-install-docker.md) for usage examples. @@ -104,7 +100,7 @@ is immediately affected. We've seen this happen across the ecosystem: A single bad push silently reaches all users with no review gate. This is structurally identical to `docker pull :latest` โ€” the anti-pattern we explicitly warn against in our Docker docs. -- **Version tags** (`@v2.0.0`) are better, but tags are mutable by default. +- **Version tags** (`@v2.0.2`) are better, but tags are mutable by default. A tag can be deleted and recreated pointing at a different commit. There are documented cases of this happening โ€” maliciously and accidentally. - **Commit SHAs** are the only truly immutable reference. A SHA cannot be @@ -112,7 +108,7 @@ is immediately affected. We've seen this happen across the ecosystem: human review gate at zero ongoing maintenance cost. We don't publish a floating major tag (`v2`). We do publish immutable version -tags (`v2.0.0`) protected by tag protection rules in GitHub โ€” but SHA pinning +tags (`v2.0.2`) protected by tag protection rules in GitHub โ€” but SHA pinning is still the recommendation for defence in depth. ### Pinning strategies @@ -128,14 +124,14 @@ The only truly immutable reference. Dependabot keeps it current automatically. ```yaml - name: Run Socket Basics # Dependabot keeps this SHA up to date โ€” see .github/dependabot.yml setup below. - uses: SocketDev/socket-basics@ # v2.0.0 + uses: SocketDev/socket-basics@ # v2.0.2 with: socket_security_api_key: ${{ secrets.SOCKET_SECURITY_API_KEY }} ``` Get the SHA for any release: ```bash -git ls-remote https://github.com/SocketDev/socket-basics refs/tags/v2.0.0 +git ls-remote https://github.com/SocketDev/socket-basics refs/tags/v2.0.2 ``` --- @@ -168,7 +164,7 @@ updates: ``` Dependabot opens a PR for each new release, updating the SHA or version tag -and keeping the `# v2.0.0` comment in sync. You review, approve, and merge +and keeping the `# v2.0.2` comment in sync. You review, approve, and merge on your own schedule โ€” automated upgrades with a human gate. --- @@ -178,7 +174,7 @@ on your own schedule โ€” automated upgrades with a human gate. | Strategy | Immutable? | Auto-updates | Review gate | |---|---|---|---| | `@v2` floating tag | โŒ (not published) | โ€” | โ€” | -| `@v2.0.0` + Dependabot | โœ… (tag protection enforced) | Yes (weekly PR) | Yes | +| `@v2.0.2` + Dependabot | โœ… (tag protection enforced) | Yes (weekly PR) | Yes | | `@` + Dependabot | โœ… always | Yes (weekly PR) | Yes | ## Basic Configuration @@ -235,12 +231,21 @@ Include these in your workflow's `jobs..permissions` section. - uses: SocketDev/socket-basics@v2.0.2 with: github_token: ${{ secrets.GITHUB_TOKEN }} - # Scan Docker images (auto-enables container scanning) - container_images: 'myorg/myapp:latest,redis:7' - # Scan Dockerfiles (auto-enables Dockerfile scanning) - dockerfiles: 'Dockerfile,docker/Dockerfile.prod' + # Trivy-backed container scanning is temporarily not available in the + # pre-built GitHub Action image. Use a native install if you need it today. + # See docs/local-installation.md. ``` +> [!NOTE] +> Container and Dockerfile scanning remain part of Socket Basics, but the current +> GitHub Action and pre-built image paths have Trivy-backed support temporarily +> disabled while we complete additional security review of the underlying scanner +> dependency path. If container or Dockerfile scanning is a near-term +> requirement, the [native installation path](local-installation.md) remains +> available as a temporary workaround while the pre-built path is under +> additional review. Review the upstream install path and artifacts carefully +> before adopting it in production CI. + **Socket Tier 1 Reachability:** ```yaml - uses: SocketDev/socket-basics@v2.0.2 @@ -298,7 +303,8 @@ Configure Socket Basics centrally from the [Socket Dashboard](https://socket.dev socket_security_api_key: ${{ secrets.SOCKET_SECURITY_API_KEY }} ``` -> **Note:** You can also pass credentials using environment variables instead of the `with:` section: +> [!NOTE] +> You can also pass credentials using environment variables instead of the `with:` section: > ```yaml > - uses: SocketDev/socket-basics@v2.0.2 > env: @@ -423,9 +429,6 @@ jobs: secret_scanning_enabled: 'true' socket_tier_1_enabled: 'true' - # Container scanning - dockerfiles: 'Dockerfile' - # Notifications (Enterprise) slack_webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }} ``` @@ -480,6 +483,21 @@ jobs: ### Container Security Pipeline +> [!NOTE] +> Container and Dockerfile scanning remain part of Socket Basics, but the current +> pre-built GitHub Action path has Trivy-backed support temporarily disabled while +> we complete additional security review of the underlying scanner dependency path. +> If container or Dockerfile scanning is a near-term requirement, the +> [native installation path](local-installation.md) remains available as a +> temporary workaround while the pre-built path is under additional review. +> Review the upstream install path and artifacts carefully before adopting it in +> production CI. + +> [!WARNING] +> This fallback path relies on upstream Trivy installation material outside the +> pinned pre-built distribution model. Review the upstream install path and +> artifacts carefully before using it in production CI. + ```yaml name: Container Security on: @@ -504,19 +522,16 @@ jobs: - name: Build Docker Image run: docker build -t myapp:${{ github.sha }} . + - name: Install pinned Trivy + run: | + TRIVY_VERSION=0.69.3 + curl -fsSL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh \ + | sh -s -- -b /usr/local/bin "v${TRIVY_VERSION}" + - name: Scan Container - uses: SocketDev/socket-basics@v2.0.2 - env: - GITHUB_PR_NUMBER: ${{ github.event.pull_request.number || github.event.issue.number }} - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - - # Scan built image and Dockerfile - container_images: 'myapp:${{ github.sha }}' - dockerfiles: 'Dockerfile' - - # Additional Trivy options - trivy_vuln_enabled: 'true' + run: | + trivy image --exit-code 1 --severity HIGH,CRITICAL "myapp:${{ github.sha }}" + trivy config --exit-code 1 --severity HIGH,CRITICAL Dockerfile ``` ### Dockerfile Auto-Discovery @@ -573,8 +588,10 @@ jobs: GITHUB_PR_NUMBER: ${{ github.event.pull_request.number || github.event.issue.number }} with: github_token: ${{ secrets.GITHUB_TOKEN }} - dockerfiles: ${{ needs.discover-dockerfiles.outputs.dockerfiles }} - trivy_vuln_enabled: 'true' + # Dockerfile discovery remains useful context for future container + # scanning support, but the current pre-built action image does not + # execute Trivy-backed scans. + verbose: 'true' ``` **How it works:** @@ -674,12 +691,19 @@ See [`action.yml`](../action.yml) for the complete list of inputs. - `trufflehog_show_unverified` โ€” Show unverified secrets - `socket_tier_1_enabled` โ€” Socket Tier 1 reachability -**Container Scanning:** +**Container Scanning (configuration surface):** - `container_images` โ€” Comma-separated images to scan - `dockerfiles` โ€” Comma-separated Dockerfiles to scan - `trivy_disabled_rules` โ€” Trivy rules to disable - `trivy_vuln_enabled` โ€” Enable vulnerability scanning +> [!NOTE] +> These inputs remain part of the action interface, but the current pre-built +> GitHub Action path has Trivy-backed support temporarily disabled while we +> complete additional security review of the underlying scanner dependency path. +> Use the [native installation path](local-installation.md) if container scanning +> is a near-term requirement. + **Notifications (Enterprise Required):** - `slack_webhook_url` โ€” Slack webhook - `jira_url`, `jira_email`, `jira_api_token`, `jira_project` โ€” Jira config @@ -734,8 +758,13 @@ permissions: **Problem:** Container image scanning fails. **Solutions:** -1. Ensure Docker is available in runner -2. For private images, add authentication: +> [!NOTE] +> The current pre-built GitHub Action path has Trivy-backed support temporarily +> disabled while the underlying scanner dependency path remains under additional +> security review. If container scanning is a near-term requirement, switch to a +> native Trivy install in the workflow. + +1. For private images, add authentication: ```yaml - name: Login to Registry run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin diff --git a/docs/github-pr-comment-guide.md b/docs/github-pr-comment-guide.md index 0cd949d..86281d3 100644 --- a/docs/github-pr-comment-guide.md +++ b/docs/github-pr-comment-guide.md @@ -7,12 +7,18 @@ Socket Basics delivers **beautifully formatted, actionable GitHub PR comments** These enhancements work across **all scanner types**: - โœ… **Socket Tier 1** (Reachability Analysis) - โœ… **SAST** (OpenGrep/Semgrep) -- โœ… **Container Scanning** (Trivy) +- โœ… **Container Scanning** (when container findings are available) - โœ… **Secret Detection** (TruffleHog) - โœ… **Future OSS Tools** (via centralized architecture) All scanners share the same UX enhancements for a consistent, professional experience. +> [!NOTE] +> Container-scanning UX is still supported by Socket Basics, but the current +> pre-built GitHub Action image does not emit Trivy-backed container findings +> while we complete additional security review of the underlying scanner +> dependency path. + ## ๐ŸŽฏ Quick Start **Want the enhanced experience?** You already have it! All features are **enabled by default** with the standard workflow setup โ€” see the [Quick Start in README](../README.md#-quick-start---github-actions). @@ -166,7 +172,7 @@ Make vulnerability IDs clickable and display CVSS scores for better risk assessm **How it works:** - CVE IDs automatically become clickable links to the National Vulnerability Database (NVD) - CVSS scores are displayed when available from the scanner -- Works for Socket Tier 1 and Trivy container/CVE scanning +- Works for Socket Tier 1 and container/CVE scanning when those findings are present - Missing CVSS scores are gracefully omitted (no breaking changes) **Example with different formats:** diff --git a/docs/local-install-docker.md b/docs/local-install-docker.md index 45cc78d..d1de3fb 100644 --- a/docs/local-install-docker.md +++ b/docs/local-install-docker.md @@ -1,6 +1,6 @@ # Local Docker Installation -Run Socket Basics locally using Docker without installing any security tools on your host machine. This guide covers using the pre-built images from GHCR / Docker Hub and building from source. +Run Socket Basics locally using Docker without installing security tools on your host machine. This guide covers the supported pre-built images from GHCR / Docker Hub and building from source when you need to inspect or customize the image. ## Table of Contents @@ -15,8 +15,8 @@ Run Socket Basics locally using Docker without installing any security tools on ## Quick Start ```bash -# 1. Pull a pinned release from Docker Hub (no build step required) -docker pull socketdev/socket-basics:1.1.3 +# 1. Pull a pinned release from GHCR (no build step required) +docker pull ghcr.io/socketdev/socket-basics:2.0.2 # 2. Create .env file with your credentials cat > .env << 'EOF' @@ -28,13 +28,16 @@ EOF docker run --rm \ -v "$PWD:/workspace" \ --env-file .env \ - socketdev/socket-basics:1.1.3 \ + ghcr.io/socketdev/socket-basics:2.0.2 \ --workspace /workspace \ --python \ --secrets \ --console-tabular-enabled ``` +The Docker image should always be pinned to an exact version such as `2.0.2`. Avoid +floating tags like `:latest` in CI/CD. + ## Using Pre-built Images Socket Basics publishes versioned, immutable images to both registries on every release. @@ -42,17 +45,26 @@ The baked-in security tool versions are recorded in the image labels so you can inspect exactly what's inside: ```bash -docker inspect ghcr.io/socketdev/socket-basics:1.1.3 \ +docker inspect ghcr.io/socketdev/socket-basics:2.0.2 \ | jq '.[0].Config.Labels' # { -# "com.socket.trivy-version": "0.69.3", # "com.socket.trufflehog-version": "3.93.8", # "com.socket.opengrep-version": "v1.16.5", -# "org.opencontainers.image.version": "1.1.3", +# "org.opencontainers.image.version": "2.0.2", # ... # } ``` +> [!NOTE] +> Container and Dockerfile scanning remain part of Socket Basics, but the current +> pre-built image path has Trivy-backed support temporarily disabled while we +> complete additional security review of the underlying scanner dependency path. +> If container or Dockerfile scanning is a near-term requirement, the +> [native installation path](local-installation.md) remains available as a +> temporary workaround while the pre-built path is under additional review. +> Review the upstream install path and artifacts carefully before adopting it in +> production CI. + ### Registries | Registry | Image | @@ -72,7 +84,7 @@ docker inspect ghcr.io/socketdev/socket-basics:1.1.3 \ -v "$GITHUB_WORKSPACE:/workspace" \ -e SOCKET_SECURITY_API_KEY=${{ secrets.SOCKET_API_KEY }} \ -e SOCKET_ORG=${{ secrets.SOCKET_ORG }} \ - ghcr.io/socketdev/socket-basics:1.1.3 \ + ghcr.io/socketdev/socket-basics:2.0.2 \ --workspace /workspace \ --all-languages \ --secrets \ @@ -83,7 +95,7 @@ docker inspect ghcr.io/socketdev/socket-basics:1.1.3 \ ```yaml security-scan: - image: ghcr.io/socketdev/socket-basics:1.1.3 + image: ghcr.io/socketdev/socket-basics:2.0.2 stage: test script: - socket-basics @@ -100,7 +112,7 @@ security-scan: ```dockerfile # Pin socket-basics and let Dependabot send upgrade PRs automatically -FROM ghcr.io/socketdev/socket-basics:1.1.3 +FROM ghcr.io/socketdev/socket-basics:2.0.2 ``` ### Staying Up to Date with Dependabot @@ -118,7 +130,7 @@ updates: interval: "weekly" ``` -Dependabot will detect the `FROM ghcr.io/socketdev/socket-basics:1.1.3` reference +Dependabot will detect the `FROM ghcr.io/socketdev/socket-basics:2.0.2` reference and open a PR with the version bump when a new release is available. ## Building the Docker Image @@ -129,10 +141,10 @@ Pull a specific release without building locally: ```bash # GHCR (preferred) -docker pull ghcr.io/socketdev/socket-basics:1.1.3 +docker pull ghcr.io/socketdev/socket-basics:2.0.2 # Docker Hub -docker pull socketdev/socket-basics:1.1.3 +docker pull socketdev/socket-basics:2.0.2 ``` ### Build from Source @@ -145,7 +157,7 @@ git clone https://github.com/SocketDev/socket-basics.git cd socket-basics # Build with version tag (multi-stage; first build is slower, subsequent ones are fast) -docker build -t socket-basics:1.1.3 . +docker build -t socket-basics:2.0.2 . # Verify the build docker images | grep socket-basics @@ -154,32 +166,32 @@ docker images | grep socket-basics ### Build for a Specific Platform (M1/M2 Macs) ```bash -docker build --platform linux/amd64 -t socket-basics:1.1.3 . +docker build --platform linux/amd64 -t socket-basics:2.0.2 . ``` ### Build with Custom Tool Versions -The image pins Trivy, TruffleHog, and OpenGrep to specific versions. You can override any of them at build time: +The image pins the bundled tools to specific versions. You can override them at build time: ```bash docker build \ - --build-arg TRIVY_VERSION=0.69.3 \ --build-arg TRUFFLEHOG_VERSION=3.93.8 \ --build-arg OPENGREP_VERSION=v1.16.5 \ - -t socket-basics:1.1.3 . + -t socket-basics:2.0.2 . ``` -Omit any `--build-arg` to use the default version for that tool. For the app tests image, build from the `app_tests` directory and use the same build args. +`TRIVY_VERSION` still exists in the Dockerfile for maintainers, but the current +published image intentionally omits the Trivy binary. For the app tests image, build +from the `app_tests` directory and use the same build args. ### Verify Installation ```bash # Check that all tools are available in the container -docker run --rm socket-basics:1.1.3 socket-basics --version -docker run --rm socket-basics:1.1.3 socket --version -docker run --rm socket-basics:1.1.3 trivy --version -docker run --rm socket-basics:1.1.3 opengrep --version -docker run --rm socket-basics:1.1.3 trufflehog --version +docker run --rm socket-basics:2.0.2 socket-basics --version +docker run --rm socket-basics:2.0.2 socket --version +docker run --rm socket-basics:2.0.2 opengrep --version +docker run --rm socket-basics:2.0.2 trufflehog --version ``` ### Smoke Test @@ -202,7 +214,7 @@ With `--app-tests` to also test the app_tests image (requires full build context ./scripts/smoke-test-docker.sh --app-tests ``` -This builds the image(s) and verifies Trivy, TruffleHog, and OpenGrep are installed and executable. A GitHub Action runs this on Dockerfile changes and daily. +This builds the image(s) and verifies the currently bundled tools are installed and executable. A GitHub Action runs this on Dockerfile changes and daily. ## Running Scans @@ -214,7 +226,7 @@ Mount your project directory into the container: # Scan current directory docker run --rm \ -v "$PWD:/workspace" \ - socket-basics:1.1.3 \ + socket-basics:2.0.2 \ --workspace /workspace \ --python \ --secrets \ @@ -231,7 +243,7 @@ docker run --rm \ # Scan a specific project directory docker run --rm \ -v "/path/to/your/project:/workspace" \ - socket-basics:1.1.3 \ + socket-basics:2.0.2 \ --workspace /workspace \ --javascript \ --secrets @@ -242,7 +254,7 @@ docker run --rm \ ```bash docker run --rm \ -v "$PWD:/workspace" \ - socket-basics:1.1.3 \ + socket-basics:2.0.2 \ --workspace /workspace \ --all-languages \ --secrets \ @@ -290,7 +302,7 @@ VERBOSE=false docker run --rm \ -v "$PWD:/workspace" \ --env-file .env \ - socket-basics:1.1.3 \ + socket-basics:2.0.2 \ --workspace /workspace \ --python \ --secrets @@ -305,7 +317,7 @@ docker run --rm \ -v "$PWD:/workspace" \ -e "SOCKET_SECURITY_API_KEY=scrt_your_api_key" \ -e "SOCKET_ORG=your-org-slug" \ - socket-basics:1.1.3 \ + socket-basics:2.0.2 \ --workspace /workspace \ --python \ --secrets \ @@ -327,7 +339,7 @@ docker run --rm \ --env-file .env.socket \ --env-file .env.notifiers \ --env-file .env.scanning \ - socket-basics:1.1.3 \ + socket-basics:2.0.2 \ --workspace /workspace \ --all-languages ``` @@ -346,29 +358,24 @@ docker run --rm \ -v "$PWD:/workspace" \ -e "SOCKET_SECURITY_API_KEY=$SOCKET_SECURITY_API_KEY" \ -e "SOCKET_ORG=$SOCKET_ORG" \ - socket-basics:1.1.3 \ + socket-basics:2.0.2 \ --workspace /workspace \ --python ``` ## Advanced Usage -### Container Scanning with Docker-in-Docker - -To scan Docker images, you need to provide Docker socket access: - -```bash -docker run --rm \ - -v "$PWD:/workspace" \ - -v "/var/run/docker.sock:/var/run/docker.sock" \ - --env-file .env \ - socket-basics:1.1.3 \ - --workspace /workspace \ - --images "nginx:latest,redis:7" \ - --console-tabular-enabled -``` +### Container Scanning Status -**Security Note:** Mounting the Docker socket gives the container full Docker access. Only use with trusted images. +> [!NOTE] +> Container and Dockerfile scanning remain part of Socket Basics, but the current +> pre-built Docker image path has Trivy-backed support temporarily disabled while +> we complete additional security review of the underlying scanner dependency path. +> If container or Dockerfile scanning is a near-term requirement, the +> [native installation path](local-installation.md) remains available as a +> temporary workaround while the pre-built path is under additional review. +> Review the upstream install path and artifacts carefully before adopting it in +> production CI. ### Save Results to File @@ -383,7 +390,7 @@ docker run --rm \ -v "$PWD:/workspace" \ -v "$PWD/scan-results:/results" \ --env-file .env \ - socket-basics:1.1.3 \ + socket-basics:2.0.2 \ --workspace /workspace \ --python \ --secrets \ @@ -400,7 +407,7 @@ docker run --rm -it \ -v "$PWD:/workspace" \ --env-file .env \ --entrypoint /bin/bash \ - socket-basics:1.1.3 + socket-basics:2.0.2 # Inside container, run commands manually: # cd /workspace @@ -429,7 +436,7 @@ docker run --rm \ -v "$PWD:/workspace" \ -v "$PWD/socket-config.json:/config.json" \ --env-file .env \ - socket-basics:1.1.3 \ + socket-basics:2.0.2 \ --workspace /workspace \ --config /config.json ``` @@ -453,7 +460,7 @@ for PROJECT in "${PROJECTS[@]}"; do docker run --rm \ -v "$PROJECT:/workspace" \ --env-file .env \ - socket-basics:1.1.3 \ + socket-basics:2.0.2 \ --workspace /workspace \ --all-languages \ --secrets \ @@ -477,7 +484,7 @@ pipeline { stage('Security Scan') { steps { script { - docker.image('ghcr.io/socketdev/socket-basics:1.1.3').inside( + docker.image('ghcr.io/socketdev/socket-basics:2.0.2').inside( "-v ${WORKSPACE}:/workspace --env-file .env" ) { sh ''' @@ -499,7 +506,7 @@ pipeline { ```yaml security-scan: - image: ghcr.io/socketdev/socket-basics:1.1.3 + image: ghcr.io/socketdev/socket-basics:2.0.2 stage: test script: - socket-basics @@ -525,7 +532,7 @@ security-scan: docker run --rm \ -v "$PWD:/workspace" \ --user "$(id -u):$(id -g)" \ - socket-basics:1.1.3 \ + socket-basics:2.0.2 \ --workspace /workspace ``` @@ -544,14 +551,14 @@ security-scan: ```bash docker run --rm \ -v "$(pwd):/workspace" \ # Use $(pwd) instead of $PWD - socket-basics:1.1.3 + socket-basics:2.0.2 ``` 2. Verify mount: ```bash docker run --rm \ -v "$PWD:/workspace" \ - socket-basics:1.1.3 \ + socket-basics:2.0.2 \ ls -la /workspace ``` @@ -581,24 +588,7 @@ security-scan: docker run --rm \ -v "$PWD:/workspace" \ --env-file "$(pwd)/.env" \ - socket-basics:1.1.3 - ``` - -### Docker Socket Permission Denied - -**Problem:** Cannot scan Docker images (permission denied on `/var/run/docker.sock`). - -**Solutions:** - -1. Add user to docker group: - ```bash - sudo usermod -aG docker $USER - newgrp docker - ``` - -2. Run with sudo (not recommended): - ```bash - sudo docker run ... + socket-basics:2.0.2 ``` ### Container Image Too Large @@ -629,7 +619,7 @@ security-scan: ```bash docker run --rm \ -v "$PWD:/workspace" \ - socket-basics:1.1.3 \ + socket-basics:2.0.2 \ --workspace /workspace \ --python \ --secrets \ @@ -650,7 +640,7 @@ security-scan: ```bash docker run --rm \ -v "$PWD:/workspace" \ - socket-basics:1.1.3 \ + socket-basics:2.0.2 \ --workspace /workspace \ --output /workspace/results.json # Save to mounted directory ``` @@ -661,7 +651,7 @@ security-scan: docker run --rm \ -v "$PWD:/workspace" \ -v "$PWD/results:/results" \ - socket-basics:1.1.3 \ + socket-basics:2.0.2 \ --workspace /workspace \ --output /results/scan.json ``` @@ -672,7 +662,7 @@ Add these to your `~/.bashrc` or `~/.zshrc` for quick access: ```bash # Socket Basics Docker aliases -alias sb-docker='docker run --rm -v "$PWD:/workspace" --env-file .env ghcr.io/socketdev/socket-basics:1.1.3 --workspace /workspace' +alias sb-docker='docker run --rm -v "$PWD:/workspace" --env-file .env ghcr.io/socketdev/socket-basics:2.0.2 --workspace /workspace' alias sb-quick='sb-docker --secrets --console-tabular-enabled' alias sb-python='sb-docker --python --secrets --console-tabular-enabled' alias sb-js='sb-docker --javascript --secrets --console-tabular-enabled' @@ -697,7 +687,7 @@ sb-all ## Best Practices 1. **Use pre-built images** โ€” Pull `ghcr.io/socketdev/socket-basics:` instead of building locally -2. **Pin to a specific version** โ€” Avoid `:latest` in production CI; pin to `1.1.3` and upgrade deliberately +2. **Pin to a specific version** โ€” Avoid `:latest` in production CI; pin to `2.0.2` and upgrade deliberately 3. **Use Dependabot** โ€” Reference the image in your Dockerfile/Compose to get automatic upgrade PRs 4. **Inspect baked-in labels** โ€” Run `docker inspect | jq '.[0].Config.Labels'` to verify tool versions 5. **Use .env files** โ€” Keep credentials out of command history @@ -716,7 +706,7 @@ set -e # Configuration PROJECT_DIR="$(pwd)" RESULTS_DIR="./scan-results" -IMAGE_NAME="socket-basics:1.1.3" +IMAGE_NAME="socket-basics:2.0.2" ENV_FILE=".env" # Create results directory diff --git a/docs/local-installation.md b/docs/local-installation.md index d36ff0a..5b89ede 100644 --- a/docs/local-installation.md +++ b/docs/local-installation.md @@ -1,6 +1,6 @@ # Local Installation Guide -Complete guide to installing Socket Basics and all security tools for native execution on your local machine. +Complete guide to installing Socket Basics and security tools for native execution on your local machine. ## Table of Contents @@ -23,7 +23,7 @@ git clone https://github.com/SocketDev/socket-basics.git cd socket-basics pip install -e . -# Install security tools +# Install pinned security tools brew install socket trivy trufflehog # Install OpenGrep (SAST scanning) @@ -37,6 +37,12 @@ opengrep --version trufflehog --version ``` +> [!NOTE] +> If container or Dockerfile scanning is a near-term requirement, the native +> installation path remains available as a temporary workaround while the +> pre-built path is under additional review. Review the upstream install path and +> artifacts carefully before adopting it in production CI. + For detailed installation instructions, continue reading below. ## Prerequisites @@ -148,7 +154,8 @@ pip install -e . ## Security Tools Installation -Socket Basics orchestrates multiple security tools. Install the ones you need: +Socket Basics orchestrates multiple security tools. Install only the scanners you plan +to use, and prefer exact version pins whenever your package manager supports them. ### Socket CLI (Dependency Analysis) @@ -180,6 +187,21 @@ export SOCKET_SECURITY_API_KEY="your-api-key" **Required for:** Container image and Dockerfile vulnerability scanning +> [!NOTE] +> Trivy-backed container and Dockerfile scanning remain part of Socket Basics, +> but the current pre-built GitHub Action and Docker image paths have that +> support temporarily disabled while the underlying scanner dependency path +> remains under additional review. This native installation path remains +> available as a temporary workaround if container scanning is a near-term +> requirement. + +> [!WARNING] +> This fallback path pulls installation material directly from upstream. Even when +> you pin the Trivy version, the installer or repository path is a separate trust +> decision. This is one reason Socket Basics has moved toward pre-built, pinned +> container-based distribution where possible. Review the upstream install path +> and artifacts carefully before using this in production CI. + **Installation:** ```bash @@ -203,8 +225,8 @@ enabled=1 EOF sudo yum -y install trivy -# Using Docker (alternative): -docker pull aquasec/trivy:latest +# Using Docker (alternative; pin explicitly): +docker pull aquasec/trivy:0.69.3 # Verify installation trivy --version @@ -245,17 +267,17 @@ OpenGrep works with the bundled Socket Basics SAST rules. No additional configur # macOS/Linux with Homebrew: brew install trufflehog -# Using Docker (alternative): -docker pull trufflesecurity/trufflehog:latest +# Using Docker (alternative; pin explicitly): +docker pull trufflesecurity/trufflehog:v3.93.8 # Manual installation (Linux): -wget https://github.com/trufflesecurity/trufflehog/releases/latest/download/trufflehog_linux_amd64.tar.gz -tar -xzf trufflehog_linux_amd64.tar.gz +wget https://github.com/trufflesecurity/trufflehog/releases/download/v3.93.8/trufflehog_3.93.8_linux_amd64.tar.gz +tar -xzf trufflehog_3.93.8_linux_amd64.tar.gz sudo mv trufflehog /usr/local/bin/ # Manual installation (macOS): -wget https://github.com/trufflesecurity/trufflehog/releases/latest/download/trufflehog_darwin_arm64.tar.gz -tar -xzf trufflehog_darwin_arm64.tar.gz +wget https://github.com/trufflesecurity/trufflehog/releases/download/v3.93.8/trufflehog_3.93.8_darwin_arm64.tar.gz +tar -xzf trufflehog_3.93.8_darwin_arm64.tar.gz sudo mv trufflehog /usr/local/bin/ # Verify installation @@ -493,7 +515,7 @@ socket-basics \ # Container scanning socket-basics \ - --container-images nginx:latest,redis:7 \ + --container-images nginx:1.27.4,redis:7.4 \ --dockerfiles Dockerfile,docker/Dockerfile.prod # Scan specific workspace diff --git a/docs/parameters.md b/docs/parameters.md index c30e785..7f5756d 100644 --- a/docs/parameters.md +++ b/docs/parameters.md @@ -293,12 +293,22 @@ socket-basics --secrets --show-unverified ## Container Scanning +> [!NOTE] +> These parameters remain part of the Socket Basics interface for container +> scanning. In the current pre-built GitHub Action and Docker image paths, +> Trivy-backed support is temporarily disabled while we complete additional +> security review of the underlying scanner dependency path. The parameters still +> apply for the [native installation path](local-installation.md) as a temporary +> workaround, and for future container scanner support in the pre-built paths. +> Review the upstream install path and artifacts carefully before adopting that +> workaround in production CI. + ### `--images IMAGES` Comma-separated list of container images to scan (auto-enables image scanning). **Example:** ```bash -socket-basics --images "nginx:latest,redis:7,postgres:15" +socket-basics --images "nginx:1.27.4,redis:7.4,postgres:15.8" ``` ### `--dockerfiles DOCKERFILES` @@ -314,7 +324,7 @@ Notification method for Trivy container scanning results. **Example:** ```bash -socket-basics --images "nginx:latest" --trivy-notify console +socket-basics --images "nginx:1.27.4" --trivy-notify console ``` ### `--trivy-disabled-rules TRIVY_DISABLED_RULES` @@ -322,7 +332,7 @@ Comma-separated list of Trivy rules to disable. **Example:** ```bash -socket-basics --images "nginx:latest" --trivy-disabled-rules "CVE-2023-1234,CVE-2023-5678" +socket-basics --images "nginx:1.27.4" --trivy-disabled-rules "CVE-2023-1234,CVE-2023-5678" ``` ### `--trivy-image-scanning-disabled` @@ -546,7 +556,7 @@ You can provide configuration via a JSON file using `--config`: "socket_org": "your-org-slug", "socket_api_key": "scrt_your_api_key", - "images": "nginx:latest,redis:7", + "images": "nginx:1.27.4,redis:7.4", "trivy_vuln_enabled": true, "slack_webhook_url": "https://hooks.slack.com/services/T00/B00/XXXX", @@ -593,7 +603,7 @@ socket-basics \ --all-languages \ --secrets \ --socket-tier1 \ - --images "myapp:latest" \ + --images "myapp:1.0.0" \ --console-tabular-enabled \ --verbose ``` @@ -624,7 +634,7 @@ socket-basics \ ```bash socket-basics \ - --images "nginx:latest,postgres:15" \ + --images "nginx:1.27.4,postgres:15.8" \ --dockerfiles "Dockerfile" \ --trivy-vuln-enabled \ --console-tabular-enabled diff --git a/docs/pre-commit-hook.md b/docs/pre-commit-hook.md index d596cc5..0d03d6b 100644 --- a/docs/pre-commit-hook.md +++ b/docs/pre-commit-hook.md @@ -35,7 +35,7 @@ Best for: Teams wanting consistent environments without installing security tool ```bash # Pull the pre-built image (no build step required) -docker pull socketdev/socket-basics:1.1.3 +docker pull ghcr.io/socketdev/socket-basics:2.0.2 ``` **2. Create pre-commit hook:** @@ -198,9 +198,9 @@ pip install -e . **Security tools:** -See [Local Installation Guide](local-installation.md) for detailed instructions on installing: +See [Local Installation Guide](local-installation.md) for detailed instructions on installing pinned versions of: - Socket CLI -- Trivy +- Trivy (required if you want native container scanning) - OpenGrep - TruffleHog diff --git a/docs/releasing.md b/docs/releasing.md deleted file mode 100644 index 202756a..0000000 --- a/docs/releasing.md +++ /dev/null @@ -1,85 +0,0 @@ -# Releasing socket-basics - -This document is for **maintainers** cutting a new release. -For usage documentation, see [github-action.md](github-action.md). - -## Release workflow: publish โ†’ tag (never tag โ†’ publish) - -Pushing a tag before the image is published creates a race condition where -`uses: SocketDev/socket-basics@vX.Y.Z` resolves an `action.yml` that references -a GHCR image that doesn't exist yet. Follow this order every time: - -``` -1. Open a release PR using the [PR template](../.github/PULL_REQUEST_TEMPLATE.md) โ€” the release checklist is pre-filled -2. Merge release PR to main (version bump + action.yml image ref update) -3. workflow_dispatch โ†’ publish-docker.yml with the new version - (builds, integration-tests, and pushes images to GHCR + Docker Hub) -4. Create git tag (e.g. v2.1.0) โ€” image already exists, zero race condition -``` - -The release PR **must** include all three of these changes together: - -- [ ] [`socket_basics/version.py`](../socket_basics/version.py) updated to new version -- [ ] [`pyproject.toml`](../pyproject.toml) `version:` field updated to match -- [ ] [`action.yml`](../action.yml) `image:` ref updated to `docker://ghcr.io/socketdev/socket-basics:` - *(after v2.0.0 this is auto-updated by the release workflow on every tag push โ€” manual update only required for the initial v2.0.0 release)* - -> ๐Ÿ’ก [`python-tests.yml`](../.github/workflows/python-tests.yml) CI will fail if `action.yml` and `pyproject.toml` versions diverge, -> so a mismatch cannot be merged accidentally. The release workflow also auto-corrects -> this via `sed` on each tag push once the pre-built image switch is in place. - -## `CHANGELOG` and release notes - -The changelog process has two phases: - -**Before the release PR (ongoing, optional but recommended):** -As PRs land, you can manually add notes to the `[Unreleased]` section of -[`CHANGELOG.md`](../CHANGELOG.md). Think of it as a running human-readable -summary of what's accumulating. The PR template checklist asks you to review -this section before merging the release PR. - -**After the tag is pushed (fully automated):** -[`scripts/update_changelog.py`](../scripts/update_changelog.py) runs as part of -the publish pipeline and: - -1. Fetches the GitHub Release's auto-generated notes (built from merged PR titles, - categorised by PR labels per [`.github/release.yml`](../.github/release.yml)) -2. **Replaces** the `[Unreleased]` section content with those generated notes -3. Inserts a new `## [VERSION] - DATE` section -4. Updates the comparison links at the bottom -5. Commits the result back to `main` via `socket-release-bot` - -> โš ๏ธ **The auto-generated notes replace whatever was in `[Unreleased]`** โ€” they are -> not merged with it. If you want specific wording in the CHANGELOG, the best lever -> is the PR title and description, since that's what GitHub's note generator pulls from. -> The `[Unreleased]` section is useful as a preview during development but should be -> treated as disposable, not authoritative. - -## After the tag is pushed - -[`publish-docker.yml`](../.github/workflows/publish-docker.yml) runs automatically and: - -1. Builds and tests the Docker image -2. Pushes to `ghcr.io/socketdev/socket-basics:` and `socketdev/socket-basics:` -3. Creates the GitHub Release with auto-generated notes (categorised by PR labels) -4. Commits an updated [`CHANGELOG.md`](../CHANGELOG.md) and [`action.yml`](../action.yml) back to `main` via `socket-release-bot` - -> Note: floating major version tags (`v2`) are intentionally not published โ€” -> see [docs/github-action.md](github-action.md#why-were-opinionated-about-pinning). - -## Immutable tags โ€” required GitHub setup - -Tag protection rules prevent tags from being deleted or force-pushed after creation. -This is what makes `@v2.0.0` trustworthy as a pin (beyond just recommending SHA pinning). - -**One-time setup** (repo admin, Settings โ†’ Rules โ†’ Rulesets): -- Create a ruleset targeting tags matching `v*` -- Enable: **Restrict deletions** + **Block force pushes** - -Once in place, every `v*` tag pushed is permanent. Combined with SHA pinning -and Dependabot, users get the full immutable release guarantee. - -## Making GHCR packages public - -After the **first** publish, a GitHub org owner needs to flip the package visibility -to public: **Package settings โ†’ Change visibility โ†’ Public**. One-time step. diff --git a/scripts/sync_release_version.py b/scripts/sync_release_version.py new file mode 100644 index 0000000..21a0fc1 --- /dev/null +++ b/scripts/sync_release_version.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python3 +"""Sync release version metadata from pyproject.toml. + +This script treats pyproject.toml as the canonical source of truth and keeps +the duplicated version fields in sync. +""" + +from __future__ import annotations + +import argparse +import re +import sys +import tomllib +from pathlib import Path + + +REPO_ROOT = Path(__file__).resolve().parent.parent +PYPROJECT_PATH = REPO_ROOT / "pyproject.toml" +VERSION_PY_PATH = REPO_ROOT / "socket_basics" / "version.py" +INIT_PY_PATH = REPO_ROOT / "socket_basics" / "__init__.py" +ACTION_YML_PATH = REPO_ROOT / "action.yml" + + +def read_canonical_version() -> str: + data = tomllib.loads(PYPROJECT_PATH.read_text()) + return data["project"]["version"] + + +def replace_first(pattern: str, replacement: str, content: str, path: Path) -> str: + updated, count = re.subn(pattern, replacement, content, count=1, flags=re.MULTILINE) + if count != 1: + raise ValueError(f"Could not update expected version field in {path}") + return updated + + +def build_expected_files(version: str) -> dict[Path, str]: + expected: dict[Path, str] = {} + + version_py = VERSION_PY_PATH.read_text() + expected[VERSION_PY_PATH] = replace_first( + r'^__version__ = "[^"]+"$', + f'__version__ = "{version}"', + version_py, + VERSION_PY_PATH, + ) + + init_py = INIT_PY_PATH.read_text() + expected[INIT_PY_PATH] = replace_first( + r'^__version__ = "[^"]+"$', + f'__version__ = "{version}"', + init_py, + INIT_PY_PATH, + ) + + action_yml = ACTION_YML_PATH.read_text() + expected[ACTION_YML_PATH] = replace_first( + r'^( image: "docker://ghcr\.io/socketdev/socket-basics:)[^"]+(")$', + rf'\g<1>{version}\2', + action_yml, + ACTION_YML_PATH, + ) + + return expected + + +def check_files(expected: dict[Path, str]) -> list[str]: + mismatches: list[str] = [] + for path, rendered in expected.items(): + current = path.read_text() + if current != rendered: + mismatches.append(str(path.relative_to(REPO_ROOT))) + return mismatches + + +def write_files(expected: dict[Path, str]) -> None: + for path, rendered in expected.items(): + path.write_text(rendered) + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser( + description="Sync socket-basics version metadata from pyproject.toml" + ) + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument( + "--check", + action="store_true", + help="Fail if any derived version files differ from pyproject.toml", + ) + group.add_argument( + "--write", + action="store_true", + help="Rewrite derived version files to match pyproject.toml", + ) + return parser.parse_args() + + +def main() -> int: + args = parse_args() + version = read_canonical_version() + expected = build_expected_files(version) + + if args.write: + write_files(expected) + print(f"Synchronized release version metadata to {version}") + return 0 + + mismatches = check_files(expected) + if mismatches: + print(f"Release version metadata is out of sync with pyproject.toml ({version}):") + for mismatch in mismatches: + print(f" - {mismatch}") + print("Run: python3 scripts/sync_release_version.py --write") + return 1 + + print(f"Release version metadata is in sync: {version}") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/socket_basics/__init__.py b/socket_basics/__init__.py index 92098b9..9330d3a 100644 --- a/socket_basics/__init__.py +++ b/socket_basics/__init__.py @@ -4,7 +4,7 @@ A comprehensive security scanning module that integrates multiple security tools: - OpenGrep for SAST (Static Application Security Testing) - Trufflehog for secret scanning -- Trivy for container and Dockerfile scanning +- Trivy-backed container and Dockerfile scanning support The module includes bundled rules and can be used as a standalone tool or library. """ @@ -12,7 +12,7 @@ from .socket_basics import SecurityScanner, main from .core.config import load_config_from_env, Config -__version__ = "1.1.3" +__version__ = "2.0.2" __author__ = "Socket.dev" __email__ = "support@socket.dev"