Skip to main content

Realtime MQTT Public Stream

Category: Backend & APIs

Get this pack →

This page is generated from the Air Pipe marketplace. Browse it live to install into your organization.

Open MQTT: clients connect with no username or password and subscribe to a public topic for live data — public sensor networks, transit feeds, prices, status boards, community IoT. It's the EMQX/HiveMQ allow_anonymous model, but multi-tenant-safe and with your pipeline able to run on the stream.

Public streams are for non-sensitive data — anyone can subscribe. For device auth, retained commands, and per-topic ACLs, use the Realtime MQTT Broker pack.


Why open MQTT is safe here​

An anonymous connection is admitted, and where tenant isolation is active the proxy restricts it to interfaces marked public: true at every SUBSCRIBE and PUBLISH (fail-closed) — it cannot reach a private topic. On a managed host that isolation is always on, the connection is scoped to your org (the org id rides the username, which isn't a secret), and the per-org abuse floors (publish rate, subscriptions, topics) apply. Open access, bounded blast radius.

Read this before running it self-hosted. That restriction is gated on tenant isolation — managed, or AP_MQTT_ORG_NAMESPACING enabled. On a plain self-hosted broker (single tenant, namespacing off) anonymous is deliberately unrestricted, exactly as EMQX/HiveMQ allow_anonymous behaves: an anonymous client can subscribe to production/# and receive every topic in that deployment. Verified against 3.10.0. If you want a public feed next to private topics self-hosted, put a subscribe_authorizer on the private interfaces — that boundary does hold, a subscribe outside its allow-list is dropped — or enable namespacing, or separate the deployments.

How Air Pipe compares​

EMQX / HiveMQAWS IoT CoreAir Pipe
Anonymous MQTT✅ (allow_anonymous)❌✅ (public: true interface; scoped to public topics where tenant isolation is on)
Safe on multi-tenant / shared infra❌ (single-tenant)✅🏆 (public-only gate + per-org floors)
Run your logic on the public message❌❌🏆 built-in

What's included​

FilePurpose
public.ymlOne public: true MQTT interface (publicdata) that stamps and fans out each message.

Endpoint​

TransportConnect URLAuth
MQTT over WebSocketwss://your-airpipe-host/mqtt (sub-protocol mqtt)none (anonymous) — or username=<ORG_UUID>, no password, on managed

Public topic: production/publicdata/stream.

Quick start​

Node (MQTT.js) — anonymous subscribe:

const mqtt = require("mqtt");
const c = mqtt.connect("wss://your-airpipe-host/mqtt"); // no username/password
c.on("connect", () => c.subscribe("production/publicdata/stream"));
c.on("message", (t, m) => console.log(t, JSON.parse(m.toString())));

Your backend — publish to the public stream:

const pub = require("mqtt").connect("wss://your-airpipe-host/mqtt",
{ username: "<ORG_UUID>", password: "<API_KEY>" }); // authenticated publisher
pub.on("connect", () =>
pub.publish("production/publicdata/stream",
JSON.stringify({ station: "SYD-01", temp_c: 22.1 }), { qos: 1 }));
// → every anonymous subscriber receives it, stamped with received_at by the pipeline

Python (paho-mqtt) — anonymous subscribe:

import paho.mqtt.client as mqtt
c = mqtt.Client(transport="websockets"); c.ws_set_options(path="/mqtt"); c.tls_set()
c.connect("your-airpipe-host", 443) # no username/password
c.subscribe("production/publicdata/stream"); c.loop_forever()

Customisation​

  • Open publish too: anonymous clients may also publish to the public topic — leave as-is for a fully open feed, or add a subscribe_authorizer / publish gate to make it read-only-public.
  • Process the stream: the Stamp action runs on every message — swap it for validation, enrichment, a DB insert, or a webhook.
  • Multiple public streams: add more public: true interfaces, each its own production/<name>/<trigger> topic.

Notes​

  • Anonymous connections can only reach public: true interfaces — private topics are never exposed.
  • Targets MQTT-over-WebSocket clients (MQTT.js, paho transport="websockets", HiveMQ web client).
  • Each message that triggers the pipeline counts as one request against your plan.
  • Only production and staging environments are accepted in the topic.

Configuration​

public.yml​

name: RealtimeMqttPublic
description: >
Public MQTT — clients connect with NO username or password and subscribe to a public topic for
live data (sensor readings, transit, prices, status). The EMQX/HiveMQ `allow_anonymous` model, but
multi-tenant-safe where tenant isolation is active (managed, or AP_MQTT_ORG_NAMESPACING): an
anonymous connection then reaches only interfaces marked `public: true`, never a private topic,
and per-org limits still bound it. On a plain self-hosted broker anonymous is unrestricted, as
with EMQX/HiveMQ allow_anonymous -- gate private topics with a subscribe_authorizer there. Interface-shaped public topics also run your
pipeline — validate/enrich the public stream, which a raw broker can't.

docs: true

# ── How it works ─────────────────────────────────────────────────────────────────
# Connect an MQTT-over-WebSocket client to wss://your-airpipe-host/mqtt with NO credentials:
# (no username, no password) — anonymous / public
# or, on a managed host, username = <ORG_UUID> and NO password (the org id is not a secret; it
# scopes the connection to your org's public topics).
#
# Then subscribe to the public interface topic:
# production/publicdata/stream
# An anonymous connection is restricted to `public: true` interfaces — any other topic is denied
# (fail-closed) — WHERE TENANT ISOLATION IS ACTIVE: managed, or self-hosted with
# AP_MQTT_ORG_NAMESPACING on. That is the condition, and it matters.
#
# ON A PLAIN SELF-HOSTED BROKER (single tenant, namespacing off) ANONYMOUS IS UNRESTRICTED, by
# design — it matches EMQX/HiveMQ `allow_anonymous`. An anonymous client can subscribe to
# `production/#` and receive every topic in the deployment. Verified on 3.10.0.
#
# So if you run this feed self-hosted alongside private topics, gate the private ones with a
# `subscribe_authorizer` (that DOES hold — a subscribe outside its allow-list is dropped), or
# turn namespacing on, or keep public and private on separate deployments.
#
# Publishing: your backend (authenticated) publishes to production/publicdata/stream and every
# anonymous subscriber receives it. Anonymous clients may also publish to the public topic if you
# want a fully open feed — remove that ability by adding a `subscribe_authorizer` / publish gate.

interfaces:

# Public MQTT interface — anonymous clients may pub/sub here (and only here).
publicdata:
mqtt: "stream" # realtime — no `output` needed
# output: http # optional: also accept over HTTP (dual interface)
public: true
summary: Public MQTT stream (no auth)
description: Anonymous clients subscribe to production/publicdata/stream for live public data.
tags: [mqtt, iot, public, pubsub, telemetry]
actions:
# Runs on each publish to the public topic — validate/stamp before it fans out.
- name: Stamp
input: a|body|
post_transforms:
- add_attribute:
received_at: a|timestamp:datetimeutctz|