Authentication
How server and browser callers authenticate to Durable Objects.
| Caller | Auth model |
|---|---|
| Server SDK / HTTP API | X-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).