From 5cf0cd4c17ca4cb9fa22276dd7c80ef11472aff4 Mon Sep 17 00:00:00 2001 From: Trisham Bharat Patil Date: Tue, 7 Jul 2026 08:34:35 +0530 Subject: [PATCH] fix(deps): add boto3 dependency for AWS Bedrock support Add boto3 as a core dependency to fix ModuleNotFoundError when using AWS Bedrock LLM provider. Update Bedrock documentation with: - AWS SSO authentication (recommended for developers) - Complete working examples for web and local repo scans - Troubleshooting section for common Bedrock issues - Clarification on AWS_REGION_NAME vs AWS_REGION Fixes issue where users encounter "No module named 'boto3'" error when attempting to use bedrock/ model prefixed LLMs. Co-Authored-By: Claude Sonnet 4.5 (1M context) --- docs/advanced/configuration.mdx | 45 ++++++++++++-- docs/llm-providers/bedrock.mdx | 101 +++++++++++++++++++++++++++++--- pyproject.toml | 8 +++ uv.lock | 97 +++++++++++++++++++++++++++--- 4 files changed, 228 insertions(+), 23 deletions(-) diff --git a/docs/advanced/configuration.mdx b/docs/advanced/configuration.mdx index 5d56c9a16..9704f1cab 100644 --- a/docs/advanced/configuration.mdx +++ b/docs/advanced/configuration.mdx @@ -8,13 +8,29 @@ Configure Strix using environment variables or a config file. ## LLM Configuration - Model name in LiteLLM format (e.g., `openai/gpt-5.4`, `anthropic/claude-sonnet-4-6`). + Model name in LiteLLM format (e.g., `openai/gpt-5.4`, `anthropic/claude-sonnet-4-6`, `bedrock/anthropic.claude-sonnet-4-6`). API key for your LLM provider. Not required for local models or cloud provider auth (Vertex AI, AWS Bedrock). + + AWS CLI profile name for Bedrock authentication. Used with AWS SSO or named profiles. + + + + AWS region where Bedrock models are enabled. Required for AWS Bedrock. Note: Use `AWS_REGION_NAME` (not `AWS_REGION`) for LiteLLM compatibility. + + + + AWS access key ID for Bedrock authentication. Alternative to `AWS_PROFILE`. + + + + AWS secret access key for Bedrock authentication. Used with `AWS_ACCESS_KEY_ID`. + + Custom API base URL. Also accepts `OPENAI_API_BASE`, `LITELLM_BASE_URL`, or `OLLAMA_API_BASE`. @@ -115,16 +131,35 @@ strix --target ./app --config /path/to/config.json ## Example Setup +### OpenAI + ```bash -# Required export STRIX_LLM="openai/gpt-5.4" export LLM_API_KEY="sk-..." +``` + +### Anthropic Direct -# Optional: Enable web search +```bash +export STRIX_LLM="anthropic/claude-sonnet-4-6" +export LLM_API_KEY="sk-ant-..." +``` + +### AWS Bedrock + +```bash +export STRIX_LLM="bedrock/anthropic.claude-sonnet-4-6" +export AWS_PROFILE="your-sso-profile" +export AWS_REGION_NAME="us-east-1" +``` + +### Optional Features + +```bash +# Enable web search export PERPLEXITY_API_KEY="pplx-..." -# Optional: Custom timeouts +# Custom timeouts export LLM_TIMEOUT="600" export STRIX_SANDBOX_EXECUTION_TIMEOUT="300" - ``` diff --git a/docs/llm-providers/bedrock.mdx b/docs/llm-providers/bedrock.mdx index 2189e9876..2ca0a531a 100644 --- a/docs/llm-providers/bedrock.mdx +++ b/docs/llm-providers/bedrock.mdx @@ -6,29 +6,47 @@ description: "Configure Strix with models via AWS Bedrock" ## Setup ```bash -export STRIX_LLM="bedrock/anthropic.claude-4-5-sonnet-20251022-v1:0" +export STRIX_LLM="bedrock/anthropic.claude-sonnet-4-6" +export AWS_REGION_NAME="us-east-1" # Region where Bedrock is enabled ``` No API key required—uses AWS credentials from environment. +**Note:** Strix includes `boto3` as a dependency. If you installed via the binary installer and encounter issues, consider installing from source: `uv tool install git+https://github.com/usestrix/strix.git` + ## Authentication -### Option 1: AWS CLI Profile +### Option 1: AWS SSO Profile (Recommended for Developers) + +```bash +export AWS_PROFILE="your-sso-profile" +export AWS_REGION_NAME="us-east-1" + +# Ensure SSO session is active +aws sso login --profile your-sso-profile + +# Verify credentials +aws sts get-caller-identity --profile your-sso-profile +``` + +**Important:** Use `AWS_REGION_NAME` (not `AWS_REGION` or `AWS_DEFAULT_REGION`) for LiteLLM compatibility. + +### Option 2: AWS CLI Profile ```bash export AWS_PROFILE="your-profile" -export AWS_REGION="us-east-1" +export AWS_REGION_NAME="us-east-1" ``` -### Option 2: Access Keys +### Option 3: Access Keys ```bash export AWS_ACCESS_KEY_ID="AKIA..." export AWS_SECRET_ACCESS_KEY="..." -export AWS_REGION="us-east-1" +export AWS_REGION_NAME="us-east-1" ``` -### Option 3: IAM Role (EC2/ECS) +### Option 4: IAM Role (EC2/ECS) Automatically uses instance role credentials. @@ -36,12 +54,77 @@ Automatically uses instance role credentials. | Model | Description | |-------|-------------| -| `bedrock/anthropic.claude-4-5-sonnet-20251022-v1:0` | Claude 4.5 Sonnet | -| `bedrock/anthropic.claude-4-5-opus-20251022-v1:0` | Claude 4.5 Opus | -| `bedrock/anthropic.claude-4-5-haiku-20251022-v1:0` | Claude 4.5 Haiku | +| `bedrock/anthropic.claude-sonnet-4-6` | Claude 4.6 Sonnet (recommended) | +| `bedrock/anthropic.claude-opus-4-6` | Claude 4.6 Opus | +| `bedrock/anthropic.claude-4-5-sonnet-20251022-v1:0` | Claude 4.5 Sonnet (versioned) | +| `bedrock/anthropic.claude-4-5-opus-20251022-v1:0` | Claude 4.5 Opus (versioned) | +| `bedrock/anthropic.claude-4-5-haiku-20251022-v1:0` | Claude 4.5 Haiku (versioned) | | `bedrock/amazon.titan-text-premier-v2:0` | Amazon Titan Premier v2 | +**Note:** Use the simplified model IDs (e.g., `claude-sonnet-4-6`) rather than cross-region inference IDs (e.g., `eu.anthropic.claude-sonnet-4-6-v1`). + ## Prerequisites 1. Enable model access in the AWS Bedrock console 2. Ensure your IAM role/user has `bedrock:InvokeModel` permission +3. `boto3` package (included as dependency in Strix 1.0.5+) + +## Complete Working Example + +```bash +# Set environment variables +export AWS_PROFILE="your-sso-profile" +export AWS_REGION_NAME="eu-west-2" +export STRIX_LLM="bedrock/anthropic.claude-sonnet-4-6" + +# Ensure SSO session is active +aws sso login --profile $AWS_PROFILE + +# Run scan +strix -n -t https://example.com --scan-mode quick +``` + +### For Large Repositories (> 1GB) + +```bash +# Use --mount to bind-mount instead of copying +strix -n -t ./ --mount ./ --scan-mode standard +``` + +### List Available Models + +```bash +aws bedrock list-foundation-models \ + --region eu-west-2 \ + --query "modelSummaries[?contains(modelId,'claude')].modelId" \ + --output table +``` + +## Troubleshooting + +### Missing boto3 + +If you see `ModuleNotFoundError: No module named 'boto3'`: + +```bash +# For uv tool install +uv pip install boto3 --python ~/.local/share/uv/tools/strix-agent/bin/python3 + +# Or reinstall from source +uv tool uninstall strix-agent +uv tool install git+https://github.com/usestrix/strix.git +``` + +### SSO Session Expired + +```bash +aws sso login --profile your-profile +``` + +### Wrong Region + +Ensure the region matches where you enabled Bedrock models: + +```bash +export AWS_REGION_NAME="us-east-1" # Not AWS_REGION or AWS_DEFAULT_REGION +``` diff --git a/pyproject.toml b/pyproject.toml index 4485d7793..aaf03b293 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,11 +42,17 @@ dependencies = [ "requests>=2.32.0", "cvss>=3.2", "caido-sdk-client>=0.2.0", + "boto3>=1.28.0", # Required for AWS Bedrock LLM provider ] [project.scripts] strix = "strix.interface.main:main" +[project.optional-dependencies] +aws = [ + "boto3>=1.28.0", # AWS Bedrock support +] + [dependency-groups] dev = [ "mypy>=1.16.0", @@ -105,6 +111,8 @@ module = [ "docker.*", "caido_sdk_client.*", "pydantic_settings.*", + "boto3.*", + "botocore.*", ] ignore_missing_imports = true disable_error_code = ["import-untyped"] diff --git a/uv.lock b/uv.lock index 3afff462f..b43bf3e9b 100644 --- a/uv.lock +++ b/uv.lock @@ -244,6 +244,34 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/05/a4/a26d5b25671d27e03afb5401a0be5899d94ff8fab6a698b1ac5be3ec29ef/bandit-1.9.4-py3-none-any.whl", hash = "sha256:f89ffa663767f5a0585ea075f01020207e966a9c0f2b9ef56a57c7963a3f6f8e", size = 134741, upload-time = "2026-02-25T06:44:13.694Z" }, ] +[[package]] +name = "boto3" +version = "1.43.41" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "botocore" }, + { name = "jmespath" }, + { name = "s3transfer" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/79/5b/e91af651bf4e902f86b9e2f8bc09ca20dbd1ad3c1e21b70bf34651cf3cee/boto3-1.43.41.tar.gz", hash = "sha256:0f56811f13677bfb4542daa0cce8532c95d9afd27b4ba7b681af36a0568624ad", size = 112677, upload-time = "2026-07-06T19:39:38.788Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/4a/babb2de16f6ff0688697d2eac7d95566151c255f6b08f547306f57dabfc2/boto3-1.43.41-py3-none-any.whl", hash = "sha256:f48f862d2720ea9203ed2d842d436b8eb2d459ea31654a7ad7c0756fdf36c6b2", size = 140029, upload-time = "2026-07-06T19:39:37.125Z" }, +] + +[[package]] +name = "botocore" +version = "1.43.41" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jmespath" }, + { name = "python-dateutil" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6a/a1/48a0f38b0cac8196764607c0bca7e3ca50d3cffc825087b743d3635413f2/botocore-1.43.41.tar.gz", hash = "sha256:27627d79af0df7dcb7ecf78d8d3d1310da09a5e9460be30bf759f1c2ed095ee8", size = 15647567, upload-time = "2026-07-06T19:39:27.119Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/61/4f/19e0b97ce1801c66a4d1d35117f36240aa20f864338f093fccc23873a231/botocore-1.43.41-py3-none-any.whl", hash = "sha256:0cc6e79b30a2a98374f16a31cd9c7a9106a51b60650bd8c34cc8223f58ae6b8d", size = 15331199, upload-time = "2026-07-06T19:39:23.694Z" }, +] + [[package]] name = "caido-sdk-client" version = "0.2.0" @@ -937,6 +965,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/78/f7/18a1afcd64f35314b68c1f23afcd9994d0bc13e65cc77517afff4e83986d/jiter-0.16.0-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64d613743df53199b1aa256a7d328340da6d7078aac7705a7db9d7a791e9cfd2", size = 343885, upload-time = "2026-06-29T13:05:12.087Z" }, ] +[[package]] +name = "jmespath" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d3/59/322338183ecda247fb5d1763a6cbe46eff7222eaeebafd9fa65d4bf5cb11/jmespath-1.1.0.tar.gz", hash = "sha256:472c87d80f36026ae83c6ddd0f1d05d4e510134ed462851fd5f754c8c3cbb88d", size = 27377, upload-time = "2026-01-22T16:35:26.279Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/2f/967ba146e6d58cf6a652da73885f52fc68001525b4197effc174321d70b4/jmespath-1.1.0-py3-none-any.whl", hash = "sha256:a5663118de4908c91729bea0acadca56526eb2698e83de10cd116ae0f4e97c64", size = 20419, upload-time = "2026-01-22T16:35:24.919Z" }, +] + [[package]] name = "jsonschema" version = "4.26.0" @@ -1064,7 +1101,7 @@ name = "macholib" version = "1.16.4" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "altgraph" }, + { name = "altgraph", marker = "python_full_version < '3.15' and sys_platform != 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/10/2f/97589876ea967487978071c9042518d28b958d87b17dceb7cdc1d881f963/macholib-1.16.4.tar.gz", hash = "sha256:f408c93ab2e995cd2c46e34fe328b130404be143469e41bc366c807448979362", size = 59427, upload-time = "2025-11-22T08:28:38.373Z" } wheels = [ @@ -1683,13 +1720,13 @@ name = "pyinstaller" version = "6.21.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "altgraph" }, - { name = "macholib", marker = "sys_platform == 'darwin'" }, - { name = "packaging" }, - { name = "pefile", marker = "sys_platform == 'win32'" }, - { name = "pyinstaller-hooks-contrib" }, - { name = "pywin32-ctypes", marker = "sys_platform == 'win32'" }, - { name = "setuptools" }, + { name = "altgraph", marker = "python_full_version < '3.15'" }, + { name = "macholib", marker = "python_full_version < '3.15' and sys_platform == 'darwin'" }, + { name = "packaging", marker = "python_full_version < '3.15'" }, + { name = "pefile", marker = "python_full_version < '3.15' and sys_platform == 'win32'" }, + { name = "pyinstaller-hooks-contrib", marker = "python_full_version < '3.15'" }, + { name = "pywin32-ctypes", marker = "python_full_version < '3.15' and sys_platform == 'win32'" }, + { name = "setuptools", marker = "python_full_version < '3.15'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/d5/4d/ec706c3fcf39e26888c35b39615ff4d5865d184069666c47492cff1fbe50/pyinstaller-6.21.0.tar.gz", hash = "sha256:bb9fab705983e393a2d1cac77d6972513057ad800215fd861dc15ff5272e98fd", size = 4061519, upload-time = "2026-06-13T14:15:06.25Z" } wheels = [ @@ -1711,7 +1748,7 @@ name = "pyinstaller-hooks-contrib" version = "2026.6" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "packaging" }, + { name = "packaging", marker = "python_full_version < '3.15'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/94/5b/c9fe0db5e83ee1c39b2258fa21d23b15e1a60786b6c5990ee5074ead8bb6/pyinstaller_hooks_contrib-2026.6.tar.gz", hash = "sha256:bef5002c32f4f50bd55b005da12cff64eca8783e7eaf86a06a62410164bab725", size = 173354, upload-time = "2026-06-08T22:37:16.152Z" } wheels = [ @@ -1774,6 +1811,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/03/e2/08a497ef684b88559c9cc5f4ad53a37e7b99e727094a86d6ea32536d5d3c/pytest_asyncio-1.4.0-py3-none-any.whl", hash = "sha256:933ca923a23075a87fb7070c0ec272a6848489824d887c85c812670932835aa1", size = 16930, upload-time = "2026-05-26T09:56:02.576Z" }, ] +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, +] + [[package]] name = "python-discovery" version = "1.4.2" @@ -2144,6 +2193,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d7/2b/9555445e1201d92b3195f45cdb153a0b68f24e0a4273f6e3d5ab46e212bb/ruff-0.15.20-py3-none-win_arm64.whl", hash = "sha256:2f5b2a6d614e8700388806a14996c40fab2c47b819ef57d790a34878858ed9ca", size = 11343498, upload-time = "2026-06-25T17:20:35.03Z" }, ] +[[package]] +name = "s3transfer" +version = "0.19.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "botocore" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f6/94/dcdaeb1713cab9c84def276cfac7388b17c7d9855bbcfe88d77e4dbafd44/s3transfer-0.19.0.tar.gz", hash = "sha256:ce436931687addc4c1712d52d40b32f53e88315723f107ffa20ba82b05a0f685", size = 165171, upload-time = "2026-06-16T19:44:51.599Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/5f/4c174edad94f82de888ac00a5ddd8d07b35609b6c94f0bdf4d74af57703e/s3transfer-0.19.0-py3-none-any.whl", hash = "sha256:777cc2415536f1debadb5c2ef7779275d0fc0fe0e042411cdd6caebeb2685262", size = 90101, upload-time = "2026-06-16T19:44:50.439Z" }, +] + [[package]] name = "setuptools" version = "82.0.1" @@ -2162,6 +2223,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, ] +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, +] + [[package]] name = "sniffio" version = "1.3.1" @@ -2211,6 +2281,7 @@ name = "strix-agent" version = "1.0.4" source = { editable = "." } dependencies = [ + { name = "boto3" }, { name = "caido-sdk-client" }, { name = "cvss" }, { name = "docker" }, @@ -2222,6 +2293,11 @@ dependencies = [ { name = "textual" }, ] +[package.optional-dependencies] +aws = [ + { name = "boto3" }, +] + [package.dev-dependencies] dev = [ { name = "bandit" }, @@ -2236,6 +2312,8 @@ dev = [ [package.metadata] requires-dist = [ + { name = "boto3", specifier = ">=1.28.0" }, + { name = "boto3", marker = "extra == 'aws'", specifier = ">=1.28.0" }, { name = "caido-sdk-client", specifier = ">=0.2.0" }, { name = "cvss", specifier = ">=3.2" }, { name = "docker", specifier = ">=7.1.0" }, @@ -2246,6 +2324,7 @@ requires-dist = [ { name = "rich" }, { name = "textual", specifier = ">=6.0.0" }, ] +provides-extras = ["aws"] [package.metadata.requires-dev] dev = [