|
| 1 | +# Security Wrapper — socket-basics |
| 2 | + |
| 3 | +Security Wrapper is a small, extensible CLI tool that orchestrates multiple security scanners (SAST, secret scanning, container scanning), normalizes their outputs into a single consolidated Socket facts JSON format, and delivers results to configured notifiers (console, Slack, Jira, webhooks, Sumo Logic, MS Sentinel, etc.). |
| 4 | + |
| 5 | +This README is a first-time, clean-slate guide to installing, running, configuring, and extending the tool. |
| 6 | + |
| 7 | +## Table of contents |
| 8 | + |
| 9 | +- Overview |
| 10 | +- Installation |
| 11 | +- Quick start |
| 12 | +- CLI reference |
| 13 | +- Environment variables (INPUT_*) |
| 14 | +- Connector architecture |
| 15 | +- Notifiers |
| 16 | +- Output format |
| 17 | +- Docker usage |
| 18 | +- Development & testing |
| 19 | +- Troubleshooting |
| 20 | +- Contributing |
| 21 | +- License |
| 22 | + |
| 23 | +## Overview |
| 24 | + |
| 25 | +Security Wrapper provides: |
| 26 | + |
| 27 | +- A unified CLI: `socket-basics` |
| 28 | +- A plugin-style connector system for integrating scanners (OpenGrep, Trivy, TruffleHog, etc.) |
| 29 | +- Configuration via CLI flags, environment variables, and `socket_basics/connectors.yaml` |
| 30 | +- Consolidation of all scanner results into a single `.socket.facts.json` compatible structure |
| 31 | +- Notification hooks to send results to external systems |
| 32 | + |
| 33 | +Design goals: |
| 34 | + |
| 35 | +- Make it easy to run multiple scanners in a single job |
| 36 | +- Normalize outputs for downstream analysis and reporting |
| 37 | +- Keep connectors isolated and pluggable |
| 38 | + |
| 39 | +## Installation |
| 40 | + |
| 41 | +Recommended: use a Python virtual environment and the `uv` tool (used in development here). The package exposes the `socket-basics` CLI through `pyproject.toml`. |
| 42 | + |
| 43 | +On macOS / Linux (zsh): |
| 44 | + |
| 45 | +```sh |
| 46 | +python -m venv .venv |
| 47 | +source .venv/bin/activate |
| 48 | +# install uv if not already available |
| 49 | +curl -LsSf https://astral.sh/uv/install.sh | sh |
| 50 | +uv sync |
| 51 | +# install this package in editable mode |
| 52 | +pip install -e . |
| 53 | +``` |
| 54 | + |
| 55 | +After installation you should have the `socket-basics` CLI available in your environment. |
| 56 | + |
| 57 | + |
| 58 | +## Quick start |
| 59 | + |
| 60 | +Run a basic scan from the repository root and print results to stdout: |
| 61 | + |
| 62 | +```sh |
| 63 | +socket-basics --python --secrets --containers --verbose |
| 64 | +``` |
| 65 | + |
| 66 | +Save results to a file: |
| 67 | + |
| 68 | +```sh |
| 69 | +socket-basics --python --secrets --containers --output scan-results.socket.facts.json |
| 70 | +``` |
| 71 | + |
| 72 | +Run with console notifications only (no output file): |
| 73 | + |
| 74 | +```sh |
| 75 | +INPUT_CONSOLE_ENABLED=true socket-basics --python --secrets |
| 76 | +``` |
| 77 | + |
| 78 | +## CLI reference |
| 79 | + |
| 80 | +Run `socket-basics --help` to see the up-to-date list of options. Below are the most commonly used flags: |
| 81 | + |
| 82 | +- `--python` / `--no-python` — enable/disable Python SAST |
| 83 | +- `--secrets` / `--no-secrets` — enable/disable secret scanning |
| 84 | +- `--containers` / `--no-containers` — enable/disable container scanning |
| 85 | +- `--all-languages` — run SAST for all languages configured by the connectors |
| 86 | +- `--output <file>` — path to write the consolidated Socket facts JSON |
| 87 | +- `--workspace <path>` — path to repository workspace (defaults to current directory) |
| 88 | +- `--repo <owner/repo>` — repository identifier for integrations |
| 89 | +- `--branch <branch>` — repository branch to analyze |
| 90 | +- `--socket-tier1` / `--no-socket-tier1` — enable/disable Socket tier1 reporting |
| 91 | +- `--socket-org <org>` — Socket organization slug (required for Socket API calls) |
| 92 | +- `--console-tabular-enabled` / `--no-console-tabular-enabled` — prefer tabular console output |
| 93 | +- `--verbose` / `--no-verbose` — enable/disable debug logging |
| 94 | + |
| 95 | +Connector-specific CLI flags are declared dynamically in `socket_basics/connectors.yaml` and will appear in `--help` when available. |
| 96 | + |
| 97 | +## Environment variables (INPUT_ prefix) |
| 98 | + |
| 99 | +All environment variables used to configure scanning behavior follow the `INPUT_{PARAM_NAME}` pattern (uppercase). The precedence order is: |
| 100 | + |
| 101 | +1. CLI arguments |
| 102 | +2. Environment variables (`INPUT_*`) |
| 103 | +3. `socket_basics/connectors.yaml` |
| 104 | +4. Built-in defaults |
| 105 | + |
| 106 | +Common environment variables used by the project (examples): |
| 107 | + |
| 108 | +- `INPUT_PYTHON_SAST_ENABLED=true|false` |
| 109 | +- `INPUT_SECRET_SCANNING_ENABLED=true|false` |
| 110 | +- `INPUT_DOCKERFILES=Dockerfile,Dockerfile.prod` |
| 111 | +- `INPUT_DOCKER_IMAGES=org/image:tag,org/other:tag` |
| 112 | +- `INPUT_SOCKET_SCANNING_ENABLED=true|false` |
| 113 | +- `INPUT_SOCKET_ORG=<org-slug>` |
| 114 | +- `INPUT_SOCKET_API_KEY=<api-key>` |
| 115 | +- `INPUT_CONSOLE_ENABLED=true|false` |
| 116 | +- `INPUT_SOCKET_CONSOLE_MODE=json|tabular` |
| 117 | +- `INPUT_SLACK_ENABLED=true|false` |
| 118 | +- `INPUT_SLACK_WEBHOOK_URL=<url>` |
| 119 | +- `INPUT_JIRA_ENABLED=true|false` |
| 120 | +- `INPUT_JIRA_PROJECT=<PROJECTKEY>` |
| 121 | + |
| 122 | +Connector-specific env vars are listed under each connector's `parameters` block in `socket_basics/connectors.yaml` (look for `env_variable` entries). |
| 123 | + |
| 124 | +## Connector architecture |
| 125 | + |
| 126 | +Connectors live under `socket_basics/core/connector/`. Each connector is a small adapter that: |
| 127 | + |
| 128 | +- Implements a `scan()` method that executes the underlying tool and returns raw results |
| 129 | +- Implements a `_process_results(raw_results)` method that converts raw output into the Socket facts structure |
| 130 | + |
| 131 | +Connectors are registered and configured via `socket_basics/connectors.yaml`. Typical fields in the YAML mapping: |
| 132 | + |
| 133 | +- `module_path`: Python import path for the connector |
| 134 | +- `class`: connector class name |
| 135 | +- `enabled_by_default`: boolean |
| 136 | +- `parameters`: list of parameter mappings with `name`, `option`, `env_variable`, `type`, and `default` |
| 137 | + |
| 138 | +Add a new connector by creating a directory under `socket_basics/core/connector/<tool>/`, implementing the connector class, and adding an entry to `connectors.yaml`. |
| 139 | + |
| 140 | +## Testing connectors (app_tests) |
| 141 | + |
| 142 | +Connector integration tests live in `app_tests/`. This folder is the authoritative place to run connector-level integration tests that exercise scanners against sample repositories or inputs. Do not rely on `local_tests/` or `samples/` for official connector testing — `app_tests/` is maintained for that purpose. |
| 143 | + |
| 144 | +## Notifiers |
| 145 | + |
| 146 | +Notifiers are responsible for delivering the consolidated report to different channels. Built-in notifiers include: |
| 147 | + |
| 148 | +- Console (JSON or tabular) |
| 149 | +- Slack |
| 150 | +- Jira |
| 151 | +- Webhook |
| 152 | +- Sumo Logic |
| 153 | +- MS Sentinel |
| 154 | + |
| 155 | +Notifier behavior is configured via `socket_basics/notifications.yaml` or via connector-specific CLI flags and `INPUT_` environment variables. |
| 156 | + |
| 157 | +## Output format |
| 158 | + |
| 159 | +All scanners' findings are normalized into a consolidated Socket facts JSON structure. High-level shape: |
| 160 | + |
| 161 | +```json |
| 162 | +{ |
| 163 | + "components": [ |
| 164 | + { |
| 165 | + "type": "file", |
| 166 | + "name": "path/to/file", |
| 167 | + "alerts": [ |
| 168 | + { |
| 169 | + "type": "sast|secret|container", |
| 170 | + "severity": "low|medium|high|critical", |
| 171 | + "message": "description", |
| 172 | + "location": {"path": "file/path", "line": 42} |
| 173 | + } |
| 174 | + ] |
| 175 | + } |
| 176 | + ] |
| 177 | +} |
| 178 | +``` |
| 179 | + |
| 180 | +If `--output` is specified the JSON is written to that file. If not specified and console notifier is enabled the output is printed to stdout in the selected console mode. |
| 181 | + |
| 182 | +Sample consolidated outputs are provided in the `samples/` directory. |
| 183 | + |
| 184 | +## Docker usage |
| 185 | + |
| 186 | +Build the project Docker image and run a scan inside the container: |
| 187 | + |
| 188 | +```sh |
| 189 | +docker build -t socketdev/security-wrapper . |
| 190 | + |
| 191 | +# Example run (prints to console; replace placeholders as needed) |
| 192 | +docker run --rm -v "$PWD:/code" \ |
| 193 | + -e "INPUT_CONSOLE_ENABLED=true" \ |
| 194 | + -e "INPUT_PYTHON_SAST_ENABLED=true" \ |
| 195 | + -e "INPUT_SECRET_SCANNING_ENABLED=true" \ |
| 196 | + -e "INPUT_SOCKET_SCANNING_ENABLED=true" \ |
| 197 | + -e "INPUT_SOCKET_ORG=your-socket-org" \ |
| 198 | + -e "INPUT_SOCKET_API_KEY=your-api-key" \ |
| 199 | + socketdev/security-wrapper \ |
| 200 | + --python --secrets --containers --output /code/scan-results.socket.facts.json |
| 201 | +``` |
| 202 | + |
| 203 | +Notes: |
| 204 | + |
| 205 | +- Image scanning (`INPUT_DOCKER_IMAGES`) requires Docker/DIND access or pre-pulled images inside the container |
| 206 | +- Dockerfile scanning only requires the Dockerfile(s) to be present in the workspace |
| 207 | + |
| 208 | +## GitHub Actions usage |
| 209 | + |
| 210 | +This repository exposes a GitHub Action (see `action.yml`) which runs the Docker image and accepts many inputs to configure scanning and notifications. Below is a comprehensive list of available inputs (names are the action inputs; when using environment variables in workflows they map to the same semantic names under `with:`): |
| 211 | + |
| 212 | +Core inputs: |
| 213 | + |
| 214 | +- `github_token` (required) — GitHub token used to post PR comments |
| 215 | + |
| 216 | +Enable flags (true/false): |
| 217 | + |
| 218 | +- `python_sast_enabled` — enable Python SAST |
| 219 | +- `golang_sast_enabled` — enable Golang SAST |
| 220 | +- `javascript_sast_enabled` — enable JavaScript SAST |
| 221 | +- `dockerfile_enabled` — enable Dockerfile analysis |
| 222 | +- `image_enabled` — enable image scanning |
| 223 | +- `secret_scanning_enabled` — enable secret scanning |
| 224 | +- `socket_scanning_enabled` — enable Socket reachability scanning |
| 225 | +- `socket_sca_enabled` — enable Socket SCA scanning |
| 226 | + |
| 227 | +Docker/trivy inputs: |
| 228 | + |
| 229 | +- `docker_images` — comma-separated Docker images to scan |
| 230 | +- `dockerfiles` — comma-separated Dockerfile paths to scan |
| 231 | + |
| 232 | +Trufflehog inputs: |
| 233 | + |
| 234 | +- `trufflehog_exclude_dir` — comma-separated dirs to exclude |
| 235 | +- `trufflehog_rules` — rules to enable |
| 236 | +- `trufflehog_show_unverified` — show unverified secrets |
| 237 | + |
| 238 | +Socket configuration: |
| 239 | + |
| 240 | +- `socket_org` — Socket organization slug (required for Socket integrations) |
| 241 | +- `socket_api_key` — API key for Socket |
| 242 | +- `socket_security_api_key` — API key for SCA scanning |
| 243 | +- `socket_sca_files` — comma-separated manifest files to include in SCA |
| 244 | + |
| 245 | +SAST and rule controls: |
| 246 | + |
| 247 | +- `all_languages_enabled` — run SAST for all supported languages |
| 248 | +- `all_rules_enabled` — run all bundled SAST rules |
| 249 | +- Per-language enable flags (each accept `true|false`): |
| 250 | + - `python_sast_enabled`, `javascript_sast_enabled`, `typescript_sast_enabled`, `go_sast_enabled`, `golang_sast_enabled`, `java_sast_enabled`, `php_sast_enabled`, `ruby_sast_enabled`, `csharp_sast_enabled`, `dotnet_sast_enabled`, `c_sast_enabled`, `cpp_sast_enabled`, `kotlin_sast_enabled`, `scala_sast_enabled`, `swift_sast_enabled`, `rust_sast_enabled`, `elixir_sast_enabled` |
| 251 | + |
| 252 | +- Per-language rule overrides (comma-separated lists): |
| 253 | + - `<lang>_enabled_rules` and `<lang>_disabled_rules` for languages such as `python`, `javascript`, `go`, `java`, `php`, `ruby`, `csharp`, `dotnet`, `c`, `cpp`, `kotlin`, `scala`, `swift`, `rust`, `elixir` |
| 254 | + |
| 255 | +Trivy-specific: |
| 256 | + |
| 257 | +- `trivy_exclude_dir` — comma-separated dirs to exclude from Trivy |
| 258 | +- `trivy_rules` — rules to enable in Trivy |
| 259 | +- `trivy_disabled_rules` — comma-separated rules to disable |
| 260 | +- `trivy_image_scanning_disabled` — disable Trivy image scanning |
| 261 | + |
| 262 | +Log forwarding / SIEM: |
| 263 | + |
| 264 | +- `sumo_logic_enabled` — enable Sumo Logic forwarding |
| 265 | +- `sumo_logic_http_source_url` — Sumo Logic HTTP source URL |
| 266 | +- `ms_sentinel_enabled` — enable Microsoft Sentinel forwarding |
| 267 | +- `ms_sentinel_workspace_id` — workspace id |
| 268 | +- `ms_sentinel_shared_key` — shared key |
| 269 | + |
| 270 | +Jira / ticketing: |
| 271 | + |
| 272 | +- `jira_enabled` — enable Jira ticket creation |
| 273 | +- `jira_url` — Jira instance URL |
| 274 | +- `jira_email` — Jira account email |
| 275 | +- `jira_api_token` — Jira API token |
| 276 | +- `jira_project` — Jira project key |
| 277 | + |
| 278 | +Slack / Teams / Webhook: |
| 279 | + |
| 280 | +- `slack_enabled` — enable Slack notifications |
| 281 | +- `slack_webhook_url` — Slack webhook URL |
| 282 | +- `teams_enabled` — enable Teams notifications |
| 283 | +- `teams_webhook_url` — Teams webhook URL |
| 284 | +- `webhook_enabled` — enable generic webhook |
| 285 | +- `webhook_url` — webhook URL |
| 286 | +- `webhook_headers` — JSON string of custom headers for the webhook |
| 287 | + |
| 288 | +Scan scope: |
| 289 | + |
| 290 | +- `scan_all` — if true, scan the entire workspace regardless of git diff |
| 291 | +- `scan_files` — comma-separated list of files to scan (if omitted, action will use git diff or `scan_all`) |
| 292 | + |
| 293 | +Branding: |
| 294 | + |
| 295 | +- The action configures brand icon/color via `branding` in `action.yml` (not user-configurable via inputs) |
| 296 | + |
| 297 | +Example GitHub Actions workflow snippet: |
| 298 | + |
| 299 | +```yaml |
| 300 | +name: Security Scan |
| 301 | +on: |
| 302 | + pull_request: |
| 303 | + types: [opened, synchronize, reopened] |
| 304 | + |
| 305 | +jobs: |
| 306 | + security-scan: |
| 307 | + runs-on: ubuntu-latest |
| 308 | + steps: |
| 309 | + - uses: actions/checkout@v4 |
| 310 | + - name: Run security wrapper |
| 311 | + uses: ./ # when running from the same repo; replace with org/repo@vX for published action |
| 312 | + with: |
| 313 | + github_token: ${{ secrets.GITHUB_TOKEN }} |
| 314 | + python_sast_enabled: 'true' |
| 315 | + secret_scanning_enabled: 'true' |
| 316 | + dockerfile_enabled: 'true' |
| 317 | + socket_scanning_enabled: 'true' |
| 318 | + socket_org: 'your-socket-org' |
| 319 | + socket_api_key: ${{ secrets.SOCKET_API_KEY }} |
| 320 | +``` |
| 321 | + |
| 322 | +Make sure to set any secrets (Socket API keys, Jira tokens, Slack webhooks) using repository or organization secrets. |
| 323 | + |
| 324 | +## GitHub PR notifier environment variables |
| 325 | + |
| 326 | +When running in GitHub Actions or other CI, the GitHub PR notifier will attempt to discover repository and branch information from the environment first, then fall back to local `git` and finally any workspace `facts` that were provided. The notifier recognizes the following environment variables and action inputs (use whichever is most convenient in your workflow): |
| 327 | + |
| 328 | +- `GITHUB_REPOSITORY` — owner/repo identifier (e.g., `org/repo`). Automatically provided by GitHub Actions. |
| 329 | +- `GITHUB_EVENT_PATH` — path to the GitHub event JSON file (Actions provides this). The notifier will read the event payload to extract PR/head info when present. |
| 330 | +- `GITHUB_REF` / `GITHUB_HEAD_REF` — branch refs provided by the Actions runner. `GITHUB_HEAD_REF` is set for pull_request workflows; otherwise `GITHUB_REF` may contain `refs/heads/<branch>`. |
| 331 | +- `GITHUB_SHA` — commit SHA; used to build exact blob links when available. |
| 332 | +- `GITHUB_PR_NUMBER` — optional environment variable you can set to force the PR number to use when posting comments. |
| 333 | +- `INPUT_PR_NUMBER` — action input equivalent to `GITHUB_PR_NUMBER` (useful when invoking the action via `with:` in a workflow). |
| 334 | +- `INPUT_GITHUB_API_URL` — override the GitHub API base (useful for GitHub Enterprise). When set, it will be normalized to a full URL if a host-only string is provided. |
| 335 | + |
| 336 | +Priority for discovery is: explicit action inputs / environment variables → event payload → local `git` discovery → `facts` provided via `--workspace`. |
| 337 | + |
| 338 | +If you need to force a PR comment to a specific PR, set `GITHUB_PR_NUMBER` (or `INPUT_PR_NUMBER` in the action `with:` block). |
| 339 | + |
| 340 | + |
| 341 | +## Development & testing |
| 342 | + |
| 343 | +- Run unit and local tests from `local_tests/` or `app_tests/`. |
| 344 | +- Use `uv run` or `python -m` to execute modules while iterating. |
| 345 | + |
| 346 | +Local quick test example: |
| 347 | + |
| 348 | +```sh |
| 349 | +# activate venv |
| 350 | +source .venv/bin/activate |
| 351 | +# run a subset of local tests |
| 352 | +python -m pytest local_tests/test_simple_scan.py -q |
| 353 | +``` |
| 354 | + |
| 355 | +Keep test artifacts under `test_results/` (do not create test files outside that directory). |
| 356 | + |
| 357 | +## Troubleshooting |
| 358 | + |
| 359 | +- If connectors fail to load, verify `module_path` and `class` in `socket_basics/connectors.yaml`. |
| 360 | +- For Socket API or notifier errors, ensure `INPUT_SOCKET_ORG` and `INPUT_SOCKET_API_KEY` (or notifier secrets) are set. |
| 361 | +- Enable `--verbose` (or `INPUT_VERBOSE=true`) to see debug logs. |
| 362 | +- For image scanning failures, confirm Docker access inside the runtime environment. |
| 363 | + |
| 364 | +## Contributing |
| 365 | + |
| 366 | +1. Implement new connectors under `socket_basics/core/connector/`. |
| 367 | +2. Add notifier implementations under `socket_basics/core/notification/` if needed. |
| 368 | +3. Add configuration entries to `socket_basics/connectors.yaml` and `socket_basics/notifications.yaml`. |
| 369 | +4. Add sample test apps to `app_tests/`. |
| 370 | + |
| 371 | +## License |
| 372 | + |
| 373 | +This project is licensed under the terms in `LICENSE` in the repository root. |
| 374 | + |
0 commit comments