lightninglabs / lightninglabs/aperture
feature: A rate-limiter for API endpoints for each L402
@hieblmi is already working on this.
Since Jan 12, 2026.
- Dominant language
- Go
- Stars
- 268
- Forks
- 78
- Avg merge
- 22h 25m
- Merged PRs (30d)
- 1
Description
The aperture reverse proxy works well in DoS prevention when on-boarding users,
but once a user paid the invoice and is authenticated a DoS attempt is still feasible if
the proxied endpoints are free of charge.
This issue describes a simple rate-limiter that mitigates a DoS in this scenario.
The rate limiter should use a token-bucket approach for configured endpoint of a L402.
Tokens are added to a bucket at a fixed rate. Each request consumes a token.
Requests fail if the bucket is empty. This allows controlled bursts but not sustained abuse.
The `golang.org/x/time/rate` package should be used to implement it.
Here is a sample configuration:
```yaml
services:
- name: "service1"
hostregexp: '^service1.com$'
pathregexp: '^/.*$'
address: "127.0.0.1:10009"
protocol: https
# Optional per-endpoint rate limits using a token bucket.
ratelimits:
- pathregex: '^/looprpc.SwapServer/LoopOutTerms.*$'
requests: 5
per: 1s
burst: 100
- pathregex: '^/looprpc.SwapServer/LoopOutQuote.*$'
requests: 2
per: 1s
burst: 2
```
Key properties:
- Scope: per service, per endpoint (path regex).
- Process local: state is in-memory per Aperture process. In clustered deployments, each instance enforces its own limits.
- The in-memory data structures should be protected by the rate limiter as well, so that client requests can't cause OOM issues.
- Evaluation: all matching rules are enforced; if any matching rule denies a request, the request is rejected.
- Protocols: applies to both REST and gRPC requests.
Behavior on limit exceed:
- HTTP/REST: returns 429 Too Many Requests and sets a Retry-After header (in seconds). Sub-second delays are rounded up to 1 second.
- gRPC: response uses HTTP/2 headers/trailers with Grpc-Status and Grpc-Message indicating the error (message: "rate limit exceeded").
- CORS headers are included consistently.
Configuration fields (under a service):
- pathregex: regular expression matched against the URL path (e.g., "/package.Service/Method").
- requests: allowed number of requests per window.
- per: size of the time window (e.g., 1s, 1m). Default: 1s.
- burst: additional burst capacity. Default: equal to requests.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.