Partner sign-in with your identity
Let partners sign in to your portal with your app's own session (a short-lived JWT) or your OpenID Connect IdP, with no second password.
By default, partners sign in to your portal with a Referalli partner account. You can let them use your identity instead, so they need no second password:
Adapter | How it works |
|---|---|
| A Referalli partner account (the default) |
| Your backend mints a short-lived JWT; Referalli verifies it against your JWKS. Fits any auth platform. |
| Your own OpenID Connect IdP, used for partners |
Set this up in Settings → SSO → Partner sign-in, or with PUT /v1/org/portal-auth.
Custom: your app's session (JWT)
This fits any provider that can sign a JWT with a private key, including Clerk, Auth0, Supabase, Firebase, Cognito and Atlas JWT templates.
Publish your public keys as a JWKS over HTTPS.
Configure the adapter:
curl -X PUT https://referalli.com/v1/org/portal-auth \ -H "cookie: referalli_session=…" -H "x-org-id: org_…" \ -H "content-type: application/json" \ -d '{ "adapter": "custom", "issuer": "https://app.example.com", "jwksUrl": "https://app.example.com/.well-known/jwks.json", "loginUrl": "https://app.example.com/partners", "autoEnrollProgramId": "prog_…" }'When a signed-in user of your app opens the partner portal, mint a token and send their browser to it:
https://referalli.com/v1/portal-auth/<org id>/jwt?token=<jwt>&next=/portal
The token must meet all of these:
It is signed with an asymmetric algorithm (RS256, PS256, ES256 or EdDSA). HS256 is refused.
issis your configured issuer, andaudisreferalli:<org id>.It carries
sub(your user id),iatandexp, withexp - iat≤ 300 seconds.It carries
email(used to create the account the first time) and, optionally,name.Each token works once. Add a
jti, or every token is unique by its hash anyway.
import { SignJWT, importPKCS8 } from 'jose';
const key = await importPKCS8(process.env.PORTAL_SIGNING_KEY, 'ES256');
const token = await new SignJWT({ email: user.email, name: user.name })
.setProtectedHeader({ alg: 'ES256', kid: 'portal-1' })
.setIssuer('https://app.example.com')
.setAudience(`referalli:${ORG_ID}`)
.setSubject(user.id)
.setIssuedAt()
.setExpirationTime('2m')
.sign(key);
res.redirect(`https://referalli.com/v1/portal-auth/${ORG_ID}/jwt?token=${token}`);If you set loginUrl, the portal's sign-in page shows a button that sends partners there.
Your OpenID Connect IdP
Choose oidc and enter the issuer, client ID and client secret. Register https://referalli.com/v1/auth/sso/callback as a redirect URI. Partners start at /v1/portal-auth/<org id>/oidc/start, and the portal's sign-in page shows the button for you. This works on your verified portal domain too.
Which partner record
After a sign-in, Referalli finds the partner's record in your program:
a partner already linked to this account;
else a partner you created with
externalRefequal to the token'ssub, not yet claimed;else, with
autoEnrollProgramIdset, a new partner enrolled in that program.
Never linked by email
The identity is jwt:<issuer>:<sub> or oidc:<issuer>:<sub>. A first sign-in with an email that another Referalli partner account already uses is refused with email_taken. To connect that account, the partner signs in to it first, then follows your link with &link=1.