Skip to content

Commit de0d81f

Browse files
m-messerclaude
andauthored
Release: main → prod (#23)
* Added GitHub Actions release workflow and updated build workflow to trigger on version tags (#18) * Feature/release workflow (#20) * Added GitHub Actions release workflow and updated build workflow to trigger on version tags * Triggered evaluation-function-base release from release workflow * Updated GitHub Actions build workflow to enable `latest` image tagging only for tag refs (#22) * Add µEd OpenAPI validation middleware (#17) * Added OpenAPI request/response validation middleware and integrated OpenAPI specification * Add embedded µEd OpenAPI specification Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Move µEd OpenAPI spec into runtime/schema Relocates the spec from api/ into runtime/schema/ alongside the existing JSON schema files, and renames it to mued_v0.1.0.yml to make the version explicit. Removes the api/ package; embed is now owned by runtime/schema. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Ignore .idea/ directory Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Make OpenAPI response validation strict for µEd routes Previously, responses that failed spec validation were only logged as warnings and forwarded anyway. Now a failed µEd response validation returns 500 to the caller. The legacy / route is unaffected — it has no matching path in the spec so the middleware passes it through unchanged. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Update Go version to 1.25 in Dockerfile for builder stage * Support OpenAPI 3.1.0 spec in router validation Pass IsOpenAPI31OrLater and AllowExtraSiblingFields options to the legacy router so description/summary siblings on $ref objects (valid in 3.1.0) don't fail validation. Also propagate errors from OpenAPIMiddleware and NewHttpServer instead of ignoring them. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Refactor error responses and improve OpenAPI middleware robustness Use `writeJSONError` helper for consistent JSON error responses in µEd handler. Enhance OpenAPI response validation to prevent buffer drainage during snapshot handling. * Add health status response to µEd handler based on test results * Update µEd test assertion to verify "status" field instead of "tests_passed" field --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * Feature/sandboxed workers (#21) * Added Linux-only nsjail-based sandboxing for worker processes, including CLI support, configuration, and testing. * Added validation for `Content-Length` in `headerPrefixPipe` and tests for oversized and negative values * Enhanced `build.yml` to compile and install nsjail from source instead of using system package. * Switched nsjail mode from "once" to "exec" for direct command execution with inherited stdio. * Replaced `--time_limit` with `--rlimit_cpu` in nsjail arguments to ensure compatibility in containers without cgroupv2. * Updated sandbox test to replace `--time_limit` with `--rlimit_cpu` and adjusted workflow to run integration tests with elevated permissions. * Feature/mu ed versioning (#14) * Added `MuEdHandler` to handle `/evaluate` and `/evaluate/health` endpoints with authentication and runtime integration, along with associated tests * Added `workflow_dispatch` trigger to GitHub Actions build workflow * Removed `NewCommandRoute` and corrected route definitions for `/evaluate` and `/evaluate/health` * Added `NormalizePath` middleware to canonicalize `/evaluate` and `/evaluate/health` paths across server and lambda integrations * Added API versioning support for `/evaluate` and `/evaluate/health` endpoints with header validation, default version handling, and capability reporting * Added OpenAPI request/response validation middleware and integrated OpenAPI specification * Add embedded µEd OpenAPI specification Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Move µEd OpenAPI spec into runtime/schema Relocates the spec from api/ into runtime/schema/ alongside the existing JSON schema files, and renames it to mued_v0.1.0.yml to make the version explicit. Removes the api/ package; embed is now owned by runtime/schema. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Ignore .idea/ directory Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Make OpenAPI response validation strict for µEd routes Previously, responses that failed spec validation were only logged as warnings and forwarded anyway. Now a failed µEd response validation returns 500 to the caller. The legacy / route is unaffected — it has no matching path in the spec so the middleware passes it through unchanged. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Simplify µEd response encoding by removing unnecessary "status" field logic --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * Feature/mu ed error handling (#15) * Added `MuEdHandler` to handle `/evaluate` and `/evaluate/health` endpoints with authentication and runtime integration, along with associated tests * Added `workflow_dispatch` trigger to GitHub Actions build workflow * Removed `NewCommandRoute` and corrected route definitions for `/evaluate` and `/evaluate/health` * Added `NormalizePath` middleware to canonicalize `/evaluate` and `/evaluate/health` paths across server and lambda integrations * Added API versioning support for `/evaluate` and `/evaluate/health` endpoints with header validation, default version handling, and capability reporting * Refactored `/evaluate` and `/evaluate/health` error handling to standardize JSON responses with `writeMuEdError` and included `X-Api-Version` header validation and degraded health status support. * Added OpenAPI request/response validation middleware and integrated OpenAPI specification * Add embedded µEd OpenAPI specification Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Move µEd OpenAPI spec into runtime/schema Relocates the spec from api/ into runtime/schema/ alongside the existing JSON schema files, and renames it to mued_v0.1.0.yml to make the version explicit. Removes the api/ package; embed is now owned by runtime/schema. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Ignore .idea/ directory Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Make OpenAPI response validation strict for µEd routes Previously, responses that failed spec validation were only logged as warnings and forwarded anyway. Now a failed µEd response validation returns 500 to the caller. The legacy / route is unaffected — it has no matching path in the spec so the middleware passes it through unchanged. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Update µEd handler to use dynamic status codes for responses --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * Fix referenceSolution content extraction to match µEd spec The spec defines task.referenceSolution as a plain object with additionalProperties, not a typed Submission wrapper. Change MuEdTask.ReferenceSolution from *MuEdSubmission to map[string]any and extract its content directly using the submission's type to determine the expected key. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Fix flaky test by replacing time.After with m.Shutdown for synchronization Replace the 1ms timing-based wait with pool.Close() via m.Shutdown, consistent with all other tests in the file that rely on the same background goroutine pattern. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 4499068 commit de0d81f

30 files changed

Lines changed: 3554 additions & 66 deletions

.github/workflows/build.yml

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,41 @@ jobs:
8383
# name: Go-results
8484
# path: TestResults.json
8585

86+
test-sandbox:
87+
name: Sandbox Integration Tests
88+
runs-on: ubuntu-latest
89+
steps:
90+
- name: Checkout
91+
uses: actions/checkout@v4
92+
with:
93+
fetch-depth: 0
94+
95+
- name: Setup Go
96+
uses: actions/setup-go@v5
97+
with:
98+
go-version-file: ./go.mod
99+
100+
- name: Install Dependencies
101+
run: go mod download
102+
103+
- name: Install nsjail
104+
run: |
105+
sudo apt-get update
106+
sudo apt-get install -y \
107+
autoconf bison flex g++ git \
108+
libprotobuf-dev libnl-route-3-dev \
109+
libtool pkg-config protobuf-compiler
110+
git clone --depth=1 https://github.com/google/nsjail.git /tmp/nsjail
111+
make -C /tmp/nsjail -j$(nproc)
112+
sudo install -m 0755 /tmp/nsjail/nsjail /usr/sbin/nsjail
113+
114+
- name: Run sandbox integration tests
115+
run: sudo -E go test -v -run 'TestSandboxedWorker' ./internal/execution/worker/...
116+
86117
build_docker:
87118
name: Build Docker Image
88119
runs-on: ubuntu-latest
89-
needs: [test, build]
120+
needs: [test, test-sandbox, build]
90121
concurrency:
91122
group: ${{ github.ref }}
92123
cancel-in-progress: ${{ github.event_name == 'pull_request' || github.ref_name != github.event.repository.default_branch }}
@@ -123,7 +154,7 @@ jobs:
123154
type=ref,event=branch
124155
type=ref,event=tag
125156
type=ref,event=pr
126-
type=raw,value=latest,enable={{is_default_branch}}
157+
type=raw,value=latest,enable=${{ github.ref_type == 'tag' }}
127158
type=edge,branch=main
128159
images: |
129160
ghcr.io/${{ github.repository }}

.github/workflows/release.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,12 @@ jobs:
6666
gh release create ${{ steps.version.outputs.version }} \
6767
--generate-notes \
6868
--title "Release ${{ steps.version.outputs.version }}"
69+
70+
- name: Trigger evaluation-function-base release
71+
if: steps.idempotency.outputs.skip == 'false'
72+
uses: peter-evans/repository-dispatch@v3
73+
with:
74+
token: ${{ secrets.EVALUATION_FUNCTION_BASE_BUILD_TRIGGER_TOKEN }}
75+
repository: ${{ github.repository_owner }}/evaluation-function-base
76+
event-type: release
77+
client-payload: '{"shimmy_version": "${{ steps.version.outputs.version }}"}'

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@ lcov.info
2323
go.work
2424

2525
# Local .env files
26-
*.local
26+
*.local.idea/

Dockerfile

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM --platform=$BUILDPLATFORM golang:1.24 as builder
1+
FROM --platform=$BUILDPLATFORM golang:1.25 as builder
22

33
WORKDIR /app
44

@@ -18,7 +18,64 @@ ARG COMMIT
1818
RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH VERSION=$VERSION COMMIT=$COMMIT \
1919
make build
2020

21-
FROM scratch
21+
# Build nsjail from source. This stage is Linux/amd64 only; nsjail is a
22+
# Linux kernel feature and does not cross-compile for other OS targets.
23+
FROM ubuntu:24.04 AS nsjail-builder
2224

23-
# add binary to empty scratch image
25+
RUN apt-get update && apt-get install -y --no-install-recommends \
26+
autoconf \
27+
bison \
28+
ca-certificates \
29+
flex \
30+
gcc \
31+
g++ \
32+
git \
33+
libcap-dev \
34+
libnl-route-3-dev \
35+
libprotobuf-dev \
36+
libtool \
37+
make \
38+
pkg-config \
39+
protobuf-compiler \
40+
&& rm -rf /var/lib/apt/lists/*
41+
42+
RUN git clone --depth=1 https://github.com/google/nsjail.git /nsjail-src
43+
WORKDIR /nsjail-src
44+
RUN make -j$(nproc)
45+
46+
# Test-only stage: golang base image (Debian bookworm) + nsjail built from source.
47+
# Go is pre-installed; all nsjail build deps are in Debian main — no universe needed.
48+
# Used by `make test-sandbox`; not referenced by the production image.
49+
FROM golang:1.24 AS test-sandbox
50+
RUN apt-get update && apt-get install -y --no-install-recommends \
51+
autoconf \
52+
bison \
53+
ca-certificates \
54+
flex \
55+
libcap-dev \
56+
libnl-route-3-dev \
57+
libprotobuf-dev \
58+
libtool \
59+
pkg-config \
60+
protobuf-compiler \
61+
&& rm -rf /var/lib/apt/lists/*
62+
RUN git clone --depth=1 https://github.com/google/nsjail.git /nsjail-src && \
63+
make -C /nsjail-src -j$(nproc) && \
64+
cp /nsjail-src/nsjail /usr/sbin/nsjail
65+
66+
# Runtime image. Cannot use scratch because nsjail requires shared libraries
67+
# (libcap, libprotobuf, libnl). Image size grows from ~8 MB to ~90-120 MB.
68+
# When --sandbox is not used, shimmy behaves identically to the scratch image.
69+
FROM ubuntu:24.04
70+
71+
RUN apt-get update && apt-get install -y --no-install-recommends \
72+
libprotobuf32t64 \
73+
libnl-route-3-200 \
74+
libcap2 \
75+
ca-certificates \
76+
&& rm -rf /var/lib/apt/lists/*
77+
78+
COPY --from=nsjail-builder /nsjail-src/nsjail /usr/sbin/nsjail
2479
COPY --from=builder /app/bin/shimmy /shimmy
80+
81+
ENTRYPOINT ["/shimmy"]

Makefile

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ GOLDFLAGS += -X main.Commit=$(COMMIT)
88
GOFLAGS = -ldflags "$(GOLDFLAGS)"
99

1010
BINARY_NAME ?= shimmy
11+
CONTAINER_ENGINE ?= docker
1112

12-
.PHONY: all build test test-unit lcov install generate-mocks update-schema
13+
.PHONY: all build test test-unit test-sandbox lcov install generate-mocks update-schema
1314

1415
all: build
1516

@@ -20,6 +21,18 @@ test: test-unit
2021

2122
test-unit:
2223
go test -covermode=count -coverprofile=coverage.out ./...
24+
25+
# Run sandbox integration tests inside a privileged container.
26+
# Supports Docker (default) and Podman: CONTAINER_ENGINE=podman make test-sandbox
27+
# On Linux with nsjail installed locally, use:
28+
# go test -v -run 'TestSandboxedWorker' ./internal/execution/worker/...
29+
test-sandbox:
30+
$(CONTAINER_ENGINE) build --target test-sandbox -t shimmy-test-sandbox .
31+
$(CONTAINER_ENGINE) run --rm --privileged \
32+
-v $(shell pwd):/workspace \
33+
-w /workspace \
34+
shimmy-test-sandbox \
35+
go test -v -run 'TestSandboxedWorker' ./internal/execution/worker/...
2336

2437
lcov:
2538
gcov2lcov -infile=coverage.out -outfile=lcov.info

README.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,3 +244,77 @@ For example, a Wolfram Language evaluation function in `evaluation.wl` would be
244244
```shell
245245
wolframscript -file evaluation.wl /tmp/shimmy/abc/request-data-123 /tmp/shimmy/abc/response-data-456
246246
```
247+
248+
### Sandboxed Execution (Linux only, experimental)
249+
250+
Shimmy can wrap each worker process in an [nsjail](https://github.com/google/nsjail) sandbox to safely execute arbitrary, untrusted code. The sandbox provides:
251+
252+
- **Filesystem confinement** — the worker can only access explicitly bind-mounted paths
253+
- **Resource limits** — CPU time, memory, and file descriptor caps
254+
- **Network isolation** — optional; disables all outbound connections
255+
- **Unprivileged UID** — worker runs as `nobody` (uid 65534) inside the jail
256+
257+
Sandboxing requires Linux and the `nsjail` binary. The Docker image built from the project's `Dockerfile` includes nsjail at `/usr/sbin/nsjail`. On the host, install it with `sudo apt install nsjail` (Ubuntu 22.04+) or build from source.
258+
259+
Enable sandboxing with `--sandbox` and configure it with the flags below:
260+
261+
| Flag | Env var | Default | Description |
262+
|------|---------|---------|-------------|
263+
| `--sandbox` | `SANDBOX_ENABLED` | `false` | Enable nsjail sandboxing |
264+
| `--sandbox-nsjail-path` | `SANDBOX_NSJAIL_PATH` | `/usr/sbin/nsjail` | Path to the nsjail binary |
265+
| `--sandbox-ro-bind` | `SANDBOX_RO_BINDS` || Host path to bind-mount read-only (repeatable) |
266+
| `--sandbox-rw-bind` | `SANDBOX_RW_BINDS` || Host path to bind-mount read-write (repeatable) |
267+
| `--sandbox-tmpfs` | `SANDBOX_TMPFS` || Path inside the sandbox to mount as tmpfs (repeatable) |
268+
| `--sandbox-cpu-time` | `SANDBOX_CPU_TIME_LIMIT` | `0` (unlimited) | CPU time limit in seconds |
269+
| `--sandbox-memory-mb` | `SANDBOX_MEMORY_LIMIT` | `0` (unlimited) | Memory limit in megabytes |
270+
| `--sandbox-max-fds` | `SANDBOX_MAX_FDS` | `0` (nsjail default) | Maximum open file descriptors |
271+
| `--sandbox-disable-network` | `SANDBOX_DISABLE_NETWORK` | `false` | Disable network access inside the sandbox |
272+
| `--sandbox-seccomp` | `SANDBOX_SECCOMP` | `false` | Enable seccomp syscall filtering |
273+
274+
A typical invocation for an untrusted Python worker:
275+
276+
```shell
277+
shimmy -c python3 -a evaluation.py \
278+
--sandbox \
279+
--sandbox-ro-bind /usr \
280+
--sandbox-ro-bind /lib \
281+
--sandbox-ro-bind /lib64 \
282+
--sandbox-rw-bind /tmp/shimmy \
283+
--sandbox-cpu-time 30 \
284+
--sandbox-memory-mb 256 \
285+
--sandbox-disable-network
286+
```
287+
288+
> **Note:** nsjail requires either root or user namespace support. In Docker, pass `--privileged` or grant `CAP_SYS_ADMIN`. In Kubernetes, configure the pod's security context accordingly.
289+
290+
#### Testing sandboxing locally
291+
292+
The sandbox integration tests verify actual security properties — filesystem isolation, CPU limits, network isolation, and stdio passthrough. They skip automatically if `nsjail` is not available.
293+
294+
**On Linux with nsjail installed:**
295+
296+
```shell
297+
go test -v -run 'TestSandboxedWorker' ./internal/execution/worker/...
298+
```
299+
300+
**On macOS (or any platform) via Docker or Podman:**
301+
302+
```shell
303+
make test-sandbox # Docker (default)
304+
CONTAINER_ENGINE=podman make test-sandbox # Podman
305+
```
306+
307+
This builds the `nsjail-builder` Dockerfile stage (the same nsjail used in production) and runs the tests inside a privileged container. Rootless Podman works fine: `--privileged` grants all capabilities within the user namespace, which is sufficient for nsjail to create its own sub-namespaces.
308+
309+
To manually verify isolation, run the Docker image with a sandboxed worker that attempts to read a protected file:
310+
311+
```shell
312+
docker run --rm --privileged \
313+
-e FUNCTION_COMMAND=/bin/sh \
314+
-e FUNCTION_ARGS="-c,cat /etc/shadow" \
315+
-e SANDBOX_ENABLED=true \
316+
-e SANDBOX_RO_BINDS="/usr:/bin:/lib:/lib64" \
317+
ghcr.io/lambda-feedback/shimmy serve
318+
```
319+
320+
The worker should exit with a non-zero code because `/etc` is not mounted inside the sandbox.

cmd/root.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,74 @@ functions on arbitrary, serverless platforms.`
139139
Value: "127.0.0.1:7321",
140140
Category: "rpc",
141141
},
142+
// sandbox flags
143+
&cli.BoolFlag{
144+
Name: "sandbox",
145+
Usage: "enable nsjail sandboxing for worker processes (Linux only).",
146+
Value: false,
147+
Category: "sandbox",
148+
EnvVars: []string{"SANDBOX_ENABLED"},
149+
},
150+
&cli.StringFlag{
151+
Name: "sandbox-nsjail-path",
152+
Usage: "path to the nsjail binary.",
153+
Value: "/usr/sbin/nsjail",
154+
Category: "sandbox",
155+
EnvVars: []string{"SANDBOX_NSJAIL_PATH"},
156+
},
157+
&cli.StringSliceFlag{
158+
Name: "sandbox-ro-bind",
159+
Usage: "host path to bind-mount read-only inside the sandbox (repeatable).",
160+
Category: "sandbox",
161+
EnvVars: []string{"SANDBOX_RO_BINDS"},
162+
},
163+
&cli.StringSliceFlag{
164+
Name: "sandbox-rw-bind",
165+
Usage: "host path to bind-mount read-write inside the sandbox (repeatable).",
166+
Category: "sandbox",
167+
EnvVars: []string{"SANDBOX_RW_BINDS"},
168+
},
169+
&cli.StringSliceFlag{
170+
Name: "sandbox-tmpfs",
171+
Usage: "path inside the sandbox to mount as tmpfs (repeatable).",
172+
Category: "sandbox",
173+
EnvVars: []string{"SANDBOX_TMPFS"},
174+
},
175+
&cli.IntFlag{
176+
Name: "sandbox-cpu-time",
177+
Usage: "CPU time limit in seconds for worker processes (0 = unlimited).",
178+
Value: 0,
179+
Category: "sandbox",
180+
EnvVars: []string{"SANDBOX_CPU_TIME_LIMIT"},
181+
},
182+
&cli.IntFlag{
183+
Name: "sandbox-memory-mb",
184+
Usage: "memory (address space) limit in megabytes for worker processes (0 = unlimited).",
185+
Value: 0,
186+
Category: "sandbox",
187+
EnvVars: []string{"SANDBOX_MEMORY_LIMIT"},
188+
},
189+
&cli.IntFlag{
190+
Name: "sandbox-max-fds",
191+
Usage: "maximum open file descriptors for worker processes (0 = nsjail default).",
192+
Value: 0,
193+
Category: "sandbox",
194+
EnvVars: []string{"SANDBOX_MAX_FDS"},
195+
},
196+
&cli.BoolFlag{
197+
Name: "sandbox-disable-network",
198+
Usage: "disable network access inside the sandbox.",
199+
Value: false,
200+
Category: "sandbox",
201+
EnvVars: []string{"SANDBOX_DISABLE_NETWORK"},
202+
},
203+
&cli.BoolFlag{
204+
Name: "sandbox-seccomp",
205+
Usage: "enable seccomp syscall filtering inside the sandbox.",
206+
Value: false,
207+
Category: "sandbox",
208+
EnvVars: []string{"SANDBOX_SECCOMP"},
209+
},
142210
},
143211
Before: func(ctx *cli.Context) error {
144212
// create the logger
@@ -263,6 +331,17 @@ func parseRootConfig(ctx *cli.Context) (config.Config, error) {
263331
"rpc-transport-tcp-address": "runtime.io.rpc.tcp.address",
264332
"worker-send-timeout": "runtime.send.timeout",
265333
"worker-stop-timeout": "runtime.stop.timeout",
334+
// sandbox
335+
"sandbox": "runtime.sandbox.enabled",
336+
"sandbox-nsjail-path": "runtime.sandbox.nsjail_path",
337+
"sandbox-ro-bind": "runtime.sandbox.ro_binds",
338+
"sandbox-rw-bind": "runtime.sandbox.rw_binds",
339+
"sandbox-tmpfs": "runtime.sandbox.tmpfs",
340+
"sandbox-cpu-time": "runtime.sandbox.cpu_time_limit",
341+
"sandbox-memory-mb": "runtime.sandbox.memory_limit",
342+
"sandbox-max-fds": "runtime.sandbox.max_fds",
343+
"sandbox-disable-network": "runtime.sandbox.disable_network",
344+
"sandbox-seccomp": "runtime.sandbox.seccomp",
266345
}
267346

268347
// parse config using env

go.mod

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/lambda-feedback/shimmy
22

3-
go 1.24.5
3+
go 1.25
44

55
require (
66
github.com/aws/aws-lambda-go v1.46.0
@@ -23,12 +23,23 @@ require (
2323
github.com/Microsoft/go-winio v0.6.2 // indirect
2424
github.com/StackExchange/wmi v1.2.1 // indirect
2525
github.com/deckarep/golang-set/v2 v2.6.0 // indirect
26+
github.com/getkin/kin-openapi v0.138.0 // indirect
2627
github.com/go-ole/go-ole v1.3.0 // indirect
28+
github.com/go-openapi/jsonpointer v0.21.0 // indirect
29+
github.com/go-openapi/swag v0.23.0 // indirect
2730
github.com/gorilla/websocket v1.4.2 // indirect
2831
github.com/holiman/uint256 v1.2.4 // indirect
32+
github.com/josharian/intern v1.0.0 // indirect
33+
github.com/mailru/easyjson v0.7.7 // indirect
34+
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
35+
github.com/oasdiff/yaml v0.0.9 // indirect
36+
github.com/oasdiff/yaml3 v0.0.12 // indirect
37+
github.com/perimeterx/marshmallow v1.1.5 // indirect
38+
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect
2939
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect
3040
github.com/tklauser/go-sysconf v0.3.12 // indirect
3141
github.com/tklauser/numcpus v0.6.1 // indirect
42+
github.com/woodsbury/decimal128 v1.3.0 // indirect
3243
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
3344
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
3445
golang.org/x/crypto v0.24.0 // indirect

0 commit comments

Comments
 (0)