{"id":50910410,"url":"https://github.com/cloudmosa/authenticator","last_synced_at":"2026-06-16T09:32:54.159Z","repository":{"id":364407405,"uuid":"1081290808","full_name":"cloudmosa/authenticator","owner":"cloudmosa","description":"Transfer MFA secrets to Cloud Phone devices","archived":false,"fork":false,"pushed_at":"2025-12-08T22:14:03.000Z","size":288,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-13T00:00:03.714Z","etag":null,"topics":["authenticator","javascript","mfa","mfa-authenticator"],"latest_commit_sha":null,"homepage":"https://mfa.cloudphone.tech","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cloudmosa.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-22T15:16:18.000Z","updated_at":"2026-03-29T08:36:35.000Z","dependencies_parsed_at":"2026-06-13T00:00:22.759Z","dependency_job_id":null,"html_url":"https://github.com/cloudmosa/authenticator","commit_stats":null,"previous_names":["cloudmosa/authenticator"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/cloudmosa/authenticator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudmosa%2Fauthenticator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudmosa%2Fauthenticator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudmosa%2Fauthenticator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudmosa%2Fauthenticator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cloudmosa","download_url":"https://codeload.github.com/cloudmosa/authenticator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudmosa%2Fauthenticator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34400451,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-16T02:00:06.860Z","response_time":126,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authenticator","javascript","mfa","mfa-authenticator"],"created_at":"2026-06-16T09:32:54.022Z","updated_at":"2026-06-16T09:32:54.152Z","avatar_url":"https://github.com/cloudmosa.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MFA Sync Service\n\nSecure, ephemeral MFA secret key sharing service for Cloud Phone devices, with or without a camera.\n\n![Authenticator Design](./mfa-sync.png)\n\n## Availability \u0026 Use\n\n1. Sign up for the [Developer Program](https://www.cloudphone.tech/developer-program)\n2. Enable [Developer Mode](https://developer.cloudfone.com/docs/guides/developer-tools/#developer-mode) on your Cloud Phone device\n3. Add this widget with the URL: [https://mfa.cloudphone.tech/sync.html](https://mfa.cloudphone.tech/sync.html) and [icon](./public/favicon-512x512.png)\n4. Visit [https://mfa.cloudphone.tech/](https://mfa.cloudphone.tech/) on your desktop or mobile (Android or iOS) and scan or enter an MFA secret\n5. Open MFA Sync on Cloud Phone and enter the PIN\n\n## Key Uri Format\n\nThis app processes data in the Key URI format.\n\n```text\notpauth://totp/Zoho:email@zoho.com?secret=JBSWY3DPEHPK3PXP\u0026period=30\u0026digits=6\u0026algorithm=SHA1\u0026issuer=Zoho\n```\n\nSee [Key Uri Format](https://github.com/google/google-authenticator/wiki/Key-Uri-Format).\n\n## Architecture\n\n```text\n┌─────────────┐         ┌──────────────┐         ┌─────────────┐\n│   Phone     │         │              │         │   Feature   │\n│   (Admin)   │────────\u003e│  VPS Server  │\u003c────────│    Phone    │\n│ Scan QR Code│         │   + Redis    │         │  Enter PIN  │\n└─────────────┘         └──────────────┘         └─────────────┘\n      │                        │                         │\n      │                        │                         │\n      └─── Generate PIN ───────┤                         │\n                               │                         │\n                               └──── Retrieve Secret ────┘\n```\n\n## Features\n\n- ✅ **Ephemeral Storage**: Secrets auto-delete after retrieval or expiration\n- ✅ **Encrypted at Rest**: AES-256-GCM encryption in Redis\n- ✅ **Rate Limited**: Protection against brute force attacks\n- ✅ **T9-Friendly**: Simple numeric PIN entry for feature phones\n- ✅ **QR Scanner**: Built-in camera scanning for admin interface\n- ✅ **TOTP Generator**: Full authenticator app functionality in browser\n- ✅ **Zero Dependencies**: Client-side uses only Web Crypto API\n\n## Quick Start\n\n### Local Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Start Redis\ndocker run -d -p 6379:6379 redis:7-alpine\n\n# Start server\nnpm start\n\n# Access at http://localhost:3000\n```\n\n### Docker Deployment\n\n```bash\n# Build and run with Docker Compose\ndocker-compose up -d\n\n# View logs\ndocker-compose logs -f\n\n# Stop\ndocker-compose down\n```\n\n## VPS Deployment\n\n### Prerequisites\n\n1. VPS with Docker installed\n2. Domain name (optional, for HTTPS)\n3. GitHub repository secrets configured\n\n### GitHub Secrets Setup\n\nAdd these secrets to your GitHub repository:\n\n```env\nVPS_HOST=your.server.ip\nVPS_USER=your-ssh-user\nVPS_SSH_KEY=\u003cyour-private-ssh-key\u003e\nALLOWED_ORIGINS=https://mfa.cloudphone.tech\n```\n\n### Server Setup\n\n```bash\n# SSH into your VPS\nssh user@your-server\n\n# Install Docker (if not installed)\ncurl -fsSL https://get.docker.com | sh\nsudo usermod -aG docker $USER\n\n# Create deployment directory\nsudo mkdir -p /opt/mfa-sync\nsudo chown $USER:$USER /opt/mfa-sync\ncd /opt/mfa-sync\n\n# Clone repository\ngit clone https://github.com/yourusername/mfa-sync.git .\n\n# Create docker-compose.yml\ncp docker-compose.yml /opt/mfa-sync/\n\n# Start services\ndocker-compose up -d\n```\n\n### SSL Certificate (Let's Encrypt)\n\n```bash\n# Install certbot\nsudo apt-get update\nsudo apt-get install certbot\n\n# Generate certificate\nsudo certbot certonly --standalone -d mfa.cloudphone.tech\n\n# Copy certificates to nginx directory\nsudo mkdir -p /opt/mfa-sync/ssl\nsudo cp /etc/letsencrypt/live/mfa.cloudphone.tech/fullchain.pem /opt/mfa-sync/ssl/cert.pem\nsudo cp /etc/letsencrypt/live/mfa.cloudphone.tech/privkey.pem /opt/mfa-sync/ssl/key.pem\nsudo chown -R $USER:$USER /opt/mfa-sync/ssl\n\n# Restart nginx\ndocker-compose restart nginx\n```\n\n## Usage\n\n### 1. Admin Interface\n\nAccess from your smartphone with a camera:\n\n```text\nhttps://mfa.cloudphone.tech.com/\n```\n\n1. Click \"📷 Scan QR Code\"\n2. Point camera at MFA QR code\n3. Secret auto-fills, or paste manually\n4. Click \"Generate PIN\"\n5. Display shows 6-digit PIN\n\n### 2. Feature Phone Interface (sync.html)\n\nAccess from your feature phone browser:\n\n```text\nhttps://mfa.cloudphone.tech/sync.html\n```\n\n1. Enter the 6-digit PIN from admin interface\n2. Click \"Retrieve Secret\" (or press Enter)\n3. Account added with live TOTP codes\n4. Codes refresh every 30 seconds\n\n## API Reference\n\n### POST /api/store\n\nStore an MFA secret and generate PIN.\n\n**Request:**\n\n```json\n{\n  \"secret\": \"JBSWY3DPEHPK3PXP\",\n  \"label\": \"GitHub\",\n  \"issuer\": \"GitHub\",\n  \"ttl\": 300\n}\n```\n\n**Response:**\n\n```json\n{\n  \"pin\": \"123456\",\n  \"expiresIn\": 300,\n  \"expiresAt\": \"2025-10-22T10:15:00.000Z\"\n}\n```\n\n### POST /api/retrieve\n\nRetrieve MFA secret with PIN (one-time use).\n\n**Request:**\n\n```json\n{\n  \"pin\": \"123456\"\n}\n```\n\n**Response:**\n\n```json\n{\n  \"secret\": \"JBSWY3DPEHPK3PXP\",\n  \"label\": \"GitHub\",\n  \"issuer\": \"GitHub\",\n  \"type\": \"totp\",\n  \"algorithm\": \"SHA1\",\n  \"digits\": 6,\n  \"period\": 30\n}\n```\n\n### GET `/api/health`\n\nHealth check endpoint.\n\n**Response:**\n\n```json\n{\n  \"status\": \"healthy\",\n  \"redis\": \"connected\"\n}\n```\n\n## Security Considerations\n\n### What This Service Does\n\n✅ Provides secure, temporary exchange of MFA secrets\n✅ Encrypts secrets at rest with AES-256-GCM\n✅ Automatically deletes secrets after retrieval\n✅ Rate limits to prevent brute force attacks\n✅ Uses in-memory storage (Redis) with TTL\n✅ One-time PIN retrieval only\n\n### What You Should Do\n\n⚠️ **Use HTTPS only** - Never deploy without SSL/TLS\n⚠️ **Restrict ALLOWED_ORIGINS** - Limit to your domain\n⚠️ **Use strong firewall rules** - Limit Redis access\n⚠️ **Monitor logs** - Watch for suspicious activity\n⚠️ **Keep secrets short-lived** - Use 5-10 minute TTLs\n⚠️ **Use on trusted networks** - Avoid public WiFi for admin interface\n\n### Threat Model\n\n- ✅ Protects against: Interception, storage leaks, unauthorized access\n- ⚠️ Limited protection: Network-level attacks require HTTPS\n- ❌ Does not protect: Compromised admin device, malicious VPS\n\n## Environment Variables\n\n```bash\nPORT=3000                      # Server port\nREDIS_URL=redis://localhost:6379  # Redis connection string\nALLOWED_ORIGINS=*              # CORS origins (comma-separated)\nNODE_ENV=production            # Environment\nPIN_TTL=120                    # Pin Time to Live (TTL) in seconds\n```\n\n## Troubleshooting\n\n### Redis Connection Failed\n\n```bash\n# Check Redis is running\ndocker ps | grep redis\n\n# View Redis logs\ndocker-compose logs redis\n\n# Test Redis connection\ndocker exec -it mfa-sync-redis-1 redis-cli ping\n```\n\n### PIN Not Found\n\n- Check TTL hasn't expired\n- Verify PIN is exactly 6-8 digits\n- Ensure no spaces in PIN entry\n- Check if already retrieved (`/api/check/:pin`)\n\n### Camera Not Working\n\n- Ensure HTTPS is enabled (required for camera API)\n- Check browser permissions\n- Try different browser (Chrome/Safari recommended)\n\n## License\n\n[Apache 2.0](./LICENSE)\n\n## Contributing\n\nIssues and pull requests welcome!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudmosa%2Fauthenticator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcloudmosa%2Fauthenticator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudmosa%2Fauthenticator/lists"}