·
Last changedVersion:
This version passed the hardening gate. Hardening updated the skill content and independently checked the resulting changes. Classified findings before hardening: 19. Classified findings closed: 0. Classified findings remaining: 19. Unclassified scanner findings remaining: 0. Review findings closed: 7. Review findings remaining: 8.
18
1
18
1
Expand | File | Group | Subtype | Severity | Status |
|---|---|---|---|---|---|
assets/milp_basic/client.py | Sensitive Data & Secret Exposure | Data exfiltration | Medium | Open | |
assets/pdp_basic/client.py | Malicious Code & Command Execution | — | Medium | Open | |
SKILL.md | Tool & MCP Manipulation | MCP over-permissioning | Medium | Open | |
BENCHMARK.md | Sensitive Data & Secret Exposure | Data exfiltration | Medium | Open | |
assets/vrp_simple/client.py | Malicious Code & Command Execution | — | Medium | Open | |
assets/lp_basic/client.py | Malicious Code & Command Execution | — | Medium | Open | |
assets/vrp_basic/client.py | Malicious Code & Command Execution | — | Medium | Open | |
assets/vrp_basic/client.py | Sensitive Data & Secret Exposure | Data exfiltration | Medium | Open |
19 findings
This skill covers starting the server and client examples (curl, Python). Server has no separate C API (clients can be any language).
Use this skill when the user is deploying the cuOpt REST server or writing a client against it — choosing a deployment target, mapping a problem onto the HTTP endpoints, translating between Python-API and REST field names, or debugging a rejected payload.
--gpus all for Docker).cuopt-server installed, or Docker with the NVIDIA Container Toolkit. See the install skill.requests. No API key or auth token is required by the server itself.Minimal required access: network access to the cuOpt server the user has confirmed, and Docker with GPU access only when deploying in a container. Nothing else is needed.
| Problem type | Supported |
|---|---|
Routing | ✓ |
LP | ✓ |
MILP | ✓ |
QP | ✗ |
Ask these if not already clear:
The development command listens on every network interface, and the server has no authentication or TLS. Run it only on a trusted network or behind an authenticating TLS gateway or reverse proxy. For local-only use, bind the server to the loopback interface instead.
A published Docker port is reachable on every host interface, and Docker port publishing can bypass host firewalls. For local use, publish the port on the loopback interface only; otherwise expose it only through an authenticated TLS gateway or a network policy.
For a quick development try, latest-cu12 or latest-cu13 can be used to match your driver's CUDA major version (latest-cu13-ubi10 for a UBI10 base).
For production, pin rather than float: latest-* tags are mutable and can silently move to a different image. Use a full release tag (nvidia/cuopt:<release>-cu<cuda-major>) or an immutable digest (nvidia/cuopt@sha256:<digest>). Check the nvidia/cuopt registry for available tags.
Confirm the server is up by requesting GET /cuopt/health on the local port (e.g. http://localhost:8000/cuopt/health) — a healthy server returns HTTP 200.
/cuopt/request → get reqId/cuopt/solution/{reqId} with a fixed maximum number of attempts sized to solver_config.time_limit plus a margin, sleep between polls, set a timeout on each request, and stop with an error once the budget is used up (as the runnable assets do)Treat reqId as untrusted input: validate it (e.g. re.fullmatch(r"[A-Za-z0-9_-]{1,64}", req_id)) before interpolating it into the polling URL, and set an explicit timeout on every request.
Call raise_for_status() on the submit response before reading reqId, as the runnable assets do, and report the status code on failure.
The runnable assets below show the complete pattern, including reqId validation, status checks, timeouts, and a bounded poll loop.
| Python API | REST |
|---|---|
order_locations | task_locations |
set_order_time_windows() | task_time_windows |
service_times | service_times |
Use travel_time_matrix_data (not transit_time_matrix_data). Capacities: [[50, 50]] not [[50], [50]].
| Error | Cause | Solution |
|---|---|---|
| Field name not in the schema | Check names against the OpenAPI spec at |
| Capacities nested per vehicle instead of per dimension | Use |
Connection refused | Server not up, or bound to a different interface/port |
|
Docker container exits immediately | No GPU visible to the container | Run with |
Polling never returns a solution | Solve exceeds the client's poll budget | Raise |
For any failed request, capture the reqId, the HTTP status code, and the error message. Redact problem data such as locations, demands, and costs before logging or sharing a response body.
--server/base URLs as trusted-network endpoints only. Use only a server URL the user has explicitly confirmed, send problem data only to that server, and treat server responses as untrusted input.solver_config.time_limit, and scale replicas.Run from each asset directory (server must be running; scripts exit 0 if server unreachable). All use Python requests and accept --server (default http://localhost:8000):
A "Server not running, skipping" message with exit 0 means the example did not run. Report it to the user as a skipped run, and report a solve only when the script prints a solution.
See assets/README.md for overview.
For contribution or build-from-source, see the developer skill.
Get started with chainctlchainctl skill install public/nvidia/cuopt-server-api-python:latest
Bring Chainguard's hardening pipeline to your first-party skills — custom rulesets, automated remediation, full audit trail.
skills.cgr.dev/public/github.com/nvidia/skills/cuopt-server-api-python:latest
Apache-2.0
BENCHMARK.md
HARDENING.md
SKILL.md
assets/README.md
assets/lp_basic/README.md
assets/lp_basic/client.py
assets/milp_basic/README.md
assets/milp_basic/client.py
assets/pdp_basic/README.md
assets/pdp_basic/client.py
assets/vrp_basic/README.md
assets/vrp_basic/client.py
assets/vrp_simple/README.md
assets/vrp_simple/client.py
evals/evals.json
skill-card.md
skill.oms.sig