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|