socketsecurity 2.2.8__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.8 → socketsecurity-2.2.11}/PKG-INFO +65 -17
  2. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/README.md +63 -15
  3. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/pyproject.toml +2 -2
  4. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/__init__.py +1 -1
  5. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/config.py +25 -0
  6. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/core/__init__.py +38 -28
  7. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/socketcli.py +60 -10
  8. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/.github/CODEOWNERS +0 -0
  9. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/.github/PULL_REQUEST_TEMPLATE/bug-fix.md +0 -0
  10. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/.github/PULL_REQUEST_TEMPLATE/feature.md +0 -0
  11. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/.github/PULL_REQUEST_TEMPLATE/improvement.md +0 -0
  12. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  13. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/.github/workflows/docker-stable.yml +0 -0
  14. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/.github/workflows/pr-preview.yml +0 -0
  15. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/.github/workflows/release.yml +0 -0
  16. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/.github/workflows/version-check.yml +0 -0
  17. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/.gitignore +0 -0
  18. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/.hooks/sync_version.py +0 -0
  19. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/.pre-commit-config.yaml +0 -0
  20. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/.python-version +0 -0
  21. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/Dockerfile +0 -0
  22. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/LICENSE +0 -0
  23. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/Makefile +0 -0
  24. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/Pipfile.lock +0 -0
  25. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/docs/README.md +0 -0
  26. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/pytest.ini +0 -0
  27. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/scripts/build_container.sh +0 -0
  28. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/scripts/deploy-test-docker.sh +0 -0
  29. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/scripts/deploy-test-pypi.sh +0 -0
  30. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/scripts/run.sh +0 -0
  31. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/core/classes.py +0 -0
  32. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/core/cli_client.py +0 -0
  33. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/core/exceptions.py +0 -0
  34. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/core/git_interface.py +0 -0
  35. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/core/helper/__init__.py +0 -0
  36. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/core/lazy_file_loader.py +0 -0
  37. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/core/logging.py +0 -0
  38. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/core/messages.py +0 -0
  39. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/core/resource_utils.py +0 -0
  40. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/core/scm/__init__.py +0 -0
  41. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/core/scm/base.py +0 -0
  42. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/core/scm/client.py +0 -0
  43. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/core/scm/github.py +0 -0
  44. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/core/scm/gitlab.py +0 -0
  45. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/core/scm_comments.py +0 -0
  46. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/core/socket_config.py +0 -0
  47. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/core/utils.py +0 -0
  48. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/output.py +0 -0
  49. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/plugins/__init__.py +0 -0
  50. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/plugins/base.py +0 -0
  51. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/plugins/jira.py +0 -0
  52. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/plugins/manager.py +0 -0
  53. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/plugins/slack.py +0 -0
  54. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/plugins/teams.py +0 -0
  55. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/socketsecurity/plugins/webhook.py +0 -0
  56. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/tests/__init__.py +0 -0
  57. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/tests/core/conftest.py +0 -0
  58. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/tests/core/create_diff_input.json +0 -0
  59. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/tests/core/test_diff_generation.py +0 -0
  60. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/tests/core/test_package_and_alerts.py +0 -0
  61. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/tests/core/test_sdk_methods.py +0 -0
  62. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/tests/core/test_supporting_methods.py +0 -0
  63. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/tests/data/fullscans/create_response.json +0 -0
  64. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/tests/data/fullscans/diff/stream_diff.json +0 -0
  65. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/tests/data/fullscans/diff/stream_diff_full.json +0 -0
  66. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/tests/data/fullscans/head_scan/metadata.json +0 -0
  67. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/tests/data/fullscans/head_scan/stream_scan.json +0 -0
  68. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/tests/data/fullscans/head_scan/stream_scan_full.json +0 -0
  69. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/tests/data/fullscans/new_scan/metadata.json +0 -0
  70. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/tests/data/fullscans/new_scan/stream_scan.json +0 -0
  71. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/tests/data/repos/repo_info_error.json +0 -0
  72. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/tests/data/repos/repo_info_no_head.json +0 -0
  73. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/tests/data/repos/repo_info_success.json +0 -0
  74. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/tests/data/settings/security-policy.json +0 -0
  75. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/tests/unit/__init__.py +0 -0
  76. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/tests/unit/test_cli_config.py +0 -0
  77. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/tests/unit/test_client.py +0 -0
  78. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/tests/unit/test_config.py +0 -0
  79. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/tests/unit/test_gitlab_auth.py +0 -0
  80. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/tests/unit/test_gitlab_auth_fallback.py +0 -0
  81. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/tests/unit/test_output.py +0 -0
  82. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/uv.lock +0 -0
  83. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/workflows/bitbucket-pipelines.yml +0 -0
  84. {socketsecurity-2.2.8 → socketsecurity-2.2.11}/workflows/github-actions.yml +0 -0
  85. {socketsecurity-2.2.8 → 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.8
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.8"
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.8'
2
+ __version__ = '2.2.11'
@@ -60,6 +60,8 @@ 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_paths: List[str] = field(default_factory=list)
64
+ workspace_name: Optional[str] = None
63
65
 
64
66
  @classmethod
65
67
  def from_args(cls, args_list: Optional[List[str]] = None) -> 'CliConfig':
@@ -106,6 +108,8 @@ class CliConfig:
106
108
  'license_file_name': args.license_file_name,
107
109
  'save_submitted_files_list': args.save_submitted_files_list,
108
110
  'save_manifest_tar': args.save_manifest_tar,
111
+ 'sub_paths': args.sub_paths or [],
112
+ 'workspace_name': args.workspace_name,
109
113
  'version': __version__
110
114
  }
