{"id":19965262,"url":"https://github.com/johanns/celox","last_synced_at":"2025-10-10T16:25:17.702Z","repository":{"id":4412376,"uuid":"2004639","full_name":"johanns/Celox","owner":"johanns","description":"Celox.ME is a secure, self-destructing message application built with Ruby on Rails 8. It features client-side encryption and automatic message expiration for maximum privacy.","archived":false,"fork":false,"pushed_at":"2025-09-24T22:31:12.000Z","size":1366,"stargazers_count":10,"open_issues_count":0,"forks_count":7,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-09-25T00:19:08.759Z","etag":null,"topics":["cryptography","hotwire","messaging","onetime","privacy","privacy-focused","rails","ruby","secrets","self-destructing"],"latest_commit_sha":null,"homepage":"https://celox.me","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/johanns.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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":"2011-07-06T04:43:48.000Z","updated_at":"2025-09-24T22:30:19.000Z","dependencies_parsed_at":"2025-05-03T23:30:57.402Z","dependency_job_id":"c53fbf4b-9d8e-474b-a962-8a2cf20556fc","html_url":"https://github.com/johanns/Celox","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/johanns/Celox","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johanns%2FCelox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johanns%2FCelox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johanns%2FCelox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johanns%2FCelox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/johanns","download_url":"https://codeload.github.com/johanns/Celox/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johanns%2FCelox/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279004687,"owners_count":26083748,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-10T02:00:06.843Z","response_time":62,"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":["cryptography","hotwire","messaging","onetime","privacy","privacy-focused","rails","ruby","secrets","self-destructing"],"created_at":"2024-11-13T02:27:59.232Z","updated_at":"2025-10-10T16:25:17.697Z","avatar_url":"https://github.com/johanns.png","language":"Ruby","readme":"# [Celox.ME](https://celox.me) :lock:\n\nCelox.**ME**ssage is a secure, self-destructing messaging application built with Ruby on Rails 8. It features client-side encryption and automatic message expiration to maximize privacy.\n\nTry the live app now at [https://celox.me](https://celox.me).\n\n## :star2: Features\n\n- **Client-Side Encryption**: Messages are encrypted in your browser before being sent, using AES-256-GCM encryption.\n- **Self-Destructing Messages**: Messages are automatically deleted after being read once or upon expiration.\n- **Flexible Expiration**: Choose from 5 minutes, 1 hour, 6 hours, or 1 day.\n- **Zero-Knowledge Architecture**: The server never sees plaintext content.\n- **Secure Key Management**: Encryption keys are generated client-side and transmitted only via URL fragments.\n- **Responsive Design**: Built with Tailwind CSS and DaisyUI for a seamless experience on any device.\n\n## :clipboard: Table of Contents\n\n- [Features](#star2-features)\n- [History](#hourglass-history)\n- [Deployment](#rocket-deployment)\n- [Architecture](#hammer_and_wrench-architecture)\n- [Security Model](#lock-security-model)\n- [Usage](#dart-usage)\n- [Workflow Diagrams](#bar_chart-workflow-diagrams)\n- [API Reference](#satellite-api-reference)\n- [Technology Stack](#hammer_and_wrench-technology-stack)\n- [Development](#rocket-development)\n- [Testing](#test_tube-testing)\n- [Configuration](#wrench-configuration)\n- [Contributing](#handshake-contributing)\n- [License](#page_facing_up-license)\n- [Security](#shield-security)\n- [Acknowledgments](#pray-acknowledgments)\n\n## :hourglass: History\n\nCelox.ME was originally started in 2011 as a personal project to learn Ruby on Rails and to build a secure, self-destructing message service that my team and I could fully trust. The motivation was twofold: to deepen my Rails expertise and to create a tool for sharing sensitive information via messengers and email—without leaving traces on those systems. Rather than relying on third-party solutions, I wanted an open-source alternative with a transparent codebase and security model. Over the years, Celox has evolved with modern Rails, security best practices, and a privacy-first architecture.\n\n## :rocket: Deployment\n\nCelox is designed for straightforward deployment on modern Ruby on Rails hosting platforms. It can be deployed using tools such as [Kamal](https://kamal-deploy.org/) or [Docker](https://www.docker.com/).\n\n### Prerequisites\n\n- **Ruby 3.4+**: Ensure you have the latest version of Ruby installed.\n- **Docker**: Ensure you have the latest version of Docker installed.\n- **SSH access** to your server.\n\n### Before You Start\n\n1. **Clone the repository** to your server or local machine:\n\n    ```bash\n    git clone https://github.com/johanns/celox.git\n    cd celox\n    ```\n\n2. **Install dependencies**:\n\n    ```bash\n    bundle install\n    npm install\n    ```\n\n3. **Generate the master key and credentials**:\n\n    ```bash\n    bin/setup-credentials\n    ```\n\n### Kamal Deployment\n\nPlease refer to the [Kamal documentation](https://kamal-deploy.org/) for an overview of the deployment process.\n\n1. **Run the Kamal configuration setup generator**:\n\n    ```bash\n    bin/setup-kamal\n    ```\n\n2. **Prepare your server with Kamal**:\n\n    ```bash\n    kamal setup\n    ```\n\n3. **Deploy the application**:\n\n    ```bash\n    kamal deploy\n    ```\n\n### Docker Deployment\n\n\u003e **Caution:**\n\u003e Due to the sensitive nature of this application, it is strongly recommended to build the Docker image locally rather than pulling a prebuilt image from a third-party registry.\n\n1. **Build the Docker image**:\n\n    ```bash\n    docker build -t celox:latest .\n    ```\n\n2. **Run the Docker container**:\n\n    ```bash\n    docker run -d -p 80:80 -p 443:443 --name celox -e TLS_DOMAIN=your-domain.com celox:latest\n    ```\n\n\u003e **Note:** Replace `your-domain.com` with your actual domain name.\n\n## :hammer_and_wrench: Architecture\n\nCelox uses a zero-knowledge architecture with bot protection, ensuring the server never has access to plaintext message content:\n\n**Privacy-preserving human verification** protects messages from bots and link previewers that would trigger permanent deletion when shared on messaging platforms.\n\n1. **Client-Side Encryption**: All encryption and decryption happen in the browser.\n2. **Fragment-Based Key Sharing**: Encryption keys are shared via URL fragments and never sent to the server.\n3. **Human Verification**: Simple math captcha prevents automated access without third-party dependencies.\n4. **Single-Read Destruction**: Messages are automatically deleted after their first successful access.\n5. **Time-Based Expiration**: Expired messages are cleaned up automatically.\n\n## :lock: Security Model\n\n### Encryption Details\n\n- **Algorithm**: AES-GCM (Galois/Counter Mode)\n- **Key Derivation**: PBKDF2 with 1,000 iterations\n- **Salt**: 16 random bytes per message\n- **IV**: 12 random bytes per message\n- **Key Length**: 256 bits\n\n### Security Features\n\n- **Zero-Knowledge**: The server never sees plaintext or encryption keys.\n- **Forward Secrecy**: Each message uses unique encryption parameters.\n- **Automatic Purging**: Messages are deleted from the database after being read.\n- **Secure Random Generation**: Cryptographically secure random number generation (WebCrypto API).\n- **Fragment-Based Key Sharing**: Encryption keys never leave the client.\n\n## :dart: Usage\n\n### Creating a Secure Message\n\n1. Go to the home page.\n2. Enter your confidential message (up to 5,000 characters).\n3. Select an expiration time (from 5 minutes to 1 day).\n4. Click \"Encrypt \u0026 Create Link.\"\n5. Share the generated secure link with your recipient.\n\n### Reading a Secure Message\n\n1. Click the secure link provided by the sender.\n2. The message will automatically decrypt if the key is present in the URL.\n3. The message is immediately deleted from the server after viewing.\n4. One-time access only—subsequent visits will display an \"already read\" message.\n\n\n## :bar_chart: Workflow Diagrams\n\n### Message Creation Flow\n\n```mermaid\nsequenceDiagram\n    participant User\n    participant Browser\n    participant Server\n    participant Database\n\n    User-\u003e\u003eBrowser: Enter message \u0026 expiration\n    Browser-\u003e\u003eBrowser: Generate encryption key (client-side)\n    Browser-\u003e\u003eBrowser: Encrypt message with AES-GCM\n    Browser-\u003e\u003eServer: POST encrypted payload\n    Server-\u003e\u003eDatabase: Store encrypted message + metadata\n    Database--\u003e\u003eServer: Return message stub\n    Server--\u003e\u003eBrowser: Return stub + retrieval URL\n    Browser-\u003e\u003eBrowser: Combine URL with encryption key fragment\n    Browser--\u003e\u003eUser: Display shareable secure link\n```\n\n### Message Retrieval Flow\n\n```mermaid\nsequenceDiagram\n    participant Recipient\n    participant Browser\n    participant Server\n    participant Database\n\n    Recipient-\u003e\u003eBrowser: Click secure link with key fragment\n    Browser-\u003e\u003eBrowser: Extract encryption key from URL fragment\n    Browser-\u003e\u003eServer: GET /m/:stub\n    Server-\u003e\u003eDatabase: Query message by stub\n    alt Message exists and unread\n        Database--\u003e\u003eServer: Return message metadata\n        Server-\u003e\u003eServer: Generate math captcha challenge\n        Server--\u003e\u003eBrowser: Return captcha form + session challenge\n        Browser--\u003e\u003eRecipient: Display human verification form\n        Recipient-\u003e\u003eBrowser: Solve math challenge\n        Browser-\u003e\u003eServer: POST /m/:stub/fetch with challenge answer\n        Server-\u003e\u003eServer: Validate challenge answer\n        alt Challenge correct\n            Server-\u003e\u003eDatabase: Mark as read + retrieve encrypted content\n            Database--\u003e\u003eServer: Return encrypted message + purge\n            Server--\u003e\u003eBrowser: Return encrypted payload\n            Browser-\u003e\u003eBrowser: Decrypt message client-side\n            Browser--\u003e\u003eRecipient: Display decrypted message\n        else Challenge incorrect\n            Server--\u003e\u003eBrowser: Return challenge error\n            Browser--\u003e\u003eRecipient: Show error + retry form\n        end\n    else Message already read\n        Database--\u003e\u003eServer: Return read timestamp\n        Server--\u003e\u003eBrowser: Return \"already read\" response\n        Browser--\u003e\u003eRecipient: Show \"already read\" message\n    else Message expired/not found\n        Server--\u003e\u003eBrowser: 404 Not Found\n        Browser--\u003e\u003eRecipient: Show error message\n    end\n```\n\nAdditional diagrams can be found in the [ADDITIONAL_DIAGRAMS.md](docs/ADDITIONAL_DIAGRAMS.md) file.\n\n ## :satellite: API Reference\n\nSee [API Reference](docs/API_REFERENCE.md) for detailed API documentation, including endpoints for creating, retrieving, and managing messages.\n\n## :hammer_and_wrench: Technology Stack\n\n### Backend\n\n- **Ruby on Rails 8.0** – Web application framework\n- **SQLite3** – Development database\n- **PostgreSQL** – Production database (recommended)\n- **Solid Queue** – Background job processing\n- **Solid Cache** – Database-backed caching\n\n### Frontend\n\n- **Hotwire (Turbo + Stimulus)** – Modern SPA-like interactions\n- **Tailwind CSS 4** – Utility-first CSS framework\n- **DaisyUI 5** – UI component library\n- **Web Crypto API** – Browser-native cryptography\n\n### JavaScript Architecture\n\n- **Stimulus Controllers** – Organized, reusable JavaScript components\n- **Import Maps** – Native ES modules without bundling\n- **Web Crypto API** – Secure client-side encryption\n\n### Development Tools\n\n- **ESLint** – JavaScript linting\n- **Prettier** – Code formatting\n- **RSpec** – Testing framework\n- **FactoryBot** – Test data generation\n- **Brakeman** – Security vulnerability scanning\n\n## :rocket: Development\n\n### Prerequisites\n\n- Ruby 3.4+ (*recommend `chruby` and `ruby-install` for version management*)\n- Rails 8.0+\n- Node.js 18+ (for ESLint and Prettier)\n- SQLite3 (development) or PostgreSQL (production)\n\n### Setup (Local Development)\n\n1. **Clone the repository**:\n\n    ```bash\n    git clone https://github.com/johanns/celox.git\n    cd celox\n    ```\n\n2. **Install dependencies**:\n\n    ```bash\n    bundle install\n    npm install\n    ```\n\n3. **Set up the database**:\n\n    ```bash\n    rails db:create\n    rails db:migrate\n    rails db:seed\n    ```\n\n4. **Start the development server**:\n\n    ```bash\n    bin/dev\n    ```\n\n5. **Open the application**:\n    ```\n    http://localhost:3000\n    ```\n\n## :test_tube: Testing\n\nRun the test suite:\n\n```bash\n# Run all tests\nbundle exec rspec\n\n# Run specific test files\nbundle exec rspec spec/models/message_spec.rb\nbundle exec rspec spec/controllers/messages_controller_spec.rb\n\n# Run with coverage\nCOVERAGE=true bundle exec rspec\n```\n\n## :wrench: Configuration\n\n### Environment Variables\n\n```bash\n# Production settings\nRAILS_ENV=production\nSECRET_KEY_BASE=your_secret_key\n```\n\n### Deployment\n\nThe application is ready for deployment with:\n\n- **Kamal** – Modern deployment tool\n- **Docker** – Containerization\n\n## :handshake: Contributing\n\n1. Fork the repository.\n2. Create a feature branch (`git checkout -b feature/amazing-feature`).\n3. Commit your changes (`git commit -m 'feat: add amazing feature'`).\n4. Push to your branch (`git push origin feature/amazing-feature`).\n5. Open a Pull Request.\n\n### Commit Convention\n\nThis project uses [Conventional Commits](https://www.conventionalcommits.org/):\n\n- `feat:` – New features\n- `fix:` – Bug fixes\n- `docs:` – Documentation changes\n- `style:` – Code style changes\n- `refactor:` – Code refactoring\n- `test:` – Test additions or changes\n- `chore:` – Maintenance tasks\n\n## :page_facing_up: License\n\nThis project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.\n\n## :shield: Security\n\n### Reporting Security Issues\n\nIf you discover a security vulnerability, please email security@celox.me instead of creating a public issue.\n\n### Security Best Practices\n\n- Messages are encrypted on the client side before transmission.\n- Encryption keys never leave the client browser.\n- All inputs are validated and sanitized on the server side.\n- Messages are automatically deleted after being read.\n- Unread messages expire after a set period.\n- CSRF protection is enabled.\n- Secure headers are configured.\n\n## :pray: Acknowledgments\n\n- Built with [Ruby on Rails](https://rubyonrails.org/)\n- UI powered by [Tailwind CSS](https://tailwindcss.com/) and [DaisyUI](https://daisyui.com/)\n- Cryptography via [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API)\n- Icons from [Heroicons](https://heroicons.com/)\n- Contributions from the open-source community\n\n---\n\nCopyright © 2011-2025 Johanns Gregorian. All rights reserved.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohanns%2Fcelox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjohanns%2Fcelox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohanns%2Fcelox/lists"}