VettCode CLI Authentication Implementation Summary
Overview
Successfully implemented web-based device authorization flow for VettCode CLI, allowing users to authenticate via the VettCode Web application without exposing passwords, OAuth secrets, or session cookies to the CLI.
Architecture
Flow Diagram
CLI VettCode Web Database
│ │ │
│──── POST /start ────────>│ │
│<──── session + code ─────│ │
│ │ │
│──── opens browser ──────>│ │
│ │ │
│ │<──── user signs in ────────│
│ │ │
│ │<──── user approves ────────│
│ │ │
│ │──── store token hash ─────>│
│ │ │
│──── POST /poll ─────────>│ │
│<──── status=approved ────│ │
│<──── token ──────────────│ │
│ │ │
│──── saves token locally ─│ │
│ │ │
│──── GET /me ────────────>│ │
│ (Bearer: token) │ │
│<──── user info ──────────│ │
What Was Implemented
Phase 1: Database Models (WEB) ✅
File: WEB/lib/models/CLICredential.ts
- Stores hashed CLI authentication tokens
- Fields: userId, tokenHash (SHA-256), deviceName, deviceInfo, createdAt, lastUsedAt, expiresAt, revokedAt
- Methods: create(), findByToken(), findByUserId(), updateLastUsed(), revoke(), revokeById(), revokeAllForUser()
- Security: Cryptographically secure token generation (32 bytes), SHA-256 hashing before storage
- Expiration: 90 days by default
File: WEB/lib/models/AuthorizationSession.ts
- Temporary sessions for device authorization flow
- Fields: sessionId, verificationCode, status, userId, deviceInfo, cliToken, createdAt, expiresAt
- Methods: create(), findBySessionId(), findByVerificationCode(), approve(), deny(), getStatus()
- Verification code format: ABCD-EFGH (8 characters, human-friendly)
- Expiration: 15 minutes
Phase 2: Authentication Middleware (WEB) ✅
File: WEB/lib/cli-auth.ts
extractBearerToken(): Extracts Bearer token from Authorization headerauthenticateCLIRequest(): Validates CLI token and returns user inforequireCLIAuth(): Throws error if not authenticated (use in API routes)- Automatically updates lastUsedAt timestamp on successful auth
Phase 3: API Endpoints (WEB) ✅
Endpoint: POST /api/cli/auth/start
- Creates authorization session
- Returns: sessionId, verificationCode, authorizationUrl, expiresAt, expiresInSeconds
- Collects device info from request
Endpoint: POST /api/cli/auth/poll
- CLI polls for authorization status
- Input: sessionId
- Returns: status ('pending' | 'approved' | 'denied' | 'expired'), token (if approved)
- Rate limiting: 2-second minimum interval between polls
- Automatic expiration handling
Endpoint: POST /api/cli/auth/verify
- Web frontend calls after user authorizes
- Requires authenticated NextAuth session
- Input: sessionId, deviceName (optional)
- Generates CLI credential, stores hash, approves session
Endpoint: POST /api/cli/auth/revoke
- Revokes CLI credential
- Can be called by CLI (self-revoke) or web (with session)
- Input: credentialId (web) or uses Authorization header (CLI)
Endpoint: GET /api/cli/auth/me
- Returns current user information
- Requires Bearer token authentication
- Returns: user id, email, name, plan, emailVerified, createdAt, scanCount
Phase 4: Web Authorization Page (WEB) ✅
File: WEB/app/cli/auth/page.tsx
- Route:
/cli/auth?session=xxx - States: loading, not-authenticated, ready, authorizing, success, error
- Not authenticated: Redirects to sign-in with Google/Email options
- Authenticated: Shows authorization UI with:
- User profile display
- Permissions list (scan projects, view results, access AI)
- Optional device name input
- "Allow CLI Access" and "Cancel" buttons
- Success: Displays confirmation, user can return to terminal
- Premium dark-first design matching VettCode branding
Phase 5: CLI Infrastructure ✅
File: CLI/src/lib/config.ts
- Configuration management
- API base URL: Defaults to production (https://vettedcodewe.vercel.app)
- Override via
VETTCODE_API_URLenvironment variable - Credential storage path:
~/.vettcode/credentials
File: CLI/src/lib/credential-store.ts
- Secure local credential storage
- Location:
~/.vettcode/credentials(cross-platform) - File permissions: 0o600 (read/write for owner only)
- Methods: save(), load(), delete(), exists(), getPath()
File: CLI/src/lib/browser.ts
- Cross-platform browser opening
- Windows:
start "" - macOS:
open - Linux:
xdg-open - Graceful degradation if browser can't open
File: CLI/src/lib/api-client.ts
- HTTP client for VettCode API
- Methods: startAuth(), pollAuth(), getMe(), revoke()
- Automatic Bearer token injection from credential store
- User-friendly error messages
Phase 6: CLI Commands ✅
Command: vettcode login
- File:
CLI/src/commands/login.ts - Flow:
- Check if already authenticated
- Start authorization (POST /api/cli/auth/start)
- Display authorization URL and verification code
- Open browser automatically
- Poll for authorization (every 3 seconds, max 15 minutes)
- Save token securely
- Verify authentication (GET /api/cli/auth/me)
- Display success message with user email and plan
- Handles: timeout, denial, expiration, network errors
- Visual feedback with ora spinners
Command: vettcode whoami
- File:
CLI/src/commands/whoami.ts - Displays current authenticated user information
- Shows: email, name, plan, email verification status, scan count, account age
- Error handling for expired/invalid credentials
Command: vettcode logout
- File:
CLI/src/commands/logout.ts - Revokes credential server-side (POST /api/cli/auth/revoke)
- Deletes local credential file
- Graceful handling if server-side revocation fails
Updated: CLI/src/cli.ts
- Added login, logout, whoami commands
- Updated help command to show authentication commands
- Imported command handlers
Security Features Implemented
Token Security
- ✅ Cryptographically secure random token generation (crypto.randomBytes)
- ✅ SHA-256 hashing before database storage
- ✅ Token only shown once (during authorization)
- ✅ 90-day expiration with lastUsedAt tracking
Authorization Flow Security
- ✅ Short-lived authorization sessions (15 minutes)
- ✅ Human-friendly verification codes (no confusing characters)
- ✅ Rate limiting on polling endpoint (2-second minimum)
- ✅ Explicit user approval required (no automatic authorization)
Credential Storage Security
- ✅ File permissions: 0o600 (owner read/write only)
- ✅ Stored in ~/.vettcode/ (hidden directory)
- ✅ Never stored in project files or Git repositories
API Security
- ✅ Bearer token authentication for CLI requests
- ✅ Server-side user ID resolution (never trust client)
- ✅ Automatic lastUsedAt timestamp updates
- ✅ Revocation support (both CLI and web)
What CLI NEVER Receives
- ✅ User passwords
- ✅ Google OAuth client secret
- ✅ NextAuth secret
- ✅ NextAuth session cookies
- ✅ Raw database credentials
Testing Status
Build Status
- ✅ WEB: TypeScript compilation successful
- ✅ CLI: TypeScript compilation successful (
npm run buildpassed) - ✅ No linting errors
Manual Testing Required
WEB Testing:
- ✅ Deploy to Vercel (already pushed to GitHub)
- ⏳ Test authorization page renders correctly
- ⏳ Test Google OAuth sign-in flow
- ⏳ Test email/password sign-in flow
- ⏳ Test authorization approval
- ⏳ Test authorization denial
- ⏳ Test session expiration
- ⏳ Test database credential creation
CLI Testing:
- ⏳ Build CLI:
npm run build - ⏳ Test
vettcode logincommand - ⏳ Verify browser opens automatically
- ⏳ Verify fallback URL display
- ⏳ Test authorization flow end-to-end
- ⏳ Test
vettcode whoamicommand - ⏳ Test
vettcode logoutcommand - ⏳ Test expired credential handling
- ⏳ Test network error handling
Integration Testing:
- ⏳ Complete flow: CLI → Browser → Authorize → CLI authenticated
- ⏳ Test multiple devices (multiple CLI credentials)
- ⏳ Test credential revocation from web
- ⏳ Test credential revocation from CLI
- ⏳ Test API authentication with Bearer token
Files Created
WEB (9 new files)
WEB/lib/models/CLICredential.ts- CLI token modelWEB/lib/models/AuthorizationSession.ts- Device flow session modelWEB/lib/cli-auth.ts- Authentication middlewareWEB/app/api/cli/auth/start/route.ts- Start authorizationWEB/app/api/cli/auth/poll/route.ts- Poll authorization statusWEB/app/api/cli/auth/verify/route.ts- Approve authorizationWEB/app/api/cli/auth/revoke/route.ts- Revoke credentialWEB/app/api/cli/auth/me/route.ts- Get current userWEB/app/cli/auth/page.tsx- Authorization page
CLI (7 new files)
CLI/src/lib/config.ts- Configuration managementCLI/src/lib/credential-store.ts- Secure credential storageCLI/src/lib/browser.ts- Browser opening utilitiesCLI/src/lib/api-client.ts- VettCode API clientCLI/src/commands/login.ts- Login commandCLI/src/commands/whoami.ts- Whoami commandCLI/src/commands/logout.ts- Logout command
CLI (1 modified file)
CLI/src/cli.ts- Added auth commands
Integration with Existing Systems
Reused Existing Infrastructure ✅
- NextAuth authentication system (unchanged)
- MongoDB database and connection
- User model (no modifications needed)
- Google OAuth configuration (unchanged)
- Existing API route patterns
- Existing CLI command structure
No Breaking Changes ✅
- Existing web authentication works unchanged
- Existing CLI commands work unchanged
- No modifications to existing database models
- No modifications to existing API routes
Environment Variables
Required (Already Set)
NEXTAUTH_URL= https://vettedcodewe.vercel.appNEXTAUTH_SECRET= (already set)MONGODB_URI= (already set)
Optional (For Development)
VETTCODE_API_URL= Override API URL for CLI testing
Next Steps
Immediate (To Complete Feature)
- Deploy WEB changes to Vercel (auto-deploy from GitHub)
- Test complete flow:
- Terminal:
vettcode login - Browser opens
- Sign in with Google/Email
- Authorize CLI
- Return to terminal
- See success message
- Terminal:
- Test API authentication:
- Verify Bearer token works
- Test
vettcode whoami - Test
vettcode logout
Future Enhancements
- Web Account Management:
- View connected CLI devices
- Revoke specific devices from web UI
- Show last used timestamps
- CLI Enhancements:
- Use authenticated API for scan uploads
- Auto-authentication for scan results
- Integration with web dashboard
- Security Improvements:
- Redis-based rate limiting (currently in-memory)
- IP-based suspicious activity detection
- Email notifications for new CLI authorizations
Commands Reference
Authentication Commands
# Sign in to VettCode vettcode login # Show current user vettcode whoami # Sign out vettcode logout
Existing Commands (Unchanged)
# Scan project vettcode scan . # Check requirements vettcode setup # Show help vettcode help
Production URLs
- Web Application: https://vettedcodewe.vercel.app
- Authorization Page: https://vettedcodewe.vercel.app/cli/auth
- API Base: https://vettedcodewe.vercel.app/api
Summary
✅ Implemented: Complete web-based device authorization flow for CLI ✅ Security: No passwords, secrets, or cookies exposed to CLI ✅ User Experience: Browser-based authorization with clear instructions ✅ Integration: Reuses existing auth system, no breaking changes ✅ Database: New models for CLI credentials and authorization sessions ✅ API: 5 new secure endpoints for authentication flow ✅ CLI: 3 new commands (login, whoami, logout) ✅ Build: All TypeScript compilation successful ⏳ Testing: Requires manual end-to-end testing
Status: Implementation complete, ready for testing and deployment.