From 516d2a26cce3eae917f56ea69526ee11bd2961fa Mon Sep 17 00:00:00 2001 From: Vishal Date: Tue, 13 Jan 2026 20:56:37 +0530 Subject: [PATCH 1/2] Add Bandit security scanning to PR validation workflow --- .github/workflows/build_validation_develop.yml | 15 +++++++++++++++ pyproject.toml | 9 +++++++++ 2 files changed, 24 insertions(+) create mode 100644 pyproject.toml diff --git a/.github/workflows/build_validation_develop.yml b/.github/workflows/build_validation_develop.yml index abe806ddf..76b1bd7ef 100644 --- a/.github/workflows/build_validation_develop.yml +++ b/.github/workflows/build_validation_develop.yml @@ -103,6 +103,21 @@ jobs: VALIDATE_TSX: true VALIDATE_TYPESCRIPT_ES: true + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.11" + cache: "pip" + + - name: Install Bandit + if: ${{ steps.filter.outputs.core == 'true' }} + run: pip install bandit + + - name: Run Bandit security checks + if: ${{ steps.filter.outputs.core == 'true' }} + run: bandit -c pyproject.toml -r . + + - name: Docs validation if: ${{ steps.filter.outputs.docs == 'true' }} run: | diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..45f7c10cb --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,9 @@ +[tool.bandit] +exclude_dirs = [ + "api_app/tests_ma", + "airlock_processor/tests", + "resource_processor/tests_rp", + "e2e_tests", + ".venv", + "venv" +] From b9917b06236a4860528a4f15132f3e0c670ca985 Mon Sep 17 00:00:00 2001 From: Vishal Date: Mon, 9 Feb 2026 23:15:19 +0530 Subject: [PATCH 2/2] Suppress existing Bandit findings with documented justifications --- api_app/main.py | 8 +++++++- api_app/models/domain/costs.py | 13 ++++++++++--- pyproject.toml | 4 ++++ resource_processor/helpers/httpserver.py | 2 +- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/api_app/main.py b/api_app/main.py index 0bdc76914..ed4b507d2 100644 --- a/api_app/main.py +++ b/api_app/main.py @@ -74,4 +74,10 @@ def get_application() -> FastAPI: FastAPIInstrumentor.instrument_app(app) if __name__ == "__main__": - uvicorn.run(app, host="0.0.0.0", port=8000, loop="asyncio") + uvicorn.run( + app, + host="0.0.0.0", + port=8000, + loop="asyncio", +) # nosec B104 - intended for containerized deployment + diff --git a/api_app/models/domain/costs.py b/api_app/models/domain/costs.py index 192454b17..852f7a7dc 100644 --- a/api_app/models/domain/costs.py +++ b/api_app/models/domain/costs.py @@ -18,9 +18,16 @@ class CurrencyEnum(StrEnum): def generate_cost_row_dict_example(granularity: GranularityEnum, currency: CurrencyEnum): return dict({ - "cost": random.uniform(0, 365), "currency": currency, "date": - (datetime.today() - timedelta( - days=-1 * random.randint(0, 1000))).date() if granularity == GranularityEnum.daily else None + "cost": random.uniform(0, 365), # nosec B311 - non-cryptographic random for sample data + "currency": currency, + "date":( + datetime.today() + - timedelta( + days=-1 * random.randint(0, 1000) # nosec B311 - non-cryptographic random for sample data + ) + ).date() + if granularity == GranularityEnum.daily + else None, }) diff --git a/pyproject.toml b/pyproject.toml index 45f7c10cb..a92e4c50b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,3 +7,7 @@ exclude_dirs = [ ".venv", "venv" ] + +skips = [ + "B101", # asserts in test code +] diff --git a/resource_processor/helpers/httpserver.py b/resource_processor/helpers/httpserver.py index 25e63418f..28b3a36ec 100644 --- a/resource_processor/helpers/httpserver.py +++ b/resource_processor/helpers/httpserver.py @@ -13,5 +13,5 @@ class ThreadedHTTPServer(ThreadingMixIn, HTTPServer): def start_server(): - server = ThreadedHTTPServer(('0.0.0.0', 8080), RequestHandler) + server = ThreadedHTTPServer(('0.0.0.0', 8080), RequestHandler) # nosec B104 - intended for containerized/dev use server.serve_forever()