Skip to content

Getting started

  • Flutter SDK 3.9.2 or higher
  • Dart SDK 3.9.2 or higher
  • Minimum SDK: API Level 26 (Android 8.0)
  • Target SDK: API Level 35 recommended
  • Java: Java 8+ or Kotlin support
  • iOS Version: iOS 15.0 or later
  • Xcode Version: Xcode 15.0 or later
  1. Register both apps. A Flutter project is two apps on the portal, one for Android and one for iOS, each with its own API key. On portal.byterialab.com, Apps → Register App: once for Android (your applicationId), once for iOS (your bundle identifier), and generate an API key for each. See How to Register Your App.
  2. Export your registry key. On every path the SDK’s native binaries (Alphyn.xcframework for iOS, the com.byterialab:alphyn-sdk AAR for Android) resolve from the Alphyn package registry at build time, so set your app API key in the build environment (and never commit it); see SDK Registry Access:
Terminal window
export ALPHYN_REGISTRY_KEY=<YOUR_APP_API_KEY>

The Alphyn Flutter SDK is a federated plugin of four packages (alphyn_sdk, alphyn_sdk_android, alphyn_sdk_ios, alphyn_sdk_platform_interface), served from the Alphyn package registry rather than pub.dev.

One command adds the plugin, wires both native layers, and installs the build-registration hooks:

Terminal window
alphyn-cli integrate --android-api-key <ANDROID_APP_KEY> --ios-api-key <IOS_APP_KEY>
flutter pub get
alphyn-cli doctor

If you use the CLI, the Platform Setup and Register every build steps below are done for you; read on to see or customize them.

Option B: from the registry, by hand (no CLI)

Section titled “Option B: from the registry, by hand (no CLI)”

Add the plugin as a hosted pub dependency, nothing to download. Register the pub token (it reads your key from ALPHYN_REGISTRY_KEY, so no secret is written to disk), add the dependency, and fetch:

Terminal window
dart pub token add https://packages.byterialab.com/pub --env-var ALPHYN_REGISTRY_KEY
pubspec.yaml
dependencies:
alphyn_sdk:
hosted: https://packages.byterialab.com/pub
version: <version>

To find the latest <version>, ask the registry GET https://packages.byterialab.com/pub/api/packages/alphyn_sdk and read .latest.version. Then fetch:

Terminal window
flutter pub get

On this manual path the Platform Setup, Initialization, and Register every build steps below are required (the CLI does them for you).

The SDK’s AAR declares every permission it needs and Android’s manifest merger adds them to your app automatically. You do not need to copy them into android/app/src/main/AndroidManifest.xml. For transparency, the merged set is:

<!-- Internet access for security checks and threat detection -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Network state access to determine connectivity -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Certificate access for keystore operations -->
<uses-permission android:name="com.android.keystore.CERTIFICATE_ACCESS" />
<!-- Credential usage for secure operations -->
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<!-- Device identity used by the attestation payload -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- Overlay protection (Android 12+) -->
<uses-permission android:name="android.permission.HIDE_OVERLAY_WINDOWS" />

You write none of this; it is the result after the merger runs.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- Required Permissions -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.android.keystore.CERTIFICATE_ACCESS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.HIDE_OVERLAY_WINDOWS" />
<application
android:label="your_app_name"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<!-- Your application components -->
</application>
</manifest>

Permission Details:

  • INTERNET: Required for communicating with Alphyn security services
  • ACCESS_NETWORK_STATE: Needed to check network connectivity before performing security checks
  • CERTIFICATE_ACCESS: Used for keystore certificate operations during security validation
  • USE_CREDENTIALS: Required for secure credential management
  • READ_PHONE_STATE: Device identity used by the attestation payload
  • HIDE_OVERLAY_WINDOWS: Overlay protection on Android 12 and later

Ensure your app uses the required minimum SDK and register the authenticated Alphyn registry in your Android Gradle repositories.

Minimum SDK

  • minSdkVersion must be 26 or higher

Registry Maven (AAR) The Android native (com.byterialab:alphyn-sdk) is served from the Alphyn package registry. Add the authenticated registry to your Android build.gradle / build.gradle.kts; alphyn-cli integrate writes this for you:

