# 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: ```bash 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`: ```properties spring.security.oauth2.client.registration..client-id=your-client-id spring.security.oauth2.client.registration..client-secret=your-client-secret spring.security.oauth2.client.provider..issuer-uri=https://your-oidc-provider ``` ## Running Locally ### Using Gradle ```bash ./gradlew bootRun ``` ### Using Docker ```bash 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 ```bash curl -H "Authorization: Bearer $TOKEN" \ http://localhost:8080/cloudflare/tunnels ``` ### Add an ingress mapping ```bash 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: ```bash ./gradlew test ``` Run integration tests: ```bash ./gradlew integrationTest ``` ## License Private - All rights reserved ## References - [Cloudflare Tunnel Documentation](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/) - [Cloudflare API v4](https://api.cloudflare.com/) - [Spring Boot Documentation](https://docs.spring.io/spring-boot/docs/current/reference/)