namespace EntitlementSL.Common; /// /// Rate-limit thresholds for Entitlement's client-facing auth endpoints (Login/RefreshToken/ /// CreateClientAdmin) — DXP has zero rate limiting anywhere; this closes that gap for /// Entitlement's own client-auth surface. Bound directly from appsettings /// "Entitlement:ClientAuthRateLimit" once at startup in Program.cs (read via IConfiguration, not /// IOptions<T> — nothing outside Program.cs's own AddRateLimiter call ever needs this, unlike /// EntitlementBLL's Options classes which BLL services inject). /// /// Distinct from GB5Shared.RateLimit.GB5RateLimitExtensions' generic per-tenant limiter (used by /// other GB5Shared SL projects for overall API abuse protection, partitioned by ClientId extracted /// from the "Login" header): these three endpoints specifically need per-IP partitioning instead, /// since Login/RefreshToken are AllowAnonymous and a caller could vary the ClientId they claim on /// every request to dodge a per-tenant bucket — IP is the only durable signal available before /// authentication succeeds. This turn does not touch or enable the generic per-tenant limiter for /// EntitlementSL; that would be a separate, broader decision. /// public class ClientAuthRateLimitOptions { public const string SectionName = "Entitlement:ClientAuthRateLimit"; /// Requests permitted per client IP, per window, for Login and RefreshToken combined /// — they share one policy/bucket since both are credential-guessing surfaces with the same /// risk profile. public int LoginRefreshPermitLimit { get; set; } = 10; public int LoginRefreshWindowSeconds { get; set; } = 60; /// Requests permitted per client IP, per window, for CreateClientAdmin — tighter than /// Login/RefreshToken: legitimate use is GOODBOOKS_ADMIN-only and inherently low-frequency /// (creating a new client's first admin is a rare, deliberate action, not something a real /// admin does repeatedly in a tight loop), so a lower ceiling costs nothing in practice while /// still meaningfully slowing an attacker who somehow obtained/guessed admin credentials. /// public int CreateClientAdminPermitLimit { get; set; } = 3; public int CreateClientAdminWindowSeconds { get; set; } = 60; /// Requests permitted per client IP, per window, for SelfProvisionTrial — /// genuinely public/anonymous and each successful call creates a real MCLIENT/MUSER row /// plus submits a real database-provisioning ChangeRequest, so this needs the tightest /// ceiling of any endpoint in this options class: legitimate use is one signup per visitor, /// not a burst. public int SelfProvisionTrialPermitLimit { get; set; } = 3; public int SelfProvisionTrialWindowSeconds { get; set; } = 3600; } /// ASP.NET Core rate-limiter policy names, registered once in Program.cs via /// AddRateLimiter and referenced from each protected endpoint's Configure() via /// Options(x => x.RequireRateLimiting(...)). public static class ClientAuthRateLimitPolicies { public const string LoginAndRefresh = "client-auth-login-refresh"; public const string CreateClientAdmin = "client-auth-create-admin"; public const string SelfProvisionTrial = "client-auth-self-provision-trial"; }