mirror of
https://github.com/Dvorinka/Containr.git
synced 2026-10-28 15:51:26 +00:00
feat(gateway): /g/:slug proxy data plane with key auth and rate limits (#66)
The admin surface under /admin/gateway managed api_services and api_keys, but no public route ever consumed them. Mounts /g/:slug and /g/:slug/* on the root router (outside /api/v1 so route_prefix stays clean) and runs the full pipeline: slug lookup -> X-API-Key/Bearer extraction -> prefix-indexed bcrypt key auth -> allowed_service_ids scope -> per-minute buckets (key and service caps) -> monthly usage_counters quotas -> gateway.ProxyRequest with per-service timeout and upstream auth headers -> usage/metrics/incident recording. Live-verified: proxied GET/POST, 401/404/429 boundaries, counter upserts, UPSTREAM_5XX incidents. Unit tests cover URL building, the rpm bucket, key extraction, and the service allowlist. Generated with [Devin](https://devin.ai) Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
1409186a1f
commit
d5909172ae
5 files changed
+465
-2
No files matched your search
@@ -269,6 +269,12 @@ func SetupRoutes(router *gin.Engine, db *database.DB, redis *database.Redis, cfg
|
||||
// endpoint, verified against the provisioned webhook secret.
|
||||
router.POST("/api/git/github-app/webhook", handleGitHubAppWebhook)
|
||||
|
||||
// Public API gateway data plane. Lives outside /api/v1 so each service's
|
||||
// route_prefix (/g/<slug>) maps cleanly; auth is the caller's api_key,
|
||||
// not a session.
|
||||
router.Any("/g/:slug", handleGatewayProxy)
|
||||
router.Any("/g/:slug/*path", handleGatewayProxy)
|
||||
|
||||
v1 := router.Group("/api/v1")
|
||||
{
|
||||
// Public routes (no authentication required)
|
||||
|
||||
Reference in new issue
Block a user