A Rust based terminal social platform for developers reminicent of the BBS days
Built for the Kiroween 2025.
Fido is a social network that lives in your terminal. Think Twitter, but keyboard-driven and without the noise. Post updates, chat with other developers, upvote good content, downvote lame content.
Production demo: https://fido-prod-ijb.web.app/
First, make sure you have Rust installed
# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Install Fido
cargo install fidogit clone https://github.com/ianburke/fido.git
cd fido
cargo build --releaseLaunch it:
fidoYou'll see an auth screen. Login with GitHub (your browser will open) or pick a test user to try it out.
That's it. Press ? for help, Tab to switch tabs, n to post, q to quit.
Your session saves to ~/.fido/session. Press Shift+L to logout.
See QUICKSTART.md for more details.
- Keyboard-driven -
j/kto navigate,u/dto vote,nto post - Direct messages - Private conversations with other users
- GitHub auth - Login with your GitHub account
- Customizable - Themes, sorting, display preferences
- Fast - Terminal-native, no web bloat
- Secure - Comprehensive security hardening with input validation, audit logging, and session management
Tab- Switch tabsj/kor arrows - Navigateu/d- Upvote/Downvoten- New post?- Helpq- Quit
Launch the full web-based terminal demo (includes nginx, ttyd, and server):
./start.shThis script:
- Builds the Rust binaries if needed
- Starts the Fido API server on port 3000
- Runs ttyd (terminal-over-web) on port 7681
- Configures nginx as a reverse proxy on port 8080
- Provides a web interface at http://localhost:8080
The script works in both local development and Docker environments.
To deploy the current web terminal stack (nginx + ttyd + fido-server) on Firebase:
export FIREBASE_PROJECT_ID=your-project-id
export GITHUB_CLIENT_ID=your-github-oauth-client-id
./scripts/deploy-firebase.shFull instructions: FIREBASE_DEPLOYMENT.md
Publish new versions to crates.io with version checking:
./publish.shThis script:
- Validates version consistency across workspace crates
- Checks if versions are already published
- Runs dry-run tests before publishing
- Publishes
fido-typesfirst, thenfido(respects dependency order) - Handles the 20-second wait for crates.io indexing
Built with Rust using a workspace architecture:
- fido-types - Shared models and data structures
- fido-tui - Terminal UI client (main binary, uses Ratatui)
- fido-server - REST API server (Axum + SQLite)
- fido-migrate - Database migration utilities
- Ratatui - Terminal UI framework
- Axum - Fast, ergonomic web framework
- Firestore - Primary backend for production/runtime when
DB_BACKEND=firestore - SQLite - Legacy/local backend and migration source
- tokio - Async runtime
- oauth2 - GitHub authentication
- Security: Input validation, audit logging, rate limiting, security headers
- Deployed on Firebase Hosting + Cloud Run with HTTPS enforcement
- QUICKSTART.md - Detailed getting started guide
- ARCHITECTURE.md - System design and technical details
- CLAUDE.md - Development guidance for AI assistants
Session expired? Press Shift+L to logout and login again.
UI look weird? Use a modern terminal with UTF-8 support (iTerm2, Alacritty, Ghostty).
To run Fido locally for development:
# Clone the repository
git clone https://github.com/ianburke/fido.git
cd fido
# Set required environment variables
export GITHUB_CLIENT_ID=your_github_client_id_here
# Build the workspace
cargo build
# Start the server
cargo run --bin fido-server
# In another terminal, connect to it
cargo run --bin fido -- --server http://localhost:3000The following environment variables must be set before starting the server:
- GITHUB_CLIENT_ID (required): GitHub OAuth application client ID
- Register an OAuth app at: https://github.com/settings/developers
- Note: Device Flow doesn't require a callback URL or client secret
- The server will fail to start in production if this is not set
-
DB_BACKEND: Storage backend (
sqliteorfirestore, default:sqlite) -
GOOGLE_CLOUD_PROJECT or FIREBASE_PROJECT_ID: Required when
DB_BACKEND=firestore -
FIRESTORE_EMULATOR_HOST: Firestore emulator host (example:
127.0.0.1:8088) -
FIRESTORE_SEED_TEST_DATA: Auto-seed test users/posts in emulator mode (default: enabled, set
false/0to disable) -
FIRESTORE_ACCESS_TOKEN: Bearer token for Firestore REST API when not using emulator
- On Cloud Run, prefer Application Default Credentials (metadata service token) instead of static keys
-
ENVIRONMENT or RUST_ENV: Application environment (
developmentorproduction, default:development)- Controls security features like CORS origins, HTTPS enforcement, and configuration validation
- Production mode enforces stricter security requirements
-
HOST: Server bind address (default:
0.0.0.0) -
PORT: Server port (default:
3000) -
DATABASE_PATH: SQLite database file path (default:
fido.db) -
FIDO_SERVER_URL: Runtime server URL override for TUI client
-
ALLOWED_ORIGINS: Comma-separated CORS allowlist (for example:
https://your-project.web.app,https://your-project.firebaseapp.com)
-
MAX_REQUEST_SIZE: Maximum request body size in bytes (default:
1048576= 1MB)- Protects against denial-of-service attacks via large payloads
-
SESSION_MAX_AGE_DAYS: Maximum session lifetime in days (default:
30)- Sessions expire after this duration regardless of activity
-
SESSION_IDLE_TIMEOUT_HOURS: Session idle timeout in hours (default:
720)- Sessions expire after this period of inactivity
# Run all tests
cargo test
# Run tests for specific crate
cargo test -p fido-server
cargo test -p fido-tui
cargo test -p fido-types
# Firestore emulator smoke check
just firestore-emulator-check
# Format code
cargo fmt
# Check for linting issues
cargo clippyFor the full web terminal experience (see Development Scripts above):
./start.shFido implements comprehensive security hardening to protect user data and prevent common web vulnerabilities:
-
GitHub OAuth Integration: Secure authentication using GitHub's Device Flow
- No client secrets required
- User-friendly device code flow for terminal applications
-
Session Security:
- 30-day maximum session lifetime (configurable)
- 30-day idle timeout (configurable)
- Automatic session invalidation on new login
- Session tokens stored securely in
~/.fido/session - All sessions invalidated when user logs out
All user input is validated before processing to prevent injection attacks:
-
Username Validation:
- 3-32 characters
- Alphanumeric, underscores, and hyphens only
- Must start with a letter or number
-
Post Content Validation:
- Maximum 280 characters
- XSS pattern detection and prevention
- HTML entity escaping
-
Bio Validation:
- Maximum 160 characters
- XSS pattern detection
-
Hashtag Validation:
- 1-50 characters
- Alphanumeric and underscores only
-
Body Size Limits: 1MB maximum request size (configurable)
- Prevents denial-of-service attacks via large payloads
-
Rate Limiting: Per-user request rate limiting
- Protects against abuse and brute-force attacks
-
SQL Injection Prevention:
- All database queries use parameterized statements
- Enum-based sort order validation
- No dynamic SQL construction from user input
All HTTP responses include security headers for defense-in-depth:
X-Content-Type-Options: nosniff- Prevents MIME type sniffingX-Frame-Options: DENY- Prevents clickjacking attacksX-XSS-Protection: 1; mode=block- Enables browser XSS protectionContent-Security-Policy- Restricts resource loadingReferrer-Policy: strict-origin-when-cross-origin- Controls referrer informationStrict-Transport-Security(production only) - Enforces HTTPS connections
Environment-aware Cross-Origin Resource Sharing:
- Production: Uses
ALLOWED_ORIGINSwhen set, otherwise defaults tohttps://fido-prod-ijb.web.app - Development: Localhost origins allowed for local testing
- CLI/TUI Clients: Requests without Origin header always allowed
-
Sanitized Error Messages: Internal errors return generic messages to clients
- Database errors don't expose schema details
- Stack traces never included in API responses
- Detailed errors logged server-side for debugging
-
Validation Errors: Specific validation feedback without internal details
Comprehensive security event logging for monitoring and investigation:
- Login attempts (success and failure)
- Session creation and revocation
- Admin actions
- Rate limit violations
- Validation failures
- Suspicious activity detection
Audit logs include:
- Event type and timestamp
- User ID (when applicable)
- Client IP address
- User-Agent header
- Event-specific details
- Admin-Only Endpoints: Protected by middleware requiring admin privileges
- Admin Flag: Database-backed
is_adminflag on user accounts - Audit Trail: All admin actions logged for accountability
- HTTPS Enforcement: Automatic HTTPS redirect in production
- Secure Cookies: Session cookies marked as
Securewhen HTTPS detected - Cookie Attributes: HttpOnly, SameSite=Lax for CSRF protection
-
Startup Validation: Server validates security configuration on startup
-
Production Requirements: Strict validation in production mode
- GITHUB_CLIENT_ID must be set
- Valid session timeouts required
- Allowed origins must be configured
-
Admin Endpoint:
/admin/config/validatereturns configuration status- Requires admin authentication
- Shows security settings without exposing secrets
To grant admin privileges to a user:
-
Using SQLite CLI:
sqlite3 fido.db UPDATE users SET is_admin = 1 WHERE username = 'your_username'; .quit
-
Using Test Data (development only):
# The test user 'alice' is automatically set as admin cargo run --bin fido-server # Login as alice in the TUI
-
Verify Admin Status:
sqlite3 fido.db "SELECT username, is_admin FROM users WHERE is_admin = 1;"
Admin users can:
- Access
/admin/cleanupendpoint to clean up expired sessions - Access
/admin/config/validateendpoint to view security configuration - Perform other administrative operations (as features are added)
When deploying Fido in production:
-
Environment Variables:
- Set
ENVIRONMENT=productionorRUST_ENV=production - Always set
GITHUB_CLIENT_IDfrom a secure source - Never commit secrets to version control
- Set
-
HTTPS:
- Always use HTTPS in production
- Ensure
Strict-Transport-Securityheader is enabled
-
Database:
- Regularly backup your SQLite database
- Set appropriate file permissions on
fido.db(600 or 640) - Consider migrating to PostgreSQL for larger deployments
-
Monitoring:
- Review audit logs regularly for suspicious activity
- Monitor rate limit violations
- Track failed login attempts
-
Session Management:
- Use default session timeouts (30 days max, 30 days idle)
- Shorter timeouts for high-security environments
- Educate users to logout when done
-
Admin Accounts:
- Limit the number of admin users
- Use strong GitHub accounts for admin users
- Audit admin actions regularly
-
Updates:
- Keep Rust and dependencies up to date
- Monitor security advisories for dependencies
- Test updates in development before production deployment
MIT

