5.3 KiB
5.3 KiB
CFTunnels - Cloudflare Tunnels Management API
A Spring Boot REST API for managing Cloudflare Tunnels with ingress mappings and an approval workflow.
Overview
CFTunnels provides a programmatic way to manage Cloudflare Tunnel configurations, allowing teams to:
- View and manage Cloudflare Tunnels
- Add, modify, and delete ingress mappings
- Request mapping changes through an approval workflow
- Track tunnel configurations locally
Features
- Tunnel Management: Create, update, and delete Cloudflare tunnels
- Ingress Mappings: Add custom ingress rules to tunnel configurations
- Approval Workflow: Request/approve/reject mapping changes
- Security: OIDC-based authentication with role-based access
- API Documentation: OpenAPI/Swagger documentation
Technology Stack
- Java 17
- Spring Boot 3.x
- Spring Data JPA
- Spring Security with OIDC
- H2 Database (configurable for PostgreSQL)
- Cloudflare API v4
Prerequisites
- Java 17 or higher
- Cloudflare account with API key
- OIDC provider (e.g., Google, Okta, Auth0)
Configuration
Copy .env.example to .env and configure:
cp .env.example .env
Required Environment Variables
| Variable | Description |
|---|---|
CLOUDFLARE_ACCOUNT_ID |
Cloudflare Account ID |
CLOUDFLARE_API_KEY |
Cloudflare API Key |
CLOUDFLARE_EMAIL |
Cloudflare account email |
SPRING_PROFILES_ACTIVE |
Environment (local, dev, prod) |
Security Configuration
OIDC settings in application.properties:
spring.security.oauth2.client.registration.<provider>.client-id=your-client-id
spring.security.oauth2.client.registration.<provider>.client-secret=your-client-secret
spring.security.oauth2.client.provider.<provider>.issuer-uri=https://your-oidc-provider
Running Locally
Using Gradle
./gradlew bootRun
Using Docker
docker-compose up --build
The API will be available at http://localhost:8080
API Documentation
Once running, access:
- Swagger UI:
http://localhost:8080/swagger-ui.html - OpenAPI JSON:
http://localhost:8080/v3/api-docs
API Endpoints
Base URL: /cloudflare
| Method | Endpoint | Description | Required Role |
|---|---|---|---|
| GET | /whoami |
Get current user info | USER |
| GET | /tunnels |
List all Cloudflare tunnels | USER |
| GET | /configured/tunnels |
List locally configured tunnels | USER |
| GET | /requests |
List all mapping requests | USER |
| GET | /tunnels/{tunnelId}/mappings |
Get tunnel configuration | DEVELOPER |
| POST | /tunnels/{tunnelId}/mappings |
Add ingress mapping | ADMIN |
| DELETE | /tunnels/{tunnelId}/mappings |
Delete ingress mapping | DEVELOPER |
| POST | /tunnels/configure/{tunnelId}/requests |
Create mapping request | DEVELOPER |
| PUT | /requests/{requestId}/approve |
Approve mapping request | APPROVER |
| PUT | /requests/{requestId}/reject |
Reject mapping request | APPROVER |
| PUT | /tunnels/configure/{tunnelId} |
Configure tunnel for environment | ADMIN |
Role-Based Access
| Role | Permissions |
|---|---|
| USER | View tunnels and requests |
| DEVELOPER | Create/modify/delete mappings, create requests |
| APPROVER | Approve/reject requests |
| ADMIN | Full access including tunnel configuration |
Example Usage
List all tunnels
curl -H "Authorization: Bearer $TOKEN" \
http://localhost:8080/cloudflare/tunnels
Add an ingress mapping
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"hostname": "api.example.com",
"service": "http://localhost:8080",
"originRequest": {"noTLSVerify": true}
}' \
http://localhost:8080/cloudflare/tunnels/{tunnelId}/mappings
Project Structure
CFTunnels/
├── src/main/java/com/hithomelabs/CFTunnels/
│ ├── CfTunnelsApplication.java # Main application
│ ├── Config/ # Configuration classes
│ ├── Controllers/ # REST controllers
│ │ └── TunnelController.java # Main API controller
│ ├── Entity/ # JPA entities
│ │ ├── Mapping.java # Ingress mapping
│ │ ├── Protocol.java # Protocol enum
│ │ ├── Request.java # Mapping request
│ │ ├── Tunnel.java # Tunnel entity
│ │ └── User.java # User entity
│ ├── Models/ # DTOs
│ ├── Repositories/ # JPA repositories
│ └── Services/ # Business logic
│ ├── CloudflareAPIService.java # Cloudflare API
│ └── MappingRequestService.java # Request workflow
└── src/main/resources/
├── application.properties # Main config
└── schema.sql # Database schema
Testing
Run tests with:
./gradlew test
Run integration tests:
./gradlew integrationTest
License
Private - All rights reserved