Groovy:

allprojects {
repositories {
google()
mavenCentral()
maven {
url System.getenv('ALPHYN_REGISTRY_URL') ?: 'https://packages.byterialab.com/maven'
credentials {
username = 'x'
password = System.getenv('ALPHYN_REGISTRY_KEY') ?: ''
}
}
}
}

Kotlin DSL:

allprojects {
repositories {
google()
mavenCentral()
maven {
url = uri(System.getenv("ALPHYN_REGISTRY_URL") ?: "https://packages.byterialab.com/maven")
credentials {
username = "x"
password = System.getenv("ALPHYN_REGISTRY_KEY") ?: ""
}
}
}
}

The build reads your app API key from ALPHYN_REGISTRY_KEY; see SDK Registry Access.

The Alphyn AAR ships consumer ProGuard rules that R8 applies to your app automatically, so no manual rules are required for a standard build. If your build pipeline strips consumer rules, add them manually:

Step 1: Create or edit android/app/proguard-rules.pro file:

# Alphyn SDK - Byteria
# Keep all Alphyn SDK classes and methods
-keep class com.byteria.sdk.** { *; }
# Keep classes annotated with @Keep
-keep @androidx.annotation.Keep class * { *; }
# Keep methods annotated with @Keep
-keepclassmembers class * {
@androidx.annotation.Keep <methods>;
}

Step 2: Reference the ProGuard rules in your android/app/build.gradle (or build.gradle.kts):

For build.gradle (Groovy):

android {
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}

For build.gradle.kts (Kotlin DSL):

