← Về thư mục
📄 / / profiles / r-and-d / raw_evidence / OpenAI4S / docs / webshare.md

Web sharing

Share a session as a read-only snapshot that anyone with the link can view at https://<share-id>.<your-domain>/, download as a portable bundle, and import into their own local OpenAI4S to run or continue.

Sharing is off by default and does nothing until you both configure a relay and enable it. The daemon never binds a public port — it dials out to a relay you run.

Trust model — read this first

Architecture

visitor ──HTTPS──▶ Caddy (*.<domain>) ──▶ openai4s relay (your VPS, stateless)
                                              ▲
                                 outbound WSS │ (daemon dials out, Bearer token)
your machine: openai4s daemon (127.0.0.1) ────┘

The relay forwards each visitor GET/HEAD through the tunnel to a read-only snapshot materialized on your machine; it never reaches the kernel, the dispatcher, or any writable gateway route.

Deploy the relay (on a VPS)

1. DNS

Point a wildcard and a tunnel host at the VPS, and pin the CA:

*.openai4s.org        A     <vps-ip>
share.openai4s.org    A     <vps-ip>        # tunnel endpoint (optional convenience)
openai4s.org          CAA   0 issue "letsencrypt.org"

Use a wildcard TLS certificate (DNS-01). Per-subdomain certificates would publish every share id into Certificate Transparency logs — the wildcard keeps share ids out of public logs. Enable 2FA on your registrar and DNS provider.

2. TLS front (Caddy)

*.openai4s.org {
    tls { dns <provider> {env.DNS_API_TOKEN} }   # needs a DNS-plugin caddy build
    reverse_proxy 127.0.0.1:8770                  # WebSocket upgrades pass through
    log { output discard }                        # Host carries the plaintext share id
}

nginx equivalent: obtain a wildcard cert via certbot --preferred-challenges dns, proxy_pass http://127.0.0.1:8770;, forward Upgrade/Connection headers for the WebSocket, and set access_log off;.

3. Relay process (systemd)

[Service]
DynamicUser=yes
EnvironmentFile=/etc/openai4s/relay.env      # 0600, holds OPENAI4S_RELAY_* if used
ExecStart=/usr/local/bin/openai4s relay serve \
    --listen 127.0.0.1:8770 --base-domain openai4s.org \
    --tokens-file /etc/openai4s/relay-tokens
Restart=always
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes

relay-tokens (mode 0600) holds one publisher token per line, label token. Generate one with openai4s relay gen-token. Editing the file is picked up live (the relay reloads on mtime change and disconnects any tunnel whose token was removed) — rotation needs no restart.

4. Firewall

Open only 80/443. Keep the relay's 127.0.0.1:8770 loopback-only behind Caddy.

Configure the daemon (your machine)

Put these in the git-ignored .env (or export them):

variable value
OPENAI4S_SHARE_RELAY_URL wss://share.openai4s.org/tunnel
OPENAI4S_SHARE_AUTH_TOKEN the publisher token from the relay's tokens file
OPENAI4S_SHARE_BASE_DOMAIN openai4s.org

The token is named *_AUTH_TOKEN on purpose so the session-package secret scanners treat it as a secret and never let it leave in a bundle. It is never written to the database.

Then enable sharing (once): Customize → Sharing, or openai4s share enable.

Use it

Expiry (auto-revoke)

A share can carry an expiry so it revokes itself. Set it in the Web dialog (Never / 1 day / 7 days / 30 days) or with --expires 30m|24h|7d (the REST body field is expires_in, in seconds; 0/absent = never). When it lapses the daemon auto-revokes it — deleting the snapshot and unregistering it from the relay, so the link returns 404. A background sweeper checks about once a minute, and any share that expired while the daemon was off is revoked on the next startup, so an expired link never comes back online. Expiry is enforced daemon-side; the relay needs no changes.

Recipients open the link, click Run locally, download the bundle (or run openai4s share import <url>), and get a quarantined, view-only session. They click Restart fresh in its recovery panel to establish a trusted runtime, then continue or fork. Imported package code is never replayed.

Security notes

End-to-end verification checklist

  1. dig share.openai4s.org and dig <random>.openai4s.org resolve to the VPS.
  2. curl -I https://<26-char-id>.openai4s.org/ on an unknown id → 404 with x-content-type-options, referrer-policy, x-robots-tag headers.
  3. Enable sharing; daemon log / openai4s share status shows connected.
  4. Create a share; open it in a private window: conversation, Notebook, and artifacts render, HTML/SVG artifacts download rather than inline, and the browser console shows zero CSP violations and zero external requests.
  5. Download the bundle; confirm its sha256 matches what the CLI printed.
  6. openai4s share import <url> into a second install → view-only quarantine → Restart fresh → continue the conversation.
  7. Revoke → the link returns 404. Restart the relay → the share auto-recovers (the daemon reconnects and re-registers). Disable → 404; re-enable → restored.

Local testing without a VPS

*.localtest.me resolves to 127.0.0.1, so you can exercise the whole path locally over plaintext:

openai4s relay serve --listen 127.0.0.1:8770 --base-domain localtest.me \
    --tokens-file /tmp/relay-tokens
# daemon .env:
OPENAI4S_SHARE_RELAY_URL=ws://127.0.0.1:8770/tunnel
OPENAI4S_SHARE_AUTH_TOKEN=<token from /tmp/relay-tokens>
OPENAI4S_SHARE_BASE_DOMAIN=localtest.me
OPENAI4S_SHARE_ALLOW_INSECURE=1        # permits ws:// on loopback for testing only

Then visit http://<share-id>.localtest.me:8770/.