Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ jobs:
run: |
make create_isolation_wheels
pip install --find-links "${{ github.workspace }}/dist" \
"${{ github.workspace }}/dist/roboflow_workflows-0.1.1-py3-none-any.whl[enterprise]" \
"$(ls "${{ github.workspace }}"/dist/roboflow_workflows-*.whl)[enterprise]" \
"${{ github.workspace }}"/dist/inference_sdk-*.whl \
"${{ github.workspace }}"/dist/inference_models-*.whl

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,6 @@ jobs:
- name: 🏗️ Build and install roboflow-workflows wheel
run: |
make create_workflows_wheel
pip install --find-links "${{ github.workspace }}/dist" "${{ github.workspace }}/dist/roboflow_workflows-0.1.1-py3-none-any.whl[enterprise]"
pip install --find-links "${{ github.workspace }}/dist" "$(ls "${{ github.workspace }}"/dist/roboflow_workflows-*.whl)[enterprise]"
- name: 🧪 Integration Tests of Inference CLI
run: RUN_TESTS_WITH_INFERENCE_PACKAGE=True INFERENCE_CLI_TESTS_API_KEY=${{ secrets.LOAD_TEST_PRODUCTION_API_KEY }} python -m pytest tests/inference_cli/integration_tests/test_workflows.py
2 changes: 1 addition & 1 deletion .github/workflows/integration_tests_inference_models.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ jobs:
- name: 🏗️ Build and install roboflow-workflows wheel
run: |
make create_workflows_wheel
pip install --find-links "${{ github.workspace }}/dist" "${{ github.workspace }}/dist/roboflow_workflows-0.1.1-py3-none-any.whl"
pip install --find-links "${{ github.workspace }}/dist" "${{ github.workspace }}"/dist/roboflow_workflows-*.whl
- name: 🧪 Integration Tests of Inference models
timeout-minutes: 45
run: USE_INFERENCE_MODELS=False MAX_BATCH_SIZE=6 python -m pytest tests/inference/models_predictions_tests
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ jobs:
- name: 🏗️ Build and install roboflow-workflows wheel (with enterprise extra)
run: |
make create_workflows_wheel
pip install --find-links "${{ github.workspace }}/dist" "${{ github.workspace }}/dist/roboflow_workflows-0.1.1-py3-none-any.whl[enterprise]"
pip install --find-links "${{ github.workspace }}/dist" "$(ls "${{ github.workspace }}"/dist/roboflow_workflows-*.whl)[enterprise]"
- name: 🧪 Integration Tests of Workflows (tensor-native)
# Tensor-native path only: ENABLE_TENSOR_DATA_REPRESENTATION is AND-gated with
# USE_INFERENCE_MODELS, which defaults to True on Linux runners, so it is not set here.
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/integration_tests_workflows_x86.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ jobs:
- name: 🏗️ Build and install roboflow-workflows wheel (with enterprise extra)
run: |
make create_workflows_wheel
pip install --find-links "${{ github.workspace }}/dist" "${{ github.workspace }}/dist/roboflow_workflows-0.1.1-py3-none-any.whl[enterprise]"
pip install --find-links "${{ github.workspace }}/dist" "$(ls "${{ github.workspace }}"/dist/roboflow_workflows-*.whl)[enterprise]"
- name: 🧪 Integration Tests of Workflows
env:
POSTGRESQL_TEST_DSN: "host=localhost port=5432 dbname=postgres user=postgres password=postgres-test-only sslmode=disable"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test_package_install_inference.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ jobs:
${{ runner.os }}-pip-${{ matrix.python-version }}-
- name: 📦 Installing `inference` package...
run: |
pip install --find-links dist/ ./dist/inference-*-py3-none-any.whl ./dist/inference_sdk-*-py3-none-any.whl ./dist/inference_models-*-py3-none-any.whl "${{ github.workspace }}/dist/roboflow_workflows-0.1.1-py3-none-any.whl[enterprise]"
pip install --find-links dist/ ./dist/inference-*-py3-none-any.whl ./dist/inference_sdk-*-py3-none-any.whl ./dist/inference_models-*-py3-none-any.whl "$(ls "${{ github.workspace }}"/dist/roboflow_workflows-*.whl)[enterprise]"
# Dependencies were resolved above; now replace any same-version
# build-environment installs with the exact checkout artifacts.
pip install --force-reinstall --no-deps ./dist/roboflow_workflows-*.whl ./dist/inference_sdk-*.whl ./dist/inference_models-*.whl
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test_package_install_inference_gpu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ jobs:
export LD_LIBRARY_PATH=/usr/local/cuda-12.5/targets/x86_64-linux/lib64:$LD_LIBRARY_PATH
export CPATH=/usr/local/cuda-12.5/targets/x86_64-linux/include:$CPATH
export LIBRARY_PATH=/usr/local/cuda-12.5/targets/x86_64-linux/lib64:$LIBRARY_PATH
pip install --find-links dist/ ./dist/inference_gpu-*-py3-none-any.whl ./dist/inference_sdk-*-py3-none-any.whl ./dist/inference_models-*-py3-none-any.whl "${{ github.workspace }}/dist/roboflow_workflows-0.1.1-py3-none-any.whl[enterprise]"
pip install --find-links dist/ ./dist/inference_gpu-*-py3-none-any.whl ./dist/inference_sdk-*-py3-none-any.whl ./dist/inference_models-*-py3-none-any.whl "$(ls "${{ github.workspace }}"/dist/roboflow_workflows-*.whl)[enterprise]"
# Dependencies were resolved above; now replace any same-version
# build-environment installs with the exact checkout artifacts.
pip install --force-reinstall --no-deps ./dist/roboflow_workflows-*.whl ./dist/inference_sdk-*.whl ./dist/inference_models-*.whl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ jobs:
export CPATH=/usr/local/cuda-12.5/targets/x86_64-linux/include:$CPATH
export LIBRARY_PATH=/usr/local/cuda-12.5/targets/x86_64-linux/lib64:$LIBRARY_PATH
wheel_name=`ls ./dist/inference_gpu-*-py3-none-any.whl | head -n 1`
pip install --find-links dist/ "${wheel_name}[clip,grounding-dino,sam,waf,yolo-world,http,hosted,transformers]" ./dist/inference_sdk-*-py3-none-any.whl ./dist/inference_models-*-py3-none-any.whl "${{ github.workspace }}/dist/roboflow_workflows-0.1.1-py3-none-any.whl[enterprise]"
pip install --find-links dist/ "${wheel_name}[clip,grounding-dino,sam,waf,yolo-world,http,hosted,transformers]" ./dist/inference_sdk-*-py3-none-any.whl ./dist/inference_models-*-py3-none-any.whl "$(ls "${{ github.workspace }}"/dist/roboflow_workflows-*.whl)[enterprise]"
# Dependencies were resolved above; now replace any same-version
# build-environment installs with the exact checkout artifacts.
pip install --force-reinstall --no-deps ./dist/roboflow_workflows-*.whl ./dist/inference_sdk-*.whl ./dist/inference_models-*.whl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ jobs:
- name: 📦 Installing `inference` package...
run: |
wheel_name=`ls ./dist/inference-*-py3-none-any.whl | head -n 1`
pip install --find-links dist/ "${wheel_name}[clip,grounding-dino,sam,waf,yolo-world,http,hosted,transformers]" ./dist/inference_sdk-*-py3-none-any.whl ./dist/inference_models-*-py3-none-any.whl "${{ github.workspace }}/dist/roboflow_workflows-0.1.1-py3-none-any.whl[enterprise]"
pip install --find-links dist/ "${wheel_name}[clip,grounding-dino,sam,waf,yolo-world,http,hosted,transformers]" ./dist/inference_sdk-*-py3-none-any.whl ./dist/inference_models-*-py3-none-any.whl "$(ls "${{ github.workspace }}"/dist/roboflow_workflows-*.whl)[enterprise]"
# Dependencies were resolved above; now replace any same-version
# build-environment installs with the exact checkout artifacts.
pip install --force-reinstall --no-deps ./dist/roboflow_workflows-*.whl ./dist/inference_sdk-*.whl ./dist/inference_models-*.whl
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/unit_tests_inference_cli_x86.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ jobs:
- name: 🏗️ Build and install roboflow-workflows wheel
run: |
make create_workflows_wheel
pip install --find-links "${{ github.workspace }}/dist" "${{ github.workspace }}/dist/roboflow_workflows-0.1.1-py3-none-any.whl[enterprise]"
pip install --find-links "${{ github.workspace }}/dist" "$(ls "${{ github.workspace }}"/dist/roboflow_workflows-*.whl)[enterprise]"
- name: 🧪 Unit Tests of Inference CLI
timeout-minutes: 30
run: python -m pytest tests/inference_cli/unit_tests
2 changes: 1 addition & 1 deletion .github/workflows/unit_tests_inference_x86.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jobs:
- name: 🏗️ Build and install roboflow-workflows wheel
run: |
make create_workflows_wheel
pip install --find-links "${{ github.workspace }}/dist" "${{ github.workspace }}/dist/roboflow_workflows-0.1.1-py3-none-any.whl[enterprise]"
pip install --find-links "${{ github.workspace }}/dist" "$(ls "${{ github.workspace }}"/dist/roboflow_workflows-*.whl)[enterprise]"
- name: 🧪 Unit Tests of Inference
timeout-minutes: 30
run: python -m pytest tests/inference/unit_tests tests/unit/core/cache/test_air_gapped.py
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jobs:
- name: 🏗️ Build roboflow-workflows + SDK + inference-models wheels
run: make create_isolation_wheels
- name: 📦 Install roboflow-workflows (test + enterprise extras) from local wheel
run: pip install --find-links "${{ github.workspace }}/dist" "${{ github.workspace }}/dist/roboflow_workflows-0.1.1-py3-none-any.whl[test,enterprise]" "${{ github.workspace }}"/dist/inference_sdk-*.whl "${{ github.workspace }}"/dist/inference_models-*.whl
run: pip install --find-links "${{ github.workspace }}/dist" "$(ls "${{ github.workspace }}"/dist/roboflow_workflows-*.whl)[test,enterprise]" "${{ github.workspace }}"/dist/inference_sdk-*.whl "${{ github.workspace }}"/dist/inference_models-*.whl
- name: 🧪 Server unit tests (tensor-native)
# ENABLE_TENSOR_DATA_REPRESENTATION is AND-gated with USE_INFERENCE_MODELS,
# which defaults to True on Linux runners, so the tensor-native code path is exercised.
Expand Down Expand Up @@ -92,13 +92,14 @@ jobs:
- name: Install only standalone package dependencies
run: |
pip install --find-links "${{ github.workspace }}/dist" \
"${{ github.workspace }}/dist/roboflow_workflows-0.1.1-py3-none-any.whl[test,enterprise]" \
"$(ls "${{ github.workspace }}"/dist/roboflow_workflows-*.whl)[test,enterprise]" \
"${{ github.workspace }}"/dist/inference_sdk-*.whl \
"${{ github.workspace }}"/dist/inference_models-*.whl
pip check
- name: Package unit and installed-wheel isolation tests
working-directory: workflows
env:
WORKFLOWS_ISOLATION_WHEEL: ${{ github.workspace }}/dist/roboflow_workflows-0.1.1-py3-none-any.whl
WORKFLOWS_ISOLATION_FIND_LINKS: ${{ github.workspace }}/dist
run: python -m pytest tests/unit_tests tests/isolation
run: |
WORKFLOWS_ISOLATION_WHEEL="$(ls "${{ github.workspace }}"/dist/roboflow_workflows-*.whl)" \
python -m pytest tests/unit_tests tests/isolation
9 changes: 5 additions & 4 deletions .github/workflows/unit_tests_workflows_x86.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jobs:
- name: 🏗️ Build roboflow-workflows + SDK + inference-models wheels
run: make create_isolation_wheels
- name: 📦 Install roboflow-workflows (test + enterprise extras) from local wheel
run: pip install --find-links "${{ github.workspace }}/dist" "${{ github.workspace }}/dist/roboflow_workflows-0.1.1-py3-none-any.whl[test,enterprise]" "${{ github.workspace }}"/dist/inference_sdk-*.whl "${{ github.workspace }}"/dist/inference_models-*.whl
run: pip install --find-links "${{ github.workspace }}/dist" "$(ls "${{ github.workspace }}"/dist/roboflow_workflows-*.whl)[test,enterprise]" "${{ github.workspace }}"/dist/inference_sdk-*.whl "${{ github.workspace }}"/dist/inference_models-*.whl
- name: 🧪 Server unit tests
timeout-minutes: 30
run: python -m pytest tests/workflows/unit_tests
Expand Down Expand Up @@ -90,13 +90,14 @@ jobs:
- name: Install only standalone package dependencies
run: |
pip install --find-links "${{ github.workspace }}/dist" \
"${{ github.workspace }}/dist/roboflow_workflows-0.1.1-py3-none-any.whl[test,enterprise]" \
"$(ls "${{ github.workspace }}"/dist/roboflow_workflows-*.whl)[test,enterprise]" \
"${{ github.workspace }}"/dist/inference_sdk-*.whl \
"${{ github.workspace }}"/dist/inference_models-*.whl
pip check
- name: Package unit and installed-wheel isolation tests
working-directory: workflows
env:
WORKFLOWS_ISOLATION_WHEEL: ${{ github.workspace }}/dist/roboflow_workflows-0.1.1-py3-none-any.whl
WORKFLOWS_ISOLATION_FIND_LINKS: ${{ github.workspace }}/dist
run: python -m pytest tests/unit_tests tests/isolation
run: |
WORKFLOWS_ISOLATION_WHEEL="$(ls "${{ github.workspace }}"/dist/roboflow_workflows-*.whl)" \
python -m pytest tests/unit_tests tests/isolation
2 changes: 1 addition & 1 deletion inference/core/version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "1.6.1"
__version__ = "1.6.2"


