tei_shield_flutter 0.2.0 copy "tei_shield_flutter: ^0.2.0" to clipboard
tei_shield_flutter: ^0.2.0 copied to clipboard

Configurable TEI Shield native Android and iOS assessments for Flutter.

tei_shield_flutter #

The 0.2.0 source is unreleased and adds VPN detection/observation. Build and stage native SDK 0.2.0 before using it; Android local builds can set teiShieldSdkAar. See VPN integration.

TEI Shield provides local device risk signals for Flutter on Android and iOS. Configure checks in Dart, run one-time assessments, or subscribe to a client that reassesses when the app returns to the foreground. Your app decides how to handle the results.

Android resolves the native SDK io.github.tranvanloccntt123:shield:0.1.0 from Maven Central. The package includes the iOS XCFramework, which is linked through CocoaPods. The Flutter package version is independent of the native SDK version.

Requirements #

  • Flutter 3.27+ and Dart 3.6+ (below Dart 4).
  • Android API 26+ and Java 17 for Android builds. The plugin compiles against Android SDK 35.
  • iOS deployment target 15.0+.
  • An Android or iOS native build. Web and desktop platforms are not supported.

Installation #

flutter pub add tei_shield_flutter

Or add the dependency to pubspec.yaml:

dependencies:
  tei_shield_flutter: ^0.1.10

Set the Android host application's minSdk to at least 26, and ensure its dependency repositories include google() and mavenCentral(). Set the iOS deployment target to at least 15.0 in the Podfile and Runner target. Run flutter pub get and rebuild the app after adding the plugin.

Quick start #

Run one check or select several checks without creating a lifecycle observer:

import 'package:flutter/widgets.dart';
import 'package:tei_shield_flutter/tei_shield_flutter.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  final signal = await TeiShield.check(ShieldCheck.emulator);
  print('${signal.code}: ${signal.status.name} (${signal.confidence})');

  final result = await TeiShield.assess(AssessmentOptions(
    checks: [ShieldCheck.emulator, ShieldCheck.sdkTextIntegrity],
  ));
  print('Completed ${result.signals.length} checks in ${result.durationMs} ms');
  // Start your app with runApp(...) here.
}

Client and lifecycle #

Keep the client and subscription in your app or widget state:

final client = await TeiShieldClient.initialize(
  options: AssessmentOptions(
    checks: [ShieldCheck.emulator, ShieldCheck.sdkTextIntegrity],
  ),
  runPolicy: const ShieldRunPolicy(
    assessOnInitialize: true,
    reassessOnForeground: true,
  ),
);

// The broadcast stream does not replay the initialization result.
final initialAssessment = client.lastAssessment;
final subscription = client.assessments.listen(
  (result) => print(result.signals),
  onError: (Object error) => print('Automatic assessment failed: $error'),
);

try {
  await client.assess();
  await client.check(ShieldCheck.emulator);
  // This override replaces the selection for this call only.
  await client.assess(AssessmentOptions(checks: [ShieldCheck.debugger]));
} catch (error) {
  print('Manual assessment failed: $error');
}

// Run during cleanup, after you finish using the client.
await subscription.cancel();
await client.close();

Both run policy flags default to false. An empty selection runs no detectors, including TeiShield.assess() with no arguments. Calls on a client are serialized. Overrides replace all options for one call without changing the client's saved options. Handle initialization and manual call failures through their returned futures; foreground assessment failures are emitted as stream errors.

lastAssessment is null until a successful assessment. Closing the client removes its lifecycle observer and closes the stream. Native work already running may still finish, but its result is discarded. Foreground observation is not a background service. See the widget example for initialization and disposal.

Checks and Android app identity #

ShieldCheck defines these checks:

debugger, injectedImages, systemWritableMount, privilegedFiles,
libcPointer, sdkTextIntegrity, toolPort, appIdentity, emulator,
missingMotionSensors, batteryUnavailable, storeAttestation

Support varies by platform and build. To select every check, pass checks: ShieldCheck.values; Android also requires app identity configuration because this selection includes ShieldCheck.appIdentity.

When selecting appIdentity on Android, supply your application's package name and an allowlist of signing certificate SHA-256 digests:

// Replace these values with your application's identity.
final identity = AppIdentityConfig(
  expectedPackage: 'com.example.app',
  signingCertificateSha256: [
    '<your-lowercase-64-character-sha256-digest>',
  ],
);
final signal = await TeiShield.check(
  ShieldCheck.appIdentity,
  appIdentity: identity,
);

Each digest must contain exactly 64 lowercase hexadecimal characters, without colons. For multiple checks or a client, pass the same identity to AssessmentOptions(appIdentity: identity, checks: ...).

Reading results #

TeiShieldAssessment contains schemaVersion, signals, and durationMs. Each TeiShieldSignal contains code, status, and confidence. Use signal.status.name for the status text.

Status Meaning
detected The check observed the corresponding risk signal.
notDetected The check did not observe that signal during this assessment.
unsupported The check is unavailable in the current environment or build.
error The check could not complete successfully.

notDetected is not proof that a device is safe. Preserve unsupported and error as distinct outcomes when applying your app's policy. These local signals do not provide remote attestation.

Development from this repository #

Published packages include the iOS framework. For a source checkout, first build native artifacts using scripts/package_android.sh and scripts/package_ios.sh, or supply existing artifacts to the preparation script. Run from the repository root:

python3 scripts/prepare_framework_packages.py
cd packages/tei_shield_flutter
flutter pub get
flutter analyze
flutter test

The preparation script validates the Android AAR/POM and stages the iOS XCFramework; it does not download or compile native artifacts. Android continues to resolve the SDK from Maven Central.

See the example setup and the integration guide.

0
likes
140
points
365
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Configurable TEI Shield native Android and iOS assessments for Flutter.

Homepage
Repository (GitHub)
View/report issues

Topics

#security #integrity #jailbreak-detection #root-detection

License

MIT (license)

Dependencies

flutter

More

Packages that depend on tei_shield_flutter

Packages that implement tei_shield_flutter