Releases: gatewayd-io/gatewayd
v0.11.1
Patch release fixing a connection pool exhaustion bug that affects deployments using plugins with the Terminate action (e.g. gatewayd-plugin-cache).
Bug Fix
Fix connection pool exhaustion in PassThroughToClient (#731)
When a plugin returned the Terminate action (e.g. cache hit), the client-to-server goroutine would set a backend read deadline and exit. The server-to-client goroutine then called receiveTrafficFromServer, which returned received == 0 with a deadline-exceeded error. However, PassThroughToClient silently discarded the error when received == 0 and returned nil, causing the goroutine to spin in an infinite loop:
Received data from database function=proxy.passthrough length=0
Because the goroutine never exited, OnTraffic never returned, Disconnect never ran, and the backend connection was permanently leaked. Under sustained traffic this exhausted the entire connection pool.
Fix: Propagate the error when received == 0 && err != nil so the goroutine exits cleanly and the connection is properly recycled.
Other Changes
- Upgrade to Go 1.25 and Alpine 3.23
- Update direct dependencies
- Add extensive CI plugin tests for cache, auth, js, and sql-ids-ips plugins (#731)
Companion Release
- gatewayd-plugin-cache v0.5.1 — fixes a data race in
OnTrafficFromServerwhere thev1.Structresponse pointer was shared between gRPC serialization and theUpdateCachegoroutine, causing corrupted responses
Full Changelog: v0.11.0...v0.11.1
v0.11.0
After more than 6 months since v0.10.3, we're excited to ship GatewayD v0.11.0, a significant releases in the project's history. The highlight is pre-authenticated backend pool connections, a foundational capability that transforms how GatewayD manages PostgreSQL connections and unlocks critical use cases like identity brokering via the auth plugin.
Highlights
Pre-Authenticate Backend Pool Connections (#721)
This is the most important change in v0.11.0. Previously, backend connections in the pool were raw TCP sockets. They had no PostgreSQL session state until a client connected and the startup handshake was forwarded through. With pre-auth, GatewayD now performs the full PostgreSQL startup handshake (including authentication) immediately after establishing each backend TCP connection, so pool connections are ready for queries before any client arrives.
Why pre-auth matters:
- Enables the auth plugin's identity broker model. The auth plugin can now authenticate frontend clients independently (via custom credentials and soon federated identity providers) and map them onto pre-authenticated backend connections. Without pre-auth, the auth plugin had no way to decouple frontend and backend authentication.
- DISCARD ALL-based connection recycling. When a client disconnects, GatewayD now sends
DISCARD ALLto reset the backend session state instead of tearing down and re-establishing the TCP connection. This is significantly faster and reduces load on the PostgreSQL server. - Full authentication method support. The startup handshake supports trust, cleartext, MD5, and SCRAM-SHA-256 authentication, covering all common PostgreSQL configurations.
Configure it via the new startupParams block in the client config:
clients:
default:
writes:
startupParams:
user: postgres
database: postgres
password: postgresImproved Connection Lifecycle & Shutdown
The traffic handling model in OnTraffic has been redesigned. Instead of using channels to coordinate the client-to-server and server-to-client goroutines, both goroutines now participate in a sync.WaitGroup. OnTraffic blocks until both goroutines have fully exited, guaranteeing the backend connection is idle before attempting session reset or recycling. This eliminates a class of race conditions where DISCARD ALL could collide with a still-active reader.
Additionally, the shutdown sequence has been improved: the server status is now set to "stopped" before proxies are shut down, so OnClose hooks can detect the shutdown-in-progress state and avoid spurious error logs. Expected shutdown errors (e.g. ErrClientNotFound during cleanup) are now logged at DEBUG level instead of ERROR.
Unified Raft Log Adapter (#686)
A new StandardLogWriter captures Go stdlib log output (used internally by raft-boltdb) and redirects it through zerolog with proper formatting and the "component": "raftboltdb" tag. Raft TCP transport output is now discarded instead of writing to stderr. This ensures all log output flows through GatewayD's structured logging pipeline.
hclog Format String Handling (#689)
Fixed a bug where hclog.Format values (used by hashicorp/go-plugin) were not rendered correctly in the hclog-to-zerolog adapter. Format strings are now properly interpolated via fmt.Sprintf.
Other Changes
- Race condition fix in Client.Send/Receive: The connection is now snapshotted under a mutex to prevent races with concurrent
Close()calls. - New Proxy methods:
ExpireBackendReadDeadline()andClearBackendDeadline()allow precise control over backend connection deadlines during goroutine teardown. - New error codes:
ErrCodePgStartupFailedandErrCodePgResetSessionFailedfor pre-auth error handling. - Test improvements: Replaced
zerolog.Logger{}andzerolog.New(nil)withzerolog.Nop()across all test files for correctness. - Makefile: Added
test-postgres-upandtest-postgres-downtargets for running local PostgreSQL containers during development. - Renovate: Added Renovate configuration for automated dependency management.
- Documentation: Fixed markdown formatting across all CLI docs.
Dependency Updates
Major dependency bumps include:
| Dependency | Old | New |
|---|---|---|
| gatewayd-plugin-sdk | v0.4.3 | v0.4.4 |
| OpenTelemetry | v1.37.0 | v1.40.0 |
| gRPC | v1.74.2 | v1.79.1 |
| jackc/pgx | v5.7.5 | v5.8.0 |
| redis/go-redis | v9.12.0 | v9.18.0 |
| hashicorp/go-plugin | v1.6.3 | v1.7.0 |
| sentry-go | v0.35.0 | v0.42.0 |
| protobuf | v1.36.7 | v1.36.11 |
| testcontainers-go | v0.38.0 | v0.40.0 |
New dependency: xdg-go/scram v1.2.0 for SCRAM-SHA-256 authentication support.
Full Changelog: v0.10.3...v0.11.0
v0.10.3
v0.10.2
What's Changed
- Add Raft State Management for Load Balancers by @sinadarbouy in #641
- Add Raft Node Support for Health Checks and Metrics Collection by @sinadarbouy in #643
- Refactor commands by @mostafa in #644
- Refactor scheduler functions by @mostafa in #649
- Refactor compat policy by @mostafa in #650
- Update deps by @mostafa in #657
- Add Raft cluster peer management (GetPeers, AddPeer, RemovePeer) by @sinadarbouy in #663
- Update deps by @mostafa in #666
Full Changelog: v0.10.1...v0.10.2
v0.10.1
This release introduces Raft-based state management for GatewayD to ensure efficient and consistent coordination between multiple instances. By leveraging HashiCorp’s Raft implementation, GatewayD now maintains a unified state for parameters like connection pools and load-balancer strategies across all instances in a cluster, ensuring high availability, consistency, scalability, and efficiency.
Key Features and Objectives:
-
High Availability: Ensures the system remains operational even if individual instances fail. Raft provides fault tolerance by replicating state across multiple nodes, enabling consistent state retrieval and updates during failover scenarios.
-
Consistency: Guarantees that all instances in the cluster share the same view of stateful parameters, such as connection pools and load-balancer strategies, maintaining synchronized operations across distributed instances.
-
Scalability: Simplifies state coordination in clusters, enabling seamless scaling of GatewayD instances without introducing inconsistencies or requiring manual intervention.
-
Efficiency: Propagates updates to stateful parameters in real-time, ensuring optimal load balancing and resource utilization across instances.
Implementation Details:
- Unified State Management: A single Raft cluster handles stateful parameters as key-value pairs, ensuring consistency across nodes without the need for complex databases.
- Real-time Updates: Changes in one instance are immediately propagated to others, maintaining consistency and optimal load balancing.
- Fault Tolerance and Recovery: Raft’s persistence via BoltDB ensures reliability, while in-memory runtime state management simplifies operations.
This update resolves inconsistencies in the previous per-instance state management approach, ensuring scalable and robust operation for GatewayD clusters. A huge thanks to @sinadarbouy for his excellent work on this implementation! 🎉
This release also includes several critical updates and fixes to enhance security, improve performance, and maintain compatibility:
Security Updates:
- OpenSSL Update: Upgraded to
3.3.2-r1to address CVE-2024-9143. - Crypto Library Fix: Resolved CVE-2024-45337 by updating
golang.org/x/cryptoto the latest version.
Dependency Updates:
- GitHub Actions: Updated
softprops/action-gh-releasetov2for enhanced functionality and compatibility. - Direct Dependencies: Updated direct dependencies to their latest stable versions.
Development Improvements:
- SDK Update: Updated the SDK to the latest version.
- Go Updates: Upgrade Go to the latest version.
- Protobuf Changes: Regenerated Protobuf message stubs with HTTP annotations for improved API compatibility.
Linter Fixes:
- Addressed all issues reported by linters to ensure cleaner and more maintainable code.
What's Changed
- Update deps by @mostafa in #631
- feat(raft): Implement Raft-based Consistent Hash State Management by @sinadarbouy in #636
- Update deps by @mostafa in #639
Full Changelog: v0.10.0...v0.10.1
v0.10.0
v0.9.10
This release marks the culmination of the v0.9.x milestone, packed with significant new features, fixes, and enhancements that have made GatewayD more robust, stable, and scalable. Key highlights include the introduction of the policy engine, aka. the Act system, in v0.9.0, the plugin scaffold feature in v0.9.5, and the load balancing feature in v0.9.7, among many others.
Over the course of this milestone, we merged 89 squashed commits into the main branch, resolved 30 issues, reviewed numerous PRs and published 11 releases — thanks to the perseverance and contributions of our amazing community. None of this would have been possible without their dedication.
Looking ahead, there's even more in store, and we invite you to get involved. Whether you're a user or a tester, your participation is crucial. If you're ready to contribute, @mostafa is here to support you every step of the way.
Full Changelog: v0.9.9...v0.9.10
v0.9.9
What's Changed
- Add metric labels by @mostafa in #612
- Add test for
plugin scaffoldcommand by @mostafa in #613 - Refactor
interface{}toanyby @mostafa in #614 - Refactor
proxy.shouldTerminatefunction and move the functionality toAct.Registryby @mostafa in #615 - Use the result of notification hooks by @mostafa in #616
- Update deps by @mostafa in #621
Full Changelog: v0.9.8...v0.9.9
v0.9.8
This release introduces several key enhancements and fixes. A significant improvement is the integration of PostgreSQL test containers for seamless integration testing, replacing hardcoded addresses with dynamic test container addresses. This ensures a consistent test environment across various packages such as api, cmd, and network, and centralizes the setup in a reusable function. Additionally, dependency updates were made, including the latest GatewayD SDK, and the gomoddirectives linter was disabled to streamline development. The plugin configuration was updated to utilize the cache plugin version 0.4.0. A major bug has been fixed that improved handling of PostgreSQL's COPY command, as explained here, plus other bugfixes and improvements.
This wouldn't be possible without @sinadarbouy's contributions. 🙏
What's Changed
- Add PostgreSQL Test Containers for Integration Testing by @sinadarbouy in #602
- Update deps by @mostafa in #609
- Fix bug in handling postgres
COPYcommand and a few others by @mostafa in #610
Full Changelog: v0.9.7...v0.9.8
v0.9.7
This release contain a major change, where each tenant can now connect to multiple databases, contrary to the previous one-tenant-one-database approach, and use server load balancing strategies to distribute the load among these databases. Random, round robin and weighted RR strategies with consistent hashing are supported, thanks to @sinadarbouy and @eabasir for their contributions.
What's Changed
- Changed the log level for plugin startup failures from debug to error by @sinadarbouy in #560
- Update deps by @mostafa in #561
- Remove the enforced value of the ARCH in docker-compose by @eabasir in #562
- Feature/integrate docker scout with git hub actions by @sinadarbouy in #564
- Bugfix/workflow vulnerability comparison by @sinadarbouy in #569
- add Tempo, Prometheus and Grafana to docker-compose by @eabasir in #571
- Update deps by @mostafa in #576
- Feature: enable multi pool client connections by @sinadarbouy in #577
- Fix casting of client connections upon enumeration by @mostafa in #584
- Update golangci lint and clean up code by @mostafa in #586
- Fix parameters camelCase support in loadEnvVars for environment variable parsing by @sinadarbouy in #588
- Fix/env vars expect lower case letters by @sinadarbouy in #587
- Add Multi-Proxy Support to Docker-Compose by @sinadarbouy in #589
- Add Random Load Balancing Strategy by @sinadarbouy in #590
- Add Weighted Round Robin Algorithm to Load Balancer by @sinadarbouy in #591
- Add Consistent Hashing Load Balancing Strategy by @sinadarbouy in #592
- Fix Consistent Hashing to Use Remote Address Instead of Local Address by @sinadarbouy in #599
- Update deps by @mostafa in #600
New Contributors
Full Changelog: v0.9.6...v0.9.7