Documentation / Visitors and technical evaluators

Public LED Demo

The deliberately constrained browser-to-RabbitMQ-to-Raspberry-Pi demonstration.

Purpose

The public demo shows a complete but deliberately tiny control path: a browser submits led.on(), the website validates it, RabbitMQ receives a signed command for website Controller, and a Raspberry Pi turns on one LED. The camera provides the physical evidence.

Non-negotiable constraints

  • The browser may submit only led.on().
  • The browser cannot select an exchange, queue, routing key, Controller ID, operation, GPIO pin, or argument.
  • The website publishes only to the queue named website Controller.
  • The message is signed, expires quickly, and includes a unique command ID.
  • The Raspberry Pi verifies the signature, target, operation, expiry, and replay state.
  • No component uses eval(), exec(), shell=True, or a remote shell.

Request flow

  1. Browser validation

    JavaScript improves feedback, but the server repeats every validation because browsers are not security boundaries.

  2. CSRF and rate limit

    The website checks the signed session token, per-client quota, global cooldown, and request size.

  3. Fixed command mapping

    The text led.on() maps internally to the typed operation led.on. No other mapping exists.

  4. Confirmed publish

    The Pi consumer or broker administrator declares the durable website Controller queue. The website publishes mandatorily to that pre-existing queue and requires a RabbitMQ publisher confirmation.

  5. Controller validation

    The Raspberry Pi rejects stale, malformed, misrouted, unsigned, or duplicate commands.

  6. Physical verification

    The camera—not the HTTP response—shows whether the LED changed state.

What “queued” means

It means RabbitMQ confirmed receipt. It does not mean the Raspberry Pi was online, the GPIO handler succeeded, the LED is wired correctly, or the camera is current.

Camera path

The website container proxies the configured camera through the same HTTPS origin at /demo-camera/. The proxy permits read-only viewing and strips browser credentials. Direct camera administration remains outside the public site.

Reference containers

The release contains two Docker-focused components: the public website image and an optional Raspberry Pi agent image under controller_agent/. The website terminates TLS with the host's mounted Let’s Encrypt certificate. The Pi agent mounts persistent replay state and the GPIO device interface required by its deployment.

Certificate and signing-key separation

The HTTPS private key, AMQP credentials, and command signing key solve different problems and remain separate. Rotating one should not require baking a new application image or silently changing another boundary.