{"id":44769893,"url":"https://github.com/koltyakov/expose","last_synced_at":"2026-03-16T01:49:55.727Z","repository":{"id":338724228,"uuid":"1158639271","full_name":"koltyakov/expose","owner":"koltyakov","description":"🚀 BYOI HTTP tunnel - automatic HTTPS, built-in WAF, real-time dashboard, single binary","archived":false,"fork":false,"pushed_at":"2026-02-28T22:22:04.000Z","size":618,"stargazers_count":4,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-28T22:53:01.830Z","etag":null,"topics":["acme","developer-tools","golang","letsencrypt","ngrok-alternative","reverse-proxy","self-hosted","tunnel","waf","websocket"],"latest_commit_sha":null,"homepage":"","language":"Go","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/koltyakov.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":"2026-02-15T17:40:04.000Z","updated_at":"2026-02-28T22:22:07.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/koltyakov/expose","commit_stats":null,"previous_names":["koltyakov/expose"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/koltyakov/expose","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/koltyakov%2Fexpose","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/koltyakov%2Fexpose/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/koltyakov%2Fexpose/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/koltyakov%2Fexpose/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/koltyakov","download_url":"https://codeload.github.com/koltyakov/expose/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/koltyakov%2Fexpose/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30231500,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-07T19:01:10.287Z","status":"ssl_error","status_checked_at":"2026-03-07T18:59:58.103Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["acme","developer-tools","golang","letsencrypt","ngrok-alternative","reverse-proxy","self-hosted","tunnel","waf","websocket"],"created_at":"2026-02-16T05:09:37.413Z","updated_at":"2026-03-16T01:49:55.708Z","avatar_url":"https://github.com/koltyakov.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# expose\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./assets/logo.png\" alt=\"expose logo\" width=\"220\" /\u003e\n\u003c/p\u003e\n\n**expose** is a self-hosted HTTP tunnel. Run your own server, then expose local HTTP ports from any machine - no third-party services required.\n\n![expose client](./assets/client-tunnel.png)\n\n## Features\n\n- **HTTPS-only** public traffic with automatic TLS (ACME) or static wildcard certificates\n- **Built-in WAF** blocks SQL injection, XSS, path traversal, and other attacks before they reach your app, including bounded JSON/form/text body inspection\n- **Static site publishing** via `expose static` for quick docs, SPAs, and local folders\n- **Multi-route configs** via `expose.yml` - expose multiple services under one subdomain with path-based routing\n- **Real-time client dashboard** with request log, latency percentiles, WAF counters, and connection stats\n- **Auto-update** - server and client can self-update in the background with zero downtime\n- **Password-protected tunnels** with a built-in access form and edge session cookie (per-tunnel or per-config)\n- **Env-first configuration** - minimal CLI flags, `.env` support, and interactive setup wizards\n- **Rate limiting** on tunnel registration plus optional public traffic throttling per hostname+client IP\n- **Persistent login** - authenticate once with `expose login`, credentials are saved locally\n- **Automatic reconnection** with exponential backoff and keepalive pings\n- **HTTP/3 over QUIC support** - clients can use `--transport=quic` for compatibility or negotiated multi-stream mode\n\n## How It Works\n\n```mermaid\nflowchart TB\n    App[\"💻 Local app\u003cbr/\u003e127.0.0.1:PORT\"]\n\n    subgraph client[\"expose client\"]\n        Fwd[\"Forward\"] --\u003e Conn[\"Connect\"] --\u003e Reg[\"Register\"]\n    end\n\n    subgraph server[\"expose server\"]\n        Hub{{\"Session hub\"}}\n        Route[\"Route by hostname\"]\n        TLS[\"TLS · WAF\"]\n        DB[(\"SQLite\")]\n\n        Hub --\u003e Route --\u003e TLS\n        Route -. resolve .-\u003e DB\n    end\n\n    Browser[\"🌐 Browser\"]\n\n    App -- \"HTTP\" --\u003e Fwd\n    Hub \u003c-- \"WebSocket or HTTP/3 tunnel\" --\u003e Conn\n    Conn -- \"token\" --\u003e Hub\n    Reg -- \"API key\" --\u003e Route\n    TLS -- \"HTTPS *.domain\" --\u003e Browser\n```\n\n1. The **server** terminates TLS, runs WAF inspection, and routes requests by hostname to the correct tunnel\n2. The **client** registers via API key, then opens a persistent WebSocket or HTTP/3 tunnel to the server\n3. Requests and responses flow over the tunnel as versioned binary frames, with raw body bytes for inline and streamed payloads\n\nFor the full request lifecycle and component breakdown, see [Architecture Overview](docs/architecture-overview.md).\nFor transport mode details (`ws|quic`) and QUIC requirements, see [Client Configuration](docs/client-configuration.md) and [UDP Deployment Topologies](docs/udp-deployment-topologies.md).\n\n## Quick Start\n\n### Prerequisites\n\n- A **server or VPS** with a public IP - or a home server with [port forwarding](docs/port-forwarding.md) configured\n- A **domain** you control (e.g. `example.com`)\n- A **DNS wildcard A record** (`*.example.com`) pointing to your server's public IP\n\n### 1. Install\n\nDownload the latest binary from [Releases](https://github.com/koltyakov/expose/releases) and place it in your `PATH`.\n\n### 2. Server - init and run\n\nOn your public-facing machine, run the interactive setup (writes a `.env` for you):\n\n```bash\nexpose server init   # guided setup\nexpose server        # start the tunnel server\n```\n\nThen create an API key for your client(s):\n\n```bash\nexpose apikey create --name default\n```\n\n### 3. Client - login and run\n\nOn any machine you want to expose:\n\n```bash\n# Login once to save credentials locally\nexpose login\n\n# Expose a local HTTP port (e.g. 3000) to the internet\nexpose http 3000\n\n# Or expose a static directory as a website\nexpose static\n```\n\nOpen the URL shown in the terminal - that's it.\n\n\u003e ⚠️ Security notice: if your server is using per-host ACME certificates (`dynamic`, or `auto` without a matching wildcard certificate), new public hostnames are often discovered and probed by bots shortly after they are created. Protect new tunnels immediately and use `--protect` for anything non-public. See [TLS Modes](docs/tls-modes.md) and [Static Sites](docs/static-sites.md).\n\nFor the full walkthrough, DNS setup guides, and multi-route configs, see [Quick Start](docs/quick-start.md).\n\n## Documentation\n\nSee the [docs/](docs/README.md) folder for all guides - server \u0026 client configuration, [static sites](docs/static-sites.md), TLS modes, DNS setup, deployment, WAF, auto-update, troubleshooting, and more.\n\n## Acknowledgements\n\n- [ngrok](https://ngrok.com/) - the gold standard for HTTP tunnels and a huge inspiration. `expose` exists because I needed more freedom and control over infrastructure, but ngrok paved the way.\n- [OpenAI](https://openai.com/) and [Anthropic](https://anthropic.com/) - AI-assisted development boosted the entire build lifecycle by 10×.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkoltyakov%2Fexpose","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkoltyakov%2Fexpose","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkoltyakov%2Fexpose/lists"}