Identity token format and exchange
Use your own identity provider when your app already knows who is reviewing. Your backend signs a short-lived JWT, and the browser passes it to Gutternote.
This option needs the Bikeshed plan. A workspace owner can upgrade in Billing.
Project configuration
On the project’s Configure page, under Who may comment, choose Your own identity provider.
- Issuer is optional. When set, the token’s
issmust match it exactly. - Max token age is 1 to 60 minutes. Default: 5.
- The project needs a signing secret. Gutternote provisions it. To get one, contact us. Do not switch a live project until the secret is in place.
JWT claims
Sign with HS256 and the project’s signing secret.
| Claim | Required | Description |
|---|---|---|
sub | yes | Stable user ID in your app. |
exp | yes | Unix time after which the token is refused. |
iat | recommended | Unix time used for the max token age. More than 2 minutes in the future is refused. |
iss | when configured | Must match the project’s issuer. |
name | no | Display name, visible to everyone who can read threads. Falls back to sub, never to email. |
email | no | Stored in lowercase. Used for domain-based agent access, and for member access when email_verified is true. |
email_verified | for member access | true only when your app has confirmed the person owns email. |
picture | no | Avatar URL. Your CSP must allow its origin. |
{ "iss": "https://id.acme.com", "sub": "user_123", "name": "Dana Reed", "email": "dana@acme.com", "email_verified": true, "iat": 1789991700, "exp": 1789992000}Sign tokens on your server. Never put the signing secret in browser code, a client-side environment variable or the page source.
Member access
A token lets a person sign in, comment and reply. Triage, resolve, stopping a
task and sending work to agents also need a workspace member. Gutternote
matches the token’s email to a member only when email_verified is true.
Set email_verified only for an address your app has confirmed. If your
sign-up never checks addresses, leave it out. Otherwise anyone who types a
teammate’s address gets that teammate’s member access. Without it, the person
can still comment. The server refuses member operations with
403 member_required.
Session lifetime
A session from a token lasts 12 hours, or the project’s session length if that
is shorter. It is never renewed. The widget asks your backend for a new token
instead. A change to email_verified applies from the next exchange.
Exchange through the widget
Pass the token:
await Gutternote.init({ key: 'pk_live_...', identityToken: await myBackend.gutternoteToken(),})Or give a same-origin endpoint:
await Gutternote.init({ key: 'pk_live_...', authEndpoint: '/api/gutternote-token',})The widget calls authEndpoint with credentials and expects
{ "token": "eyJ..." }. It calls it only when the project requires your
identity provider. If the call fails, the widget stays readable and uses no
other identity.
Exchange through the HTTP API
POST /v1/sessions/tokenGutternote-Key: pk_live_...Origin: https://preview.acme.comContent-Type: application/json
{ "token": "eyJ..." }