Non-Production Environment Access Control
Overview
Swagger UI access is controlled by IP address in non-production environments for security purposes. Only requests from whitelisted IP addresses can access the Swagger documentation and testing interface.
Applies to:
- ApiService - Core backend API
- IntegrationServiceAPI - External integrations API
Both services implement the same IP whitelisting middleware and require separate configuration in their respective appsettings.{Environment}.json files.
Environment Access:
- Development (Local): No IP restrictions - fully open
- Testing/Staging/UAT: IP whitelist required
- Production: Swagger completely disabled
...
How IP Whitelisting Works
Request Flow
┌─────────────────────────────────────────────────────────────┐
│ IP WHITELIST VALIDATION FLOW │
└─────────────────────────────────────────────────────────────┘
┌──────────────┐
│ Developer │
│ Browser │
└──────┬───────┘
│
│ Request: GET /swagger
▼
┌──────────────────────────┐
│ API Service │
│ (Behind Azure Proxy) │
└──────┬───────────────────┘
│
│ Middleware intercepts
│ /swagger/* requests
▼
┌──────────────────────────────┐
│ IP Whitelist Middleware │
└──────┬───────────────────────┘
│
│ Extract client IP:
│ - Check RemoteIpAddress
│ - Check X-Forwarded-For header
▼
┌──────────────────────────────┐
│ Compare against whitelist │
└──────┬───────────────────────┘
│
├─── IP Allowed ───┐ IP Blocked ───┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Continue │ │ Serve │ │ 403 │
│ to Swagger │ │ Swagger UI │ │ Forbidden │
└──────────────┘ └──────────────┘ └──────────────┘
...
Implementation
Middleware Configuration
Location:
ApiService/Program.cs:331-385IntegrationServiceAPI/Program.cs:210-259
The middleware intercepts requests to protected paths and validates the client IP address against the configured whitelist. When behind a proxy (like Azure App Service), it uses the X-Forwarded-For header to determine the real client IP.
Protected Paths:
/swagger- Swagger UI interface/scalar- Scalar API documentation/openapi- OpenAPI specification JSON
IP Validation Logic
var remoteIp = context.Connection.RemoteIpAddress;
// Check X-Forwarded-For header for real client IP (when behind Azure proxy)
if (context.Request.Headers.TryGetValue("X-Forwarded-For", out var forwardedFor))
{
var firstIp = forwardedFor.ToString().Split(',')[0].Trim();
if (System.Net.IPAddress.TryParse(firstIp, out var parsedIp))
{
remoteIp = parsedIp;
}
}
if (remoteIp == null || !IpWhitelistHelper.IsIpAllowed(remoteIp, allowedIPs))
{
context.Response.StatusCode = 403;
await context.Response.WriteAsync("Access to Swagger is restricted. Your IP: " + remoteIp);
return;
}
...
Configuration
Current Whitelisted IPs
The following IPs are currently configured in appsettings.json for both ApiService and IntegrationServiceAPI:
{
"Swagger": {
"AllowedIPs": [
"46.21.99.50/24", // EG Sweden 1
"213.115.39.74", // EG Sweden 2
"212.112.154.248/24", // EG Denmark 1
"185.128.100.29", // EG Denmark 2
"185.128.103.244", // EG Denmark 3
"202.131.131.48/29", // EG India 1
"202.131.139.48/29", // EG India 2
"203.193.141.104/29", // EG India 3
"203.193.140.104/29" // EG India 4
]
}
}
Adding New IPs
To add a new IP address:
- Edit the
Swagger:AllowedIPsarray inappsettings.json(or environment-specific file) - Add the IP address with a comment explaining its purpose
- Restart the API service
Supported formats:
- Individual IPv4:
"192.168.1.100" - Individual IPv6:
"2001:0db8:85a3::7334" - CIDR notation:
"192.168.1.0/24"
...
Finding Your IP Address
When blocked, the error message displays your IP:
Access to Swagger is restricted. Your IP: 203.0.113.45
This is the IP address you need to add to the whitelist.
Alternatively, use a command:
- PowerShell:
(Invoke-WebRequest -Uri "https://api.ipify.org").Content - Linux/Mac:
curl https://api.ipify.org
...
X-Forwarded-For Header
Why It's Needed
When the API is deployed behind Azure App Service or reverse proxies, RemoteIpAddress shows the proxy's IP, not the client's real IP. The X-Forwarded-For header contains the original client IP address.
How It Works
Client (203.0.113.45)
→ Azure Load Balancer
→ API Service (sees 10.0.0.1 as RemoteIpAddress)
Without X-Forwarded-For:
- API sees proxy IP only
- Whitelist check fails even if client IP is allowed
With X-Forwarded-For:
- API extracts real client IP from header
- Whitelist check succeeds
Header Format
X-Forwarded-For: client-ip, proxy1-ip, proxy2-ip
The middleware takes the first IP in the list (the original client).
...
Access Locations
The Partner Portal allows Swagger access from the following EG office locations:
Sweden Offices:
- 46.21.99.50/24 (subnet)
- 213.115.39.74
Denmark Offices:
- 212.112.154.248/24 (subnet)
- 185.128.100.29
- 185.128.103.244
India Offices:
- 202.131.131.48/29 (subnet)
- 202.131.139.48/29 (subnet)
- 203.193.141.104/29 (subnet)
- 203.193.140.104/29 (subnet)
Adding New Locations
If you need to add a new developer location:
...
...
Troubleshooting
Issue: "Access to Swagger is restricted"
Error Message:
Access to Swagger is restricted. Your IP: 203.0.113.45
Solution:
- Note the IP address shown
- Add it to
appsettings.{Environment}.json - Restart the API service
- Try accessing Swagger again
Issue: IP Added but Still Blocked
Causes and Solutions:
- Wrong environment file: Verify you edited the correct
appsettings.{Environment}.jsonfile - Service not restarted: Configuration is loaded at startup - restart required
- IP format incorrect: Use IP address only, no protocol or extra characters
- Wrong:
https://192.168.1.100,http://192.168.1.100 - Correct:
192.168.1.100,192.168.1.0/24
- Wrong:
Issue: Different IP Than Expected
When behind VPN, proxy, or NAT, your public IP differs from your local IP. The API sees your public IP, not your local machine IP (192.168.x.x). Add the IP shown in the error message.
...
Security Best Practices
1. Use Specific IPs When Possible
Use individual IPs or small CIDR ranges:
"AllowedIPs": ["203.0.113.45", "192.168.1.0/24"]
Never allow all IPs:
"AllowedIPs": ["0.0.0.0/0"] // Defeats the purpose!
2. Document Whitelisted IPs
Add comments explaining why each IP is whitelisted:
{
"Swagger": {
"AllowedIPs": [
"203.0.113.45", // Main office - Added 2025-01-15
"198.51.100.50", // QA team - Added 2025-02-01
"192.0.2.0/24" // VPN range - Added 2025-02-10
]
}
}
3. Regularly Review Whitelist
Monthly review:
- Remove IPs of former employees
- Remove temporary testing IPs
- Verify all listed IPs are still needed
- Update documentation
4. Production: Disable Swagger Entirely
Never rely on IP whitelisting alone for production. Swagger is completely disabled in production environments.
...
Environment Summary
| Environment | Swagger Access | IP Restrictions | Configuration File |
|---|---|---|---|
| Development (Local) | Fully Open | None | N/A |
| Testing | IP Whitelist | Required | appsettings.Testing.json |
| Staging | IP Whitelist | Required | appsettings.Staging.json |
| UAT | IP Whitelist | Required | appsettings.UAT.json |
| Production | Disabled | N/A | N/A |
...
Related Files
Middleware Implementation
- ApiService:
Source/EGU.PartnerPortal.ApiService/Program.cs:331-385 - IntegrationServiceAPI:
Source/EGU.PartnerPortal.IntegrationServiceAPI/Program.cs:210-259
Helper Utilities
- IP Whitelist Helper:
Source/EGU.PartnerPortal.Shared/Utilities/IpWhitelistHelper.cs
Configuration Files
Source/EGU.PartnerPortal.ApiService/appsettings.{Environment}.jsonSource/EGU.PartnerPortal.IntegrationServiceAPI/appsettings.{Environment}.json