socketsecurity 2.2.9__tar.gz → 2.2.11__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/PKG-INFO +65 -17
  2. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/README.md +63 -15
  3. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/pyproject.toml +2 -2
  4. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/__init__.py +1 -1
  5. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/config.py +8 -7
  6. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/core/__init__.py +38 -28
  7. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/socketcli.py +38 -25
  8. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/.github/CODEOWNERS +0 -0
  9. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/.github/PULL_REQUEST_TEMPLATE/bug-fix.md +0 -0
  10. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/.github/PULL_REQUEST_TEMPLATE/feature.md +0 -0
  11. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/.github/PULL_REQUEST_TEMPLATE/improvement.md +0 -0
  12. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  13. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/.github/workflows/docker-stable.yml +0 -0
  14. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/.github/workflows/pr-preview.yml +0 -0
  15. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/.github/workflows/release.yml +0 -0
  16. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/.github/workflows/version-check.yml +0 -0
  17. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/.gitignore +0 -0
  18. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/.hooks/sync_version.py +0 -0
  19. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/.pre-commit-config.yaml +0 -0
  20. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/.python-version +0 -0
  21. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/Dockerfile +0 -0
  22. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/LICENSE +0 -0
  23. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/Makefile +0 -0
  24. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/Pipfile.lock +0 -0
  25. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/docs/README.md +0 -0
  26. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/pytest.ini +0 -0
  27. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/scripts/build_container.sh +0 -0
  28. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/scripts/deploy-test-docker.sh +0 -0
  29. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/scripts/deploy-test-pypi.sh +0 -0
  30. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/scripts/run.sh +0 -0
  31. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/core/classes.py +0 -0
  32. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/core/cli_client.py +0 -0
  33. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/core/exceptions.py +0 -0
  34. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/core/git_interface.py +0 -0
  35. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/core/helper/__init__.py +0 -0
  36. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/core/lazy_file_loader.py +0 -0
  37. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/core/logging.py +0 -0
  38. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/core/messages.py +0 -0
  39. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/core/resource_utils.py +0 -0
  40. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/core/scm/__init__.py +0 -0
  41. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/core/scm/base.py +0 -0
  42. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/core/scm/client.py +0 -0
  43. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/core/scm/github.py +0 -0
  44. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/core/scm/gitlab.py +0 -0
  45. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/core/scm_comments.py +0 -0
  46. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/core/socket_config.py +0 -0
  47. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/core/utils.py +0 -0
  48. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/output.py +0 -0
  49. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/plugins/__init__.py +0 -0
  50. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/plugins/base.py +0 -0
  51. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/plugins/jira.py +0 -0
  52. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/plugins/manager.py +0 -0
  53. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/plugins/slack.py +0 -0
  54. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/plugins/teams.py +0 -0
  55. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/socketsecurity/plugins/webhook.py +0 -0
  56. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/tests/__init__.py +0 -0
  57. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/tests/core/conftest.py +0 -0
  58. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/tests/core/create_diff_input.json +0 -0
  59. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/tests/core/test_diff_generation.py +0 -0
  60. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/tests/core/test_package_and_alerts.py +0 -0
  61. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/tests/core/test_sdk_methods.py +0 -0
  62. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/tests/core/test_supporting_methods.py +0 -0
  63. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/tests/data/fullscans/create_response.json +0 -0
  64. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/tests/data/fullscans/diff/stream_diff.json +0 -0
  65. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/tests/data/fullscans/diff/stream_diff_full.json +0 -0
  66. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/tests/data/fullscans/head_scan/metadata.json +0 -0
  67. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/tests/data/fullscans/head_scan/stream_scan.json +0 -0
  68. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/tests/data/fullscans/head_scan/stream_scan_full.json +0 -0
  69. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/tests/data/fullscans/new_scan/metadata.json +0 -0
  70. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/tests/data/fullscans/new_scan/stream_scan.json +0 -0
  71. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/tests/data/repos/repo_info_error.json +0 -0
  72. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/tests/data/repos/repo_info_no_head.json +0 -0
  73. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/tests/data/repos/repo_info_success.json +0 -0
  74. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/tests/data/settings/security-policy.json +0 -0
  75. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/tests/unit/__init__.py +0 -0
  76. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/tests/unit/test_cli_config.py +0 -0
  77. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/tests/unit/test_client.py +0 -0
  78. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/tests/unit/test_config.py +0 -0
  79. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/tests/unit/test_gitlab_auth.py +0 -0
  80. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/tests/unit/test_gitlab_auth_fallback.py +0 -0
  81. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/tests/unit/test_output.py +0 -0
  82. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/uv.lock +0 -0
  83. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/workflows/bitbucket-pipelines.yml +0 -0
  84. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/workflows/github-actions.yml +0 -0
  85. {socketsecurity-2.2.9 → socketsecurity-2.2.11}/workflows/gitlab-ci.yml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: socketsecurity
3
- Version: 2.2.9
3
+ Version: 2.2.11
4
4
  Summary: Socket Security CLI for CI/CD
5
5
  Project-URL: Homepage, https://socket.dev
6
6
  Author-email: Douglas Coburn <douglas@socket.dev>
