Skip to main content

Auth & Device Registration

Authentication in the boilerplate has two distinct layers that work in sequence:

  1. Auth0 — proves who the user is (email address, identity)
  2. Device registration — proves this specific device is authorized to make MPC requests

Both layers are required before any key generation or signing can happen.

The full flow

Sign-in with Auth0

The sign-in flow lives in src/queries/api/auth/useSignIn.ts. It uses the react-native-auth0 SDK to open the Auth0 Universal Login, gets credentials, registers the user with auth-svc, and stores the user's identity in the auth store.

// src/queries/api/auth/useSignIn.ts
const { auth0Audience } = useServiceConfigStore();
const { authorize, clearCredentials } = useAuth0();

await authorize({
scope: `openid profile email offline_access ${auth0Config.scope}`,
additionalParameters: { prompt: 'login' },
audience: auth0Audience, // audience of the active server preset
});

// Retrieve the access token from the credentials manager
const cred = await auth0Client.credentialsManager.getCredentials();

// Register the user with auth-svc
await APIClient.registerUser({ access_token: cred.accessToken });

// Get user info and save to store
const user = await auth0Client.auth.userInfo({ token: cred.accessToken, tokenType: TokenType.bearer });
signIn({ email: user.email, id: user.sub });

The offline_access scope enables refresh tokens, so returning users are silently re-authenticated on app startup without seeing the login screen again. This is handled in src/provider/AuthProvider.tsx.

When the active deployment has policy evaluation enabled, the sign-in screen uses useSignInWithPolicy (src/queries/api/auth/useSignInWithPolicy.ts) instead. The flow is identical, except the user is also registered with the policy service. See Policy Engine for the rest of what that flag changes.

Device registration

Every device that wants to perform MPC operations must be registered with auth-svc. The device is identified by an ECDSA public key stored in the platform's secure hardware:

  • iOS — iOS Secure Enclave (Keychain)
  • Android — Android Keystore with StrongBox

The device registration challenge-response is handled in src/libs/silent-shard/secure-key.ts and the registration API calls:

// src/libs/silent-shard/secure-key.ts

// 1. Create the device keypair in TEE (no-op if it already exists)
export const initializeSecureKey = () => {
SecureKey.createIfNotExistSecureKey(secureKeyAlias);
};

// 2. MessageSigner — signs all messages from silent-shard-sdk to the cloud node
// The cloud node verifies device identity using this key's public key
export const getMessageSigner = () => {
return SecureKey.createMessageSigner(secureKeyAlias);
};

Learn more about the MessageSigner — how the TEE key is used for transport-level authentication between the SDK and the cloud node.

→ Message Signer docs

// Device registration (src/queries/api/auth/useRegisterDevice.ts)

// 1. Get the device ID (ECDSA public key hex)
const secureKey = getSecureKey();

// 2. Fetch a challenge from auth-svc
const { challenge } = await APIClient.getDeviceChallenge(secureKey.publicKeyHex);

// 3. Sign the challenge with the TEE private key
const signature = secureKey.sign(Buffer.from(JSON.stringify({ challenge }), 'utf-8').toString('base64'));

// 4. Register the device — auth-svc stores the device_id and links it to the user
await APIClient.registerDevice({ device_id: secureKey.publicKeyHex, signature });

If auth-svc reports the device key already belongs to another user, the hook generates a fresh device key and tries again — at most a few attempts, then it gives up with an error.

The device private key never leaves the secure hardware. Only the signature is transmitted. Even if network traffic is intercepted, it is useless without the device.

Silent sign-in on startup

When the app relaunches, src/provider/AuthProvider.tsx silently checks for existing credentials. If a valid (or refreshable) token exists, the user is restored without seeing the login screen. If not, they are redirected to sign-in.