111
115
  try:
@@ -129,6 +133,14 @@ class CliConfig:
129
133
  if args.owner:
130
134
  config_args['integration_org_slug'] = args.owner
131
135
 
136
+ # Validate that sub_paths and workspace_name are used together
137
+ if args.sub_paths and not args.workspace_name:
138
+ logging.error("--sub-path requires --workspace-name to be specified")
139
+ exit(1)
140
+ if args.workspace_name and not args.sub_paths:
141
+ logging.error("--workspace-name requires --sub-path to be specified")
142
+ exit(1)
143
+
132
144
  return cls(**config_args)
133
145
 
134
146
  def to_dict(self) -> dict:
@@ -285,6 +297,19 @@ def create_argument_parser() -> argparse.ArgumentParser:
285
297
  default="[]",
286
298
  help="Files to analyze (JSON array string)"
287
299
  )
300
+ path_group.add_argument(
301
+ "--sub-path",
302
+ dest="sub_paths",
303
+ metavar="<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"
306
+ )
307
+ path_group.add_argument(
308
+ "--workspace-name",
309
+ dest="workspace_name",
310
+ metavar="<name>",
311
+ help="Workspace name suffix to append to repository name (repo-name-workspace_name)"
312
+ )
288
313
 
289
314
  path_group.add_argument(
290
315
  "--excluded-ecosystems",
@@ -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:
@@ -136,13 +136,42 @@ def main_code():
136
136
  raise Exception(f"Unable to find path {config.target_path}")
137
137
 
138
138
  if not config.repo:
139
- config.repo = "socket-default-repo"
139
+ base_repo_name = "socket-default-repo"
140
+ if config.workspace_name:
141
+ config.repo = f"{base_repo_name}-{config.workspace_name}"
142
+ else:
143
+ config.repo = base_repo_name
140
144
  log.debug(f"Using default repository name: {config.repo}")
141
145
 
142
146
  if not config.branch:
143
147
  config.branch = "socket-default-branch"
144
148
  log.debug(f"Using default branch name: {config.branch}")
145
149
 
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:
155
+ import os
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]
166
+
167
+ # Modify repository name if workspace_name is provided
168
+ if config.workspace_name and config.repo:
169
+ config.repo = f"{config.repo}-{config.workspace_name}"
170
+ log.debug(f"Modified repository name with workspace suffix: {config.repo}")
171
+ elif config.workspace_name and not config.repo:
172
+ # If no repo name was set but workspace_name is provided, we'll use it later
173
+ log.debug(f"Workspace name provided: {config.workspace_name}")
174
+
146
175
  scm = None
