Skip to content

feat(tls): add mkcert-based self-signed TLS for *.obol.stack #155

@bussyjd

Description

@bussyjd

Summary

Add automatic TLS certificate generation using mkcert so the entire Obol Stack runs over HTTPS. This eliminates the need for gateway.controlUi.allowInsecureAuth in OpenClaw and enables full device authentication security.

Problem

OpenClaw's Control UI requires crypto.subtle (Web Crypto API) for device identity authentication. This API is only available in secure contexts (HTTPS or localhost). Since the stack uses custom domains like openclaw-demo.obol.stack over HTTP, the browser cannot provide device identity, forcing us to set allowInsecureAuth: true — a security downgrade that skips device auth entirely.

Browsers check the hostname, not the resolved IP — so http://obol.stack resolving to 127.0.0.1 does NOT qualify as a secure context. Only https:// or literal localhost does.

Solution

Use mkcert (v1.4.4) to generate a local CA and wildcard certificate for *.obol.stack.

Implementation

  1. obolup.sh — Install mkcert as a pinned binary (same pattern as kubectl/helm/k3d)
  2. obol stack init — Generate CA + wildcard cert:
    • mkcert -install (trusts CA in OS Keychain + Firefox NSS store)
    • mkcert -cert-file tls.crt -key-file tls.key "*.obol.stack" obol.stack
    • Save to ~/.config/obol/tls/
  3. obol stack up — Create TLS Secret + enable Traefik HTTPS:
    • kubectl create secret tls obol-stack-tls -n traefik
    • Enable websecure Gateway listener with tls.mode: Terminate
    • Add HTTP → HTTPS redirect
  4. OpenClaw overlay — Remove allowInsecureAuth: true from generated overlays
  5. HTTPRoutes — Update to reference websecure listener (or both)

What already exists

Piece Status
k3d port mapping 8443:443 Already configured
Traefik websecure entrypoint (port 8443) Exists, tls.enabled: false
Gateway websecure listener Not yet defined
mkcert dependency Not present

Files to modify

File Change
obolup.sh Add MKCERT_VERSION="1.4.4" + install logic
internal/stack/stack.go Generate certs during Init(), create TLS Secret during Up()
internal/embed/infrastructure/helmfile.yaml Enable TLS on websecure, add Gateway websecure listener
internal/embed/k3d-config.yaml Verify port mappings (already done)
internal/openclaw/openclaw.go Remove allowInsecureAuth from overlay generation
internal/openclaw/chart/values.yaml Remove allowInsecureAuth default
internal/openclaw/chart/templates/_helpers.tpl Remove controlUi rendering

Security impact

With TLS enabled, the full OpenClaw security model works:

  • Token/password auth (enforced)
  • Device identity (Ed25519 keypair via crypto.subtle)
  • Device pairing (approval flow for new devices)
  • No allowInsecureAuth or dangerouslyDisableDeviceAuth needed

Browser considerations

  • Chrome/Safari: Trust OS Keychain automatically via mkcert -install
  • Firefox: Uses own NSS store — mkcert -install handles this if nss-tools/certutil is installed
  • WebSocket (wss://): Works transparently with trusted CA (Firefox silently fails without pre-trusted CA — no exception dialog for WebSocket)

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions