lightninglabs / lightninglabs/aperture

feature: A rate-limiter for API endpoints for each L402

Open
#200 0 comments 0 reactions 1 assignee View on GitHub

@hieblmi is already working on this.

Since Jan 12, 2026.

enhancement
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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.