Description
Implement a backend proxy layer to handle OAuth/OIDC discovery endpoint requests from the DTaaS frontend. This resolves Chrome's CORS policy and Private Network Access restrictions that currently block direct access to the GitLab OAuth server from the browser.
Problem Statement
The DTaaS frontend (intocps.org) cannot directly access GitLab's OAuth/OIDC endpoint (dtaas.com/gitlab/.well-known/openid-configuration) due to browser security restrictions:
-
Chrome CORS Blocking: Direct requests from the public frontend to the private GitLab server are blocked with:
Access to fetch at 'https://dtaas.com/gitlab/.well-known/openid-configuration'
from origin 'https://intocps.org' has been blocked by CORS policy:
Permission was denied for this request to access the `local` address space.
-
Private Network Access Restriction: Chrome enforces Private Network Access (RFC 1918) restrictions, preventing public origins from accessing private/local network addresses, even with proper CORS headers.
-
Impact: OAuth/OIDC login flow fails at the initial discovery phase, preventing user authentication.
-
Environment: This issue occurs in both development and production environments where the frontend is on a public domain and GitLab OAuth server is on a private network.
Current Behavior
Frontend (Public)
↓ [BLOCKED]
GitLab OAuth Server (Private Network)
Browser console errors:
Access to fetch blocked by CORS policy
Failed to load resource: net::ERR_FAILED
net::ERR_BLOCKED_BY_CLIENT
Proposed Solution
Implement a backend proxy layer that routes OAuth/OIDC discovery requests through the public DTaaS API, allowing the browser to communicate with a same-origin endpoint while the backend handles private network access.
Architecture
Frontend (Public: intocps.org)
↓
Backend API Gateway (intocps.org/api/oauth/...)
↓ [Private Network Access - No Browser Restrictions]
GitLab OAuth Server (dtaas.com)
Implementation Details
1. Backend Endpoint
Add a new endpoint to the DTaaS backend API (Python/FastAPI or equivalent):
# Example: backend/dtaas/api/oauth.py
@router.get("/oauth/openid-config")
async def get_openid_configuration():
"""
Proxy for GitLab's .well-known/openid-configuration
Allows frontend to access OAuth discovery without CORS/Private Network Access blocking
"""
gitlab_oauth_url = os.getenv("GITLAB_OAUTH_SERVER")
config_url = f"{gitlab_oauth_url}/gitlab/.well-known/openid-configuration"
async with httpx.AsyncClient() as client:
response = await client.get(config_url)
response.raise_for_status()
return response.json()
@router.post("/oauth/token")
async def exchange_code_for_token(request: OAuthTokenRequest):
"""
Exchange authorization code for access token
"""
gitlab_oauth_url = os.getenv("GITLAB_OAUTH_SERVER")
token_url = f"{gitlab_oauth_url}/oauth/token"
payload = {
"client_id": os.getenv("GITLAB_OAUTH_CLIENT_ID"),
"client_secret": os.getenv("GITLAB_OAUTH_CLIENT_SECRET"),
"code": request.code,
"grant_type": "authorization_code",
"redirect_uri": request.redirect_uri,
}
async with httpx.AsyncClient() as client:
response = await client.post(token_url, data=payload)
response.raise_for_status()
return response.json()
2. Environment Configuration
Add to deployment configuration:
GITLAB_OAUTH_SERVER=https://dtaas.com
GITLAB_OAUTH_CLIENT_ID=<client_id>
GITLAB_OAUTH_CLIENT_SECRET=<client_secret>
OAUTH_REDIRECT_URI=https://intocps.org/_oauth
3. Frontend Changes
Update OAuth discovery logic to use backend proxy:
// Before (Direct - Blocked)
const response = await fetch(
'https://dtaas.com/gitlab/.well-known/openid-configuration'
);
// After (Via Backend Proxy)
const response = await fetch(
'https://intocps.org/api/oauth/openid-config'
);
Benefits
- ✅ Resolves Chrome CORS and Private Network Access blocking
- ✅ Credentials kept on backend (not exposed to browser)
- ✅ Works consistently across all browsers and environments
- ✅ Production-ready security posture
- ✅ Maintainable and scalable architecture
- ✅ No need for browser configuration changes or flags
Alternative Solution 1: Nginx Proxy Headers
Configure the GitLab/OAuth server's reverse proxy to add CORS headers. Note: This alone does NOT bypass Private Network Access restrictions.
Nginx Configuration
Add to the OAuth server's nginx configuration:
location /gitlab/.well-known/openid-configuration {
add_header 'Access-Control-Allow-Origin' 'https://intocps.org' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization' always;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' '86400';
return 204;
}
proxy_pass http://gitlab_backend;
}
location /oauth/authorize {
add_header 'Access-Control-Allow-Origin' 'https://intocps.org' always;
proxy_pass http://gitlab_backend;
}
location /oauth/token {
add_header 'Access-Control-Allow-Origin' 'https://intocps.org' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
proxy_pass http://gitlab_backend;
}
Limitations
- ⚠️ Does NOT resolve Private Network Access blocking — Chrome still blocks requests from public origins to private addresses regardless of CORS headers
- ⚠️ Requires access to OAuth server's nginx configuration
- ⚠️ Only suitable for development environments with flagged Chrome instances
- ✅ Useful as a supplementary measure to ensure proper CORS headers are present
Alternative Solution 2: DNS and Certificate
Register the GitLab OAuth server with a valid public DNS entry and trusted SSL certificate, so Chrome no longer treats it as a "local" address.
Limitations
- ⚠️ Requires public DNS registration and SSL certification
- ⚠️ Exposes internal infrastructure to the public internet
- ⚠️ Significant security and operational overhead
- ⚠️ Not practical for private/internal deployments
Implementation Scope
Phase 1: Core Proxy (Priority)
Phase 2: Enhanced Security (Optional)
Phase 3: Nginx Configuration (Optional)
Testing Strategy
Manual Testing
- Deploy with backend proxy enabled
- Verify frontend can access OAuth discovery endpoint at
GET /api/oauth/openid-config
- Verify OAuth login flow completes without CORS errors
- Test in both Chrome and other browsers
- Verify credentials are not logged or exposed
Automated Testing
- Unit tests for proxy endpoints
- Integration tests for OAuth flow
- Browser automation tests (Selenium/Playwright) for end-to-end flow
Related Issues & Documentation
Additional Context
This feature addresses a fundamental architectural limitation in the current OAuth setup and is essential for:
- Reliable user authentication in production
- Multi-user deployments with centralized identity management
- Compliance with modern browser security standards
- Long-term maintainability of the authentication system
The backend proxy pattern is industry-standard and recommended by OWASP and OAuth 2.0 specifications for browser-based applications accessing protected resources.
Would this solution require user passing OIDC credentials to proxy?
No, absolutely not. This is actually one of the security benefits of the backend proxy approach.
Here's the OAuth 2.0 Authorization Code flow breakdown:
Flow: Where Credentials Go
1. User clicks "Login"
↓
2. Frontend → GitLab's /oauth/authorize endpoint
(User enters credentials directly on GitLab's server)
↓
3. User authorizes app on GitLab
↓
4. GitLab redirects back to Frontend with authorization CODE
↓
5. Frontend → Backend Proxy with CODE
↓
6. Backend Proxy + Backend Secret → GitLab's /oauth/token endpoint
(Exchange code for access token)
↓
7. Backend returns token to Frontend
What Users Pass To The Proxy
✅ Authorization code only — This is a single-use, short-lived code (expires in minutes)
✅ Not sensitive — Code is worthless without the client_secret
What Users Never Pass To Proxy
❌ Username/Password — Entered directly on GitLab's server, never sent to proxy
❌ OIDC tokens — Backend handles token exchange, frontend gets the final access token
❌ Client secret — Stays on backend only
Security Advantage
The backend proxy actually improves security because:
- Client secret stays on backend — Never exposed to browser or user
- User credentials never touch the proxy — Only GitLab authentication server sees them
- Token exchange happens server-to-server — No browser involvement in sensitive operations
- Credentials not logged in browser — Unlike if frontend did direct token exchange
In contrast, if your frontend were doing direct token exchange with credentials, that would be a red flag. But the Authorization Code flow with backend proxy is the OAuth 2.0 recommended pattern — it's what Google, GitHub, and every major platform does.
So you're good on the security front! 🔒
Description
Implement a backend proxy layer to handle OAuth/OIDC discovery endpoint requests from the DTaaS frontend. This resolves Chrome's CORS policy and Private Network Access restrictions that currently block direct access to the GitLab OAuth server from the browser.
Problem Statement
The DTaaS frontend (
intocps.org) cannot directly access GitLab's OAuth/OIDC endpoint (dtaas.com/gitlab/.well-known/openid-configuration) due to browser security restrictions:Chrome CORS Blocking: Direct requests from the public frontend to the private GitLab server are blocked with:
Private Network Access Restriction: Chrome enforces
Private Network Access(RFC 1918) restrictions, preventing public origins from accessing private/local network addresses, even with proper CORS headers.Impact: OAuth/OIDC login flow fails at the initial discovery phase, preventing user authentication.
Environment: This issue occurs in both development and production environments where the frontend is on a public domain and GitLab OAuth server is on a private network.
Current Behavior
Browser console errors:
Access to fetch blocked by CORS policyFailed to load resource: net::ERR_FAILEDnet::ERR_BLOCKED_BY_CLIENTProposed Solution
Implement a backend proxy layer that routes OAuth/OIDC discovery requests through the public DTaaS API, allowing the browser to communicate with a same-origin endpoint while the backend handles private network access.
Architecture
Implementation Details
1. Backend Endpoint
Add a new endpoint to the DTaaS backend API (Python/FastAPI or equivalent):
2. Environment Configuration
Add to deployment configuration:
3. Frontend Changes
Update OAuth discovery logic to use backend proxy:
Benefits
Alternative Solution 1: Nginx Proxy Headers
Configure the GitLab/OAuth server's reverse proxy to add CORS headers. Note: This alone does NOT bypass Private Network Access restrictions.
Nginx Configuration
Add to the OAuth server's nginx configuration:
Limitations
Alternative Solution 2: DNS and Certificate
Register the GitLab OAuth server with a valid public DNS entry and trusted SSL certificate, so Chrome no longer treats it as a "local" address.
Limitations
Implementation Scope
Phase 1: Core Proxy (Priority)
Phase 2: Enhanced Security (Optional)
Phase 3: Nginx Configuration (Optional)
Testing Strategy
Manual Testing
GET /api/oauth/openid-configAutomated Testing
Related Issues & Documentation
Additional Context
This feature addresses a fundamental architectural limitation in the current OAuth setup and is essential for:
The backend proxy pattern is industry-standard and recommended by OWASP and OAuth 2.0 specifications for browser-based applications accessing protected resources.
Would this solution require user passing OIDC credentials to proxy?
No, absolutely not. This is actually one of the security benefits of the backend proxy approach.
Here's the OAuth 2.0 Authorization Code flow breakdown:
Flow: Where Credentials Go
What Users Pass To The Proxy
✅ Authorization code only — This is a single-use, short-lived code (expires in minutes)
✅ Not sensitive — Code is worthless without the
client_secretWhat Users Never Pass To Proxy
❌ Username/Password — Entered directly on GitLab's server, never sent to proxy
❌ OIDC tokens — Backend handles token exchange, frontend gets the final access token
❌ Client secret — Stays on backend only
Security Advantage
The backend proxy actually improves security because:
In contrast, if your frontend were doing direct token exchange with credentials, that would be a red flag. But the Authorization Code flow with backend proxy is the OAuth 2.0 recommended pattern — it's what Google, GitHub, and every major platform does.
So you're good on the security front! 🔒