Pingerchips LogoPingerchips
Durable ObjectsCookbook

Authentication

How server and browser callers authenticate to Durable Objects.

CallerAuth model
Server SDK / HTTP APIX-App-Key + X-App-Secret headers
Browser (real-time subscribe)a capability token minted by your server

This is the same model as every other Pingerchips product — see Authentication.


Server auth (headers)

Every HTTP request to /api/v1/objects/... carries two headers:

X-App-Key:    {appKey}
X-App-Secret: {appSecret}

No request signing, no timestamp. The {app_id} path segment must be the App Key or App ID of the authenticated app.

pingerchips-js-server sets the headers for you:

import PingerchipsServer from 'pingerchips-js-server';

const pc = new PingerchipsServer(APP_KEY, APP_SECRET);
await pc.object('order', 'order-42').set('status', 'shipped');

Browser auth (capability token)

The App Secret must never reach the browser. Your server mints a token granting object:read:{type}/{key}, bound to one socket.

Server: issue it

pingerchips-js-server >= 3.0.0 provides authenticateObject:

import PingerchipsServer from 'pingerchips-js-server';

const pc = new PingerchipsServer(
  process.env.PINGERCHIPS_APP_KEY,
  process.env.PINGERCHIPS_APP_SECRET,
);

app.post('/auth/durable', (req, res) => {
  const { socket_id, object_type, object_key, auth_info } = req.body;

  const user = verifyUser(auth_info?.token);
  if (!user || !canRead(user, object_type, object_key)) {
    return res.status(403).json({ error: 'Forbidden' });
  }

  // { auth: "{appKey}.{payloadB64}.{sigB64}" }
  // caps: object:read:{object_type}/{object_key}, bound to socket_id
  res.json(pc.authenticateObject(socket_id, object_type, object_key));
});

The result is a fast-path capability token — a pure function of the App Secret, the socket id, and the capability; no round-trip to Pingerchips. A token for order/order-42 cannot be used for order/order-99, and a token minted for socket A is rejected on socket B. Layout: Authentication.

To grant several objects on one token, use pc.authorize(socketId, { objects: [{ type, key }, …] }).

Browser: use it

const pc = new Pingerchips('YOUR_APP_KEY', {
  authEndpoint: '/auth/durable',
});

const order = await pc.object('order', 'order-42');

The SDK calls your endpoint automatically — POSTing { socket_id, object_type, object_key, auth_info } and expecting { auth } back. See the Client SDK.


Security notes

  • The App Secret stays server-side, always.
  • Scope each token to exactly the objects the client needs.
  • Run your authorization check in the auth endpoint before minting.
  • Tokens are bound to the socket — a reconnect needs a fresh token (the client SDK re-fetches automatically).

On this page