147
176
  if config.scm == "github":
148
177
  from socketsecurity.core.scm.github import Github, GithubConfig
@@ -179,6 +208,24 @@ def main_code():
179
208
  # Check if we have supported manifest files
180
209
  has_supported_files = files_to_check and core.has_manifest_files(files_to_check)
181
210
 
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
214
+ import os
215
+ from pathlib import Path
216
+
217
+ # Get manifest files from all scan paths
218
+ try:
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")
225
+ except Exception as e:
226
+ log.debug(f"Error finding files in scan paths: {e}")
227
+ has_supported_files = False
228
+
182
229
  # Case 3: If no supported files or files are empty, force API mode (no PR comments)
183
230
  if not has_supported_files:
184
231
  force_api_mode = True
@@ -264,7 +311,7 @@ def main_code():
264
311
  log.info("Push initiated flow")
265
312
  if scm.check_event_type() == "diff":
266
313
  log.info("Starting comment logic for PR/MR event")
267
- diff = core.create_new_diff(config.target_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)
268
315
  comments = scm.get_comments_for_pr()
269
316
  log.debug("Removing comment alerts")
270
317
 
@@ -317,14 +364,14 @@ def main_code():
317
364
  )
318
365
  else:
319
366
  log.info("Starting non-PR/MR flow")
320
- diff = core.create_new_diff(config.target_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)
321
368
 
322
369
  output_handler.handle_output(diff)
323
370
 
324
371
  elif config.enable_diff and not force_api_mode:
325
372
  # New logic: --enable-diff forces diff mode even with --integration api (no SCM)
326
373
  log.info("Diff mode enabled without SCM integration")
327
- diff = core.create_new_diff(config.target_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)
328
375
  output_handler.handle_output(diff)
329
376
 
330
377
  elif config.enable_diff and force_api_mode:
@@ -337,11 +384,12 @@ def main_code():
337
384
  }
338
385
  log.debug(f"params={serializable_params}")
339
386
  diff = core.create_full_scan_with_report_url(
340
- config.target_path,
387
+ scan_paths,
341
388
  params,
342
389
  no_change=should_skip_scan,
343
390
  save_files_list_path=config.save_submitted_files_list,
344
- save_manifest_tar_path=config.save_manifest_tar
391
+ save_manifest_tar_path=config.save_manifest_tar,
392
+ base_paths=base_paths
345
393
  )
346
394
  log.info(f"Full scan created with ID: {diff.id}")
347
395
  log.info(f"Full scan report URL: {diff.report_url}")
@@ -356,21 +404,23 @@ def main_code():
356
404
  }
357
405
  log.debug(f"params={serializable_params}")
358
406
  diff = core.create_full_scan_with_report_url(
359
- config.target_path,
407
+ scan_paths,
360
408
  params,
361
409
  no_change=should_skip_scan,
362
410
  save_files_list_path=config.save_submitted_files_list,
363
- save_manifest_tar_path=config.save_manifest_tar
411
+ save_manifest_tar_path=config.save_manifest_tar,
412
+ base_paths=base_paths
364
413
  )
365
414
  log.info(f"Full scan created with ID: {diff.id}")
366
415
  log.info(f"Full scan report URL: {diff.report_url}")
367
416
  else:
368
417
  log.info("API Mode")
369
418
  diff = core.create_new_diff(
370
- config.target_path, params,
419
+ scan_paths, params,
371
420
  no_change=should_skip_scan,
372
421
  save_files_list_path=config.save_submitted_files_list,
373
- save_manifest_tar_path=config.save_manifest_tar
422
+ save_manifest_tar_path=config.save_manifest_tar,
423
+ base_paths=base_paths
374
424
  )
375
425
  output_handler.handle_output(diff)
376
426
 
File without changes
File without changes
File without changes