if __name__ == "__main__":
Expand Down
2 changes: 1 addition & 1 deletion requirements/requirements.workflows.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# keep in sync with workflows/pyproject.toml version
roboflow-workflows[enterprise]==0.1.1
roboflow-workflows[enterprise]==0.1.2
8 changes: 8 additions & 0 deletions workflows/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@

---

## `0.1.2`

### Fixed

- Webhook sink: SSRF hardening (destination validation, DNS pinning, redirect and proxy refusal) now applies only when `ALLOW_WEBHOOK_WORKFLOWS_SINK_TO_NON_GLOBAL_ADDRESSES=false`. The default restores the previous plain `requests` transport, so environment `HTTP_PROXY` / `HTTPS_PROXY` work again.

---

## `0.1.1`

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion workflows/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "roboflow-workflows"
version = "0.1.1"
version = "0.1.2"
description = "Roboflow Workflows execution engine and block library"
readme = "README.md"
license = {file = "LICENSE"}
Expand Down
58 changes: 49 additions & 9 deletions workflows/roboflow_workflows/core_steps/sinks/webhook/v1.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,21 @@

### Supported destinations

By default (`ALLOW_WEBHOOK_WORKFLOWS_SINK_TO_NON_GLOBAL_ADDRESSES=true`) requests
are sent with plain `requests` semantics: environment proxies are honoured,
redirects are followed, and any destination is allowed. This preserves existing
self-hosted private-network webhooks.

