Skip to main content

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_id scoped identity (a single device can carry independent identities for multiple apps).

What it does not own

  • Crypto primitives — uses Apple CryptoKit and Android KeyStore.
  • 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.
The Dart package is orchestration-only — all crypto and attestation lives in the native plugins. Calls flow through MethodChannels into Swift/Kotlin code.

Public API

The SDK exposes the same surface across all three platforms:
MethodPurpose
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.
Dart 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 multiple app_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 DeviceAuthProvider that wraps SynheartAuth.
  • 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).
The Dart-side 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)

  1. Private key MUST be hardware-backed and non-exportable.
  2. Every external request MUST be signed; there is no unsigned path.
  3. Signature covers method + path + timestamp + raw_body_bytes exactly (not parsed JSON).
  4. Server-side timestamp freshness window: 300 seconds.
  5. Nonce replay protection enforced for write endpoints (POST/PUT/PATCH/DELETE); recommended for GET.
  6. Key rotation MUST be authenticated by the current key.

auth-service endpoints used

EndpointWhen
POST /auth/v1/device/challengeStep 1 of registration.
POST /auth/v1/device/registerStep 5 of registration.
POST /auth/v1/device/rotate-keyKey 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.