Skip to content

feat: add rate limiting to /invite endpoint#439

Open
mrigangha wants to merge 1 commit intonetlify:masterfrom
mrigangha:dev
Open

feat: add rate limiting to /invite endpoint#439
mrigangha wants to merge 1 commit intonetlify:masterfrom
mrigangha:dev

Conversation

@mrigangha
Copy link
Copy Markdown

- Summary
The /invite endpoint had no rate limiting despite being an email-sending
endpoint protected by requireAdminCredentials. A compromised admin token
could be used to send bulk invite emails with no throttling. This PR wires
a tollbooth limiter to /invite matching the pattern already used by /token.

Closes #413

- Test plan
Added TestInviteRateLimit which sends 10 requests (exhausting the burst)
and asserts the 11th returns 429 Too Many Requests. All existing invite
tests continue to pass.

make test 2>&1 | grep -E "TestInvite"
--- PASS: TestInvite/TestInvite (0.13s)
--- PASS: TestInvite/TestInviteExternalGitlab (0.14s)
--- PASS: TestInvite/TestInviteExternalGitlab_MismatchedEmails (0.13s)
--- PASS: TestInvite/TestInviteRateLimit (0.67s)
--- PASS: TestInvite/TestInvite_WithoutAccess (0.07s)
--- PASS: TestInvite/TestVerifyInvite (0.17s)
--- PASS: TestInvite/TestVerifyInvite_NoPassword (0.12s)

- Description for the changelog
Add tollbooth rate limiting to the /invite endpoint (10 req/min, burst of 10)

- A picture of a cute animal (not mandatory but encouraged)
🐾

@mrigangha mrigangha requested a review from a team as a code owner April 13, 2026 16:56
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 13, 2026

📝 Walkthrough

Summary by CodeRabbit

  • Improvements
    • Implemented rate limiting on the invite endpoint to improve platform stability and prevent abuse. Users are now limited to 10 requests per 60 seconds.

Walkthrough

The changes add rate limiting to the /invite endpoint to mitigate abuse risks from compromised admin credentials. The route middleware now includes a tollbooth-based rate limiter configured to permit 10 requests per 60 seconds with a burst capacity of 10. A test is added to verify that requests exceeding the limit receive 429 status responses.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: add rate limiting to /invite endpoint' clearly and concisely summarizes the main change.
Description check ✅ Passed The description provides relevant context about why rate limiting was added, how it works, test coverage, and expected behavior.
Linked Issues check ✅ Passed The PR successfully implements rate limiting for the /invite endpoint using tollbooth with 10 req/min and burst of 10, matching the pattern used by /token and preventing bulk email abuse from compromised admin tokens.
Out of Scope Changes check ✅ Passed All changes are directly scoped to adding rate limiting to the /invite endpoint; no unrelated modifications are present.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.11.4)

Error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions
The command is terminated due to an error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
api/invite_test.go (1)

10-33: ⚠️ Potential issue | 🟠 Major

Replace os.Setenv with t.Setenv and remove the unused os import.

Line 33 uses os.Setenv() which mutates process-wide state without cleanup, creating test isolation issues and test order dependencies. Use t.Setenv() instead—it automatically restores the environment variable after the test completes.

Suggested fix
 import (
 	"bytes"
 	"encoding/json"
 	"fmt"
 	"net/http"
 	"net/http/httptest"
 	"net/url"
-	"os"
 	"testing"
 	"time"
@@
 func TestInvite(t *testing.T) {
-	os.Setenv("GOTRUE_RATE_LIMIT_HEADER", "My-Custom-Header")
+	t.Setenv("GOTRUE_RATE_LIMIT_HEADER", "My-Custom-Header")
 	api, config, instanceID, err := setupAPIForTestForInstance()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api/invite_test.go` around lines 10 - 33, Replace the process-wide os.Setenv
call in the TestInvite test with t.Setenv to ensure the environment variable is
scoped to the test and automatically restored; update the TestInvite function to
call t.Setenv("GOTRUE_RATE_LIMIT_HEADER", "My-Custom-Header") instead of
os.Setenv, and remove the now-unused os import from the invite_test.go top
imports so there are no unused import errors; locate the TestInvite function and
the InviteTestSuite type to apply the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@api/invite_test.go`:
- Around line 10-33: Replace the process-wide os.Setenv call in the TestInvite
test with t.Setenv to ensure the environment variable is scoped to the test and
automatically restored; update the TestInvite function to call
t.Setenv("GOTRUE_RATE_LIMIT_HEADER", "My-Custom-Header") instead of os.Setenv,
and remove the now-unused os import from the invite_test.go top imports so there
are no unused import errors; locate the TestInvite function and the
InviteTestSuite type to apply the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: efba17e7-2760-4c1b-8d63-e0177561d406

📥 Commits

Reviewing files that changed from the base of the PR and between 5d912ce and ddebcf9.

📒 Files selected for processing (2)
  • api/api.go
  • api/invite_test.go

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add rate limiting to the invite endpoint

1 participant