socketsecurity 2.2.59__tar.gz → 2.2.62__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 (93) hide show
  1. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/PKG-INFO +111 -11
  2. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/README.md +108 -9
  3. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/pyproject.toml +3 -2
  4. socketsecurity-2.2.62/session.md +127 -0
  5. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/__init__.py +1 -1
  6. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/config.py +27 -5
  7. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/core/__init__.py +4 -1
  8. socketsecurity-2.2.62/socketsecurity/core/helper/socket_facts_loader.py +387 -0
  9. socketsecurity-2.2.62/socketsecurity/plugins/formatters/__init__.py +5 -0
  10. socketsecurity-2.2.62/socketsecurity/plugins/formatters/slack.py +272 -0
  11. socketsecurity-2.2.62/socketsecurity/plugins/slack.py +712 -0
  12. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/socketcli.py +4 -3
  13. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/uv.lock +285 -274
  14. socketsecurity-2.2.59/socketsecurity/plugins/slack.py +0 -95
  15. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/.github/CODEOWNERS +0 -0
  16. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/.github/PULL_REQUEST_TEMPLATE/bug-fix.md +0 -0
  17. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/.github/PULL_REQUEST_TEMPLATE/feature.md +0 -0
  18. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/.github/PULL_REQUEST_TEMPLATE/improvement.md +0 -0
  19. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  20. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/.github/workflows/docker-stable.yml +0 -0
  21. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/.github/workflows/pr-preview.yml +0 -0
  22. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/.github/workflows/release.yml +0 -0
  23. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/.github/workflows/version-check.yml +0 -0
  24. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/.gitignore +0 -0
  25. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/.hooks/sync_version.py +0 -0
  26. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/.pre-commit-config.yaml +0 -0
  27. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/.python-version +0 -0
  28. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/CHANGELOG.md +0 -0
  29. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/Dockerfile +0 -0
  30. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/LICENSE +0 -0
  31. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/Makefile +0 -0
  32. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/docs/README.md +0 -0
  33. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/pytest.ini +0 -0
  34. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/scripts/build_container.sh +0 -0
  35. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/scripts/build_container_flexible.sh +0 -0
  36. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/scripts/deploy-test-docker.sh +0 -0
  37. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/scripts/deploy-test-pypi.sh +0 -0
  38. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/scripts/docker-entrypoint.sh +0 -0
  39. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/scripts/run.sh +0 -0
  40. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/core/classes.py +0 -0
  41. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/core/cli_client.py +0 -0
  42. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/core/exceptions.py +0 -0
  43. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/core/git_interface.py +0 -0
  44. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/core/helper/__init__.py +0 -0
  45. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/core/lazy_file_loader.py +0 -0
  46. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/core/logging.py +0 -0
  47. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/core/messages.py +0 -0
  48. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/core/resource_utils.py +0 -0
  49. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/core/scm/__init__.py +0 -0
  50. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/core/scm/base.py +0 -0
  51. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/core/scm/client.py +0 -0
  52. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/core/scm/github.py +0 -0
  53. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/core/scm/gitlab.py +0 -0
  54. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/core/scm_comments.py +0 -0
  55. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/core/socket_config.py +0 -0
  56. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/core/tools/reachability.py +0 -0
  57. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/core/utils.py +0 -0
  58. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/output.py +0 -0
  59. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/plugins/__init__.py +0 -0
  60. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/plugins/base.py +0 -0
  61. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/plugins/jira.py +0 -0
  62. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/plugins/manager.py +0 -0
  63. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/plugins/teams.py +0 -0
  64. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/socketsecurity/plugins/webhook.py +0 -0
  65. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/tests/__init__.py +0 -0
  66. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/tests/core/conftest.py +0 -0
  67. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/tests/core/create_diff_input.json +0 -0
  68. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/tests/core/test_diff_generation.py +0 -0
  69. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/tests/core/test_package_and_alerts.py +0 -0
  70. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/tests/core/test_sdk_methods.py +0 -0
  71. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/tests/core/test_supporting_methods.py +0 -0
  72. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/tests/data/fullscans/create_response.json +0 -0
  73. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/tests/data/fullscans/diff/stream_diff.json +0 -0
  74. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/tests/data/fullscans/diff/stream_diff_full.json +0 -0
  75. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/tests/data/fullscans/head_scan/metadata.json +0 -0
  76. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/tests/data/fullscans/head_scan/stream_scan.json +0 -0
  77. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/tests/data/fullscans/head_scan/stream_scan_full.json +0 -0
  78. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/tests/data/fullscans/new_scan/metadata.json +0 -0
  79. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/tests/data/fullscans/new_scan/stream_scan.json +0 -0
  80. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/tests/data/repos/repo_info_error.json +0 -0
  81. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/tests/data/repos/repo_info_no_head.json +0 -0
  82. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/tests/data/repos/repo_info_success.json +0 -0
  83. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/tests/data/settings/security-policy.json +0 -0
  84. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/tests/unit/__init__.py +0 -0
  85. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/tests/unit/test_cli_config.py +0 -0
  86. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/tests/unit/test_client.py +0 -0
  87. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/tests/unit/test_config.py +0 -0
  88. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/tests/unit/test_gitlab_auth.py +0 -0
  89. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/tests/unit/test_gitlab_auth_fallback.py +0 -0
  90. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/tests/unit/test_output.py +0 -0
  91. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/workflows/bitbucket-pipelines.yml +0 -0
  92. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/workflows/github-actions.yml +0 -0
  93. {socketsecurity-2.2.59 → socketsecurity-2.2.62}/workflows/gitlab-ci.yml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: socketsecurity
