GeezerVison is showing github.com — feat: add Slack formatter for Socket Facts reachability analysis (#144) · SocketDev/socket-python-cli@13b8fe5
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: README.md +37-8Lines changed: 37 additions & 8 deletions - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
@@ -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,43 @@ 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 webhook configuration (enables plugin when set). Alternatively, use --slack-webhook CLI flag. | | 226 | 225 |
| 227 | | -Example `SOCKET_SLACK_CONFIG_JSON` value | | 226 | +Example `SOCKET_SLACK_CONFIG_JSON` value (simple webhook): | 228 | 227 |
| 229 | 228 | ````json | 230 | 229 | {"url": "https://REPLACE_ME_WEBHOOK"} | 231 | 230 | ```` | 232 | 231 |
| | 232 | +Example with advanced filtering (reachability-only alerts): | | 233 | +
| | 234 | +````json | | 235 | +{ | | 236 | + "url": [ | | 237 | + { | | 238 | + "name": "prod_alerts", | | 239 | + "url": "https://hooks.slack.com/services/YOUR/WEBHOOK/URL" | | 240 | + } | | 241 | + ], | | 242 | + "url_configs": { | | 243 | + "prod_alerts": { | | 244 | + "reachability_alerts_only": true, | | 245 | + "always_send_reachability": true | | 246 | + } | | 247 | + } | | 248 | +} | | 249 | +```` | | 250 | +
| | 251 | +**Advanced Configuration Options:** | | 252 | +
| | 253 | +The `url_configs` object allows per-webhook filtering: | | 254 | +
| | 255 | +- `reachability_alerts_only` (boolean, default: false): When `--reach` is enabled, only send blocking alerts (error=true) from diff scans | | 256 | +- `always_send_reachability` (boolean, default: true): Send reachability alerts even on non-diff scans when `--reach` is enabled. Set to false to only send reachability alerts when there are diff alerts. | | 257 | +- `repos` (array): Only send alerts for specific repositories (e.g., `["owner/repo1", "owner/repo2"]`) | | 258 | +- `alert_types` (array): Only send specific alert types (e.g., `["malware", "typosquat"]`) | | 259 | +- `severities` (array): Only send alerts with specific severities (e.g., `["high", "critical"]`) | | 260 | +
| 233 | 261 | ## Automatic Git Detection | 234 | 262 |
| 235 | 263 | The CLI now automatically detects repository information from your git environment, significantly simplifying usage in CI/CD pipelines: | @@ -490,7 +518,8 @@ Implementation targets: | 490 | 518 | ### Environment Variables | 491 | 519 |
| 492 | 520 | #### Core Configuration | 493 | | -- `SOCKET_SECURITY_API_KEY`: Socket Security API token (alternative to --api-token parameter) | | 521 | +- `SOCKET_SECURITY_API_TOKEN`: Socket Security API token (alternative to --api-token parameter) | | 522 | + - For backwards compatibility, also accepts: `SOCKET_SECURITY_API_KEY`, `SOCKET_API_KEY`, `SOCKET_API_TOKEN` | 494 | 523 | - `SOCKET_SDK_PATH`: Path to local socketdev repository (default: ../socketdev) | 495 | 524 |
| 496 | 525 | #### GitLab Integration | |
Collapse file Copy file name to clipboardExpand all lines: pyproject.toml +3-2Lines changed: 3 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -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.60" | 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" | |
Collapse file Copy file name to clipboard +1-1Lines changed: 1 addition & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
| 1 | 1 | __author__ = 'socket.dev' | 2 | | -__version__ = '2.2.59' | | 2 | +__version__ = '2.2.60' | 3 | 3 | USER_AGENT = f'SocketPythonCLI/{__version__}' |
Collapse file Copy file name to clipboardExpand all lines: socketsecurity/config.py +27-5Lines changed: 27 additions & 5 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -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 @@ def from_args(cls, args_list: Optional[List[str]] = None) -> '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 @@ def from_args(cls, args_list: Optional[List[str]] = None) -> '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,16 +159,21 @@ def from_args(cls, args_list: Optional[List[str]] = None) -> '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", | 157 | 170 | levels=os.getenv("SOCKET_JIRA_LEVELS", "block,warn").split(","), | 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( | |
|