@@ -39,7 +39,7 @@ Requires-Dist: packaging
39
39
  Requires-Dist: prettytable
40
40
  Requires-Dist: python-dotenv
41
41
  Requires-Dist: requests
42
- Requires-Dist: socketdev<4.0.0,>=3.0.5
42
+ Requires-Dist: socketdev<4.0.0,>=3.0.6
43
43
  Provides-Extra: dev
44
44
  Requires-Dist: hatch; extra == 'dev'
45
45
  Requires-Dist: pre-commit; extra == 'dev'
@@ -97,15 +97,60 @@ Pre-configured workflow examples are available in the [`workflows/`](workflows/)
97
97
 
98
98
  These examples are production-ready and include best practices for each platform.
99
99
 
100
+ ## Monorepo Workspace Support
101
+
102
+ 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.
103
+
104
+ ### Key Features
105
+
106
+ - **Multiple Sub-paths**: Specify multiple `--sub-path` options to scan different directories within your monorepo
107
+ - **Combined Workspace**: All sub-paths are scanned together as a single workspace in Socket
108
+ - **Git Context Preserved**: Repository metadata (commits, branches, etc.) comes from the main target-path
109
+ - **Workspace Naming**: Use `--workspace-name` to differentiate scans from different parts of your monorepo
110
+
111
+ ### Usage Examples
112
+
113
+ **Scan multiple frontend and backend workspaces:**
114
+ ```bash
115
+ socketcli --target-path /path/to/monorepo \
116
+ --sub-path frontend \
117
+ --sub-path backend \
118
+ --sub-path services/api \
119
+ --workspace-name main-app
120
+ ```
121
+
122
+ **GitHub Actions for monorepo workspace:**
123
+ ```bash
124
+ socketcli --target-path $GITHUB_WORKSPACE \
125
+ --sub-path packages/web \
126
+ --sub-path packages/mobile \
127
+ --workspace-name mobile-web \
128
+ --scm github \
129
+ --pr-number $PR_NUMBER
130
+ ```
131
+
132
+ This will:
133
+ - Scan manifest files in `./packages/web/` and `./packages/mobile/`
134
+ - Combine them into a single workspace scan
135
+ - Create a repository in Socket named like `my-repo-mobile-web`
136
+ - Preserve git context (commits, branch info) from the repository root
137
+
138
+ ### Requirements
139
+
140
+ - Both `--sub-path` and `--workspace-name` must be specified together
141
+ - `--sub-path` can be used multiple times to include multiple directories
142
+ - All specified sub-paths must exist within the target-path
143
+
100
144
  ## Usage
101
145
 
102
146
  ```` shell
103
- socketcli [-h] [--api-token API_TOKEN] [--repo REPO] [--integration {api,github,gitlab}] [--owner OWNER] [--branch BRANCH]
104
- [--committers [COMMITTERS ...]] [--pr-number PR_NUMBER] [--commit-message COMMIT_MESSAGE] [--commit-sha COMMIT_SHA]
105
- [--target-path TARGET_PATH] [--sbom-file SBOM_FILE] [--files FILES] [--save-submitted-files-list SAVE_SUBMITTED_FILES_LIST]
106
- [--default-branch] [--pending-head] [--generate-license] [--enable-debug] [--enable-json] [--enable-sarif]
107
- [--disable-overview] [--disable-security-issue] [--allow-unverified] [--ignore-commit-files] [--disable-blocking]
108
- [--scm SCM] [--timeout TIMEOUT] [--exclude-license-details]
147
+ socketcli [-h] [--api-token API_TOKEN] [--repo REPO] [--repo-is-public] [--branch BRANCH] [--integration {api,github,gitlab,azure,bitbucket}]
148
+ [--owner OWNER] [--pr-number PR_NUMBER] [--commit-message COMMIT_MESSAGE] [--commit-sha COMMIT_SHA] [--committers [COMMITTERS ...]]
149
+ [--target-path TARGET_PATH] [--sbom-file SBOM_FILE] [--license-file-name LICENSE_FILE_NAME] [--save-submitted-files-list SAVE_SUBMITTED_FILES_LIST]
150
+ [--save-manifest-tar SAVE_MANIFEST_TAR] [--files FILES] [--sub-path SUB_PATH] [--workspace-name WORKSPACE_NAME]
151
+ [--excluded-ecosystems EXCLUDED_ECOSYSTEMS] [--default-branch] [--pending-head] [--generate-license] [--enable-debug]
152
+ [--enable-json] [--enable-sarif] [--disable-overview] [--exclude-license-details] [--allow-unverified] [--disable-security-issue]
153
+ [--ignore-commit-files] [--disable-blocking] [--enable-diff] [--scm SCM] [--timeout TIMEOUT] [--include-module-folders] [--version]
109
154
  ````
110
155
 
111
156
  If you don't want to provide the Socket API Token every time then you can use the environment variable `SOCKET_SECURITY_API_KEY`
@@ -121,11 +166,11 @@ If you don't want to provide the Socket API Token every time then you can use th
121
166
  | Parameter | Required | Default | Description |
122
167
  |:-----------------|:---------|:--------|:------------------------------------------------------------------------|
