synheart-auth-flutter
Source-available. This repository is open for reading, auditing, and filing issues. We do not accept pull requests — see CONTRIBUTING.md for the rationale and how to contribute via issues. Security reports go through SECURITY.md. Flutter plugin for Synheart device authentication. Provides hardware-backed ECDSA P-256 device identity and request signing via platform channels to the native iOS and Android SDKs.
Architecture: This is a thin Dart wrapper — all cryptographic operations, key storage, and registration logic run natively on-device (iOS Secure Enclave / Android Keystore).
Repository Structure
| Repository | Purpose |
|---|---|
| synheart-auth | RFC and specification |
| synheart-auth-flutter | Flutter plugin (this repository) |
| synheart-auth-kotlin | Android/Kotlin native SDK |
| synheart-auth-swift | iOS/Swift native SDK |
Installation
Add to your pubspec.yaml:
dependencies:
synheart_auth: ^0.1.0
Or:
flutter pub add synheart_auth
Native SDK requirement
The plugin depends on the native Synheart Auth SDKs to do the actual crypto. They are published separately:
- Android: synheart-auth-kotlin — until the artifact is published to Maven Central, the Android plugin pulls Kotlin sources from a sibling checkout at
../synheart-auth-kotlin/. Clone both repos side-by-side, or vendor the Kotlin sources into your app. - iOS: synheart-auth-swift — add as a Swift Package dependency in your host app.
Quick Start
import 'package:synheart_auth/synheart_auth.dart';
// 1. Configure once at app launch
await SynheartAuth.instance.configure('https://api.synheart.ai/auth');
// 2. Sign every HTTP request (registration is performed by
// the Synheart runtime; this Flutter shell only signs).
final headers = await SynheartAuth.instance.signRequest(
appId: 'com.myapp',
method: 'POST',
path: '/ingest/v1/hsi',
bodyBytes: utf8.encode(jsonBody),
);
// headers contains all 6 auth headers — add to your HTTP request
Registration runs in the runtime, not this plugin. The
registerDeviceandrotateKeymethods on this Flutter plugin currently throwUnsupportedError; device registration and key rotation are driven by the Synheart runtime via the Synheart Core SDK. Use this plugin standalone only when you need to sign requests against a runtime-registered device key.
API Reference
SynheartAuth
| Method | Description |
|---|---|
configure(baseUrl) |
Set the auth service URL. Must be called first. |
isRegistered(appId) |
Check if device is registered for this app. |
signRequest(...) |
Sign an HTTP request. Returns SignedHeaders with all 6 auth headers. |
getDeviceId(appId) |
Get the device ID, or null if not registered. |
resetDeviceIdentity(appId) |
Delete all local auth state. |
correctClockSkew(serverTimestamp) |
Correct clock offset using server timestamp. |
registerDevice(appId) |
Throws UnsupportedError — registration runs in the Synheart runtime. |
rotateKey(appId) |
Throws UnsupportedError — key rotation runs in the Synheart runtime. |
Error Handling
All errors are subclasses of SynheartAuthError:
| Error | Description |
|---|---|
NetworkError |
Network connectivity failure |
ChallengeExpired |
Registration challenge timed out |
KeyInvalidated |
Device key was invalidated (biometric change, etc.) |
ClockSkew |
Client/server clock difference exceeds threshold |
AlreadyRegistered |
Device already registered for this app |
NotRegistered |
Device not yet registered |
NotConfigured |
configure() not called |
RegistrationInProgress |
A registration call is already in flight |
ServerError |
Server returned an error response |
CryptoError |
Native crypto operation failed |
StorageError |
Persistent state read/write failed |
InvalidStateTransition |
Lifecycle violation (see DeviceAuthState) |
Integration with synheart-core
synheart-auth implements the AuthProvider interface from synheart-core-flutter:
import 'package:synheart_core/synheart_core.dart';
import 'package:synheart_auth/synheart_auth.dart';
class DeviceAuthProvider implements AuthProvider {
final String appId;
DeviceAuthProvider(this.appId);
@override
Future<Map<String, String>> signRequest({
required String method,
required String path,
required Uint8List bodyBytes,
}) async {
final signed = await SynheartAuth.instance.signRequest(
appId: appId,
method: method,
path: path,
bodyBytes: bodyBytes,
);
return signed.toMap();
}
@override
Future<bool> onAuthError({
required int statusCode,
required Map<String, String> responseHeaders,
}) async {
// Handle clock skew, key rotation, etc.
return false;
}
}
Testing
flutter test
The SDK supports test injection via SynheartAuth.forTesting(bridge:).
Not a Medical Device
This SDK is intended for wellness and research use only. It is not a medical device, is not intended to diagnose, treat, cure, or prevent any disease or condition, and has not been evaluated by the FDA or any other regulatory body.
License
Apache License 2.0 — see LICENSE.
Libraries
- synheart_auth
- Synheart device authentication SDK.