SSO Integration Guide
Overview
This guide covers how to integrate Single Sign-On (SSO) authentication with the LATTS documentation site to control access and ensure only authorized team members can view internal documentation. We focus on Cloudflare Access as the primary solution for modern, scalable authentication.
Recommended: Cloudflare Access
Cloudflare Access is the preferred authentication solution for static sites like Hugo documentation. It provides enterprise-grade security with minimal configuration.
Prerequisites
- Cloudflare account with domain management
- GitHub organization for team management
- Static site hosted on Cloudflare Pages or custom domain
Step-by-Step Setup
1. Enable Cloudflare Zero Trust
Navigate to Zero Trust Dashboard
- Go to dash.cloudflare.com
- Click Zero Trust in the sidebar
- Complete onboarding if first-time setup
Configure Team Domain
- Set your team domain:
latts-team.cloudflareaccess.com - This domain will handle authentication flows
- Set your team domain:
2. Add GitHub as Identity Provider
Create GitHub OAuth Application
- Go to
https://github.com/organizations/latts-ie/settings/applications - Click New OAuth App
- Configure:
- Application name:
LATTS Docs - Cloudflare Access - Homepage URL:
https://docs.latts.ie - Authorization callback URL:
https://latts-team.cloudflareaccess.com/cdn-cgi/access/callback
- Application name:
- Go to
Configure GitHub in Cloudflare
- In Zero Trust Dashboard → Settings → Authentication
- Click Add new → GitHub
- Enter GitHub OAuth credentials:
- App ID: GitHub Client ID
- Client Secret: GitHub Client Secret
- Connection name:
GitHub - LATTS Team
3. Create Access Application
Add New Application
- Go to Zero Trust → Access → Applications
- Click Add an application → Self-hosted
Configure Application Details
- Application name:
LATTS Internal Documentation - Application domain:
docs.latts.ie(or your domain) - Path:
/*(protect entire site)
- Application name:
Set Access Policies
- Policy name:
LATTS Organization Members - Action:
Allow - Include rules:
- GitHub Organizations:
latts-ie
- GitHub Organizations:
- Click Save policy
- Policy name:
4. Advanced Access Control
For more granular permissions:
# Team-based access control
Include:
- GitHub Teams: latts-ie/developers
- GitHub Teams: latts-ie/documentation-team
# Email domain restrictions
Include:
- Emails ending in: company.com, latts.ie
# Geographic restrictions
Include:
- Country: Ireland, United Kingdom
# Time-based access (business hours only)
Require:
- Time-based: Monday-Friday, 9:00-17:00 GMT
Configuration Examples
Basic Organization Access
{
"name": "LATTS Team Access",
"decision": "allow",
"include": [
{
"github": {
"name": "latts-ie",
"teams": ["all"]
}
}
]
}
Granular Team Access
{
"name": "Documentation Team Access",
"decision": "allow",
"include": [
{
"github": {
"name": "latts-ie",
"teams": ["developers", "documentation-team", "leads"]
}
}
],
"require": [
{
"email_domain": ["latts.ie", "company.com"]
}
]
}
Alternative: GitHub OAuth with oauth2-proxy
For self-hosted deployments or custom authentication flows:
Prerequisites
- Docker environment for oauth2-proxy
- GitHub organization with team management
- Reverse proxy capability (nginx, Apache, etc.)
Setup Steps
Configure oauth2-proxy
# docker-compose.yml version: '3' services: oauth2-proxy: image: quay.io/oauth2-proxy/oauth2-proxy:v7.4.0 command: - --provider=github - --email-domain=* - --upstream=http://hugo-site:80 - --http-address=0.0.0.0:4180 - --github-org=latts-ie - --github-team=latts-ie/developers - --github-team=latts-ie/documentation-team environment: OAUTH2_PROXY_CLIENT_ID: ${GITHUB_CLIENT_ID} OAUTH2_PROXY_CLIENT_SECRET: ${GITHUB_CLIENT_SECRET} OAUTH2_PROXY_COOKIE_SECRET: ${COOKIE_SECRET}Nginx Reverse Proxy Configuration
server { listen 443 ssl; server_name docs.latts.ie; # SSL configuration ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; # Authentication endpoint location /oauth2/ { proxy_pass http://oauth2-proxy:4180; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Scheme $scheme; proxy_set_header X-Auth-Request-Redirect $request_uri; } # Authentication subrequest location = /oauth2/auth { proxy_pass http://oauth2-proxy:4180; proxy_pass_request_body off; proxy_set_header Content-Length ""; proxy_set_header X-Original-URI $request_uri; } # Protected documentation location / { auth_request /oauth2/auth; error_page 401 = /oauth2/sign_in; proxy_pass http://hugo-site:80; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Scheme $scheme; # Pass user information to backend auth_request_set $user $upstream_http_x_auth_request_user; auth_request_set $email $upstream_http_x_auth_request_email; proxy_set_header X-User $user; proxy_set_header X-Email $email; } }
Azure Active Directory Integration
For enterprise environments using Azure AD:
Prerequisites
- Azure AD tenant access
- Application registration permissions
- Understanding of OIDC/SAML protocols
Setup Steps
Register Application in Azure AD
- Go to Azure Portal → Azure Active Directory → App registrations
- Create new registration:
- Name:
LATTS Internal Documentation - Redirect URI:
https://latts-team.cloudflareaccess.com/cdn-cgi/access/callback - Account types: Single tenant
- Name:
Configure in Cloudflare Access
- Add Azure AD as identity provider in Zero Trust
- Use Azure AD application credentials
- Configure group-based access control
Group-based Access Control
{ "name": "Azure AD Group Access", "decision": "allow", "include": [ { "azureAD": { "connection_id": "azure-ad-connection", "identity_groups": [ "documentation-readers", "latts-team-all" ] } } ] }
Security Best Practices
Session Management
- Session timeout: 8 hours maximum
- Secure cookies: HTTPS-only, SameSite=Strict
- Cookie secrets: Use cryptographically secure random values
- Rotate secrets: Quarterly rotation schedule
Access Control
- Least privilege: Grant minimum necessary access
- Regular audits: Monthly access reviews
- Group-based permissions: Avoid individual user grants
- Audit logging: Enable comprehensive access logs
Infrastructure Security
- HTTPS enforcement: Redirect all HTTP to HTTPS
- Security headers: Implement CSP, HSTS, XSS protection
- Rate limiting: Prevent authentication abuse
- DDoS protection: Use Cloudflare’s built-in protection
Configuration Examples
Security Headers
# static/_headers (for Cloudflare Pages)
/*
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
Strict-Transport-Security: max-age=31536000; includeSubDomains
Content-Security-Policy: default-src 'self'; img-src 'self' data: https:; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; script-src 'self' 'unsafe-inline'
Rate Limiting (Cloudflare Rules)
{
"expression": "(http.request.uri.path contains \"/cdn-cgi/access/\" and rate(5m) > 20)",
"action": "challenge",
"description": "Rate limit authentication attempts"
}
Testing and Validation
Local Testing
- Test OAuth flow with development applications
- Verify group membership affects access decisions
- Test session timeout and renewal behavior
- Validate error handling for authentication failures
Production Testing
- End-to-end authentication with real user accounts
- Different browser environments and incognito mode
- Mobile device compatibility for team members
- Edge case scenarios like expired sessions
Automated Testing
#!/bin/bash
# Authentication flow test script
# Test unauthenticated access (should redirect)
response=$(curl -s -o /dev/null -w "%{http_code}" https://docs.latts.ie/)
if [ "$response" -eq 302 ]; then
echo "✅ Unauthenticated access properly redirects"
else
echo "❌ Authentication not working (got $response)"
fi
# Test authentication endpoint
auth_response=$(curl -s -o /dev/null -w "%{http_code}" https://docs.latts.ie/cdn-cgi/access/get-identity)
echo "Auth endpoint response: $auth_response"
Monitoring and Maintenance
Cloudflare Analytics
- Authentication events: Monitor login attempts and failures
- Geographic patterns: Review access locations for anomalies
- Device analytics: Track authentication device types
- Performance metrics: Monitor authentication latency
Log Analysis
# Example log queries for Cloudflare Access
# Failed authentication attempts
grep "access_denied" /var/log/cloudflare-access.log | tail -10
# Geographic anomalies
grep "country" /var/log/cloudflare-access.log | sort | uniq -c
# High-frequency users
grep "user_email" /var/log/cloudflare-access.log | cut -d'"' -f4 | sort | uniq -c | sort -nr
Regular Maintenance Tasks
Weekly
- Review failed authentication logs
- Check for unusual access patterns
- Verify team membership changes
Monthly
- Audit user access permissions
- Review and update access policies
- Test authentication flow end-to-end
- Check SSL certificate expiration
Quarterly
- Rotate OAuth application secrets
- Review and update security policies
- Conduct access control audit
- Update documentation based on changes
Troubleshooting
Common Issues
Authentication loops or redirects
- Verify callback URLs match exactly in OAuth app
- Check for trailing slashes in domain configuration
- Ensure HTTPS is properly configured
Users in organization but can’t access
- Verify organization membership is public
- Check if user has two-factor authentication enabled
- Confirm OAuth app is approved for organization
Session expires immediately
- Check cookie domain configuration
- Verify system clock synchronization
- Review session timeout settings
Debug Commands
# Test DNS resolution
dig docs.latts.ie
# Check SSL certificate
openssl s_client -connect docs.latts.ie:443 -servername docs.latts.ie
# Test authentication endpoint
curl -v https://docs.latts.ie/cdn-cgi/access/get-identity
# Verify Cloudflare Access policies
curl -H "Authorization: Bearer ${CF_API_TOKEN}" \
"https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/access/apps"
Cost Analysis
Cloudflare Access Pricing
- Free tier: Up to 50 users
- Teams plan: $3/user/month for 1,000+ users
- Enterprise: Custom pricing for advanced features
Comparison with Alternatives
| Solution | Setup Time | Monthly Cost | Maintenance | Security Level |
|---|---|---|---|---|
| Cloudflare Access | 30 minutes | $0-150/month | Low | Enterprise |
| oauth2-proxy | 2-4 hours | Server costs | Medium | High |
| Azure AD | 1-2 hours | $6-22/user/month | Medium | Enterprise |
| Repository visibility | 5 minutes | $0 | Very Low | Basic |
See Also
- Cloudflare Pages + SSO Setup Guide - Complete deployment walkthrough
- Quick Start Guide - Rapid deployment option
- Hugo Development Guide - Local development setup
- Cloudflare Access Documentation
- GitHub OAuth Apps Guide