Thanks to visit codestin.com
Credit goes to github.com

Skip to content
/ cftl Public

Adds application-level security to Cloudflare Zero Trust with AUD validation and email access control.

License

Notifications You must be signed in to change notification settings

hezzitlda/cftl

Repository files navigation

πŸ›‘οΈ CF Zero Trust Third Layer (CFTL)

Additional Security Layer for Cloudflare Access Applications

CFTL provides an extra validation layer on top of Cloudflare Zero Trust, adding application-level security with AUD validation and email-based access control.

Docker License: MIT

πŸ” Three Layers of Security

Layer Component Purpose
1 Cloudflare Access Identity validation (SSO, MFA, policies)
2 Cloudflare Tunnel Secure network connection + JWT validation
3 CFTL (This System) Additional AUD validation + email restrictions

πŸš€ Quick Start

Using Docker Image

services:
  cftl:
    image: hezzit/cftl:latest
    container_name: cftl
    restart: always
    environment:
      - TUNNEL_TOKEN=your_tunnel_token_here #     v aud     v comma-separated list of emails
      - CONFIGS=your-app.example.com:my-app:3000:your_aud:[email protected]
        #			^ hostname		  ^ service:port				
    networks:
      - app-network
    depends_on:
      - app

  # Your application
  my-app:
    image: your-app:latest
    container_name: my-app
    networks:
      - app-network
    # No external ports - access only through CFTL

networks:
  app-network:
    external: false

🎯 Configuration System

CFTL uses a flexible alias-based configuration system that allows you to define reusable components and organize your services in multiple ways.

Basic Structure

# Define reusable components with aliases
AUDS=aud_alias:aud_value
EMAILS=email_alias:[email protected],[email protected]
HOSTNAMES=hostname_alias:hostname.example.com
SERVICES=service_alias:service_name

# Configure services using aliases
CONFIGS=hostname_alias:service_alias:port:aud_alias:email_alias

Configuration Examples

Simple Configuration (Single Service)

# Define components
AUDS=prod:abc123def456789
EMAILS=team:[email protected],[email protected]
HOSTNAMES=app:myapp.example.com
SERVICES=backend:my-backend-service

# Configure the service
CONFIGS=app:backend:3000:prod:team

Multiple Services

# Define shared components
AUDS=prod:abc123def456789
EMAILS=admin:[email protected]|dev:[email protected]
HOSTNAMES=api:api.example.com|web:web.example.com
SERVICES=backend:backend-api|frontend:nginx

# Configure each service
CONFIGS_API=api:backend:3000:prod:admin
CONFIGS_WEB=web:frontend:80:prod:dev

Advanced Organization Patterns

Pattern 1: Environment-Based
# Development environment
AUDS_DEV=dev:dev_aud_123
EMAILS_DEV=devteam:[email protected],[email protected]
HOSTNAMES_DEV=ide:ide.dev.example.com|debug:debug.dev.example.com
SERVICES_DEV=vscode:code-server
CONFIGS_DEV_IDE=ide:vscode:8080:dev:devteam
CONFIGS_DEV_DEBUG=debug:vscode:8081:dev:devteam

# Production environment
AUDS_PROD=prod:prod_aud_456
EMAILS_PROD=ops:[email protected]
HOSTNAMES_PROD=app:app.example.com|api:api.example.com
SERVICES_PROD=web:nginx|api:backend
CONFIGS_PROD_APP=app:web:80:prod:ops
CONFIGS_PROD_API=api:api:3000:prod:ops
Pattern 2: Team-Based
# Frontend team resources
AUDS_FRONTEND=fe:frontend_aud
EMAILS_FRONTEND=fe_team:[email protected]
HOSTNAMES_FRONTEND=app:app.example.com|preview:preview.example.com

# Backend team resources
AUDS_BACKEND=be:backend_aud
EMAILS_BACKEND=be_team:[email protected]
HOSTNAMES_BACKEND=api:api.example.com|admin:admin.example.com

# Shared services
SERVICES=nginx:nginx|node:nodejs|python:python-app

# Service configurations
CONFIGS_FE_APP=app:nginx:80:fe:fe_team
CONFIGS_FE_PREVIEW=preview:node:3000:fe:fe_team
CONFIGS_BE_API=api:python:8000:be:be_team
CONFIGS_BE_ADMIN=admin:node:4000:be:be_team
Pattern 3: Simplified (Using Defaults)
# When you don't need aliases, values without ':' use '0' as default alias
AUDS=abc123def456789
[email protected],[email protected]
HOSTNAMES=app.example.com
SERVICES=backend

# Reference using '0' alias
CONFIGS=0:0:3000:0:0

Special Cases

Service Without Authentication

# Empty AUD and emails fields = no third layer protection
CONFIGS_PUBLIC=public:nginx:80::

Only AUD Validation (No Email Restriction)

CONFIGS_API=api:backend:3000:prod:
#                                   ^ no email restriction

Mixed Configuration Styles

# You can mix all patterns in one deployment
AUDS=prod:prod_aud|staging:staging_aud
[email protected]  # Uses '0' as default alias
HOSTNAMES_PROD=app:app.example.com
HOSTNAMES_DEV=dev:dev.example.com
SERVICES=backend:my-backend|frontend:nginx

# Multiple CONFIGS variations
CONFIGS=app:backend:3000:prod:0|dev:frontend:80:staging:0  # Using default email alias
CONFIGS_PUBLIC=public.example.com:nginx:80::  # Direct values without aliases

πŸ“‹ Complete Setup Guide

Step 1: Configure Authentication Method

First, set up your identity provider integration:

πŸ“– Guide: Identity Provider Integration

