Octet.start(...)
The single bring-up call. Verifies the license key locally, activates against the Octet backend if needed, brings up the proof pipeline, and returns a fully-usable OctetSdk handle.
Signature
public enum Octet {
public static let sdkVersion: String // "1.1.0"
public static func start(
config: OctetConfig,
startPosition: Position? = nil
) async throws -> OctetSdk
}
object Octet {
const val SDK_VERSION: String // "1.1.0"
suspend fun start(
context: Context,
config: OctetConfig,
startPosition: Position? = null,
): OctetSdk
}
startPosition is an optional hint used internally during pipeline bring-up. Most integrators omit it.
What it does, in order
- Loads (or generates) a per-install UUID from secure storage (Keychain on iOS,
EncryptedSharedPreferenceson Android). - Auto-detects the app id from the bundle (
Bundle.main.bundleIdentifier/context.packageName). - Verifies the license key's PASETO signature locally against the SDK's embedded public keys.
- Validates the cached activation token if present. Otherwise calls
POST /v1/activateto acquire one. - Brings up the internal proof pipeline.
- Attaches the resulting
LicenseStatusto the returnedOctetSdk.
OctetConfig
public struct OctetConfig: Sendable {
public let licenseKey: String
public var proofUploadUrl: String? // opt-in proof upload; nil disables (default)
public var telemetryEnabled: Bool // aggregate usage counters; default true
public var advanced: AdvancedConfig
public init(
licenseKey: String,
proofUploadUrl: String? = nil,
telemetryEnabled: Bool = true,
advanced: AdvancedConfig = AdvancedConfig()
)
public static let defaultActivationServerUrl: String // "https://api.octetproof.com"
}
data class OctetConfig(
val licenseKey: String,
val proofUploadUrl: String? = null, // opt-in proof upload; null disables (default)
val telemetryEnabled: Boolean = true, // aggregate usage counters; default true
val advanced: AdvancedConfig = AdvancedConfig(),
) {
companion object {
const val DEFAULT_ACTIVATION_SERVER_URL: String // "https://api.octetproof.com"
}
}
licenseKey is the only required field. It is a PASETO v4.public token in the wire form octet_live_v4.public.… (prod) or octet_test_… (staging).
AdvancedConfig
Still small. Battery profile, sensor tuning, and ML knobs stay internal. What is public: the activation server, log level, device-attestation cadence, and the per-platform attestation knobs.
public struct AdvancedConfig: Sendable {
public var activationServerUrl: String // default: production
public var logLevel: LogLevel // default: .info
public var enableCertPinning: Bool // default: false
public var attestationCadence: AttestationCadence // default: .periodic(interval: 300)
public init(
activationServerUrl: String = OctetConfig.defaultActivationServerUrl,
logLevel: LogLevel = .info,
enableCertPinning: Bool = false,
attestationCadence: AttestationCadence = .periodic(interval: 300)
)
}
public enum LogLevel { case verbose, debug, info, warn, error }
public enum AttestationCadence: Sendable {
case perSession
case periodic(interval: TimeInterval) // default; 5 minutes
case perProof
}
data class AdvancedConfig(
val activationServerUrl: String = OctetConfig.DEFAULT_ACTIVATION_SERVER_URL,
val logLevel: LogLevel = LogLevel.INFO,
// Google Cloud project NUMBER for Play Integrity; null uses the Play-Console-linked project.
val playIntegrityCloudProjectNumber: Long? = null,
val attestationCadence: AttestationCadence = AttestationCadence.Periodic(intervalSeconds = 300),
)
enum class LogLevel { VERBOSE, DEBUG, INFO, WARN, ERROR }
sealed class AttestationCadence {
object PerSession : AttestationCadence()
data class Periodic(val intervalSeconds: Int) : AttestationCadence() // default; 5 minutes
object PerProof : AttestationCadence()
}
Override activationServerUrl only when pointing at a staging or local backend.
attestationCadence and the Android playIntegrityCloudProjectNumber are covered
in Device Attestation. enableCertPinning opts
into the bundled certificate pin set for api.octetproof.com. The Play Integrity
cloud-project knob is Android-only: App Attest on iOS has no equivalent.
Example
let config = OctetConfig(
licenseKey: "octet_live_v4.public.…"
// advanced left to defaults
)
let sdk = try await Octet.start(config: config)
lifecycleScope.launch {
val sdk = Octet.start(
context = applicationContext,
config = OctetConfig(licenseKey = "octet_live_v4.public.…")
)
}
Failure modes
Octet.start(...) throws a typed LicenseError for every license-related failure. Other failures propagate as their native error types. The SDK does not throw a raw Error / Exception for license reasons.
LicenseError case |
Meaning |
|---|---|
MalformedKey |
The key isn't a valid signed token. |
NoActivation |
No cached activation, offline. |
Expired |
License past day 105, OR cached activation past 7-day offline grace. |
ActivationWindowClosed |
Fresh device trying to activate after day 90. |
Revoked |
Admin revoke. |
Network(message) / Network(cause) |
Transient network failure during activation. |
ServerRejected(httpStatus, reason) |
Backend rejected for another reason (e.g., app_blocked). |
See also
- License & Activation for the timeline model and activation flow.
OctetSdkfor whatstartreturns.- License Types for the full
LicenseErrorreference.