Documentation Index
Fetch the complete documentation index at: https://docs.synheart.ai/llms.txt
Use this file to discover all available pages before exploring further.
synheart-auth is the mobile-side device-identity SDK. It generates an ECDSA P-256 key pair in hardware (Secure Enclave on iOS, Android Keystore on Android), registers the device with the Synheart auth service, and signs every outbound request from the cloud paths in your app.
The SDK is normatively defined by RFC-AUTH-MOBILE-0001. Mode A (hardware ECDSA) only — backend HMAC API-key flow is out of scope.
If you’re using Synheart Core, you get
synheart-auth automatically — Core wires its crypto callbacks into the runtime during Synheart.initialize. You only deal with this SDK directly if you’re integrating without Core.What it owns
- Key pair generation in hardware (non-exportable).
- Device registration via challenge + attestation (App Attest on iOS, Play Integrity on Android).
- Request signing per RFC-AUTH-MOBILE-0001 §8.
- Key invalidation detection and recovery.
- Key rotation.
- Clock-skew correction.
- Per-
app_idscoped identity (a single device can carry independent identities for multiple apps).
What it does not own
- Crypto primitives — uses Apple
CryptoKitand AndroidKeyStore. - Attestation providers — uses App Attest / Play Integrity native APIs.
- Capability and consent tokens — those live in
synheart-core/ runtime. - Cloud HTTP transport beyond the auth-service endpoints. The SDK returns signed-headers; consumers attach them to their own requests.
Packages
Flutter / Dart
synheart_auth 0.1.0 — MethodChannel wrapper around the native plugins. No crypto in Dart.iOS / Swift
SynheartAuth (SwiftPM + CocoaPods). Crypto runs in Secure Enclave.Android / Kotlin
ai.synheart:synheart-auth. Crypto runs in Android Keystore.MethodChannels into Swift/Kotlin code.
Public API
The SDK exposes the same surface across all three platforms:| Method | Purpose |
|---|---|
configure(baseUrl) | Sets the auth-service base URL. Must be called before any other method. |
isRegistered(appId) | Returns whether a device identity exists locally for this app. |
registerDevice(appId) | One-time registration. Generates key, attests, calls /auth/v1/device/register. |
signRequest(appId, method, path, bodyBytes?) | Returns six signed headers (see Signing). |
getDeviceId(appId) | Returns the server-issued device_id, or null when unregistered. |
rotateKey(appId) | Rotates the signing key while preserving device_id. |
resetDeviceIdentity(appId) | Destructive. Wipes local key + device_id; forces full re-registration. |
correctClockSkew(serverTimestamp) | Stores the offset learned from a server-supplied timestamp on a CLOCK_SKEW error. |
SynheartAuth.instance is a singleton; Kotlin uses class SynheartAuth constructed once per app context; Swift uses class SynheartAuth with the same shape. All operations that touch the network or hardware return async/Future/suspend per platform.
Multi-app-id model
A device may hold independent key pairs for multipleapp_ids. Storage, registration, and signing are scoped per app_id; key alias is synheart_auth_{app_id} (deterministic). This lets a single device run several Synheart-backed apps without identity collision.
How Synheart Core consumes it
synheart-core does not call SynheartAuth HTTP-shaped methods directly. Per the runtime-only networking policy:
- The Core SDK constructs a
DeviceAuthProviderthat wrapsSynheartAuth. - The Core SDK registers the auth provider’s crypto callbacks (
generate_key,sign_bytes,get_attestation,key_exists,delete_key) with the Synheart runtime. - The runtime owns the network calls to the auth service (challenge → attestation → register).
registerDevice / rotateKey are flagged in source as “performed by the runtime” — they exist for direct consumers (CLIs, custom integrations) that don’t use Core.
Security invariants (from RFC §6)
- Private key MUST be hardware-backed and non-exportable.
- Every external request MUST be signed; there is no unsigned path.
- Signature covers
method + path + timestamp + raw_body_bytesexactly (not parsed JSON). - Server-side timestamp freshness window: 300 seconds.
- Nonce replay protection enforced for write endpoints (POST/PUT/PATCH/DELETE); recommended for GET.
- Key rotation MUST be authenticated by the current key.
auth-service endpoints used
| Endpoint | When |
|---|---|
POST /auth/v1/device/challenge | Step 1 of registration. |
POST /auth/v1/device/register | Step 5 of registration. |
POST /auth/v1/device/rotate-key | Key rotation flow. |
Reading order
Registration
Challenge → keygen → attestation → register.
Request Signing
Message construction, the six headers, server-side verification.
State Machine
unregistered → challengeReceived → keyReady → registering → registered.Errors
Error taxonomy, key invalidation, clock skew recovery.