Popular options:

  • GitHub OAuth
  • Google
  • Azure AD
  • Generic OIDC

Step 2: Create Access Policies

Define who can access your applications:

πŸ“– Guide: Access Policies

Example policy:

Step 3: Create Access Application

Set up your application in Cloudflare Access:

πŸ“– Guide: Self-Hosted Applications

Configuration:

  1. Application Name: Your App Name
  2. Application Domain: your-app.example.com
  3. Authentication Method: Select your configured method (GitHub, Google, etc.)
  4. Policies: Select your access policy
  5. Save and copy the Application AUD (you'll need this later)

Step 4: Create Cloudflare Tunnel

Set up secure connection to your application:

πŸ“– Guide: Create Remote Tunnel

Configuration:

  1. Tunnel Name: Your tunnel name
  2. Public Hostname: your-app.example.com (same as Access app)
  3. Service: http://localhost:8080 (CFTL proxy port)

⚠️ IMPORTANT - Additional Settings:

  • Navigate to Access tab in tunnel configuration
  • Enable "Validate JWT"
  • Select your Access Application (created in Step 3)
  1. Save and copy the Tunnel Token

Step 5: Configure CFTL

Choose your configuration style:

Option A: Simple Configuration

CONFIGS=your-app.example.com:your-service:3000:your_aud_from_step_3:[email protected]

Option B: Multi-Service Configuration

TUNNEL_TOKEN=your_tunnel_token

# Define all your AUDs
AUDS=prod:aud_123|staging:aud_456

# Define email groups
EMAILS=admin:[email protected]|dev:[email protected],[email protected]

# Define all hostnames
HOSTNAMES=app:app.example.com|api:api.example.com|admin:admin.example.com

# Define service types
SERVICES=web:nginx|backend:nodejs-api

# Configure each service
CONFIGS_APP=app:web:80:prod:admin
CONFIGS_API=api:backend:3000:prod:dev
CONFIGS_ADMIN=admin:backend:4000:staging:admin

Step 6: Deploy

docker-compose up -d

πŸ”§ Environment Variables

Core Variables

Variable Description Required Example
TUNNEL_TOKEN Cloudflare Tunnel token βœ… eyJhbGci...
PORT CFTL listening port ❌ 8080 (default)
VERBOSE Enable verbose logging ❌ false (default)

Configuration Variables

Variable Pattern Description Example
AUDS* AUD definitions AUDS=prod:abc123 or AUDS_DEV=dev:xyz789
EMAILS* Email group definitions EMAILS=admin:[email protected]
HOSTNAMES* Hostname definitions HOSTNAMES=app:app.example.com
SERVICES* Service type definitions SERVICES=backend:my-backend
CONFIGS* Service configurations CONFIGS_APP=app:backend:3000:prod:admin

Note: All patterns support multiple definitions (AUDS, AUDS_1, AUDS_PROD, etc.)

πŸ” How It Works

  1. User visits your-app.example.com
  2. Cloudflare Access validates identity (Layer 1)
  3. Cloudflare Tunnel validates JWT and forwards to CFTL (Layer 2)
  4. CFTL validates AUD and email authorization (Layer 3)
  5. If all layers pass, request is forwarded to your application

User Headers Passed to Application

When authentication is successful, your application receives these HTTP headers:

Header Description Example
X-Auth-User-Email User's email address [email protected]
X-Auth-User-ID Unique user ID (CF Access sub) 7335d417-61da-459d-899c-0a01c76a2f94
X-Auth-User-Country User's authentication country US
X-Auth-Method Authentication method used cf-access-third-layer
X-Auth-Service Service name (internal) app_example_com
X-Auth-AUD Validated CF Access AUD abc123def456...
X-Auth-Issuer CF Access issuer URL https://yourteam.cloudflareaccess.com
X-Auth-Token-Type Token type app
X-Auth-Identity-Nonce CF identity cache key 6ei69kawdKzMIAPF

Using Headers in Your Application

Flask (Python):

@app.route('/')
def index():
    user_email = request.headers.get('X-Auth-User-Email')
    user_country = request.headers.get('X-Auth-User-Country')
    return f"Welcome {user_email} from {user_country}"

Express.js (Node.js):

app.get('/', (req, res) => {
    const userEmail = req.headers['x-auth-user-email'];
    const userCountry = req.headers['x-auth-user-country'];
    res.send(`Welcome ${userEmail} from ${userCountry}`);
});

Note: Only services with third layer protection receive user headers. Services without third layer (bypass mode) are direct proxied without authentication headers.

πŸ› οΈ Troubleshooting

Check System Status

docker-compose logs cftl

Common Issues

Issue Possible Cause Solution
DENIED: No CF Access token Domain mismatch between Access App and CFTL Ensure Access Application domain matches CFTL hostname exactly
DENIED: AUD mismatch Wrong AUD in configuration Copy correct AUD from Access Application
DENIED: Unauthorized email Email not in authorized list Add email to EMAILS configuration
Nginx error page (white/plain) Issue between CFTL and your app Check app connectivity and port configuration
Browser error (empty response/connection reset) Issue between Tunnel and Access App Ensure tunnel hostname matches Access Application domain exactly
Tunnel not connecting Invalid tunnel token Generate new token from tunnel settings

Test Individual Layers

# Test if tunnel is working
curl -I https://your-app.example.com

# Check CFTL logs for third layer validation
docker-compose logs -f cftl

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.


Built with ❀️ by Hezzit. Contributions are welcome!

⭐ If this project helped you, please give it a star!

About

Adds application-level security to Cloudflare Zero Trust with AUD validation and email access control.

Topics

Resources

License

Stars

Watchers

Forks

Packages