-
You send the customer to Entire. Make an unguessable state value, tie it to the customer’s browser session (for example in a signed, HttpOnly cookie), and redirect to:
-
The customer approves. They sign in to Entire, choose a project they manage, and choose all of its repositories or a list. The page shows the permissions you registered. For
repositories:createit shows “Create repositories in this project”. Only people who manage the project can install plugins. -
Entire sends the customer back. On approval, the browser returns to your
redirect_uriwith two query parameters,receiptandstate. If the customer cancels, it returns witherror=access_deniedand the state instead. - You verify the receipt. Check every item in the list below before you trust it.
- You store the installation ID. It is the only key you need. Show the customer a confirmation page.
Verifying an install receipt
The receipt is a compact JWT signed with EdDSA. The SDK’sApp.AcceptReceipt does all of this:
- The
statequery parameter equals the state you stored for this browser session. Compare in constant time. A mismatch is a forged or replayed callback. - The header
typisentire-install-receipt+jwt, andalgisEdDSA. - The
issclaim is one of Entire’s Cores. Check this before you fetch keys, because the issuer decides where the keys come from. - The signature verifies against the key named by
kidin the issuer’s JWKS at{iss}/.well-known/jwks.json. audincludesurn:entire:plugin:{slug}, andplugin_idis your slug.exphas not passed. Receipts last five minutes, so verify them as soon as they arrive.- The
stateclaim inside the receipt equals your stored state. - You have not accepted this
jtibefore.
installation_id, project (the project’s name) and project_id.