A PubSub token grants read or write on named channels for a number of minutes. Your server mints one per member, and decides who may write. The browser never holds the project API token.
pubsub
The claim
The vendored REST spec’s POST /api/pubsub/tokens requires two fields. ttl is “The maximum time, in minutes, for which the access token will be valid. Between 1 and 43,200 (30 days)“. channels is “User-defined channel names. Each channel is an object with read and/or write properties”. It also takes member_id, “The unique identifier of the member”, and state, “An arbitrary JSON object available to store stateful application information in”. It answers with a token. So the token is where the permissions live: a reader’s token names the channel with read true and write false, and a publisher’s has write true. The SDK wraps the call as client.pubsub.create_token.
How it works
def reader_token(member_id):
return client.pubsub.create_token(
ttl=TOKEN_TTL_MINUTES, member_id=member_id,
channels={CHANNEL: {"read": True, "write": False}},
state={"role": "reader"})
@app.post("/pubsub/token")
def token():
body = request.get_json(force=True)
member_id = body.get("member_id")
if not member_id:
abort(400)
wants_write = body.get("role") == "publisher"
has_key = bool(BOARD_KEY) and request.headers.get("X-Board-Key") == BOARD_KEY
if wants_write and not has_key:
abort(403)
minted = publisher_token(member_id) if wants_write else reader_token(member_id)
return jsonify({"token": minted["token"], "channel": CHANNEL})
What the platform receives, for a reader and then for the board:
The route hands the browser the minted token and the channel name, and nothing else. The browser asks for a role; the server decides whether it gets it. A request that asks to publish must carry the board’s key in X-Board-Key, a secret only the board process holds. The server refuses a request without it with 403 rather than downgrading it. Replace the header check with your own session check when you have sign-in.
Limitations
You prove the tokens and the route. Whether a subscribed browser receives a publish is the Browser SDK’s and the platform’s side. The token gates who may publish; it does not deliver anything by itself.
state is yours to define. The spec only says it must be valid JSON with a size limit.
What to change first
Give the reader’s channel write true and run the verifier. The reader body assertion fails. A customer’s phone that can write to the board is the bug this split of two token shapes exists to prevent.