Skip to content

Commit 112d59b

Browse files
ecordellmiparnisari
authored andcommitted
feat: add Memory Protection Middleware via RTML
1 parent 1baad60 commit 112d59b

29 files changed

+3348
-91
lines changed

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
internal/**/mock_*.go linguist-generated=true
12
*.pb.go linguist-generated=true
23
*.pb.*.go linguist-generated=true
34
proto/internal/buf.lock linguist-generated=true

.github/workflows/build-test.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ jobs:
5959
username: "${{ env.DOCKERHUB_PUBLIC_USER }}"
6060
password: "${{ env.DOCKERHUB_PUBLIC_ACCESS_TOKEN }}"
6161
- uses: "authzed/actions/go-build@70432bd54a9e690d7fe19817dda46d8e4c0a2c3a" # main
62+
with:
63+
ldflags: "-checklinkname=0"
6264
- name: "Image tests"
6365
run: "go run mage.go test:image"
6466

.goreleaser.nightly.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ builds:
1212
- "arm64"
1313
mod_timestamp: "{{ .CommitTimestamp }}"
1414
ldflags:
15-
- "-s -w"
15+
- "-s -w -checklinkname=0"
1616
- "-X github.com/jzelinskie/cobrautil/v2.Version=v{{ .Version }}"
1717
kos:
1818
- id: "spicedb"

.goreleaser.windows.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ builds:
1717
- "amd64"
1818
mod_timestamp: "{{ .CommitTimestamp }}"
1919
ldflags:
20-
- "-s -w"
20+
- "-s -w -checklinkname=0"
2121
- "-X github.com/jzelinskie/cobrautil/v2.Version=v{{ .Version }}"
2222
archives:
2323
- files:

.goreleaser.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ builds:
2020
- "arm64"
2121
mod_timestamp: "{{ .CommitTimestamp }}"
2222
ldflags:
23-
- "-s -w"
23+
- "-s -w -checklinkname=0"
2424
- "-X github.com/jzelinskie/cobrautil/v2.Version=v{{ .Version }}"
2525
archives:
2626
- files:
@@ -95,7 +95,7 @@ brews:
9595
if build.head?
9696
versionVar = "github.com/jzelinskie/cobrautil/v2.Version"
9797
versionCmd = "$(git describe --always --abbrev=7 --dirty --tags)"
98-
system "go build --ldflags '-s -w -X #{versionVar}=#{versionCmd}' ./cmd/spicedb"
98+
system "go build --ldflags '-s -w -checklinkname=0 -X #{versionVar}=#{versionCmd}' ./cmd/spicedb"
9999
end
100100
bin.install "spicedb"
101101
generate_completions_from_executable(bin/"spicedb", "completion", shells: [:bash, :zsh, :fish])

Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ FROM golang:1.25.3-alpine@sha256:aee43c3ccbf24fdffb7295693b6e33b21e01baec1b2a55a
33
WORKDIR /go/src/app
44
RUN apk update && apk add --no-cache git
55
COPY . .
6-
RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg/mod CGO_ENABLED=0 go build -v ./cmd/...
6+
# https://github.com/odigos-io/go-rtml#about-ldflags-checklinkname0
7+
RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg/mod CGO_ENABLED=0 go build -v -ldflags=-checklinkname=0 ./cmd/...
78

89
# use `docker buildx imagetools inspect <image>` to get the multi-platform sha256
910
FROM golang:1.25.3-alpine@sha256:aee43c3ccbf24fdffb7295693b6e33b21e01baec1b2a55acc351fde345e9ec34 AS health-probe-builder

cmd/spicedb/serve_integration_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,56 @@ func TestServe(t *testing.T) {
9292
}
9393
}
9494

