Sign in with Tanvrit
Tanvrit is a fully-conformant OpenID Connect provider. Add it like you would Google or GitHub.
1. Register your relying party
Open the developer portal, sign in with your Tanvrit admin account, and create an OIDC client. You'll get back:
client_id— your relying party identifier (e.g.com.example.demo).client_secret— only for confidential clients (server-side apps that can keep a secret). Public clients (mobile, SPA) skip this and rely on PKCE alone.redirect_uris— exact-match allowlist. Add every URL you'll redirect users back to.
2. Discover endpoints
Tanvrit publishes an OIDC discovery document — drop it into any standard OIDC library:
GET https://api.tanvrit.com/.well-known/openid-configuration
Returns:
{
"issuer": "https://api.tanvrit.com",
"authorization_endpoint": "https://api.tanvrit.com/oauth/authorize",
"token_endpoint": "https://api.tanvrit.com/oauth/token",
"userinfo_endpoint": "https://api.tanvrit.com/oauth/userinfo",
"revocation_endpoint": "https://api.tanvrit.com/oauth/revoke",
"jwks_uri": "https://api.tanvrit.com/.well-known/jwks.json",
"id_token_signing_alg_values_supported": ["RS256"],
"code_challenge_methods_supported": ["S256"],
"grant_types_supported": ["authorization_code", "refresh_token"],
"scopes_supported": ["openid", "profile", "email"]
}
3. Run the dance
Option A — use the Tanvrit SDK helper
If you're already on the Tanvrit auth SDK (KMP — JVM, Android, iOS, Web, Desktop), the easiest integration is the SignInWithTanvrit helper:
import com.tanvrit.auth.oidc.SignInWithTanvrit
// 1. Begin the dance.
val start = SignInWithTanvrit.start(
issuer = "https://api.tanvrit.com",
clientId = "com.example.demo",
redirectUri = "https://app.example.com/auth/callback",
scopes = listOf("openid", "profile", "email"),
)
// Persist start.codeVerifier and start.state across the redirect.
platformOpenBrowser(start.authorizeUrl)
// 2. After the redirect, exchange the code for tokens.
val tokens = SignInWithTanvrit.exchange(
issuer = "https://api.tanvrit.com",
code = receivedCode,
codeVerifier = persistedCodeVerifier,
clientId = "com.example.demo",
redirectUri = "https://app.example.com/auth/callback",
)
// tokens.idToken is a signed RS256 JWT carrying sub/email/name; verify against /jwks.json.
// tokens.accessToken authenticates calls to /oauth/userinfo and /api/v1/* routes.
Option B — any OIDC library
Tanvrit is fully spec-compliant. Standard libraries work without modification:
// Node.js — passport-openidconnect
new OpenIDConnectStrategy({
issuer: 'https://api.tanvrit.com',
authorizationURL: 'https://api.tanvrit.com/oauth/authorize',
tokenURL: 'https://api.tanvrit.com/oauth/token',
userInfoURL: 'https://api.tanvrit.com/oauth/userinfo',
clientID: 'com.example.demo',
clientSecret: 'sk_…', // omit for public clients
callbackURL: 'https://app.example.com/auth/callback',
scope: ['openid', 'profile', 'email'],
})
4. Verify the ID token
The id_token you receive is an RS256-signed JWT. Verify it against the public keys at /.well-known/jwks.json — every standard JOSE library handles this.
Required claims:
iss— must equalhttps://api.tanvrit.com(or your configured issuer).aud— must equal yourclient_id.exp— must not be in the past.nonce— if you sent one to/authorize, must match exactly.
PKCE is required
All clients (public and confidential) MUST use PKCE with method S256. Tanvrit rejects authorize requests without a code_challenge.
Hosted login UX
If your user isn't already signed into Tanvrit, /oauth/authorize redirects them to /oauth/login for a phone-OTP login, then bounces them back to your authorize URL with a Tanvrit session cookie. Cross-app SSO falls out naturally — once they're signed in for one Tanvrit-using app, every other consenting app gets a one-click consent.
Token lifetimes
- Authorization code: 5 minutes, single-use.
- ID token: 1 hour.
- Access token: 1 hour.
- Refresh tokens: not issued in the current MVP. Re-run
/authorizewhen your access token expires; cross-app SSO makes this a silent round-trip.
Revocation
RFC 7009 token revocation is supported:
POST https://api.tanvrit.com/oauth/revoke
Content-Type: application/x-www-form-urlencoded
token=ya29…&token_type_hint=access_token
Always returns 200 OK regardless of whether the token existed (per spec — avoids an enumeration oracle).
Next: Onboarding checklist