The Versola OAuth SDK signs a user in through the system browser, keeps the session in the platform’s secure storage, refreshes it and attaches the token to API calls, so your app doesn’t assemble those pieces from parts. It exists for Android (Kotlin), iOS (Swift 6) and Flutter, which is a binding over the two native SDKs. You need a provider that meets the contract on Provider guides.
How do I install the Versola OAuth SDK?
Each platform has its own dependency and its own guide.
| Platform | Install | You import |
|---|---|---|
| Android | implementation("io.versola:oauth-android:<version>") from Maven Central | versola.oauth.OAuthClient |
| iOS | Swift Package Manager: https://github.com/versolauth/versola-sdk, product VersolaOAuth | import OAuthClient |
| Flutter | Git dependency on https://github.com/versolauth/versola-sdk.git, path flutter/versola_oauth | package:versola_oauth/versola_oauth.dart |
Write the current version of the SDK where a snippet says <version>. It is shown in the top bar of these pages and on the Releases page.
The setup steps, the redirect declaration and a working sign-in are on Android, iOS and Flutter.
How is it built?
The protocol logic is written once per native platform, in Kotlin for Android and in Swift for iOS, against a shared specification. Flutter is a binding over the two native SDKs, so no protocol logic runs in Dart. Every platform exposes the same OAuthClient, the same seven session states and the same four error categories.
| Platform | Language and floor | Package or module |
|---|---|---|
| Android | Kotlin, minSdk 26 | Package versola.oauth, artefact io.versola:oauth-android |
| iOS | Swift 6, iOS 17.4 | Product VersolaOAuth, module OAuthClient |
| Flutter | Dart 3.13, Flutter 3.47 | package:versola_oauth |
What does the SDK do without extra code?
Each item is a rule of the SDK, and none has an off switch.
- PKCE with
S256, a freshstateandnonceper request from the platform’s secure random generator, and the redirect checked (state, thenissper RFC 9207 when the provider advertises or sends it, thencode) before any network call. - ID-token validation before anything is stored: signature against the provider’s keys,
iss,audandazp,expandiatwith a bounded clock-skew tolerance (default60 s, at most 5 minutes),nonce, andauth_timeundermax_age. - Single-flight refresh: concurrent callers share one token request, and a rotated refresh token is persisted before the old one is forgotten.
- Secure storage: Keystore-wrapped files under
noBackupFilesDiron Android, the Keychain withAfterFirstUnlockThisDeviceOnlyand no iCloud sync on iOS. - The system browser only: an Auth Tab or Custom Tab on Android,
ASWebAuthenticationSessionon iOS. You can’t pass a web view in. - A token goes only to the origins you list in
protectedOrigins. A request to any other origin passes through untouched, and redirects are not followed on protected requests. - DPoP (RFC 9449) when you opt in and the provider advertises
ES256, with a hardware-backed, non-exportable key. Otherwise bearer with a logged warning, or an error if you made DPoP required. - Pushed authorization requests (RFC 9126) when the provider advertises an endpoint for them.
- No client secret: a native app can’t keep one, so the configuration has no field for it.
If a check can’t complete, the operation fails with a typed error. No check can be switched off, and none is loosened to make a provider work. See Session states and errors.
Which providers does it support?
The SDK asks four things of a provider: discovery (or explicit endpoints), the authorization code flow with PKCE S256 for a public client, an ID token signed with an asymmetric algorithm, and an iss claim equal to the discovered issuer. Everything else is discovered, and the SDK adapts to what is absent.
| Provider | Status |
|---|---|
| Keycloak 26.4 | Covered by the integration tests |
| Ory Hydra v26.2.0 | Covered by the integration tests |
The details, including which provider needs offline_access for a refresh token and which has no sign-out endpoint, are on Provider guides.
How is the SDK tested?
The table lists what the SDK’s own tests run on each platform.
| Platform | Tests |
|---|---|
| Android | JVM and Robolectric unit tests. Keystore tests on an emulator for storage and DPoP keys. An instrumented smoke test in the sample app. Integration tests against Keycloak 26.4 and Ory Hydra v26.2.0 containers |
| iOS | XCTest unit tests on the iOS simulator. Integration tests against Keycloak 26.4 and Ory Hydra v26.2.0 containers |
| Flutter | A Pigeon bridge over the native SDKs. Dart tests against a mocked channel. Unit tests of the native glue. The same integration scenarios through the bridge, as native tests in the example app |
Next steps
- Android, iOS and Flutter: install the SDK and sign in on your platform.
- Provider guides: the provider contract and what differs between vendors.
- Session states and errors: the seven states and four error categories every platform shares.
- Server errors, 429 and Retry-After: what the SDK retries when a provider answers 500, 503 or 429, and the code your app needs.