
Research
2025 Report: Destructive Malware in Open Source Packages
Destructive malware is rising across open source registries, using delays and kill switches to wipe code, break builds, and disrupt CI/CD.
socketsecurity
Advanced tools
The Socket Security CLI was created to enable integrations with other tools like GitHub Actions, GitLab, BitBucket, local use cases and more. The tool will get the head scan for the provided repo from Socket, create a new one, and then report any new alerts detected. If there are new alerts with blocking actions it'll exit with a non-Zero exit code.
The CLI now features automatic detection of git repository information, making it much simpler to use in CI/CD environments. Most parameters are now optional and will be detected automatically from your git repository.
GitHub Actions:
socketcli --target-path $GITHUB_WORKSPACE --scm github --pr-number $PR_NUMBER
GitLab CI:
socketcli --target-path $CI_PROJECT_DIR --scm gitlab --pr-number ${CI_MERGE_REQUEST_IID:-0}
Local Development:
socketcli --target-path ./my-project
The CLI will automatically detect:
Pre-configured workflow examples are available in the workflows/ directory:
These examples are production-ready and include best practices for each platform.
The Socket CLI supports scanning specific workspaces within monorepo structures while preserving git context from the repository root. This is useful for organizations that maintain multiple applications or services in a single repository.
--sub-path options to scan different directories within your monorepo--workspace-name to differentiate scans from different parts of your monorepoScan multiple frontend and backend workspaces:
socketcli --target-path /path/to/monorepo \
--sub-path frontend \
--sub-path backend \
--sub-path services/api \
--workspace-name main-app
GitHub Actions for monorepo workspace:
socketcli --target-path $GITHUB_WORKSPACE \
--sub-path packages/web \
--sub-path packages/mobile \
--workspace-name mobile-web \
--scm github \
--pr-number $PR_NUMBER
This will:
./packages/web/ and ./packages/mobile/my-repo-mobile-web--sub-path and --workspace-name must be specified together--sub-path can be used multiple times to include multiple directoriessocketcli [-h] [--api-token API_TOKEN] [--repo REPO] [--repo-is-public] [--branch BRANCH] [--integration {api,github,gitlab,azure,bitbucket}]
[--owner OWNER] [--pr-number PR_NUMBER] [--commit-message COMMIT_MESSAGE] [--commit-sha COMMIT_SHA] [--committers [COMMITTERS ...]]
[--target-path TARGET_PATH] [--sbom-file SBOM_FILE] [--license-file-name LICENSE_FILE_NAME] [--save-submitted-files-list SAVE_SUBMITTED_FILES_LIST]
[--save-manifest-tar SAVE_MANIFEST_TAR] [--files FILES] [--sub-path SUB_PATH] [--workspace-name WORKSPACE_NAME]
[--excluded-ecosystems EXCLUDED_ECOSYSTEMS] [--default-branch] [--pending-head] [--generate-license] [--enable-debug]
[--enable-json] [--enable-sarif] [--disable-overview] [--exclude-license-details] [--allow-unverified] [--disable-security-issue]
[--ignore-commit-files] [--disable-blocking] [--enable-diff] [--scm SCM] [--timeout TIMEOUT] [--include-module-folders]
[--reach] [--reach-version REACH_VERSION] [--reach-analysis-timeout REACH_ANALYSIS_TIMEOUT]
[--reach-analysis-memory-limit REACH_ANALYSIS_MEMORY_LIMIT] [--reach-ecosystems REACH_ECOSYSTEMS] [--reach-exclude-paths REACH_EXCLUDE_PATHS]
[--reach-min-severity {low,medium,high,critical}] [--reach-skip-cache] [--reach-disable-analytics] [--reach-output-file REACH_OUTPUT_FILE]
[--only-facts-file] [--version]
If you don't want to provide the Socket API Token every time then you can use the environment variable SOCKET_SECURITY_API_KEY
| Parameter | Required | Default | Description |
|---|---|---|---|
| --api-token | False | Socket Security API token (can also be set via SOCKET_SECURITY_API_KEY env var) |
| Parameter | Required | Default | Description |
|---|---|---|---|
| --repo | False | auto | Repository name in owner/repo format (auto-detected from git remote) |
| --repo-is-public | False | False | If set, flags a new repository creation as public. Defaults to false. |
| --integration | False | api | Integration type (api, github, gitlab, azure, bitbucket) |
| --owner | False | Name of the integration owner, defaults to the socket organization slug | |
| --branch | False | auto | Branch name (auto-detected from git) |
| --committers | False | auto | Committer(s) to filter by (auto-detected from git commit) |
| Parameter | Required | Default | Description |
|---|---|---|---|
| --pr-number | False | "0" | Pull request number |
| --commit-message | False | auto | Commit message (auto-detected from git) |
| --commit-sha | False | auto | Commit SHA (auto-detected from git) |
| Parameter | Required | Default | Description |
|---|---|---|---|
| --target-path | False | ./ | Target path for analysis |
| --sbom-file | False | SBOM file path | |
| --license-file-name | False | license_output.json | Name of the file to save the license details to if enabled |
| --save-submitted-files-list | False | Save list of submitted file names to JSON file for debugging purposes | |
| --save-manifest-tar | False | Save all manifest files to a compressed tar.gz archive with original directory structure | |
| --files | False | auto | Files to analyze (JSON array string). Auto-detected from git commit changes when not specified |
| --sub-path | False | Sub-path within target-path for manifest file scanning (can be specified multiple times). All sub-paths are combined into a single workspace scan while preserving git context from target-path. Must be used with --workspace-name | |
| --workspace-name | False | Workspace name suffix to append to repository name (repo-name-workspace_name). Must be used with --sub-path | |
| --excluded-ecosystems | False | [] | List of ecosystems to exclude from analysis (JSON array string). You can get supported files from the Supported Files API |
| Parameter | Required | Default | Description |
|---|---|---|---|
| --default-branch | False | auto | Make this branch the default branch (auto-detected from git and CI environment when not specified) |
| --pending-head | False | auto | If true, the new scan will be set as the branch's head scan (automatically synced with default-branch) |
| --include-module-folders | False | False | If enabled will include manifest files from folders like node_modules |
| Parameter | Required | Default | Description |
|---|---|---|---|
| --generate-license | False | False | Generate license information |
| --enable-debug | False | False | Enable debug logging |
| --enable-json | False | False | Output in JSON format |
| --enable-sarif | False | False | Enable SARIF output of results instead of table or JSON format |
| --disable-overview | False | False | Disable overview output |
| --exclude-license-details | False | False | Exclude license details from the diff report (boosts performance for large repos) |
| --version | False | False | Show program's version number and exit |
| Parameter | Required | Default | Description |
|---|---|---|---|
| --allow-unverified | False | False | Allow unverified packages |
| --disable-security-issue | False | False | Disable security issue checks |
| Parameter | Required | Default | Description |
|---|---|---|---|
| --reach | False | False | Enable reachability analysis to identify which vulnerable functions are actually called by your code |
| --reach-version | False | latest | Version of @coana-tech/cli to use for analysis |
| --reach-analysis-timeout | False | 1200 | Timeout in seconds for the reachability analysis (default: 1200 seconds / 20 minutes) |
| --reach-analysis-memory-limit | False | 4096 | Memory limit in MB for the reachability analysis (default: 4096 MB / 4 GB) |
| --reach-concurrency | False | Control parallel analysis execution (must be >= 1) | |
| --reach-additional-params | False | Pass custom parameters to the coana CLI tool | |
| --reach-ecosystems | False | Comma-separated list of ecosystems to analyze (e.g., "npm,pypi"). If not specified, all supported ecosystems are analyzed | |
| --reach-exclude-paths | False | Comma-separated list of file paths or patterns to exclude from reachability analysis | |
| --reach-min-severity | False | Minimum severity level for reporting reachability results (low, medium, high, critical) | |
| --reach-skip-cache | False | False | Skip cache and force fresh reachability analysis |
| --reach-disable-analytics | False | False | Disable analytics collection during reachability analysis |
| --reach-output-file | False | .socket.facts.json | Path where reachability analysis results should be saved |
| --only-facts-file | False | False | Submit only the .socket.facts.json file to an existing scan (requires --reach and a prior scan) |
Reachability Analysis Requirements:
npm - Required to install and run @coana-tech/clinpx - Required to execute @coana-tech/cliuv - Required for Python environment managementThe CLI will automatically install @coana-tech/cli if not present. Use --reach to enable reachability analysis during a full scan, or use --only-facts-file with --reach to submit reachability results to an existing scan.
| Parameter | Required | Default | Description |
|---|---|---|---|
| --ignore-commit-files | False | False | Ignore commit files |
| --disable-blocking | False | False | Disable blocking mode |
| --enable-diff | False | False | Enable diff mode even when using --integration api (forces diff mode without SCM integration) |
| --scm | False | api | Source control management type |
| --timeout | False | Timeout in seconds for API requests |
The Python CLI currently Supports the following plugins:
| Environment Variable | Required | Default | Description |
|---|---|---|---|
| SOCKET_JIRA_ENABLED | False | false | Enables/Disables the Jira Plugin |
| SOCKET_JIRA_CONFIG_JSON | True | None | Required if the Plugin is enabled. |
Example SOCKET_JIRA_CONFIG_JSON value
{"url": "https://REPLACE_ME.atlassian.net", "email": "example@example.com", "api_token": "REPLACE_ME", "project": "REPLACE_ME" }
| Environment Variable | Required | Default | Description |
|---|---|---|---|
| SOCKET_SLACK_ENABLED | False | false | Enables/Disables the Slack Plugin |
| SOCKET_SLACK_CONFIG_JSON | True | None | Required if the Plugin is enabled. |
Example SOCKET_SLACK_CONFIG_JSON value
{"url": "https://REPLACE_ME_WEBHOOK"}
The CLI now automatically detects repository information from your git environment, significantly simplifying usage in CI/CD pipelines:
Note on merge commits:
Standard merges (two parents) are supported.
For octopus merges (three or more parents), Git only reports changes relative to the first parent. This can lead to incomplete or empty file lists if changes only exist relative to other parents. In these cases, differential scanning may be skipped. To ensure coverage, use--ignore-commit-filesto force a full scan or specify files explicitly with--files.
The CLI uses intelligent default branch detection with the following priority:
--default-branch flag: Takes highest priority when specifiedfalse if none of the above methods succeedBoth --default-branch and --pending-head parameters are automatically synchronized to ensure consistent behavior.
The CLI supports GitLab integration with automatic authentication pattern detection for different token types.
GitLab API supports two authentication methods, and the CLI automatically detects which one to use:
Bearer Token Authentication (Authorization: Bearer <token>)
$CI_JOB_TOKEN)glpat- prefixPrivate Token Authentication (PRIVATE-TOKEN: <token>)
The CLI automatically determines the authentication method using this logic:
if token == $CI_JOB_TOKEN:
use Bearer authentication
elif token starts with "glpat-":
use Bearer authentication
elif token is long (>40 chars) and alphanumeric:
use Bearer authentication
else:
use PRIVATE-TOKEN authentication
If the initial authentication method fails with a 401 error, the CLI automatically retries with the alternative method:
This ensures maximum compatibility across different GitLab configurations and token types.
| Variable | Description | Example |
|---|---|---|
GITLAB_TOKEN | GitLab API token (required for GitLab integration) | glpat-xxxxxxxxxxxxxxxxxxxx |
CI_JOB_TOKEN | GitLab CI job token (automatically used in GitLab CI) | Automatically provided by GitLab CI |
GitLab CI with job token (recommended):
variables:
GITLAB_TOKEN: $CI_JOB_TOKEN
GitLab CI with personal access token:
variables:
GITLAB_TOKEN: $GITLAB_PERSONAL_ACCESS_TOKEN # Set in GitLab project/group variables
Local development:
export GITLAB_TOKEN="glpat-your-personal-access-token"
socketcli --integration gitlab --repo owner/repo --pr-number 123
The CLI determines scanning behavior intelligently:
The CLI determines which files to scan based on the following logic:
Git Commit Files (Default): The CLI automatically checks files changed in the current git commit. If any of these files match supported manifest patterns (like package.json, requirements.txt, etc.), a scan is triggered.
--files Parameter Override: When specified, this parameter takes precedence over git commit detection. It accepts a JSON array of file paths to check for manifest files.
--ignore-commit-files Flag: When set, git commit files are ignored completely, and the CLI will scan all manifest files in the target directory regardless of what changed.
Automatic Fallback: If no manifest files are found in git commit changes and no --files are specified, the CLI automatically switches to "API mode" and performs a full repository scan.
Important: The CLI doesn't scan only the specified files - it uses them to determine whether a scan should be performed and what type of scan to run. When triggered, it searches the entire
--target-pathfor all supported manifest files.
--ignore-commit-files, always performs a full scan regardless of changes--enable-diff, forces differential mode even when using --integration api (without SCM integration)package.json, a differential scan will be triggered automatically with PR comment integration..github/workflows/socket.yaml), the CLI automatically switches to API mode and performs a full repository scan.--files: If you specify --files '["package.json"]', the CLI will check if this file exists and is a manifest file before determining scan type.--ignore-commit-files: This forces a full scan of all manifest files in the target path, regardless of what's in your commit.--enable-diff: Forces diff mode without SCM integration - useful when you want differential scanning but are using --integration api. For example: socketcli --integration api --enable-diff --target-path /path/to/reposocketcli --target-path /path/to/repo --scm github --pr-number $PR_NUMThe CLI provides a debugging option to save the list of files that were submitted for scanning:
socketcli --save-submitted-files-list submitted_files.json
This will create a JSON file containing:
Example output file:
{
"timestamp": "2025-01-22 10:30:45 UTC",
"total_files": 3,
"total_size_bytes": 2048,
"total_size_human": "2.00 KB",
"files": [
"./package.json",
"./requirements.txt",
"./Pipfile"
]
}
This feature is useful for:
Note: This option works with both differential scans (when git commits are detected) and full scans (API mode).
For backup, sharing, or analysis purposes, you can save all manifest files to a compressed tar.gz archive:
socketcli --save-manifest-tar manifest_files.tar.gz
This will create a compressed archive containing all the manifest files that were found and submitted for scanning, preserving their original directory structure relative to the scanned directory.
Example usage with other options:
# Save both files list and archive
socketcli --save-submitted-files-list files.json --save-manifest-tar backup.tar.gz
# Use with specific target path
socketcli --target-path ./my-project --save-manifest-tar my-project-manifests.tar.gz
The manifest archive feature is useful for:
Note: The tar.gz archive preserves the original directory structure, making it easy to extract and examine the files in their proper context.
When your repo uses an octopus merge (3+ parents), the CLI may not detect all changed files.
This is expected Git behavior: the default diff only compares the merge result to the first parent.
This project uses pyproject.toml as the primary dependency specification.
The following Make targets provide streamlined workflows for common development tasks:
pyenv local 3.11 # Ensure correct Python version
make first-time-setup
pyenv local 3.11 # Ensure correct Python version
SOCKET_SDK_PATH=~/path/to/socketdev make first-time-local-setup
The default SDK path is ../socketdev if not specified.
After changing dependencies in pyproject.toml:
make update-deps
After pulling changes:
make sync-all
High-level workflows:
make first-time-setup: Complete setup using PyPI packagesmake first-time-local-setup: Complete setup for local SDK developmentmake update-lock: Update uv.lock file after changing pyproject.tomlmake sync-all: Sync dependencies after pulling changesmake dev-setup: Setup for local development (included in first-time-local-setup)Implementation targets:
make local-dev: Installs dependencies needed for local developmentmake setup: Creates virtual environment and installs dependencies from uv.lockmake sync: Installs exact versions from uv.lockmake clean: Removes virtual environment and cache filesmake test: Runs pytest suite using uv runmake lint: Runs ruff for code formatting and linting using uv runSOCKET_SECURITY_API_KEY: Socket Security API token (alternative to --api-token parameter)SOCKET_SDK_PATH: Path to local socketdev repository (default: ../socketdev)GITLAB_TOKEN: GitLab API token for GitLab integration (supports both Bearer and PRIVATE-TOKEN authentication)CI_JOB_TOKEN: GitLab CI job token (automatically provided in GitLab CI environments)For manual setup without using the Make targets, follow these steps:
python -m venv .venv
source .venv/bin/activate
uv sync
uv add --dev pre-commit
pre-commit install
Note: This manual setup is an alternative to the streamlined Make targets described above. For most development workflows, using
make first-time-setupormake first-time-local-setupis recommended.
FAQs
Socket Security CLI for CI/CD
We found that socketsecurity demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 4 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
Destructive malware is rising across open source registries, using delays and kill switches to wipe code, break builds, and disrupt CI/CD.

Security News
Socket CTO Ahmad Nassri shares practical AI coding techniques, tools, and team workflows, plus what still feels noisy and why shipping remains human-led.

Research
/Security News
A five-month operation turned 27 npm packages into durable hosting for browser-run lures that mimic document-sharing portals and Microsoft sign-in, targeting 25 organizations across manufacturing, industrial automation, plastics, and healthcare for credential theft.