A modern command-line interface for managing Cloudflare services with advanced cache management capabilities.
- Overview
- Features
- System Requirements
- Installation
- Quick Start
- Usage
- Configuration
- Security
- Architecture
- Development
- Troubleshooting
- Contributing
- License
CFCTL is a production-grade command-line interface designed for efficient management of Cloudflare services. Built with Go 1.24 and the Cloudflare SDK v6, it provides an interactive terminal user interface (TUI) for cache management, domain administration, and secure multi-account credential handling.
- Secure Credential Management: Leverages system-native keyring services for encrypted storage of API credentials
- Multi-Account Support: Seamlessly manage multiple Cloudflare accounts from a single interface
- Advanced Cache Purging: Five distinct purge methods for granular cache control
- Interactive Terminal UI: Built with Bubble Tea framework for smooth, responsive user experience
- Cross-Platform Compatibility: Native binaries for macOS (Intel/Apple Silicon) and Linux (AMD64/ARM64)
CFCTL provides comprehensive cache purging capabilities:
- Purge by URL: Remove specific files from cache by providing exact URLs
- Purge by Hostname: Clear all cached assets for a specific hostname
- Purge by Tag: Remove cache entries matching specific tags (Enterprise feature)
- Purge by Prefix: Clear cache for all URLs matching a path prefix
- Purge Everything: Complete zone cache invalidation with safety confirmations
- Secure storage of API tokens and global API keys via system keyring
- Support for multiple Cloudflare accounts with easy switching
- Account removal with automatic credential cleanup
- Persistent configuration with YAML-based storage
- List all zones associated with configured accounts
- Interactive domain selection interface
- Cached domain listings with configurable TTL
- Modern terminal UI with smooth animations
- Keyboard-driven navigation (Vim-style key bindings supported)
- Colored output with optional monochrome mode
- Confirmation prompts for destructive operations
- Real-time operation feedback
| Platform | Architecture | Minimum Version |
|---|---|---|
| macOS | AMD64 (Intel) | macOS 10.15+ |
| macOS | ARM64 (Apple Silicon) | macOS 11.0+ |
| Linux | AMD64 | Kernel 3.10+ |
| Linux | ARM64 | Kernel 3.10+ |
Runtime Requirements:
- System keyring service:
- macOS: Keychain Services (built-in)
- Linux: Secret Service API (GNOME Keyring, KDE Wallet, or compatible)
Build Requirements (for compilation from source):
- Go 1.24 or later
- Make (GNU Make 3.81+)
- Git
- HTTPS connectivity to Cloudflare API endpoints
- Outbound access to
api.cloudflare.com(port 443)
# Clone the repository
git clone https://github.com/siyamsarker/cfctl.git
cd cfctl
# Build and install
make build
sudo ./scripts/install.shThe installation script will:
- Detect your system architecture automatically
- Install the binary to
/usr/local/bin/cfctl - Create configuration directory at
~/.config/cfctl - Set appropriate executable permissions
# Build for your platform
make build
# Install to system path
sudo cp bin/cfctl /usr/local/bin/
# Verify installation
cfctl --version# Build for macOS (Intel)
make build-darwin
# Build for Linux (AMD64)
make build-linux
# Build for all platforms
make build-allCompiled binaries will be available in the bin/ directory:
cfctl-darwin-amd64- macOS Intelcfctl-darwin-arm64- macOS Apple Siliconcfctl-linux-amd64- Linux AMD64cfctl-linux-arm64- Linux ARM64
# Using Makefile (Recommended)
sudo make uninstall
# Using Uninstall Script
sudo ./scripts/uninstall.shThis will remove:
- Binary from
/usr/local/bin/cfctl - Configuration directory (with user confirmation)
- Cache directory (if exists)
- Note: Keyring credentials require manual removal (instructions provided during uninstall)
-
Launch CFCTL
cfctl
Note: If you encounter keyring access issues, you may need to run with
sudo cfctl -
Configure Cloudflare Account
- Select "Configure Account" from the main menu
- Choose authentication method (API Token recommended)
- Enter account details and credentials
-
Manage Accounts
- You can add multiple accounts and switch between them using "Select Account"
- To remove an account and its credentials, use "Remove Account" from the main menu
-
Obtain API Credentials
API Token (Recommended)
- Navigate to Cloudflare API Tokens
- Click "Create Token"
- Use "Edit zone DNS" template or create custom with permissions:
- Zone - Zone - Read
- Zone - Cache Purge - Purge
- Copy the generated token
Global API Key (Legacy)
- Navigate to Cloudflare API Tokens
- Locate "Global API Key" section
- Click "View" and copy the key
Managing Domains
cfctl
# Navigate to: Manage Domains → Select Domain → Choose OperationPurging Cache
- Select domain from the domain list
- Choose purge method:
- Purge by URL (for specific files)
- Purge by Hostname (for entire subdomains)
- Purge Everything (with double confirmation)
- Follow interactive prompts
- Confirm operation
cfctl [flags]| Flag | Short | Type | Description |
|---|---|---|---|
--account |
-a |
string | Use specific Cloudflare account |
--config |
-c |
string | Config file path (default: ~/.config/cfctl/config.yaml) |
--no-color |
boolean | Disable colored output | |
--debug |
boolean | Enable debug mode with verbose logging | |
--quiet |
-q |
boolean | Suppress non-error output |
--version |
-v |
boolean | Display version information |
--help |
-h |
boolean | Display help information |
Use specific account
cfctl --account productionCustom configuration file
cfctl --config /path/to/config.yamlDebug mode for troubleshooting
cfctl --debugDisable colors for CI/CD environments
cfctl --no-color| Key | Action |
|---|---|
↑ / k |
Navigate up |
↓ / j |
Navigate down |
Enter |
Select / Confirm |
Esc / q |
Back / Cancel |
Ctrl+C |
Quit application |
Tab |
Next field (forms) |
Shift+Tab |
Previous field (forms) |
CFCTL generally runs without elevated privileges. However, sudo may be required in these scenarios:
When sudo is needed:
- Installing/uninstalling the binary (
sudo make install,sudo make uninstall) - Running the installation scripts (
sudo ./scripts/install.sh) - Keyring access issues on some Linux distributions
When sudo is NOT needed:
- Normal application usage (
cfctl) - Viewing help or version (
cfctl --help,cfctl --version) - Most runtime operations
# Run with sudo if you encounter keyring access issues
sudo cfctlWhen run with sudo, CFCTL automatically uses the invoking user's home directory for configuration and credentials:
sudo cfctl --config /path/to/config.yamlDefault: ~/.config/cfctl/config.yaml
Override via:
- Command-line flag:
--config /path/to/config.yaml - Environment variable:
CFCTL_CONFIG=/path/to/config.yaml
version: 1
defaults:
account: "" # Default account name (empty = prompt on startup)
theme: "dark" # UI theme: dark, light, system
output: "interactive" # Output mode: interactive, json, table
api:
timeout: 30 # Request timeout in seconds (default: 30)
retries: 3 # Number of retry attempts (default: 3)
ui:
confirmations: true # Show confirmation prompts (default: true)
animations: true # Enable UI animations (default: true)
colors: true # Enable colored output (default: true)
cache:
domains_ttl: 300 # Domain list cache TTL in seconds (default: 300)
enabled: true # Enable local caching (default: true)
accounts: [] # Account list (managed by application)defaults
account: Automatically select this account on startup (omit to show account selector)theme: Color scheme for terminal UIoutput: Future-proofing for non-interactive modes
api
timeout: Maximum wait time for API requests (seconds)retries: Automatic retry attempts for failed requests
ui
confirmations: Require user confirmation for destructive operationsanimations: Enable/disable UI transition animationscolors: Control colored output (overridden by--no-colorflag)
cache
domains_ttl: How long to cache domain listings before refreshingenabled: Toggle local caching of API responses
| Variable | Description |
|---|---|
CFCTL_CONFIG |
Override config file location |
NO_COLOR |
Disable colored output (set to any value) |
CFCTL_DEBUG |
Enable debug logging (set to any value) |
HOME |
User home directory (for config/credential paths) |
XDG_CONFIG_HOME |
XDG base directory (overrides ~/.config) |
CFCTL prioritizes security by leveraging platform-native keyring services for credential storage, ensuring your API credentials are encrypted and protected by your operating system's security infrastructure.
| Platform | Service | Storage Location | Encryption |
|---|---|---|---|
| macOS | Keychain Services | ~/Library/Keychains/login.keychain-db |
AES-128 with user's login password |
| Linux | Secret Service API | Implementation-specific encrypted database | User session password or custom password |
Supported Linux Keyring Backends:
- GNOME Keyring (GNOME desktops)
- KDE Wallet (KDE desktops)
- KeePassXC (cross-platform)
What Gets Stored Where:
System Keyring (Encrypted):
├── Service: "cfctl"
├── Account: "your-account-name"
└── Secret: API Token or Global API Key
Configuration File (~/.config/cfctl/config.yaml):
├── Account names (non-sensitive)
├── Authentication type (token/key)
├── UI preferences
├── API settings
└── NO SECRETS ✓
Security Guarantees:
- Zero Plaintext Storage: Credentials are never stored in plain text anywhere on disk
- OS-Level Encryption: API tokens encrypted using your operating system's native encryption (AES-128 on macOS)
- Safe Configuration Files:
config.yamlcontains no sensitive data and can be safely version controlled - Authentication Required: Keyring access requires user authentication on first use
- Memory Protection: Credentials cleared from memory after use
- Isolation: Each account stored separately with unique keyring entries
macOS:
# View keyring entries (requires authentication)
security find-generic-password -s "cfctl" -w
# Check if credentials exist without revealing them
security find-generic-password -s "cfctl" -a "your-account-name"Linux:
# Search for CFCTL credentials
secret-tool search service cfctl
# List all CFCTL keyring entries
secret-tool search service cfctl account "your-account-name"Verify Config Safety:
# Check that config contains no secrets
cat ~/.config/cfctl/config.yaml | grep -i "token\|key\|password\|secret"
# Should return nothing-
Use API Tokens instead of Global API Keys
- Tokens provide scoped permissions
- Can be revoked without affecting other integrations
- Support fine-grained access control
- More secure than Global API Keys
-
Apply Principle of Least Privilege
Minimum required permissions for CFCTL:
Zone - Zone - Read (View domains) Zone - Cache Purge - Purge (Clear cache)How to create a scoped token:
- Go to Cloudflare API Tokens
- Click "Create Token"
- Use "Edit zone DNS" template or create custom token
- Select only the permissions listed above
- Optionally restrict to specific zones
- Set token expiration date (recommended: 90 days)
-
Rotate Credentials Regularly
Recommended rotation schedule:
- API Tokens: Every 90 days
- Global API Keys: Every 60 days (if you must use them)
How to rotate:
1. Generate new token at Cloudflare Dashboard 2. Launch CFCTL and navigate to "Configure Account" 3. Update credentials with new token 4. Verify new token works 5. Revoke old token at Cloudflare Dashboard -
Use Separate Tokens per Environment
- Development: Limited zone access, short expiration
- Staging: Staging zones only, read-only if possible
- Production: Production zones with team review, audit logging enabled
-
Audit Account Access
- Review configured accounts monthly
- Remove unused accounts immediately
- Check Cloudflare audit logs for unexpected API activity
- Monitor token usage in Cloudflare Dashboard
-
Secure Your System
- Use strong password for your OS user account
- Enable disk encryption (FileVault on macOS, LUKS on Linux)
- Keep CFCTL updated to latest version
- Use trusted networks or VPN
- ✅ API Tokens (stored in system keyring)
- ✅ Global API Keys (stored in system keyring)
- ✅ All authentication credentials
- ❌ Account names (just identifiers)
- ❌ Configuration preferences (timeout, colors, etc.)
- ❌ Cached domain lists (zone names and IDs are public via DNS)
- ❌ UI settings
# Safe to share or version control:
~/.config/cfctl/config.yaml # Contains no secrets
# Keep private (requires authentication to access):
macOS: ~/Library/Keychains/login.keychain-db
Linux: Implementation-specific keyring databaseFor comprehensive security information, see SECURITY.md:
- Responsible vulnerability disclosure policy
- Detailed security architecture
- Security best practices guide
- Incident response procedures
- Security testing guidelines
To ensure the best experience and security when using CFCTL:
✅ DO:
- Use API Tokens: Always prefer API Tokens with scoped permissions over Global API Keys.
- Verify Permissions: Ensure your token has
Zone:ReadandCache:Purgepermissions. - Use the TUI: Navigate using the interactive menu for safer operations.
- Regularly Update: Keep CFCTL updated to the latest version for security fixes.
- Remove Unused Accounts: Use the "Remove Account" feature to clean up old credentials.
❌ DO NOT:
- Share your Config: Never share your
config.yamlor local keychain entries. - Use Root Unnecessarily: Run as a regular user unless you specifically need system-wide installation.
- Edit Config Manually: Avoid manually editing
config.yamlto prevent corruption; use the CLI. - Force Quit: Avoid using
kill -9as it may leave the keyring in a locked state. - Ignore Errors: If an API call fails, check the error message before retrying repeatedly to avoid rate limits.
cfctl/
├── cmd/
│ └── cfctl/ # Application entry point
│ └── main.go # CLI initialization, flag parsing
├── internal/
│ ├── api/ # Cloudflare API client
│ │ ├── cache.go # Cache purge operations
│ │ ├── client.go # API client initialization
│ │ ├── client_test.go # Client unit tests
│ │ └── zones.go # Zone/domain operations
│ ├── config/ # Configuration management
│ │ ├── accounts.go # Account CRUD operations
│ │ ├── config.go # Config file handling
│ │ ├── validator.go # Input validation
│ │ └── validator_test.go
│ ├── handlers/ # Business logic layer
│ ├── ui/ # Terminal UI components
│ │ ├── welcome.go # Welcome screen
│ │ ├── menu.go # Main menu
│ │ ├── account_*.go # Account management screens
│ │ ├── domain_list.go # Domain selection
│ │ ├── purge_*.go # Cache purge interfaces
│ │ ├── settings.go # Settings screen
│ │ ├── styles.go # UI styling (Lip Gloss)
│ │ └── help.go # Help screen
│ └── utils/ # Utility functions
│ ├── helpers.go # General helpers
│ ├── validator.go # Validation utilities
│ └── validator_test.go
├── pkg/
│ └── cloudflare/ # Public types and models
├── configs/
│ └── default.yaml # Default configuration template
├── scripts/
│ ├── install.sh # Installation script
│ └── uninstall.sh # Uninstallation script
├── bin/ # Compiled binaries (generated)
├── Makefile # Build automation
├── go.mod # Go module dependencies
├── go.sum # Dependency checksums
├── LICENSE # MIT License
└── README.md
| Component | Library | Version | Purpose |
|---|---|---|---|
| Language | Go | 1.24.0 | Core implementation |
| Cloudflare SDK | cloudflare-go | v6.5.0 | API client |
| TUI Framework | Bubble Tea | v1.3.10 | Interactive terminal UI |
| UI Styling | Lip Gloss | v1.1.0 | Terminal styling |
| UI Components | Bubbles | v0.21.0 | Reusable TUI widgets |
| CLI Framework | Cobra | v1.10.2 | Command-line interface |
| Configuration | Viper | v1.21.0 | Config file management |
| Keyring | go-keyring | v0.2.6 | Secure credential storage |
| Testing | testify | v1.11.1 | Test assertions |
cmd/cfctl: Application bootstrap, flag parsing, environment setup
internal/api: Cloudflare API integration layer
- Client initialization with authentication
- Zone listing and filtering
- Cache purge operations (all methods)
- Error handling and retry logic
internal/config: Configuration and credential management
- YAML configuration loading/saving
- Account CRUD operations
- Keyring integration for secure storage
- Input validation
internal/ui: Bubble Tea-based terminal interface
- Screen navigation and state management
- Form rendering and input handling
- Visual styling and theming
- User interaction flows
internal/utils: Shared utilities
- URL validation
- String manipulation
- Data formatting
pkg/cloudflare: Public types for external use (future extensibility)
The Makefile provides comprehensive build automation:
| Target | Description |
|---|---|
make build |
Build for current platform |
make build-all |
Build for all platforms |
make build-darwin |
Build macOS binaries (Intel + ARM) |
make build-linux |
Build Linux binaries (AMD64 + ARM64) |
make test |
Run unit tests |
make test-coverage |
Generate coverage report |
make lint |
Run golangci-lint |
make fmt |
Format code with gofmt |
make tidy |
Tidy Go modules |
make clean |
Remove build artifacts |
make install |
Build and install locally (requires sudo) |
make uninstall |
Uninstall from system (requires sudo) |
make run |
Build and run application |
Build Flags:
-ldflags="-s -w -X main.version=$(VERSION)"-s: Omit symbol table-w: Omit DWARF debug info-X main.version=...: Embed version string
-
Clone Repository
git clone https://github.com/siyamsarker/cfctl.git cd cfctl -
Install Dependencies
go mod download
-
Build Application
make build
-
Run Tests
make test
Running Locally
make runRunning with Debug Mode
./bin/cfctl --debugCode Formatting
make fmtLinting (requires golangci-lint)
make lintTest Coverage
make test-coverage
# Opens coverage.html in browserRun All Tests
go test ./...Run Specific Package Tests
go test ./internal/config -vRun Tests with Coverage
go test -v -coverprofile=coverage.out ./...
go tool cover -html=coverage.outTest Configuration
- Unit tests:
*_test.gofiles - Test framework:
stretchr/testify - Mock objects: Interface-based mocking
-
Create Feature Branch
git checkout -b feature/your-feature-name
-
Implement Changes
- Add code in appropriate
internal/package - Write unit tests
- Update UI components if needed
- Add code in appropriate
-
Test Changes
make test make lint -
Update Documentation
- Update README.md if user-facing
- Add inline code documentation
- Update default.yaml if adding config options
-
Submit Pull Request
- Ensure all tests pass
- Follow conventional commit messages
- Reference related issues
- Follow Effective Go
- Use
gofmtfor formatting - Keep functions focused and testable
- Document exported functions and types
- Write descriptive commit messages
Enable Debug Logging
cfctl --debugCheck Configuration
cat ~/.config/cfctl/config.yamlVerify Credentials
# macOS
security find-generic-password -s "cfctl" -a "<account_name>"
# Linux (using secret-tool)
secret-tool lookup service cfctl account "<account_name>"Error: Binary not found
# Ensure you've built the application first
make build
# Verify binary location
ls -la bin/Error: Permission denied during installation
# Use sudo for system-wide installation
sudo ./scripts/install.shError: Command not found after installation
# Verify installation path
which cfctl
# Check if /usr/local/bin is in PATH
echo $PATH | grep "/usr/local/bin"
# If not, add to your shell profile (~/.bashrc, ~/.zshrc):
export PATH="/usr/local/bin:$PATH"Error: Unable to load configuration
# Check config file exists and is valid YAML
cat ~/.config/cfctl/config.yaml
# Reset to default configuration
rm ~/.config/cfctl/config.yaml
cfctl # Will recreate with defaultsError: Keyring access denied
macOS:
# Grant terminal access to keychain in System Preferences
# Security & Privacy → Privacy → Full Disk Access → Add TerminalLinux:
# Ensure keyring service is running
systemctl --user status gnome-keyring
# Or for KDE
systemctl --user status kwalletd5Error: API authentication failed
# Verify credentials at Cloudflare dashboard
# Regenerate API token if necessary
cfctl
# Navigate to: Configure Account → Update credentialsError: No domains found
# Verify API token has Zone:Read permission
# Check account has zones configured at Cloudflare dashboardError: Request timeout
# Increase timeout in ~/.config/cfctl/config.yaml
api:
timeout: 60 # Increase from default 30 secondsError: Rate limit exceeded
# Wait for rate limit reset
# Consider reducing operation frequency
# Enterprise plans have higher rate limitsError: Invalid zone ID
# Clear cached zone list
rm -rf ~/.cache/cfctl/ # If cache directory exists
cfctl # Refresh zone listUI rendering incorrectly
# Try disabling colors
cfctl --no-color
# Check terminal compatibility
echo $TERM # Should be xterm-256color or similarKeyboard navigation not working
# Ensure terminal supports ANSI escape sequences
# Try different terminal emulator (iTerm2, GNOME Terminal, etc.)Error: Go version mismatch
# Check Go version
go version
# Install Go 1.24 or later from https://go.dev/dl/Error: Module dependency issues
# Clean and refresh modules
go clean -modcache
go mod download
go mod tidyError: Build failed with linker error
# Ensure sufficient disk space
df -h
# Try clean build
make clean
make buildIf you encounter issues not covered here:
- Check Existing Issues: GitHub Issues
- Enable Debug Mode: Run with
--debugflag and include output in issue report - Create New Issue: Provide:
- Operating system and version
- Go version (
go version) - CFCTL version (
cfctl --version) - Steps to reproduce
- Debug output if applicable
Contributions are welcome and appreciated. To contribute:
- Search existing issues to avoid duplicates
- Use issue templates when available
- Provide detailed reproduction steps
- Include system information (OS, Go version, CFCTL version)
-
Fork the Repository
git clone https://github.com/siyamsarker/cfctl.git cd cfctl -
Create Feature Branch
git checkout -b feature/your-feature-name
-
Make Changes
- Write clean, documented code
- Follow existing code style
- Add tests for new functionality
- Update documentation
-
Test Thoroughly
make test make lint make build -
Commit Changes
git commit -m "feat: add your feature description"Follow Conventional Commits:
feat:New featurefix:Bug fixdocs:Documentation changestest:Test additions/changesrefactor:Code refactoringchore:Maintenance tasks
-
Push and Create PR
git push origin feature/your-feature-name
Then open a pull request on GitHub
- Code Quality: All code must pass
make lintandmake test - Documentation: Update README.md for user-facing changes
- Tests: Maintain or improve test coverage
- Commits: Use clear, descriptive commit messages
- Dependencies: Minimize external dependencies
- Automated CI checks must pass
- Code review by maintainers
- Address review feedback
- Squash commits if requested
- Merge upon approval
This project is licensed under the MIT License. See the LICENSE file for full text.
Repository: github.com/siyamsarker/cfctl
Documentation: Cloudflare API Documentation
Issues: GitHub Issues
Author: Siyam Sarker