# packages/auth/README.md · versecafe/solid-native

[View on GitCafe](https://git.cafe/versecafe/solid-native/blob/8ec111b04c5c361b1bd7ff86ec086a87a275264f/packages/auth/README.md)

Repository: [versecafe/solid-native](https://git.cafe/versecafe/solid-native)

Visibility: public

Requested revision: 8ec111b04c5c361b1bd7ff86ec086a87a275264f

Requested commit: 8ec111b04c5c361b1bd7ff86ec086a87a275264f

Commit: 8ec111b04c5c361b1bd7ff86ec086a87a275264f

Blob: 517829fbf984c524c22eefd5dd42028e56eda682

Size: 2869 bytes

[Immutable source](https://git.cafe/versecafe/solid-native/blob/8ec111b04c5c361b1bd7ff86ec086a87a275264f/packages/auth/README.md?format=markdown)

````
# Device verification and passkeys

```ts
import * as device from '@solid-native/auth/device';
import * as passkeys from '@solid-native/auth/passkeys';

const capabilities = await device.capabilities();
const verified = await device.verify({ reason: 'Confirm this action', policy: 'device' });

const credential = await passkeys.create(registrationOptionsFromYourServer);
if (credential) await sendRegistrationToYourServer(credential);
const assertion = await passkeys.get(authenticationOptionsFromYourServer);
if (assertion) await sendAssertionToYourServer(assertion);
```

Local `device.verify` is not server sign-in and does not unlock secure storage.
`biometric` requires a supported strong biometric; `device` permits the system's
device-credential fallback. It returns `false` for cancellation and rejects
unavailability/lockout. Capability checks do not prompt or guarantee that the next
verification succeeds. `biometricEnrolled` is `null` when the OS cannot determine it.

Passkeys use AuthenticationServices on iOS and Credential Manager on Android.
Options and responses use WebAuthn JSON with canonical, unpadded base64url byte
fields, not ArrayBuffers. The supported subset includes ES256 credentials,
user-verification preferences, allow/exclude credential IDs, and none/direct
attestation. Unknown/unsupported options reject instead of being silently dropped:
timeout, transports, resident-key overrides, extensions, and conditional mediation
are not in the initial cross-platform contract. iOS passkeys require iOS 16+;
nonempty registration exclusions require iOS 17.4+. User cancellation returns
`null`. Provider errors reject.

**Your server must generate one-time challenges and verify all responses**, including
RP ID, allowed native/web origins, challenge, user verification, signature, and
credential ownership. Sending back the provider's JSON is not itself authentication.
No private key is returned. iCloud Keychain can be the provider, but the OS/user
chooses providers; the API does not promise a particular provider or synchronization.

Production setup is app-specific:

- iOS: signed Associated Domains entitlement `webcredentials:your-domain`, matching
  `apple-app-site-association` on that domain, and Face ID usage description.
- Android: matching signed package/certificate entries and credential-sharing
  relation in the domain's Digital Asset Links, installed Credential Manager
  provider, biometric permission, and a foreground FragmentActivity.

The sample host compiles/registers the modules but has no claimed relying-party
domain or production signing. End-to-end creation/sign-in and iCloud sync are
therefore not established by local tests. A third-party GitHub client cannot create
native passkeys for `github.com` without GitHub's domain authorization; use its
documented OAuth flow through `@solid-native/web` instead.

````
