Docs/Getting Started/Upgrading from 2.x

Upgrading from 2.x

3.0 is a major release. This page lists what changes for an app moving from 2.0.0, breaking changes first. The 2.0 docs stay at /docs/v2.0/. For the full list, see What's new in 3.0.

1. Update the version

.package(url: "https://github.com/octetproof/octet-sdk-ios", exact: "3.0.0")
implementation("com.octetproof:sdk:3.0.0")

If you verify proofs yourself with octet-verify, run 1.5.0 or later. To enforce a verdict tier on your backend with --require-verdict, run 1.6.0 or later.

2. Review the breaking changes

Usage reporting is always on

After the first proof of each UTC day, the SDK sends one device_active usage record with the next background heartbeat, so Octet can count active devices for billing. The record carries no location, no proof data, no user or account identity and no new device identifier. It never blocks or delays a proof.

OctetConfig.creditServiceUrl is only for testing. Leaving it unset, or setting it to nil / null, does not turn reporting off.

Update your app's privacy disclosures to include the daily usage record. See Data collection and Metrics and usage reporting.

A pinned claimedRegion must be an assigned ISO 3166 code

A pinned claimedRegion whose code is malformed or not assigned in ISO 3166 produces no proof, and the verdict reason is regionUnresolved. 2.0.0 signed it.

Android: a debugger refuses proofs outside a sandbox session

An attached debugger or native tracer now refuses a proof with TAMPERING, as on iOS. A sandbox session (sandboxBypassToken set) still allows one, so debugging against the sandbox keeps working.

Android: BootstrapReason.NewDevicesBlocked

BootstrapReason gains NewDevicesBlocked. A when (reason) over BootstrapReason without an else branch no longer compiles. Add the new case or an else branch:

try {
    val sdk = Octet.start(context = applicationContext, config = config)
} catch (e: LicenseError.BootstrapFailed) {
    when (e.reason) {
        // Open the server-signed link exactly as received.
        BootstrapReason.NewDevicesBlocked -> e.upgradeUrl?.let { openInBrowser(it) }
        else -> showStartupError(e)
    }
}

On iOS the new case is .newDevicesBlocked(upgradeUrl:). A switch with a default keeps compiling. See License Types.

Android: Kotlin binary compatibility

AdvancedConfig and LicenseStatus gained constructor parameters with defaults. Source that uses named arguments compiles unchanged. Code compiled against 2.0.0 that calls their constructors or copy must be recompiled.

3. Check the behavior changes

  • The first proof after Octet.start waits for startup to finish, for up to 30 s, instead of returning noFix / NO_FIX. If your app applies its own timeout to the first call, allow for this.
  • TLS pins. The built-in pins for Octet's hosts are updated. If you turned on certificate pinning with 2.0.0, upgrade to 3.0.0.

4. Adopt what is new

  • Gateway routing. Route every SDK network call through your own HTTPS host or through Octet's hosted gateway with OctetConfig.advanced.transport. See Gateway routing.
  • Assurance tier. Read LocationProof.spoofingVerdict to decide what a YES is worth. See OctetVerdict.
  • Verdict tier on verification. VerifyOptions.requireVerdict fails a proof below the tier you require. See Octet.verify.
  • PLAUSIBLE containment. Turn on OctetConfig.advanced.acceptPlausibleContainment to let disc queries answer from a PLAUSIBLE proof. See Predicates.
  • Upgrade link on new-device refusal. Handle newDevicesBlocked and open its upgradeUrl. See License Types.