Add an app
Kindgi knows an app through its entry: data that says how people sign in to
it, what its permissions mean in plain words, how its tokens are withdrawn,
and how it reports access removed at the app. The app's tools sit next to
its entry.
Google, Microsoft, GitHub and LinkedIn have entries in @kindgi/connections.
An app that signs people in with standard OAuth 2.0 (the authorization code
flow, with PKCE) fits the sign-in Kindgi already has, so adding it takes
its entry and its tools in @kindgi/connections, its setup page in these
docs, and a runtime release that serves it: a runtime registers only the
apps whose entries it ships with. An app that signs in
some other way needs code in the runtime as well.
An entry
Section titled “An entry”export const acmeCrm = defineApp({ id: 'acme-crm', name: 'Acme CRM', signIn: { kind: 'oauth2', authorizeUrl: 'https://crm.acme.com/oauth/authorize', tokenUrl: 'https://crm.acme.com/oauth/token', revokeUrl: 'https://crm.acme.com/oauth/revoke', pkce: 'S256', }, owners: ['member'], permissions: { 'contacts.read': { grants: 'contacts:read', says: 'Read your contacts', changes: false }, 'notes.write': { grants: 'notes:write', says: 'Add notes as you', changes: true }, }, account: { kind: 'openid', issuers: ['https://crm.acme.com'], scopes: ['openid', 'email'] }, removal: { revoke: 'oauth2-revoke' }, rateLimits: [{ per: 'connection', units: 600, perSeconds: 60 }], setupGuide: '/guides/connections/acme-crm/',});idandname: how tools and people refer to the app.signIn: how people sign in.oauth2takes the app's authorize, token and revoke addresses, any extra parameters its authorize page needs (authorizeParams), scopes it asks for at every sign-in (scopes), and the resource the app may name its granted scopes with (scopeResource). For an app that signs people in at a directory, such as Microsoft, settenant({}, or with adefault), and{tenant}in its addresses is filled from each registration's directory. For an app that may give no refresh token, such as LinkedIn, setrefreshToken: 'optional'. A connect that brings none then works until just before its access token ends, which the app's token answer must say (expires_in), and needs reconnecting from then. A refresh token the app gives anyway is used as usual. By default, a connect that brings no refresh token, with none kept from before, is refused.owners: who can own a connection to it:'member', a person in your workspace, for their own account;'company', for the company's; or both.account: how Kindgi learns whose account it is, so lists and approvals can show it.openidreads the sign-in's ID token;profileasks a URL with the new token, and reads the account's id and a label from named fields of the answer.removal: how a token is withdrawn at the app (revoke), whether that withdraws everything the person allowed your registration (revokeIsGrantWide: Google's does), and how the app reports access removed at the app (notices), if it does.rateLimits: the app's limits for each connection: how many units it allows in how many seconds, and incosts, how many units a call takes, by its operation's name. One not listed takes 1, and a cost of 0 leaves the call out of that limit.setupGuide: the page in these docs that tells an admin how to register the app, as a path such as/guides/connections/acme-crm/.
Permissions
Section titled “Permissions”Each permission has a name your tools use, the app's own scope or
permission it grants, plain words people see when they connect and when
they approve, and whether it changes anything (changes: false is read
only). Where the app reviews what its permissions reach, such as Google's
sensitive and restricted scopes, review gives that permission's class.
Name what a tool needs, and nothing more: a tool that only reads asks only for read permissions. A person can allow less than what's asked on the app's page, and Kindgi keeps only what they allowed. A reconnect never takes away what a connection already has. If they allow at least what it has, Kindgi keeps the new grant, and a connection that needed reconnecting works again. If they allow less, the connection stays as it was. Either way, if the connection still can't do what was asked, the reconnect is declined, naming what they didn't allow.