Set `ALLOW_WEBHOOK_WORKFLOWS_SINK_TO_NON_GLOBAL_ADDRESSES=false` to enable the
hardened transport:

* Only `http://` and `https://` URLs are accepted.
* Set `ALLOW_WEBHOOK_WORKFLOWS_SINK_TO_NON_GLOBAL_ADDRESSES=false` to require
destinations to resolve exclusively to public, globally routable unicast addresses.
This rejects loopback, private (RFC1918), link-local (including cloud metadata
endpoints), CGNAT, reserved, and multicast targets.
* Destinations must resolve exclusively to public, globally routable unicast
addresses. This rejects loopback, private (RFC1918), link-local (including
cloud metadata endpoints), CGNAT, reserved, and multicast targets.
* HTTP redirects are rejected and reported as a failed notification; the
`Location` header is not followed.
* Non-global destinations are allowed by default to preserve existing self-hosted
private-network webhooks.
* Environment HTTP(S) proxies are refused.

### Setting Query Parameters
You can easily set query parameters for your request:
Expand Down Expand Up @@ -532,6 +538,7 @@ def execute_request(


ALLOWED_METHODS = ("GET", "POST", "PUT")
METHOD_TO_HANDLER = {"GET": requests.get, "POST": requests.post, "PUT": requests.put}


def _execute_request(
Expand All @@ -546,6 +553,17 @@ def _execute_request(
) -> None:
if method not in ALLOWED_METHODS:
raise ValueError(f"Handler for HTTP method `{method}` not registered")
if ALLOW_WEBHOOK_WORKFLOWS_SINK_TO_NON_GLOBAL_ADDRESSES:
return _execute_request_legacy(
url=url,
method=method,
query_parameters=query_parameters,
headers=headers,
json_payload=json_payload,
form_data=form_data,
multi_part_encoded_files=multi_part_encoded_files,
timeout=timeout,
)
# Reject a backslash in the raw authority before Requests normalises it.
# `urlsplit` accepts \ in the netloc, but urllib3 later interprets it as a
# path separator, which can smuggle a target past a scheme/host review.
Expand All @@ -569,9 +587,7 @@ def _execute_request(
# the body (the block does not consume it), and `allow_redirects` is not
# honoured by an adapter's `send()` so a 3xx surfaces here.
with contextlib.closing(
SSRFProtectedHTTPAdapter(
allow_non_global_addresses=ALLOW_WEBHOOK_WORKFLOWS_SINK_TO_NON_GLOBAL_ADDRESSES
)
SSRFProtectedHTTPAdapter(allow_non_global_addresses=False)
) as adapter:
with contextlib.closing(
adapter.send(
Expand All @@ -584,3 +600,27 @@ def _execute_request(
if 300 <= response.status_code < 400:
raise requests.HTTPError("Webhook redirects are not allowed")
response.raise_for_status()


def _execute_request_legacy(
url: str,
method: Literal["GET", "POST", "PUT"],
query_parameters: Dict[str, Any],
headers: Dict[str, Any],
json_payload: Dict[str, Any],
form_data: Dict[str, Any],
multi_part_encoded_files: Dict[str, Any],
timeout: int,
) -> None:
# Pre-SSRF-hardening transport, kept verbatim: plain `requests`, env proxies
# honoured, redirects followed, no destination validation.
response = METHOD_TO_HANDLER[method](
url,
params=query_parameters,
headers=headers,
json=json_payload,
files=multi_part_encoded_files,
data=form_data,
timeout=timeout,
)
response.raise_for_status()
Loading
Loading