android {
buildTypes {
getByName("release") {
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
}

Why These Rules Are Needed:

  • The SDK uses reflection and dynamic class loading for security features

  • ProGuard/R8 may remove or rename SDK classes, breaking functionality

  • These rules ensure the SDK’s security mechanisms work correctly in release builds

  • Without these rules, you may experience crashes or unexpected behavior in production

  • Always test your release build thoroughly after adding ProGuard rules

  • Manual rules are only needed if your build pipeline strips the AAR’s consumer rules

  • The SDK’s security features depend on proper class and method preservation

The iOS implementation requires two configurations in your ios/Runner/Info.plist file:

Ensure your ios/Podfile sets the minimum iOS version:

# Uncomment this line to define a global platform for your project
platform :ios, '15.0'

The SDK requires background modes to perform security checks. Add the following to your Info.plist:

Option A: Edit Info.plist directly

Add the following inside the main <dict> section:

<!-- Background Task Scheduler Permitted Identifiers -->
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>com.byterialab.backgroundcheck</string>
</array>
<!-- Background Modes -->
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
</array>

Note: You can also configure this through Xcode if preferred, but editing Info.plist directly is simpler and ensures all required keys are properly set, especially the BGTaskSchedulerPermittedIdentifiers which is critical for background task registration.

Add the following configuration to allow network access for security checks:

<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>alphyn-attestation-api.byterialab.com</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>

3. URL Scheme Query Permissions (Required)

Section titled “3. URL Scheme Query Permissions (Required)”

The SDK requires permission to query for jailbreak-related URL schemes to detect jailbreak apps on the device. Add the following to your Info.plist:

<!-- URL Scheme Query Permissions -->
<key>LSApplicationQueriesSchemes</key>
<array>
<string>cydia</string>
<string>sileo</string>
<string>zbra</string>
<string>filza</string>
<string>undecimus</string>
<string>installer</string>
<string>taig</string>
<string>dopamine</string>
<string>trollstore</string>
<string>trollstorehelper</string>
</array>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- Existing keys... -->
<!-- Background Task Scheduler Identifiers -->
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>com.byterialab.backgroundcheck</string>
</array>
<!-- Background Modes -->
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
</array>
<!-- Network Security Configuration -->
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>alphyn-attestation-api.byterialab.com</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
</dict>
</dict>
</dict>
<!-- URL Scheme Query Permissions -->
<key>LSApplicationQueriesSchemes</key>
<array>
<string>cydia</string>
<string>sileo</string>
<string>zbra</string>
<string>filza</string>
<string>undecimus</string>
<string>installer</string>
<string>taig</string>
<string>dopamine</string>
<string>trollstore</string>
<string>trollstorehelper</string>
</array>
</dict>
</plist>

These configurations allow the SDK to:

  • Register and schedule background tasks using BGTaskScheduler (via BGTaskSchedulerPermittedIdentifiers)
  • Perform background security checks and monitoring using BGAppRefreshTask (via UIBackgroundModes with fetch)
  • Communicate with the Alphyn security services for threat detection and device verification (via NSAppTransportSecurity)
  • Check for jailbreak apps on the device (via LSApplicationQueriesSchemes)

Important Notes for Info.plist:

  • The BGTaskSchedulerPermittedIdentifiers key is required and must include com.byterialab.backgroundcheck.
  • The fetch background mode is required for BGAppRefreshTask to allow background security checks.
  • The LSApplicationQueriesSchemes list is what the jailbreak detector probes. canOpenURL returns false for any scheme the host app has not declared, so a shortened list silently narrows detection and produces no error.
  • The NSAppTransportSecurity exception is required; the SDK cannot reach the backend without it. The attestation host presents a certificate from a private CA (CN=Byteria Root CA) that the system trust store does not carry, so without the exception the connection is refused inside ATS with TLS error -9802 and the SDK’s own certificate check is never reached, so init fails at launch. NSExceptionAllowsInsecureHTTPLoads is the key that carries the connection past ATS; the SDK then validates the chain itself against a root anchor bundled in Alphyn.framework, and that pinning stays the effective transport control. The exception is scoped to that one domain and weakens nothing else.
  • After adding these configurations, clean and rebuild your project. If you encounter registration errors related to background tasks, delete the app from your device/simulator and reinstall it.

4. AppDelegate Background Task Registration (Required)

Section titled “4. AppDelegate Background Task Registration (Required)”

You must call AlphynSDK.register() synchronously in your AppDelegate.swift before Flutter starts. This registers background tasks with the iOS system.

Add the following to your AppDelegate.swift:

import Alphyn
import Flutter
import UIKit
@main
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// CRITICAL: Register background tasks BEFORE Flutter starts
do {
try AlphynSDK.register()
} catch {
print("AlphynSDK.register() failed: \(error.localizedDescription)")
}
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}

Important: AlphynSDK.register() must be called synchronously in didFinishLaunchingWithOptions before GeneratedPluginRegistrant.register(). Background task registration cannot be deferred to Dart code because iOS requires it during app launch.

You should initialize the SDK in your Dart code, preferably in your main() function before running the app.

import 'package:alphyn_sdk/alphyn_sdk.dart';
import 'package:flutter/foundation.dart'; // kDebugMode
import 'package:flutter/material.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Initialize the SDK. The debug hashes are development-only and each
// platform has its own, because a Flutter project registers as two
// separate Alphyn apps.
await AlphynSdk.initialize(
interval: 45.0,
androidDebugHash: kDebugMode ? 'YOUR_ANDROID_DEBUG_HASH' : null,
iosDebugHash: kDebugMode ? 'YOUR_IOS_DEBUG_HASH' : null,
);
runApp(const MyApp());
}

Parameters:

  • interval: Interval in seconds between security scans (e.g., 45.0 for 45 seconds). Defaults to 45.0.
  • androidDebugHash: optional development-only hash from the Alphyn Portal, applied only when running on Android
  • iosDebugHash: the same, applied only when running on iOS. Each platform is a separate Alphyn app with its own hashes. Do not ship either in production.

Alphyn is fail-closed: a build whose hash was never registered terminates at launch, with no build-time error. On the CLI path the hooks below are installed for you; on the manual path you set them up yourself.

  • Android. The app hash is the SHA-256 of your signing certificate, so it is stable across builds and you register it once per signing key. Run the SDK-provided post-action-android.sh <apk-path> <YOUR_ANDROID_API_KEY> after each signed build. For Play App Signing, also enroll Google’s re-signing certificate once; see Play App Signing.
  • iOS. A build registers at archive time through an Xcode archive post-action; set it up once: Register via Xcode post-action. Debug and simulator builds never register, which is why development needs the pinned iosDebugHash above.