95+
func TestServeWithMemoryProtectionMiddleware(t *testing.T) {
96+
t.Parallel()
97+
98+
pool, err := dockertest.NewPool("")
99+
require.NoError(t, err)
100+
101+
serverToken := "mykey"
102+
serveResource, err := pool.RunWithOptions(&dockertest.RunOptions{
103+
Repository: "authzed/spicedb",
104+
Tag: "ci",
105+
Cmd: []string{"serve", "--log-level=debug", "--grpc-preshared-key", serverToken, "--telemetry-endpoint=\"\""},
106+
ExposedPorts: []string{"50051/tcp"},
107+
Env: []string{"GOMEMLIMIT=1B"}, // NOTE: Absurdly low on purpose
108+
}, func(config *docker.HostConfig) {
109+
config.RestartPolicy = docker.RestartPolicy{
110+
Name: "no",
111+
}
112+
})
113+
require.NoError(t, err)
114+
t.Cleanup(func() {
115+
require.NoError(t, pool.Purge(serveResource))
116+
})
117+
118+
serverPort := serveResource.GetPort("50051/tcp")
119+
conn, err := grpc.NewClient(fmt.Sprintf("localhost:%s", serverPort),
120+
grpc.WithTransportCredentials(insecure.NewCredentials()),
121+
grpcutil.WithInsecureBearerToken(serverToken),
122+
)
123+
124+
require.NoError(t, err)
125+
t.Cleanup(func() {
126+
_ = conn.Close()
127+
})
128+
129+
// Health requests bypass the memory middleware
130+
require.Eventually(t, func() bool {
131+
resp, err := healthpb.NewHealthClient(conn).Check(context.Background(), &healthpb.HealthCheckRequest{Service: "authzed.api.v1.SchemaService"})
132+
return err == nil && resp.GetStatus() == healthpb.HealthCheckResponse_SERVING
133+
}, 5*time.Second, 1*time.Second, "server never became healthy")
134+
135+
// Other requests have the memory middleware
136+
client := v1.NewSchemaServiceClient(conn)
137+
_, err = client.WriteSchema(context.Background(), &v1.WriteSchemaRequest{
138+
Schema: `definition user {}`,
139+
})
140+
s, ok := status.FromError(err)
141+
require.True(t, ok)
142+
require.Equal(t, codes.ResourceExhausted, s.Code())
143+
}
144+
95145
func gracefulShutdown(pool *dockertest.Pool, serveResource *dockertest.Resource) bool {
96146
closed := make(chan bool, 1)
97147
go func() {

development/prometheus.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
global:
3-
scrape_interval: "15s"
4-
evaluation_interval: "15s"
3+
scrape_interval: "1s"
4+
evaluation_interval: "1s"
55

66
scrape_configs:
77
- job_name: "spicedb"

go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ require (
112112
go.opentelemetry.io/otel/trace v1.38.0
113113
go.uber.org/atomic v1.11.0
114114
go.uber.org/goleak v1.3.0
115+
go.uber.org/mock v0.6.0
115116
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b
116117
golang.org/x/mod v0.29.0
117118
golang.org/x/sync v0.17.0
@@ -138,6 +139,8 @@ tool (
138139
github.com/golangci/golangci-lint/v2/cmd/golangci-lint
139140
// support running mage with go run mage.go
140141
github.com/magefile/mage/mage
142+
// mocks are generated with go:generate directives.
143+
go.uber.org/mock/mockgen
141144
// vulncheck always uses the current directory's go.mod.
142145
golang.org/x/vuln/cmd/govulncheck
143146
)
@@ -313,6 +316,7 @@ require (
313316
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
314317
github.com/kulti/thelper v0.7.1 // indirect
315318
github.com/kunwardeep/paralleltest v1.0.14 // indirect
319+
github.com/kylelemons/godebug v1.1.0 // indirect
316320
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
317321
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
318322
github.com/lasiar/canonicalheader v1.1.2 // indirect
@@ -352,6 +356,7 @@ require (
352356
github.com/nishanths/exhaustive v0.12.0 // indirect
353357
github.com/nishanths/predeclared v0.2.2 // indirect
354358
github.com/nunnatsa/ginkgolinter v0.21.0 // indirect
359+
github.com/odigos-io/go-rtml v0.0.1 // indirect
355360
github.com/opencontainers/go-digest v1.0.0 // indirect
356361
github.com/opencontainers/image-spec v1.1.0 // indirect
357362
github.com/opencontainers/runc v1.2.8 // indirect

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2232,6 +2232,8 @@ github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm
22322232
github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c=
22332233
github.com/nunnatsa/ginkgolinter v0.21.0 h1:IYwuX+ajy3G1MezlMLB1BENRtFj16+Evyi4uki1NOOQ=
22342234
github.com/nunnatsa/ginkgolinter v0.21.0/go.mod h1:QlzY9UP9zaqu58FjYxhp9bnjuwXwG1bfW5rid9ChNMw=
2235+
github.com/odigos-io/go-rtml v0.0.1 h1:5w21AOXZGq/6UhECv5B9RCrW7R8PzA8YgwdxqtajD0w=
2236+
github.com/odigos-io/go-rtml v0.0.1/go.mod h1:LqKwlorUKSNj1WQ0p/5e9+aOkirEiHQx+FOxdhku/cs=
22352237
github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
22362238
github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
22372239
github.com/onsi/gomega v1.38.0 h1:c/WX+w8SLAinvuKKQFh77WEucCnPk4j2OTUr7lt7BeY=
@@ -2596,6 +2598,8 @@ go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwE
25962598
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
25972599
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
25982600
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
2601+
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
2602+
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
25992603
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
26002604
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
26012605
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=

0 commit comments

Comments
 (0)