123
168
  | --repo | False | *auto* | Repository name in owner/repo format (auto-detected from git remote) |
124
- | --integration | False | api | Integration type (api, github, gitlab) |
169
+ | --repo-is-public | False | False | If set, flags a new repository creation as public. Defaults to false. |
170
+ | --integration | False | api | Integration type (api, github, gitlab, azure, bitbucket) |
125
171
  | --owner | False | | Name of the integration owner, defaults to the socket organization slug |
126
172
  | --branch | False | *auto* | Branch name (auto-detected from git) |
127
173
  | --committers | False | *auto* | Committer(s) to filter by (auto-detected from git commit) |
128
- | --repo-is-public | False | False | If set, flags a new repository creation as public. Defaults to false. |
129
174
 
130
175
  #### Pull Request and Commit
131
176
  | Parameter | Required | Default | Description |
@@ -139,17 +184,20 @@ If you don't want to provide the Socket API Token every time then you can use th
139
184
  |:----------------------------|:---------|:----------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
140
185
  | --target-path | False | ./ | Target path for analysis |
141
186
  | --sbom-file | False | | SBOM file path |
142
- | --files | False | *auto* | Files to analyze (JSON array string). Auto-detected from git commit changes when not specified |
143
- | --excluded-ecosystems | False | [] | List of ecosystems to exclude from analysis (JSON array string). You can get supported files from the [Supported Files API](https://docs.socket.dev/reference/getsupportedfiles) |
144
187
  | --license-file-name | False | `license_output.json` | Name of the file to save the license details to if enabled |
145
188
  | --save-submitted-files-list | False | | Save list of submitted file names to JSON file for debugging purposes |
146
189
  | --save-manifest-tar | False | | Save all manifest files to a compressed tar.gz archive with original directory structure |
190
+ | --files | False | *auto* | Files to analyze (JSON array string). Auto-detected from git commit changes when not specified |
191
+ | --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 |
192
+ | --workspace-name | False | | Workspace name suffix to append to repository name (repo-name-workspace_name). Must be used with --sub-path |
193
+ | --excluded-ecosystems | False | [] | List of ecosystems to exclude from analysis (JSON array string). You can get supported files from the [Supported Files API](https://docs.socket.dev/reference/getsupportedfiles) |
147
194
 
148
195
  #### Branch and Scan Configuration
149
- | Parameter | Required | Default | Description |
150
- |:-----------------|:---------|:--------|:------------------------------------------------------------------------------------------------------|
151
- | --default-branch | False | *auto* | Make this branch the default branch (auto-detected from git and CI environment when not specified) |
152
- | --pending-head | False | *auto* | If true, the new scan will be set as the branch's head scan (automatically synced with default-branch) |
196
+ | Parameter | Required | Default | Description |
197
+ |:-------------------------|:---------|:--------|:------------------------------------------------------------------------------------------------------|
198
+ | --default-branch | False | *auto* | Make this branch the default branch (auto-detected from git and CI environment when not specified) |
199
+ | --pending-head | False | *auto* | If true, the new scan will be set as the branch's head scan (automatically synced with default-branch) |
200
+ | --include-module-folders | False | False | If enabled will include manifest files from folders like node_modules |
153
201
 
154
202
  #### Output Configuration
155
203
  | Parameter | Required | Default | Description |
@@ -160,6 +208,7 @@ If you don't want to provide the Socket API Token every time then you can use th
160
208
  | --enable-sarif | False | False | Enable SARIF output of results instead of table or JSON format |
161
209
  | --disable-overview | False | False | Disable overview output |
162
210
  | --exclude-license-details | False | False | Exclude license details from the diff report (boosts performance for large repos) |
211
+ | --version | False | False | Show program's version number and exit |
163
212
 
164
213
  #### Security Configuration
165
214
  | Parameter | Required | Default | Description |
@@ -175,7 +224,6 @@ If you don't want to provide the Socket API Token every time then you can use th
175
224
  | --enable-diff | False | False | Enable diff mode even when using --integration api (forces diff mode without SCM integration) |
176
225
  | --scm | False | api | Source control management type |
177
226
  | --timeout | False | | Timeout in seconds for API requests |
178
- | --include-module-folders | False | False | If enabled will include manifest files from folders like node_modules |
179
227
 
180
228
  #### Plugins
181
229
 
@@ -41,15 +41,60 @@ Pre-configured workflow examples are available in the [`workflows/`](workflows/)
41
41
 
42
42
  These examples are production-ready and include best practices for each platform.
43
43
 
44
+ ## Monorepo Workspace Support
45
+
46
+ 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.
47
+
48
+ ### Key Features
49
+
50
+ - **Multiple Sub-paths**: Specify multiple `--sub-path` options to scan different directories within your monorepo
51
+ - **Combined Workspace**: All sub-paths are scanned together as a single workspace in Socket
52
+ - **Git Context Preserved**: Repository metadata (commits, branches, etc.) comes from the main target-path
53
+ - **Workspace Naming**: Use `--workspace-name` to differentiate scans from different parts of your monorepo
54
+
55
+ ### Usage Examples
56
+
57
+ **Scan multiple frontend and backend workspaces:**
58
+ ```bash
59
+ socketcli --target-path /path/to/monorepo \
60
+ --sub-path frontend \
61
+ --sub-path backend \
62
+ --sub-path services/api \
63
+ --workspace-name main-app
64
+ ```
65
+
66
+ **GitHub Actions for monorepo workspace:**
67
+ ```bash
68
+ socketcli --target-path $GITHUB_WORKSPACE \
69
+ --sub-path packages/web \
70
+ --sub-path packages/mobile \
71
+ --workspace-name mobile-web \
72
+ --scm github \
73
+ --pr-number $PR_NUMBER
74
+ ```
75
+
76
+ This will:
77
+ - Scan manifest files in `./packages/web/` and `./packages/mobile/`
78
+ - Combine them into a single workspace scan
79
+ - Create a repository in Socket named like `my-repo-mobile-web`
80
+ - Preserve git context (commits, branch info) from the repository root
81
+
82
+ ### Requirements
83
+
84
+ - Both `--sub-path` and `--workspace-name` must be specified together
85
+ - `--sub-path` can be used multiple times to include multiple directories
86
+ - All specified sub-paths must exist within the target-path
87
+
44
88
  ## Usage
45
89
 
46
90
  ```` shell
47
- socketcli [-h] [--api-token API_TOKEN] [--repo REPO] [--integration {api,github,gitlab}] [--owner OWNER] [--branch BRANCH]
48
- [--committers [COMMITTERS ...]] [--pr-number PR_NUMBER] [--commit-message COMMIT_MESSAGE] [--commit-sha COMMIT_SHA]
49
- [--target-path TARGET_PATH] [--sbom-file SBOM_FILE] [--files FILES] [--save-submitted-files-list SAVE_SUBMITTED_FILES_LIST]
50
- [--default-branch] [--pending-head] [--generate-license] [--enable-debug] [--enable-json] [--enable-sarif]
51
- [--disable-overview] [--disable-security-issue] [--allow-unverified] [--ignore-commit-files] [--disable-blocking]
52
- [--scm SCM] [--timeout TIMEOUT] [--exclude-license-details]
91
+ socketcli [-h] [--api-token API_TOKEN] [--repo REPO] [--repo-is-public] [--branch BRANCH] [--integration {api,github,gitlab,azure,bitbucket}]
92
+ [--owner OWNER] [--pr-number PR_NUMBER] [--commit-message COMMIT_MESSAGE] [--commit-sha COMMIT_SHA] [--committers [COMMITTERS ...]]
93
+ [--target-path TARGET_PATH] [--sbom-file SBOM_FILE] [--license-file-name LICENSE_FILE_NAME] [--save-submitted-files-list SAVE_SUBMITTED_FILES_LIST]
94
+ [--save-manifest-tar SAVE_MANIFEST_TAR] [--files FILES] [--sub-path SUB_PATH] [--workspace-name WORKSPACE_NAME]
95
+ [--excluded-ecosystems EXCLUDED_ECOSYSTEMS] [--default-branch] [--pending-head] [--generate-license] [--enable-debug]
96
+ [--enable-json] [--enable-sarif] [--disable-overview] [--exclude-license-details] [--allow-unverified] [--disable-security-issue]
97
+ [--ignore-commit-files] [--disable-blocking] [--enable-diff] [--scm SCM] [--timeout TIMEOUT] [--include-module-folders] [--version]
53
98
  ````
54
99
 
55
100
  If you don't want to provide the Socket API Token every time then you can use the environment variable `SOCKET_SECURITY_API_KEY`
@@ -65,11 +110,11 @@ If you don't want to provide the Socket API Token every time then you can use th
65
110
  | Parameter | Required | Default | Description |
66
111
  |:-----------------|:---------|:--------|:------------------------------------------------------------------------|
67
112
  | --repo | False | *auto* | Repository name in owner/repo format (auto-detected from git remote) |
68
- | --integration | False | api | Integration type (api, github, gitlab) |
113
+ | --repo-is-public | False | False | If set, flags a new repository creation as public. Defaults to false. |
114
+ | --integration | False | api | Integration type (api, github, gitlab, azure, bitbucket) |
69
115
  | --owner | False | | Name of the integration owner, defaults to the socket organization slug |
70
116
  | --branch | False | *auto* | Branch name (auto-detected from git) |
71
117
  | --committers | False | *auto* | Committer(s) to filter by (auto-detected from git commit) |
72
- | --repo-is-public | False | False | If set, flags a new repository creation as public. Defaults to false. |
73
118
 
74
119
  #### Pull Request and Commit
75
120
  | Parameter | Required | Default | Description |
@@ -83,17 +128,20 @@ If you don't want to provide the Socket API Token every time then you can use th
83
128
  |:----------------------------|:---------|:----------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
84
129
  | --target-path | False | ./ | Target path for analysis |
85
130
  | --sbom-file | False | | SBOM file path |
86
- | --files | False | *auto* | Files to analyze (JSON array string). Auto-detected from git commit changes when not specified |
87
- | --excluded-ecosystems | False | [] | List of ecosystems to exclude from analysis (JSON array string). You can get supported files from the [Supported Files API](https://docs.socket.dev/reference/getsupportedfiles) |
88
131
  | --license-file-name | False | `license_output.json` | Name of the file to save the license details to if enabled |
89
132
  | --save-submitted-files-list | False | | Save list of submitted file names to JSON file for debugging purposes |
90
133
  | --save-manifest-tar | False | | Save all manifest files to a compressed tar.gz archive with original directory structure |
134
+ | --files | False | *auto* | Files to analyze (JSON array string). Auto-detected from git commit changes when not specified |
135
+ | --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 |
136
+ | --workspace-name | False | | Workspace name suffix to append to repository name (repo-name-workspace_name). Must be used with --sub-path |
137
+ | --excluded-ecosystems | False | [] | List of ecosystems to exclude from analysis (JSON array string). You can get supported files from the [Supported Files API](https://docs.socket.dev/reference/getsupportedfiles) |
91
138
 
92
139
  #### Branch and Scan Configuration
93
- | Parameter | Required | Default | Description |
94
- |:-----------------|:---------|:--------|:------------------------------------------------------------------------------------------------------|
95
- | --default-branch | False | *auto* | Make this branch the default branch (auto-detected from git and CI environment when not specified) |
96
- | --pending-head | False | *auto* | If true, the new scan will be set as the branch's head scan (automatically synced with default-branch) |
140
+ | Parameter | Required | Default | Description |
141
+ |:-------------------------|:---------|:--------|:------------------------------------------------------------------------------------------------------|
142
+ | --default-branch | False | *auto* | Make this branch the default branch (auto-detected from git and CI environment when not specified) |
143
+ | --pending-head | False | *auto* | If true, the new scan will be set as the branch's head scan (automatically synced with default-branch) |
144
+ | --include-module-folders | False | False | If enabled will include manifest files from folders like node_modules |
97
145
 
98
146
  #### Output Configuration
99
147
  | Parameter | Required | Default | Description |
@@ -104,6 +152,7 @@ If you don't want to provide the Socket API Token every time then you can use th
104
152
  | --enable-sarif | False | False | Enable SARIF output of results instead of table or JSON format |
105
153
  | --disable-overview | False | False | Disable overview output |
106
154
  | --exclude-license-details | False | False | Exclude license details from the diff report (boosts performance for large repos) |
155
+ | --version | False | False | Show program's version number and exit |
107
156
 
108
157
  #### Security Configuration
109
158
  | Parameter | Required | Default | Description |
@@ -119,7 +168,6 @@ If you don't want to provide the Socket API Token every time then you can use th
119
168
  | --enable-diff | False | False | Enable diff mode even when using --integration api (forces diff mode without SCM integration) |
120
169
  | --scm | False | api | Source control management type |
121
170
  | --timeout | False | | Timeout in seconds for API requests |
122
- | --include-module-folders | False | False | If enabled will include manifest files from folders like node_modules |
123
171
 
124
172
  #### Plugins
125
173
 
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
6
6
 
7
7
  [project]
8
8
  name = "socketsecurity"
9
- version = "2.2.9"
9
+ version = "2.2.11"
10
10
  requires-python = ">= 3.10"
11
11
  license = {"file" = "LICENSE"}
12
12
  dependencies = [
@@ -16,7 +16,7 @@ dependencies = [
16
16
  'GitPython',
17
17
  'packaging',
18
18
  'python-dotenv',
19
- 'socketdev>=3.0.5,<4.0.0'
19
+ 'socketdev>=3.0.6,<4.0.0'
20
20
  ]
21
21
  readme = "README.md"
22
22
  description = "Socket Security CLI for CI/CD"
@@ -1,2 +1,2 @@
1
1
  __author__ = 'socket.dev'
2
- __version__ = '2.2.9'
2
+ __version__ = '2.2.11'
@@ -60,7 +60,7 @@ class CliConfig:
60
60
  license_file_name: str = "license_output.json"
61
61
  save_submitted_files_list: Optional[str] = None
62
62
  save_manifest_tar: Optional[str] = None
63
- sub_path: Optional[str] = None
63
+ sub_paths: List[str] = field(default_factory=list)
64
64
  workspace_name: Optional[str] = None
65
65
 
66
66
  @classmethod
@@ -108,7 +108,7 @@ class CliConfig:
108
108
  'license_file_name': args.license_file_name,
109
109
  'save_submitted_files_list': args.save_submitted_files_list,
110
110
  'save_manifest_tar': args.save_manifest_tar,
111
- 'sub_path': args.sub_path,
111
+ 'sub_paths': args.sub_paths or [],
112
112
  'workspace_name': args.workspace_name,
113
113
  'version': __version__
114
114
  }
@@ -133,11 +133,11 @@ class CliConfig:
133
133
  if args.owner:
134
134
  config_args['integration_org_slug'] = args.owner
135
135
 
136
- # Validate that sub_path and workspace_name are used together
137
- if args.sub_path and not args.workspace_name:
136
+ # Validate that sub_paths and workspace_name are used together
137
+ if args.sub_paths and not args.workspace_name:
138
138
  logging.error("--sub-path requires --workspace-name to be specified")
139
139
  exit(1)
140
- if args.workspace_name and not args.sub_path:
140
+ if args.workspace_name and not args.sub_paths:
141
141
  logging.error("--workspace-name requires --sub-path to be specified")
142
142
  exit(1)
143
143
 
@@ -299,9 +299,10 @@ def create_argument_parser() -> argparse.ArgumentParser:
299
299
  )
300
300
  path_group.add_argument(
301
301
  "--sub-path",
302
- dest="sub_path",
302
+ dest="sub_paths",
303
303
  metavar="<path>",
304
- help="Sub-path within target-path for manifest file scanning (while preserving git context from target-path)"
304
+ action="append",
305
+ help="Sub-path within target-path for manifest file scanning (can be specified multiple times). All sub-paths will be combined into a single workspace scan while preserving git context from target-path"
305
306
  )
306
307
  path_group.add_argument(
307
308
  "--workspace-name",
@@ -451,14 +451,14 @@ class Core:
451
451
  log.debug(f"Created temporary empty file for baseline scan: {temp_path}")
452
452
  return [temp_path]
453
453
 
454
- def create_full_scan(self, files: List[str], params: FullScanParams, base_path: str = None) -> FullScan:
454
+ def create_full_scan(self, files: List[str], params: FullScanParams, base_paths: List[str] = None) -> FullScan:
455
455
  """
456
456
  Creates a new full scan via the Socket API.
457
457
 
458
458
  Args:
459
459
  files: List of file paths to scan
460
460
  params: Parameters for the full scan
461
- base_path: Base path for the scan (optional)
461
+ base_paths: List of base paths for the scan (optional)
462
462
 
463
463
  Returns:
464
464
  FullScan object with scan results
@@ -466,7 +466,7 @@ class Core:
466
466
  log.info("Creating new full scan")
467
467
  create_full_start = time.time()
468
468
 
469
- res = self.sdk.fullscans.post(files, params, use_types=True, use_lazy_loading=True, max_open_files=50, base_path=base_path)
469
+ res = self.sdk.fullscans.post(files, params, use_types=True, use_lazy_loading=True, max_open_files=50, base_paths=base_paths)
470
470
  if not res.success:
471
471
  log.error(f"Error creating full scan: {res.message}, status: {res.status}")
472
472
  raise Exception(f"Error creating full scan: {res.message}, status: {res.status}")
@@ -480,20 +480,22 @@ class Core:
480
480
 
481
481
  def create_full_scan_with_report_url(
482
482
  self,
483
- path: str,
483
+ paths: List[str],
484
484
  params: FullScanParams,
485
485
  no_change: bool = False,
486
486
  save_files_list_path: str = None,
487
- save_manifest_tar_path: str = None
487
+ save_manifest_tar_path: str = None,
488
+ base_paths: List[str] = None
488
489
  ) -> Diff:
489
490
  """Create a new full scan and return with html_report_url.
490
491
 
491
492
  Args:
492
- path: Path to look for manifest files
493
+ paths: List of paths to look for manifest files
493
494
  params: Query params for the Full Scan endpoint
494
495
  no_change: If True, return empty result
495
496
  save_files_list_path: Optional path to save submitted files list for debugging
496
497
  save_manifest_tar_path: Optional path to save manifest files tar.gz archive
498
+ base_paths: List of base paths for the scan (optional)
497
499
 
498
500
  Returns:
499
501
  Dict with full scan data including html_report_url
@@ -507,24 +509,27 @@ class Core:
507
509
  if no_change:
508
510
  return diff
509
511
 
510
- # Find manifest files
511
- files = self.find_files(path)
512
+ # Find manifest files from all paths
513
+ all_files = []
514
+ for path in paths:
515
+ files = self.find_files(path)
516
+ all_files.extend(files)
512
517
 
513
518
  # Save submitted files list if requested
514
- if save_files_list_path and files:
515
- self.save_submitted_files_list(files, save_files_list_path)
519
+ if save_files_list_path and all_files:
520
+ self.save_submitted_files_list(all_files, save_files_list_path)
516
521
 
517
- # Save manifest tar.gz if requested
518
- if save_manifest_tar_path and files:
519
- self.save_manifest_tar(files, save_manifest_tar_path, path)
522
+ # Save manifest tar.gz if requested (use first path as base)
523
+ if save_manifest_tar_path and all_files and paths:
524
+ self.save_manifest_tar(all_files, save_manifest_tar_path, paths[0])
520
525
 
521
- if not files:
526
+ if not all_files:
522
527
  return diff
523
528
 
524
529
  try:
525
530
  # Create new scan
526
531
  new_scan_start = time.time()
527
- new_full_scan = self.create_full_scan(files, params, base_path=path)
532
+ new_full_scan = self.create_full_scan(all_files, params, base_paths=base_paths)
528
533
  new_scan_end = time.time()
529
534
  log.info(f"Total time to create new full scan: {new_scan_end - new_scan_start:.2f}")
530
535
  except APIFailure as e:
@@ -847,37 +852,42 @@ class Core:
847
852
 
848
853
  def create_new_diff(
849
854
  self,
850
- path: str,
855
+ paths: List[str],
851
856
  params: FullScanParams,
852
857
  no_change: bool = False,
853
858
  save_files_list_path: str = None,
854
- save_manifest_tar_path: str = None
859
+ save_manifest_tar_path: str = None,
860
+ base_paths: List[str] = None
855
861
  ) -> Diff:
856
862
  """Create a new diff using the Socket SDK.
857
863
 
858
864
  Args:
859
- path: Path to look for manifest files
865
+ paths: List of paths to look for manifest files
860
866
  params: Query params for the Full Scan endpoint
861
867
  no_change: If True, return empty diff
862
868
  save_files_list_path: Optional path to save submitted files list for debugging
863
869
  save_manifest_tar_path: Optional path to save manifest files tar.gz archive
870
+ base_paths: List of base paths for the scan (optional)
864
871
  """
865
872
  log.debug(f"starting create_new_diff with no_change: {no_change}")
866
873
  if no_change:
867
874
  return Diff(id="NO_DIFF_RAN", diff_url="", report_url="")
868
875
 
869
- # Find manifest files
870
- files = self.find_files(path)
876
+ # Find manifest files from all paths
877
+ all_files = []
878
+ for path in paths:
879
+ files = self.find_files(path)
880
+ all_files.extend(files)
871
881
 
872
882
  # Save submitted files list if requested
873
- if save_files_list_path and files:
874
- self.save_submitted_files_list(files, save_files_list_path)
883
+ if save_files_list_path and all_files:
884
+ self.save_submitted_files_list(all_files, save_files_list_path)
875
885
 
876
- # Save manifest tar.gz if requested
877
- if save_manifest_tar_path and files:
878
- self.save_manifest_tar(files, save_manifest_tar_path, path)
886
+ # Save manifest tar.gz if requested (use first path as base)
887
+ if save_manifest_tar_path and all_files and paths:
888
+ self.save_manifest_tar(all_files, save_manifest_tar_path, paths[0])
879
889
 
880
- if not files:
890
+ if not all_files:
881
891
  return Diff(id="NO_DIFF_RAN", diff_url="", report_url="")
882
892
 
883
893
  try:
@@ -900,7 +910,7 @@ class Core:
900
910
  # Create baseline scan with empty file
901
911
  empty_files = Core.empty_head_scan_file()
902
912
  try:
903
- head_full_scan = self.create_full_scan(empty_files, tmp_params, base_path=path)
913
+ head_full_scan = self.create_full_scan(empty_files, tmp_params, base_paths=base_paths)
904
914
  head_full_scan_id = head_full_scan.id
905
915
  log.debug(f"Created empty baseline scan: {head_full_scan_id}")
906
916
 
@@ -923,7 +933,7 @@ class Core:
923
933
  # Create new scan
924
934
  try:
925
935
  new_scan_start = time.time()
926
- new_full_scan = self.create_full_scan(files, params, base_path=path)
936
+ new_full_scan = self.create_full_scan(all_files, params, base_paths=base_paths)
927
937
  new_scan_end = time.time()
928
938
  log.info(f"Total time to create new full scan: {new_scan_end - new_scan_start:.2f}")
929
939
  except APIFailure as e:
@@ -147,15 +147,22 @@ def main_code():
147
147
  config.branch = "socket-default-branch"
148
148
  log.debug(f"Using default branch name: {config.branch}")
149
149
 
150
- # Calculate the scan path - combine target_path with sub_path if provided
151
- scan_path = config.target_path
152
- if config.sub_path:
150
+ # Calculate the scan paths - combine target_path with sub_paths if provided
151
+ scan_paths = []
152
+ base_paths = [config.target_path] # Always use target_path as the single base path
153
+
154
+ if config.sub_paths:
153
155
  import os
154
- scan_path = os.path.join(config.target_path, config.sub_path)
155
- log.debug(f"Using sub-path for scanning: {scan_path}")
156
- # Verify the scan path exists
157
- if not os.path.exists(scan_path):
158
- raise Exception(f"Sub-path does not exist: {scan_path}")
156
+ for sub_path in config.sub_paths:
157
+ full_scan_path = os.path.join(config.target_path, sub_path)
158
+ log.debug(f"Using sub-path for scanning: {full_scan_path}")
159
+ # Verify the scan path exists
160
+ if not os.path.exists(full_scan_path):
161
+ raise Exception(f"Sub-path does not exist: {full_scan_path}")
162
+ scan_paths.append(full_scan_path)
163
+ else:
164
+ # Use the target path as the single scan path
165
+ scan_paths = [config.target_path]
159
166
 
160
167
  # Modify repository name if workspace_name is provided
161
168
  if config.workspace_name and config.repo:
@@ -201,19 +208,22 @@ def main_code():
201
208
  # Check if we have supported manifest files
202
209
  has_supported_files = files_to_check and core.has_manifest_files(files_to_check)
203
210
 
204
- # If using sub_path, we need to check if manifest files exist in the scan path
205
- if config.sub_path and not files_explicitly_specified:
206
- # Override file checking to look in the scan path instead
211
+ # If using sub_paths, we need to check if manifest files exist in the scan paths
212
+ if config.sub_paths and not files_explicitly_specified:
213
+ # Override file checking to look in the scan paths instead
207
214
  import os
208
215
  from pathlib import Path
209
216
 
210
- # Get manifest files from the scan path
217
+ # Get manifest files from all scan paths
211
218
  try:
212
- scan_files = core.find_files(scan_path)
213
- has_supported_files = len(scan_files) > 0
214
- log.debug(f"Found {len(scan_files)} manifest files in scan path: {scan_path}")
219
+ all_scan_files = []
220
+ for scan_path in scan_paths:
221
+ scan_files = core.find_files(scan_path)
222
+ all_scan_files.extend(scan_files)
223
+ has_supported_files = len(all_scan_files) > 0
224
+ log.debug(f"Found {len(all_scan_files)} manifest files across {len(scan_paths)} scan paths")
215
225
  except Exception as e:
216
- log.debug(f"Error finding files in scan path {scan_path}: {e}")
226
+ log.debug(f"Error finding files in scan paths: {e}")
217
227
  has_supported_files = False
218
228
 
219
229
  # Case 3: If no supported files or files are empty, force API mode (no PR comments)
@@ -301,7 +311,7 @@ def main_code():
301
311
  log.info("Push initiated flow")
302
312
  if scm.check_event_type() == "diff":
303
313
  log.info("Starting comment logic for PR/MR event")
304
- diff = core.create_new_diff(scan_path, params, no_change=should_skip_scan, save_files_list_path=config.save_submitted_files_list, save_manifest_tar_path=config.save_manifest_tar)
314
+ diff = core.create_new_diff(scan_paths, params, no_change=should_skip_scan, save_files_list_path=config.save_submitted_files_list, save_manifest_tar_path=config.save_manifest_tar, base_paths=base_paths)
305
315
  comments = scm.get_comments_for_pr()
306
316
  log.debug("Removing comment alerts")
307
317
 
@@ -354,14 +364,14 @@ def main_code():
354
364
  )
355
365
  else:
356
366
  log.info("Starting non-PR/MR flow")
357
- diff = core.create_new_diff(scan_path, params, no_change=should_skip_scan, save_files_list_path=config.save_submitted_files_list, save_manifest_tar_path=config.save_manifest_tar)
367
+ diff = core.create_new_diff(scan_paths, params, no_change=should_skip_scan, save_files_list_path=config.save_submitted_files_list, save_manifest_tar_path=config.save_manifest_tar, base_paths=base_paths)
358
368
 
359
369
  output_handler.handle_output(diff)
360
370
 
361
371
  elif config.enable_diff and not force_api_mode:
362
372
  # New logic: --enable-diff forces diff mode even with --integration api (no SCM)
363
373
  log.info("Diff mode enabled without SCM integration")
364
- diff = core.create_new_diff(scan_path, params, no_change=should_skip_scan, save_files_list_path=config.save_submitted_files_list, save_manifest_tar_path=config.save_manifest_tar)
374
+ diff = core.create_new_diff(scan_paths, params, no_change=should_skip_scan, save_files_list_path=config.save_submitted_files_list, save_manifest_tar_path=config.save_manifest_tar, base_paths=base_paths)
365
375
  output_handler.handle_output(diff)
366
376
 
367
377
  elif config.enable_diff and force_api_mode:
@@ -374,11 +384,12 @@ def main_code():
374
384
  }
375
385
  log.debug(f"params={serializable_params}")
376
386
  diff = core.create_full_scan_with_report_url(
377
- scan_path,
387
+ scan_paths,
378
388
  params,
379
389
  no_change=should_skip_scan,
380
390
  save_files_list_path=config.save_submitted_files_list,
381
- save_manifest_tar_path=config.save_manifest_tar
391
+ save_manifest_tar_path=config.save_manifest_tar,
392
+ base_paths=base_paths
382
393
  )
383
394
  log.info(f"Full scan created with ID: {diff.id}")
384
395
  log.info(f"Full scan report URL: {diff.report_url}")
@@ -393,21 +404,23 @@ def main_code():
393
404
  }
394
405
  log.debug(f"params={serializable_params}")
395
406
  diff = core.create_full_scan_with_report_url(
396
- scan_path,
407
+ scan_paths,
397
408
  params,
398
409
  no_change=should_skip_scan,
399
410
  save_files_list_path=config.save_submitted_files_list,
400
- save_manifest_tar_path=config.save_manifest_tar
411
+ save_manifest_tar_path=config.save_manifest_tar,
412
+ base_paths=base_paths
401
413
  )
402
414
  log.info(f"Full scan created with ID: {diff.id}")
403
415
  log.info(f"Full scan report URL: {diff.report_url}")
404
416
  else:
405
417
  log.info("API Mode")
406
418
  diff = core.create_new_diff(
407
- scan_path, params,
419
+ scan_paths, params,
408
420
  no_change=should_skip_scan,
409
421
  save_files_list_path=config.save_submitted_files_list,
410
- save_manifest_tar_path=config.save_manifest_tar
422
+ save_manifest_tar_path=config.save_manifest_tar,
423
+ base_paths=base_paths
411
424
  )
412
425
  output_handler.handle_output(diff)
413
426
 
File without changes
File without changes
File without changes