No description
  • Rust 76%
  • JavaScript 13.7%
  • HTML 6.1%
  • CSS 4.2%
Find a file
despiegk b98d68e30d
Some checks failed
Build & Test / check (push) Failing after 2s
chore: fix startup info output, kind flags, and add build logs
- hero_proxy: add print_startup_info(), fix kind.cmdline=true (was cli=true), add dependencies[] to --info JSON
- hero_proxy_admin: fix socket_dir display to show base dir, add dependencies[]
- hero_proxy_server: fix socket_dir display to show base dir, add dependencies[]
- add release build logs for aarch64 and x86_64 musl targets

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 21:05:27 +02:00
.forgejo/workflows ci: rename release artifacts to target-triple shape (home#212) (#46) 2026-05-06 16:03:37 +00:00
.hero chore: fix startup info output, kind flags, and add build logs 2026-05-10 21:05:27 +02:00
crates chore: fix startup info output, kind flags, and add build logs 2026-05-10 21:05:27 +02:00
docs feat(proxy): per-method authz on management RPC + admin impersonation 2026-05-05 15:34:44 +02:00
patches/rustls-acme-0.15.1 refactor: simplify socket discovery and fix RPC base path for UI 2026-04-08 12:28:48 +02:00
.env.example add tls support 2026-02-18 08:07:07 +01:00
.gitignore Initial hero_proxy: reverse proxy for hero services 2026-02-16 00:34:57 +01:00
Cargo.lock chore: migrate to hero_admin_lib shared assets 2026-05-10 16:19:59 +02:00
Cargo.toml chore: migrate to hero_admin_lib shared assets 2026-05-10 16:19:59 +02:00
Cargo.toml.hero_builder_backup chore: apply hero_builder drift fixes — bump deps, add --info/--help, add build artifacts 2026-05-10 14:21:19 +02:00
PURPOSE.md fix: socket naming (ui.sock→admin.sock), add PURPOSE.md, logging compliance 2026-05-07 13:13:54 +02:00
README.md fix: socket naming (ui.sock→admin.sock), add PURPOSE.md, logging compliance 2026-05-07 13:13:54 +02:00

Hero Proxy

HTTP/HTTPS reverse proxy and service discovery for the Hero ecosystem. Routes incoming traffic to Hero services via URL-prefix → Unix domain socket forwarding, with TLS termination (self-signed or Let's Encrypt), SSH tunnels, OAuth, and a full management API.

Architecture

Internet / Browser
       │
  :80 (HTTP) / :443 (HTTPS)
       │
  hero_proxy_server
    ├── {domain}/* → ~/hero/var/sockets/{service}/*.sock
    ├── TLS (self-signed or Let's Encrypt / ACME)
    ├── SSH reverse-port tunnels
    ├── OAuth2 / bearer / signature auth per route
    └── OpenRPC JSON-RPC 2.0 management API
              │
       ~/hero/var/sockets/hero_proxy/rpc.sock

Crates

Crate Type Description
hero_proxy binary CLI — registers and starts/stops all services via hero_proc
hero_proxy_server binary TCP proxy + service discovery + OpenRPC API
hero_proxy_ui binary Admin dashboard
hero_proxy_sdk library Auto-generated typed client
weblib library Reusable web / TLS / ACME library

Sockets

All sockets under $HERO_SOCKET_DIR/hero_proxy/ (default ~/hero/var/sockets/hero_proxy/).

Socket Protocol Description
rpc.sock OpenRPC / JSON-RPC 2.0 Management API
admin.sock HTTP Admin dashboard

Ports (TCP)

Port Protocol Description
9997 HTTP Proxy ingress (dev / LAN)
9996 HTTPS Proxy ingress (TLS)
443 HTTPS Production ingress (Let's Encrypt)
80 HTTP Redirect → HTTPS (Let's Encrypt mode)

Service Management (Nushell)

All service lifecycle operations are done through Nushell using the service_proxy and proxy modules from hero_skills.

use services/service_proxy.nu *
use clients/proxy.nu *

Install and start

# Build release binaries, install to ~/hero/bin, register with hero_proc, start
service proxy start --update --reset

# Or using the service_proxy module directly
service_proxy install
service_proxy start

Stop / restart

service_proxy stop
service_proxy restart   # stop → rebuild → start

Status and logs

service_proxy status    # hero_proc list for hero_proxy_*
service_proxy logs      # streaming logs from hero_proxy_server
service_proxy logs-ui   # streaming logs from hero_proxy_ui

Dev build (faster iteration)

service_proxy start --dev   # cargo build (debug), install, start

TLS / ACME Configuration

TLS settings are persisted in the database so they survive restarts without environment variables. DB values always take precedence over env vars.

# Set the domain for Let's Encrypt (required)
proxy system config set --dns-name proxy.example.com

# Set contact email (strongly recommended — expiry notifications)
proxy system config set --acme-email admin@example.com

# Switch to production CA (default is staging — safe to test first)
proxy system config set --acme-production true

# View current effective config and where each value comes from
proxy system config get

# Clear a field (reverts to env var fallback, or unset)
proxy system config remove dns_name

Response from proxy system config get

{
  dns_name:               "proxy.example.com"
  acme_email:             "admin@example.com"
  acme_production:        true
  dns_name_source:        "db"     # db | env | unset
  acme_email_source:      "db"     # db | env | unset
  acme_production_source: "db"     # db | env | default
}

Env var fallbacks (legacy / alternative)

DB key (via API) Environment variable Default
acme_dns_name HERO_PROXY_DNS_NAME — (self-signed)
acme_email HERO_PROXY_ACME_EMAIL — (no email)
acme_production HERO_PROXY_ACME_PRODUCTION false (staging)

Changes take effect the next time a listener with tls_mode=letsencrypt is started. Running listeners are not hot-reloaded — restart the listener after changing config.


Quick-start: public HTTPS with Let's Encrypt

# 1. Install and start the service
service_proxy install
service_proxy start

# 2. Configure ACME (while service is running — no restart needed for config)
proxy system config set --dns-name proxy.example.com --acme-email admin@example.com
proxy system config set --acme-production true

# 3. Add an HTTPS listener (starts the ACME challenge immediately)
proxy listener add "0.0.0.0:443" --protocol https --tls-mode letsencrypt

# 4. Verify
proxy listener status
proxy tls check proxy.example.com

Quick-start: SSH tunnel to a public server

# Create HTTP + HTTPS + DNS-bridge tunnels in one call and start them
proxy tunnel quick_add edge.example.com admin --auth-key-path ~/.ssh/id_ed25519

# Check status
proxy tunnel status
proxy tunnel check_dns 3

Domain routing

# Route a hostname to a local service socket
proxy domain add app.example.com socket /run/myapp.sock

# Route with bearer-token auth
proxy domain add api.example.com https https://127.0.0.1:9000 --auth-mode bearer

# Route with OAuth (Google)
proxy oauth set google google $CLIENT_ID $CLIENT_SECRET \
    --scopes "openid email profile"
proxy domain add dash.example.com http http://127.0.0.1:8080 \
    --auth-mode oauth --oauth-provider google

# List / inspect routes
proxy domain list
proxy domain get 3

Development

# Fast check without producing a binary
cargo check -p hero_proxy_server

# Run tests
cargo test

# Clippy
cargo clippy --all-targets -- -D warnings

# Format
cargo fmt

Documentation

The Nushell client reference lives in hero_skills:

  • tools/modules/clients/proxy.nu — all RPC commands
  • tools/docs/proxy.md — full command reference