3
- Version: 2.2.59
3
+ Version: 2.2.62
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>
@@ -35,12 +35,13 @@ Classifier: Programming Language :: Python :: 3.12
35
35
  Requires-Python: >=3.10
36
36
  Requires-Dist: bs4>=0.0.2
37
37
  Requires-Dist: gitpython
38
+ Requires-Dist: markdown>=3.10
38
39
  Requires-Dist: mdutils
39
40
  Requires-Dist: packaging
40
41
  Requires-Dist: prettytable
41
42
  Requires-Dist: python-dotenv
42
43
  Requires-Dist: requests
43
- Requires-Dist: socketdev<4.0.0,>=3.0.22
44
+ Requires-Dist: socketdev<4.0.0,>=3.0.25
44
45
  Provides-Extra: dev
45
46
  Requires-Dist: hatch; extra == 'dev'
46
47
  Requires-Dist: pre-commit; extra == 'dev'
@@ -158,14 +159,14 @@ socketcli [-h] [--api-token API_TOKEN] [--repo REPO] [--repo-is-public] [--branc
158
159
  [--only-facts-file] [--version]
159
160
  ````
160
161
 
161
- If you don't want to provide the Socket API Token every time then you can use the environment variable `SOCKET_SECURITY_API_KEY`
162
+ If you don't want to provide the Socket API Token every time then you can use the environment variable `SOCKET_SECURITY_API_TOKEN`
162
163
 
163
164
  ### Parameters
164
165
 
165
166
  #### Authentication
166
- | Parameter | Required | Default | Description |
167
- |:------------|:---------|:--------|:--------------------------------------------------------------------------------|
168
- | --api-token | False | | Socket Security API token (can also be set via SOCKET_SECURITY_API_KEY env var) |
167
+ | Parameter | Required | Default | Description |
168
+ |:------------|:---------|:--------|:----------------------------------------------------------------------------------|
169
+ | --api-token | False | | Socket Security API token (can also be set via SOCKET_SECURITY_API_TOKEN env var) |
169
170
 
170
171
  #### Repository
171
172
  | Parameter | Required | Default | Description |
@@ -278,15 +279,113 @@ Example `SOCKET_JIRA_CONFIG_JSON` value
278
279
 
279
280
  | Environment Variable | Required | Default | Description |
280
281
  |:-------------------------|:---------|:--------|:-----------------------------------|
281
- | SOCKET_SLACK_ENABLED | False | false | Enables/Disables the Slack Plugin |
282
- | SOCKET_SLACK_CONFIG_JSON | True | None | Required if the Plugin is enabled. |
282
+ | SOCKET_SLACK_CONFIG_JSON | False | None | Slack configuration (enables plugin when set). Supports webhook or bot mode. Alternatively, use --slack-webhook CLI flag for simple webhook mode. |
283
+ | SOCKET_SLACK_BOT_TOKEN | False | None | Slack Bot User OAuth Token (starts with `xoxb-`). Required when using bot mode. |
283
284
 
284
- Example `SOCKET_SLACK_CONFIG_JSON` value
285
+ **Slack supports two modes:**
286
+
287
+ 1. **Webhook Mode** (default): Posts to incoming webhooks
288
+ 2. **Bot Mode**: Posts via Slack API with bot token authentication
289
+
290
+ ###### Webhook Mode Examples
291
+
292
+ Simple webhook:
293
+
294
+ ````json
295
+ {"url": "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"}
296
+ ````
297
+
298
+ Multiple webhooks with advanced filtering:
285
299
 
286
300
  ````json
287
- {"url": "https://REPLACE_ME_WEBHOOK"}
301
+ {
302
+ "mode": "webhook",
303
+ "url": [
304
+ {
305
+ "name": "prod_alerts",
306
+ "url": "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
307
+ },
308
+ {
309
+ "name": "critical_only",
310
+ "url": "https://hooks.slack.com/services/YOUR/OTHER/WEBHOOK/URL"
311
+ }
312
+ ],
313
+ "url_configs": {
314
+ "prod_alerts": {
315
+ "reachability_alerts_only": true,
316
+ "severities": ["high", "critical"]
317
+ },
318
+ "critical_only": {
319
+ "severities": ["critical"]
320
+ }
321
+ }
322
+ }
288
323
  ````
289
324
 
325
+ ###### Bot Mode Examples
326
+
327
+ **Setting up a Slack Bot:**
328
+ 1. Go to https://api.slack.com/apps and create a new app
329
+ 2. Under "OAuth & Permissions", add the `chat:write` bot scope
330
+ 3. Install the app to your workspace and copy the "Bot User OAuth Token"
331
+ 4. Invite the bot to your channels: `/invite @YourBotName`
332
+
333
+ Basic bot configuration:
334
+
335
+ ````json
336
+ {
337
+ "mode": "bot",
338
+ "bot_configs": [
339
+ {
340
+ "name": "security_alerts",
341
+ "channels": ["security-alerts", "dev-team"]
342
+ }
343
+ ]
344
+ }
345
+ ````
346
+
347
+ Bot with filtering (reachability-only alerts):
348
+
349
+ ````json
350
+ {
351
+ "mode": "bot",
352
+ "bot_configs": [
353
+ {
354
+ "name": "critical_reachable",
355
+ "channels": ["security-critical"],
356
+ "severities": ["critical", "high"],
357
+ "reachability_alerts_only": true
358
+ },
359
+ {
360
+ "name": "all_alerts",
361
+ "channels": ["security-all"],
362
+ "repos": ["myorg/backend", "myorg/frontend"]
363
+ }
364
+ ]
365
+ }
366
+ ````
367
+
368
+ Set the bot token:
369
+ ```bash
370
+ export SOCKET_SLACK_BOT_TOKEN="xoxb-your-bot-token-here"
371
+ ```
372
+
373
+ **Configuration Options:**
374
+
375
+ Webhook mode (`url_configs`):
376
+ - `reachability_alerts_only` (boolean, default: false): When `--reach` is enabled, only send blocking alerts (error=true) from diff scans
377
+ - `repos` (array): Only send alerts for specific repositories (e.g., `["owner/repo1", "owner/repo2"]`)
378
+ - `alert_types` (array): Only send specific alert types (e.g., `["malware", "typosquat"]`)
379
+ - `severities` (array): Only send alerts with specific severities (e.g., `["high", "critical"]`)
380
+
381
+ Bot mode (`bot_configs` array items):
382
+ - `name` (string, required): Friendly name for this configuration
383
+ - `channels` (array, required): Channel names (without #) where alerts will be posted
384
+ - `severities` (array, optional): Only send alerts with specific severities (e.g., `["high", "critical"]`)
385
+ - `repos` (array, optional): Only send alerts for specific repositories
386
+ - `alert_types` (array, optional): Only send specific alert types
387
+ - `reachability_alerts_only` (boolean, default: false): Only send reachable vulnerabilities when using `--reach`
388
+
290
389
  ## Automatic Git Detection
291
390
 
292
391
  The CLI now automatically detects repository information from your git environment, significantly simplifying usage in CI/CD pipelines:
@@ -547,7 +646,8 @@ Implementation targets:
547
646
  ### Environment Variables
548
647
 
549
648
  #### Core Configuration
550
- - `SOCKET_SECURITY_API_KEY`: Socket Security API token (alternative to --api-token parameter)
649
+ - `SOCKET_SECURITY_API_TOKEN`: Socket Security API token (alternative to --api-token parameter)
650
+ - For backwards compatibility, also accepts: `SOCKET_SECURITY_API_KEY`, `SOCKET_API_KEY`, `SOCKET_API_TOKEN`
551
651
  - `SOCKET_SDK_PATH`: Path to local socketdev repository (default: ../socketdev)
552
652
 
553
653
  #### GitLab Integration
@@ -101,14 +101,14 @@ socketcli [-h] [--api-token API_TOKEN] [--repo REPO] [--repo-is-public] [--branc
101
101
  [--only-facts-file] [--version]
102
102
  ````
103
103
 
104
- If you don't want to provide the Socket API Token every time then you can use the environment variable `SOCKET_SECURITY_API_KEY`
104
+ If you don't want to provide the Socket API Token every time then you can use the environment variable `SOCKET_SECURITY_API_TOKEN`
105
105
 
106
106
  ### Parameters
107
107
 
108
108
  #### Authentication
109
- | Parameter | Required | Default | Description |
110
- |:------------|:---------|:--------|:--------------------------------------------------------------------------------|
111
- | --api-token | False | | Socket Security API token (can also be set via SOCKET_SECURITY_API_KEY env var) |
109
+ | Parameter | Required | Default | Description |
110
+ |:------------|:---------|:--------|:----------------------------------------------------------------------------------|
111
+ | --api-token | False | | Socket Security API token (can also be set via SOCKET_SECURITY_API_TOKEN env var) |
112
112
 
113
113
  #### Repository
114
114
  | Parameter | Required | Default | Description |
@@ -221,15 +221,113 @@ Example `SOCKET_JIRA_CONFIG_JSON` value
221
221
 
222
222
  | Environment Variable | Required | Default | Description |
223
223
  |:-------------------------|:---------|:--------|:-----------------------------------|
224
- | SOCKET_SLACK_ENABLED | False | false | Enables/Disables the Slack Plugin |
225
- | SOCKET_SLACK_CONFIG_JSON | True | None | Required if the Plugin is enabled. |
224
+ | SOCKET_SLACK_CONFIG_JSON | False | None | Slack configuration (enables plugin when set). Supports webhook or bot mode. Alternatively, use --slack-webhook CLI flag for simple webhook mode. |
225
+ | SOCKET_SLACK_BOT_TOKEN | False | None | Slack Bot User OAuth Token (starts with `xoxb-`). Required when using bot mode. |
226
226
 
227
- Example `SOCKET_SLACK_CONFIG_JSON` value
227
+ **Slack supports two modes:**
228
+
229
+ 1. **Webhook Mode** (default): Posts to incoming webhooks
230
+ 2. **Bot Mode**: Posts via Slack API with bot token authentication
231
+
232
+ ###### Webhook Mode Examples
233
+
234
+ Simple webhook:
235
+
236
+ ````json
237
+ {"url": "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"}
238
+ ````
239
+
240
+ Multiple webhooks with advanced filtering:
228
241
 
229
242
  ````json
230
- {"url": "https://REPLACE_ME_WEBHOOK"}
243
+ {
244
+ "mode": "webhook",
245
+ "url": [
246
+ {
247
+ "name": "prod_alerts",
248
+ "url": "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
249
+ },
250
+ {
251
+ "name": "critical_only",
252
+ "url": "https://hooks.slack.com/services/YOUR/OTHER/WEBHOOK/URL"
253
+ }
254
+ ],
255
+ "url_configs": {
256
+ "prod_alerts": {
257
+ "reachability_alerts_only": true,
258
+ "severities": ["high", "critical"]
259
+ },
260
+ "critical_only": {
261
+ "severities": ["critical"]
262
+ }
263
+ }
264
+ }
231
265
  ````
232
266
 
267
+ ###### Bot Mode Examples
268
+
269
+ **Setting up a Slack Bot:**
270
+ 1. Go to https://api.slack.com/apps and create a new app
271
+ 2. Under "OAuth & Permissions", add the `chat:write` bot scope
272
+ 3. Install the app to your workspace and copy the "Bot User OAuth Token"
273
+ 4. Invite the bot to your channels: `/invite @YourBotName`
274
+
275
+ Basic bot configuration:
276
+
277
+ ````json
278
+ {
279
+ "mode": "bot",
280
+ "bot_configs": [
281
+ {
282
+ "name": "security_alerts",
283
+ "channels": ["security-alerts", "dev-team"]
284
+ }
285
+ ]
286
+ }
287
+ ````
288
+
289
+ Bot with filtering (reachability-only alerts):
290
+
291
+ ````json
292
+ {
293
+ "mode": "bot",
294
+ "bot_configs": [
295
+ {
296
+ "name": "critical_reachable",
297
+ "channels": ["security-critical"],
298
+ "severities": ["critical", "high"],
299
+ "reachability_alerts_only": true
300
+ },
301
+ {
302
+ "name": "all_alerts",
303
+ "channels": ["security-all"],
304
+ "repos": ["myorg/backend", "myorg/frontend"]
305
+ }
306
+ ]
307
+ }
308
+ ````
309
+
310
+ Set the bot token:
311
+ ```bash
312
+ export SOCKET_SLACK_BOT_TOKEN="xoxb-your-bot-token-here"
313
+ ```
314
+
315
+ **Configuration Options:**
316
+
317
+ Webhook mode (`url_configs`):
318
+ - `reachability_alerts_only` (boolean, default: false): When `--reach` is enabled, only send blocking alerts (error=true) from diff scans
319
+ - `repos` (array): Only send alerts for specific repositories (e.g., `["owner/repo1", "owner/repo2"]`)
320
+ - `alert_types` (array): Only send specific alert types (e.g., `["malware", "typosquat"]`)
321
+ - `severities` (array): Only send alerts with specific severities (e.g., `["high", "critical"]`)
322
+
323
+ Bot mode (`bot_configs` array items):
324
+ - `name` (string, required): Friendly name for this configuration
325
+ - `channels` (array, required): Channel names (without #) where alerts will be posted
326
+ - `severities` (array, optional): Only send alerts with specific severities (e.g., `["high", "critical"]`)
327
+ - `repos` (array, optional): Only send alerts for specific repositories
328
+ - `alert_types` (array, optional): Only send specific alert types
329
+ - `reachability_alerts_only` (boolean, default: false): Only send reachable vulnerabilities when using `--reach`
330
+
233
331
  ## Automatic Git Detection
234
332
 
235
333
  The CLI now automatically detects repository information from your git environment, significantly simplifying usage in CI/CD pipelines:
@@ -490,7 +588,8 @@ Implementation targets:
490
588
  ### Environment Variables
491
589
 
492
590
  #### Core Configuration
493
- - `SOCKET_SECURITY_API_KEY`: Socket Security API token (alternative to --api-token parameter)
591
+ - `SOCKET_SECURITY_API_TOKEN`: Socket Security API token (alternative to --api-token parameter)
592
+ - For backwards compatibility, also accepts: `SOCKET_SECURITY_API_KEY`, `SOCKET_API_KEY`, `SOCKET_API_TOKEN`
494
593
  - `SOCKET_SDK_PATH`: Path to local socketdev repository (default: ../socketdev)
495
594
 
496
595
  #### GitLab Integration
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
6
6
 
7
7
  [project]
8
8
  name = "socketsecurity"
9
- version = "2.2.59"
9
+ version = "2.2.62"
10
10
  requires-python = ">= 3.10"
11
11
  license = {"file" = "LICENSE"}
12
12
  dependencies = [
@@ -16,8 +16,9 @@ dependencies = [
16
16
  'GitPython',
17
17
  'packaging',
18
18
  'python-dotenv',
19
- 'socketdev>=3.0.22,<4.0.0',
19
+ "socketdev>=3.0.25,<4.0.0",
20
20
  "bs4>=0.0.2",
21
+ "markdown>=3.10",
21
22
  ]
22
23
  readme = "README.md"
23
24
  description = "Socket Security CLI for CI/CD"
@@ -0,0 +1,127 @@
1
+ # Session Directions: Add Slack Bot Mode Support
2
+
3
+ ## Context
4
+ The Socket Python CLI currently supports Slack notifications via incoming webhooks. We need to add an alternative "bot" mode that uses a Slack App with Bot Token for more flexible channel routing.
5
+
6
+ ## Current Implementation
7
+ - File: `socketsecurity/plugins/slack.py`
8
+ - File: `socketsecurity/config.py`
9
+ - Env var: `SOCKET_SLACK_CONFIG_JSON`
10
+ - Current config uses `url` and `url_configs` for webhook routing
11
+
12
+ ## Requirements
13
+
14
+ ### 1. Add Mode Selection
15
+ - Add top-level `mode` field to Slack config
16
+ - Valid values: "webhook" (default), "bot"
17
+ - Mode determines which authentication and routing method to use
18
+
19
+ ### 2. Webhook Mode (existing, default)
20
+ ```json
21
+ {
22
+ "enabled": true,
23
+ "mode": "webhook",
24
+ "url": ["https://hooks.slack.com/..."],
25
+ "url_configs": {
26
+ "webhook_0": {"repos": ["repo1"], "severities": ["critical"]}
27
+ }
28
+ }
29
+ ```
30
+ Keep all existing webhook functionality unchanged.
31
+
32
+ ### 3. Bot Mode (new)
33
+ ```json
34
+ {
35
+ "enabled": true,
36
+ "mode": "bot",
37
+ "bot_configs": [
38
+ {
39
+ "name": "critical_alerts",
40
+ "channels": ["security-alerts", "critical-incidents"],
41
+ "repos": ["prod-app"],
42
+ "severities": ["critical"],
43
+ "reachability_alerts_only": true
44
+ },
45
+ {
46
+ "name": "all_alerts",
47
+ "channels": ["dev-alerts"],
48
+ "severities": ["high", "medium"]
49
+ }
50
+ ]
51
+ }
52
+ ```
53
+
54
+ - New env var: `SOCKET_SLACK_BOT_TOKEN` (Bot User OAuth Token starting with `xoxb-`)
55
+ - Use `bot_configs` array instead of `url` + `url_configs`
56
+ - Each bot_config has:
57
+ - `name`: identifier for logging
58
+ - `channels`: array of Slack channel names or IDs to post to
59
+ - All existing filter options: `repos`, `severities`, `alert_types`, `reachability_alerts_only`, `always_send_reachability`
60
+
61
+ ### 4. Channel Routing
62
+ - Slack API accepts both channel names (without #) and channel IDs (C1234567890)
63
+ - Recommend supporting both: try name first, fallback to ID if needed
64
+ - API endpoint: `https://slack.com/api/chat.postMessage`
65
+ - Request format:
66
+ ```python
67
+ {
68
+ "channel": "channel-name", # or "C1234567890"
69
+ "blocks": blocks
70
+ }
71
+ ```
72
+ - Headers: `{"Authorization": f"Bearer {bot_token}", "Content-Type": "application/json"}`
73
+
74
+ ### 5. Implementation Tasks
75
+
76
+ #### config.py
77
+ - No changes needed (config is loaded from JSON env var)
78
+
79
+ #### slack.py
80
+ 1. Update `send()` method:
81
+ - Check `self.config.get("mode", "webhook")`
82
+ - If "webhook": call existing `_send_webhook_alerts()` (refactor current logic)
83
+ - If "bot": call new `_send_bot_alerts()`
84
+
85
+ 2. Create `_send_bot_alerts()` method:
86
+ - Get bot token from env: `os.getenv("SOCKET_SLACK_BOT_TOKEN")`
87
+ - Validate token exists and starts with "xoxb-"
88
+ - Get `bot_configs` from config
89
+ - For each bot_config, filter alerts same way as webhooks
90
+ - For each channel in bot_config's channels array, post message via chat.postMessage API
91
+
92
+ 3. Create `_post_to_slack_api()` helper method:
93
+ - Takes bot_token, channel, blocks
94
+ - Posts to https://slack.com/api/chat.postMessage
95
+ - Returns response
96
+ - Log errors with channel name/ID for debugging
97
+
98
+ 4. Error handling:
99
+ - Log if bot token missing when mode is "bot"
100
+ - Handle API errors (invalid channel, missing permissions, rate limits)
101
+ - Parse Slack API response JSON (it returns 200 with error in body)
102
+
103
+ 5. Reuse existing:
104
+ - All filtering logic (`_filter_alerts`)
105
+ - All block building (`create_slack_blocks_from_diff`, `_create_reachability_slack_blocks_from_structured`)
106
+ - All reachability data loading
107
+
108
+ ### 6. Testing Considerations
109
+ - Test both modes don't interfere with each other
110
+ - Test channel name resolution
111
+ - Test channel ID usage
112
+ - Test multiple channels per bot_config
113
+ - Test error handling when bot token invalid or missing
114
+ - Verify block count limits still respected (50 blocks)
115
+
116
+ ### 7. Documentation Updates (README.md)
117
+ Add bot mode configuration examples and SOCKET_SLACK_BOT_TOKEN env var documentation.
118
+
119
+ ## Key Files to Modify
120
+ 1. `socketsecurity/plugins/slack.py` - main implementation
121
+ 2. `README.md` - add bot mode documentation
122
+
123
+ ## Notes
124
+ - Slack chat.postMessage returns HTTP 200 even on errors. Check response JSON for `"ok": false`
125
+ - Rate limit: 1 message per second per channel (more generous than webhooks)
126
+ - Channel names are case-insensitive, don't need # prefix
127
+ - Public and private channels both work if bot is invited
@@ -1,3 +1,3 @@
1
1
  __author__ = 'socket.dev'
2
- __version__ = '2.2.59'
2
+ __version__ = '2.2.62'
3
3
  USER_AGENT = f'SocketPythonCLI/{__version__}'
@@ -57,6 +57,7 @@ class CliConfig:
57
57
  version: str = __version__
58
58
  jira_plugin: PluginConfig = field(default_factory=PluginConfig)
59
59
  slack_plugin: PluginConfig = field(default_factory=PluginConfig)
60
+ slack_webhook: Optional[str] = None
60
61
  license_file_name: str = "license_output.json"
61
62
  save_submitted_files_list: Optional[str] = None
62
63
  save_manifest_tar: Optional[str] = None
@@ -85,8 +86,14 @@ class CliConfig:
85
86
  parser = create_argument_parser()
86
87
  args = parser.parse_args(args_list)
87
88
 
88
- # Get API token from env or args
89
- api_token = os.getenv("SOCKET_SECURITY_API_KEY") or args.api_token
89
+ # Get API token from env or args (check multiple env var names)
90
+ api_token = (
91
+ os.getenv("SOCKET_SECURITY_API_KEY") or
92
+ os.getenv("SOCKET_SECURITY_API_TOKEN") or
93
+ os.getenv("SOCKET_API_KEY") or
94
+ os.getenv("SOCKET_API_TOKEN") or
95
+ args.api_token
96
+ )
90
97
 
91
98
  # Strip quotes from commit message if present
92
99
  commit_message = args.commit_message
@@ -128,6 +135,7 @@ class CliConfig:
128
135
  'save_manifest_tar': args.save_manifest_tar,
129
136
  'sub_paths': args.sub_paths or [],
130
137
  'workspace_name': args.workspace_name,
138
+ 'slack_webhook': args.slack_webhook,
131
139
  'reach': args.reach,
132
140
  'reach_version': args.reach_version,
133
141
  'reach_analysis_timeout': args.reach_analysis_timeout,
@@ -151,6 +159,11 @@ class CliConfig:
151
159
  except json.JSONDecodeError:
152
160
  logging.error(f"Unable to parse excluded_ecosystems: {config_args['excluded_ecosystems']}")
153
161
  exit(1)
162
+ # Build Slack plugin config, merging CLI arg with env config
163
+ slack_config = get_plugin_config_from_env("SOCKET_SLACK")
164
+ if args.slack_webhook:
165
+ slack_config["url"] = args.slack_webhook
166
+
154
167
  config_args.update({
155
168
  "jira_plugin": PluginConfig(
156
169
  enabled=os.getenv("SOCKET_JIRA_ENABLED", "false").lower() == "true",
@@ -158,9 +171,9 @@ class CliConfig:
158
171
  config=get_plugin_config_from_env("SOCKET_JIRA")
159
172
  ),
160
173
  "slack_plugin": PluginConfig(
161
- enabled=os.getenv("SOCKET_SLACK_ENABLED", "false").lower() == "true",
174
+ enabled=bool(slack_config) or bool(args.slack_webhook),
162
175
  levels=os.getenv("SOCKET_SLACK_LEVELS", "block,warn").split(","),
163
- config=get_plugin_config_from_env("SOCKET_SLACK")
176
+ config=slack_config
164
177
  )
165
178
  })
166
179
 
@@ -212,7 +225,7 @@ def create_argument_parser() -> argparse.ArgumentParser:
212
225
  "--api-token",
213
226
  dest="api_token",
214
227
  metavar="<token>",
215
- help="Socket Security API token (can also be set via SOCKET_SECURITY_API_KEY env var)",
228
+ help="Socket Security API token (can also be set via SOCKET_SECURITY_API_TOKEN env var)",
216
229
  required=False
217
230
  )
218
231
  auth_group.add_argument(
@@ -475,6 +488,15 @@ def create_argument_parser() -> argparse.ArgumentParser:
475
488
  help=argparse.SUPPRESS
476
489
  )
477
490
 
491
+ # Plugin Configuration
492
+ plugin_group = parser.add_argument_group('Plugin Configuration')
493
+ plugin_group.add_argument(
494
+ "--slack-webhook",
495
+ dest="slack_webhook",
496
+ metavar="<url>",
497
+ help="Slack webhook URL for notifications (automatically enables Slack plugin)"
498
+ )
499
+
478
500
  # Advanced Configuration
479
501
  advanced_group = parser.add_argument_group('Advanced Configuration')
480
502
  advanced_group.add_argument(
@@ -553,7 +553,10 @@ class Core:
553
553
 
554
554
  # Finalize tier1 scan if reachability analysis was enabled
555
555
  if self.cli_config and self.cli_config.reach:
556
- facts_file_path = self.cli_config.reach_output_file or ".socket.facts.json"
556
+ facts_file_path = os.path.join(
557
+ self.cli_config.target_path or ".",
558
+ self.cli_config.reach_output_file
559
+ )
557
560
  log.debug(f"Reachability analysis enabled, finalizing tier1 scan for full scan {full_scan.id}")
558
561
  try:
559
562
  success = self.finalize_tier1_scan(full_scan.id, facts_file_path)