A secure, password-protected web viewer for private GitHub releases powered by Cloudflare Workers
Share your private GitHub releases with friends, team members, or testers without exposing your GitHub token or dealing with CORS issues. PrivyLease uses Cloudflare Workers to handle authentication server-side while providing direct CDN downloads for maximum speed and zero bandwidth cost.
The Problem: Sharing private GitHub releases is challenging. You can't give everyone your GitHub credentials, and embedding tokens in web pages exposes them to the world. Browser security restrictions (CORS) make direct API access difficult.
The Solution: PrivyLease acts as a secure middleman. Your Cloudflare Worker authenticates with GitHub using your private token, while users access releases through a simple password-protected web interface. Downloads happen directly from GitHub's CDN for maximum speed and zero bandwidth cost.
Perfect For: Beta testing, internal builds, game releases, private software distribution
- β¨ Features
- π Installation
- π οΈ Usage
- π Documentation
- β Troubleshooting
- π° Costs & Limits
- π€ Contributing
- π License
- π Acknowledgments
π Password Protected - Share with anyone using a simple password π Secure Token Storage - GitHub token stays server-side (encrypted), never exposed to browsers π‘οΈ Rate Limiting - Optional brute force protection with automatic blocking (requires KV setup) β‘ Direct CDN Downloads - Files download directly from GitHub's CDN (no proxy overhead) π° Zero Bandwidth Cost - Worker only handles authentication, not file transfers π« No CORS Issues - Worker handles all GitHub API authentication π Free Tier Friendly - 100,000 requests/day on Cloudflare's free plan π± Beautiful UI - Modern, responsive interface that works on all devices π Works Everywhere - No browser restrictions or special requirements π HTTPS Only - All traffic encrypted with Cloudflare SSL βοΈ Easy Setup - Deploy in 10 minutes with automated GitHub Actions workflow
- A GitHub account with a private repository containing releases
- A Cloudflare account (free tier)
- A GitHub Personal Access Token with
reposcope
-
Create Cloudflare Account
- Go to https://workers.cloudflare.com/
- Sign up for a free account and verify your email
-
Create Worker
- Visit https://dash.cloudflare.com/
- Click "Workers & Pages" in the sidebar
- Click "Create application" β "Create Worker"
- Name it
github-proxy(or any name you prefer) - Click "Deploy"
-
Add Worker Code
- Click "Edit code" on the worker page
- Delete the default code
- Copy and paste the entire contents of
cloudflare-worker.jsfrom this repository - Click "Save and Deploy"
-
Configure Environment Variables
- Go to "Settings" β "Variables"
- Add the following variables:
Variable Name Type Value Description GITHUB_TOKENSecret β Encrypt Your GitHub token Token with reposcopeVIEWER_PASSWORDSecret β Encrypt Your chosen password Password for accessing releases REPO_NAMEVariable username/repoYour GitHub repository path - Click "Save and Deploy" after adding all variables
-
Choose a Secure Password
β οΈ Security Warning: Your password protects access to private GitHub releases. Choose a strong password to prevent unauthorized access.Password Requirements:
- Minimum length: 12 characters (recommended: 16+)
- Complexity: Include uppercase, lowercase, numbers, and symbols
- Avoid: Dictionary words, common patterns, personal information
- Uniqueness: Don't reuse passwords from other services
Examples:
- β
Good:
Tr3eH0use!2024$Secure - β Weak:
password123,github2024,myname123
Additional Security Best Practices:
- Change passwords regularly (every 90 days)
- Use a password manager to generate and store strong passwords
- Never share passwords via email or chat
- Consider using different passwords for different repositories
-
Set Up KV Namespace (Optional - Recommended for Enhanced Security)
Why set this up? Enables rate limiting to prevent brute force attacks (5 failed attempts = 15-minute block). If skipped, the worker still works but logs a warning about reduced security.
Step-by-step instructions based on the latest Cloudflare UI:
A. Create KV Namespace:
- Go to the Cloudflare Dashboard.
- In the left sidebar, find and click on Storage & Databases to expand it.
- Select KV from the dropdown menu.
- Click the Create namespace button.
- Name it
rate-limit. - Click Add.
B. Bind Namespace to Worker:
- Navigate back to your Worker's page (e.g., via the "Recently modified applications" on the home screen or by clicking Compute (Workers) in the sidebar).
- Click on your worker's name (e.g.,
github-downloader). - Select the Settings tab.
- In the sub-navigation menu that appears, click on Bindings.
- Click on Add Bindings.
- Scroll down to the KV Namespace section and click Add binding.
- Set Variable name: to
KV(this must be exact and is case-sensitive). - For KV namespace, select the
rate-limitnamespace you just created. - Click Save and Deploy.
C. Verify Setup:
- After deployment, check your Worker logs by going to the Observability tab.
- If KV is working correctly, you should not see any rate limiting warnings.
- If it's not configured, the logs will show:
"Rate limiting disabled: KV namespace not configured".
Troubleshooting:
- The binding variable name must be exactly
KV. - A "Save and Deploy" is required for binding changes to take effect.
- The namespace must be created before you can bind it.
-
Copy Worker URL
- Your worker URL will look like:
https://github-proxy.your-subdomain.workers.dev - Save this URL - you'll need it in the next step
- Your worker URL will look like:
-
Fork or Clone This Repository
git clone https://github.com/yourusername/Privylease.git cd Privylease -
Add Repository Secret
- Go to your repository Settings β Secrets and variables β Actions
- Click "New repository secret"
- Name:
CLOUDFLARE_WORKER_URL - Value: Your Cloudflare Worker URL from Step 1
- Click "Add secret"
-
Enable GitHub Pages
- Go to your repository Settings β Pages
- Under "Build and deployment":
- Source: Select GitHub Actions (not "Deploy from a branch")
- Click "Save"
- Important: This must be set to "GitHub Actions" for the automated deployment to work
-
Deploy
- The GitHub Actions workflow (
.github/workflows/deploy.yml) will automatically:- Configure the
index.htmlwith your Cloudflare Worker URL - Deploy the viewer to GitHub Pages
- Configure the
- Go to Actions tab to monitor the deployment
- Once complete, your viewer will be available at:
https://yourusername.github.io/Privylease/
- The GitHub Actions workflow (
Share the following with your users:
- Viewer URL:
https://yourusername.github.io/Privylease/ - Password: The password you set in
VIEWER_PASSWORD
That's it! Users can now access your private releases securely.
-
Access the Viewer
- Open the GitHub Pages URL shared with you
- Example:
https://username.github.io/Privylease/
-
Enter Password
- Enter the password provided by the administrator
- Click "Unlock"
-
Browse Releases
- View all available releases with their details
- See release dates, version tags, and file information
-
Download Files
- Click the "Download" button next to any file
- The download will start directly from GitHub's CDN
- No account or authentication required!
Simply create releases in your private GitHub repository as usual. They will automatically appear in the viewer.
- Go to your Cloudflare Worker dashboard
- Settings β Variables
- Edit
VIEWER_PASSWORD - Click "Save and Deploy"
- Share the new password with users
- Go to your Cloudflare Worker dashboard
- Settings β Variables
- Edit
REPO_NAMEto point to a different repository - Click "Save and Deploy"
- Add your domain to Cloudflare
- In Worker dashboard: Go to "Triggers"
- Click "Add Custom Domain"
- Enter your domain (e.g.,
releases.yourdomain.com) - Update the
CLOUDFLARE_WORKER_URLsecret in your GitHub repository - Re-run the GitHub Actions deployment
# Test without password (should return 401)
curl https://your-worker.workers.dev/releases
# Test with password (should return releases JSON)
curl -H "X-Password: YourPassword123" \
https://your-worker.workers.dev/releases
# Get download URL for a specific asset
curl -H "X-Password: YourPassword123" \
https://your-worker.workers.dev/download-url/ASSET_ID- Open your GitHub Pages URL
- Enter password and click "Unlock"
- Verify releases are displayed
- Click a download button
- Verify file downloads successfully
βββββββββββββββ ββββββββββββββββββββ βββββββββββββββ
β Browser βββββββββ>β Cloudflare Workerβββββββββ>β GitHub β
β (Client) β β (Auth Only) β β API β
βββββββββββββββ ββββββββββββββββββββ βββββββββββββββ
β β β
β 1. Request with β 2. Authenticate with β
β password β GitHub token β
β β β
β 3. Get download URL β β
β<ββββββββββββββββββββββββββ€ β
β β β
β 4. Direct download from GitHub CDN β
β<βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
Token never leaves Cloudflare Worker
β
Password validated server-side
β
No worker bandwidth usage - direct CDN downloads
β
Faster downloads - no proxy overhead
Key Points:
- The browser never sees your GitHub token
- Authentication happens on Cloudflare's servers
- Downloads are direct from GitHub's CDN (no proxy)
- Worker only provides the authenticated download URL
- URLs expire after a few minutes for security
The Cloudflare Worker exposes the following endpoints:
Returns a list of all releases from the configured repository.
Headers:
X-Password: Your viewer password
Response:
[
{
"id": 123456,
"name": "v1.0.0",
"tag_name": "v1.0.0",
"published_at": "2025-01-01T00:00:00Z",
"assets": [
{
"id": 789,
"name": "app-release.apk",
"size": 52428800
}
]
}
]Gets an authenticated download URL for a specific asset.
Headers:
X-Password: Your viewer password
Response:
{
"downloadUrl": "https://objects.githubusercontent.com/..."
}Note: Download URLs expire after a few minutes (GitHub security feature).
Components:
- Cloudflare Worker (
cloudflare-worker.js) - Handles authentication and GitHub API requests - HTML Viewer (
index.html) - Beautiful web interface for browsing and downloading releases - GitHub Actions (
.github/workflows/deploy.yml) - Automates deployment to GitHub Pages
Security Features:
- Password validation on every request with constant-time comparison
- Optional rate limiting (5 attempts = 15-minute block) using Cloudflare KV
- GitHub token stored as encrypted Cloudflare secret
- HTTPS-only communication
- No token exposure to browser/client
- Download URLs are time-limited by GitHub
Symptoms: Getting "Invalid password" even though the password is correct.
Solutions:
- Verify
VIEWER_PASSWORDis spelled correctly in Cloudflare (case-sensitive) - Passwords are case-sensitive - check for typos
- Click "Save and Deploy" after changing variables
- Clear browser cache and try again
Symptoms: Cannot load releases in the viewer.
Solutions:
- Verify
GITHUB_TOKENis set correctly in Cloudflare - Ensure token has
reposcope (check at https://github.com/settings/tokens) - Check
REPO_NAMEformat isusername/repo(no spaces, no URL) - Test your token manually:
curl -H "Authorization: token YOUR_TOKEN" \ https://api.github.com/repos/username/repo/releases - Check Cloudflare Worker logs for detailed errors
Symptoms: Download button doesn't work or fails.
Solutions:
- Check Cloudflare Worker logs in the dashboard
- Verify the asset exists in your GitHub release
- Download URLs expire after a few minutes - try getting a fresh URL
- Test the download endpoint:
curl -H "X-Password: YourPassword" \ https://your-worker.workers.dev/download-url/ASSET_ID - Check if GitHub is experiencing issues
Symptoms: Viewer shows connection errors.
Solutions:
- Verify worker is deployed (check Cloudflare dashboard)
- Confirm worker URL is correct in
CLOUDFLARE_WORKER_URLsecret - Check "Real-time Logs" in worker dashboard for errors
- Ensure worker route/domain is configured properly
- Try redeploying the worker
Symptoms: Rate limiting warnings in worker logs, or rate limiting not working.
Solutions:
- Verify KV namespace exists: Go to Dashboard β Storage & Databases β KV.
- Check binding: Go to your Worker β Settings β Bindings β KV Namespace Bindings.
- Ensure variable name is exactly
KV(case-sensitive). - Make sure you clicked "Save and Deploy" after adding the binding.
- Check your worker's Observability tab for specific error messages.
Symptoms: Changes not reflected on the live site.
Solutions:
- Check GitHub Actions tab for deployment status
- Verify
CLOUDFLARE_WORKER_URLsecret is set correctly - Re-run the workflow manually from Actions tab
- Check that Pages is enabled with source set to "GitHub Actions"
- Wait a few minutes - GitHub Pages can take time to update
- Check Worker Logs: Cloudflare Dashboard β Your Worker β Logs
- Check GitHub Actions: Repository β Actions tab
- Test with cURL: Use the commands in the Testing section
- GitHub Resources:
- Cloudflare Resources:
- Dashboard: https://dash.cloudflare.com/
- Docs: https://developers.cloudflare.com/workers/
- Requests: 100,000 per day
- CPU Time: 10ms per request
- Scripts: Up to 30 workers
- Worker Bandwidth: Not used (direct CDN downloads)
- Perfect for: Personal projects, small teams, beta testing
For a small team (10 people) with 5 releases:
- Daily requests to worker: ~200-500
- Worker bandwidth: $0 (downloads are direct from GitHub CDN)
- Cost: $0 (well within free tier)
Cloudflare Workers Paid Plan ($5/month):
- Requests: 10 million per month
- CPU Time: 50ms per request
- Useful for: Large teams, high-traffic public releases
- Private repositories: Unlimited
- GitHub Actions: 2,000 minutes/month
- GitHub Pages: Free hosting
- Release storage: Unlimited
- Bandwidth: Unlimited for release downloads
Bottom Line: Most users will stay completely free! π
Contributions are welcome! Whether you're fixing bugs, improving documentation, or adding new features, your help makes PrivyLease better for everyone.
- Fork the repository
- Create a feature branch
git checkout -b feature/amazing-feature
- Make your changes and commit
git commit -m 'Add amazing feature' - Push to your fork
git push origin feature/amazing-feature
- Open a Pull Request
- π¨ UI/UX improvements
- π Additional security features
- π± Mobile app or native integrations
- π Internationalization (i18n)
- π Usage analytics
- π Documentation improvements
- π Bug fixes
This project is licensed under the MIT License - see the LICENSE file for details.
- Cloudflare Workers - For providing an excellent serverless platform with a generous free tier
- GitHub - For their robust API, CDN infrastructure, and free hosting via GitHub Pages
- The Open Source Community - For inspiration, best practices, and continuous support
Special thanks to everyone who has contributed to making PrivyLease better!
Made with β€οΈ for secure and easy private release sharing