# Native app setup
## 1. Register the app
Create a Native application in the dashboard. Public client: it gets no usable client secret, and the `client_credentials` grant is unavailable to it. Default grants: authorization_code, implicit, refresh_token, plus the device code grant for TVs/consoles.
## 2. Callback URLs
React Native (Expo) typical setup:
```
[your app scheme]://YOUR-TENANT-DOMAIN/ios/[bundle id]/callback
```
Register the exact value under Allowed Callback URLs. For logout, register the logout variant under Allowed Logout URLs.
Auth0's current guidance: prefer claimed HTTPS URIs (App Links on Android, Universal Links on iOS) over bare custom schemes where the platform supports it, because custom schemes can be intercepted by another app.
## 3. Authenticate with PKCE
Use the Auth0 React Native SDK (`react-native-auth0`), which handles PKCE for you:
```
import Auth0 from "react-native-auth0";
const auth0 = new Auth0({ domain: "YOUR-TENANT-DOMAIN", clientId: "[your value]" });
const credentials = await auth0.webAuth.authorize({ scope: "openid profile email" });
```
`credentials.accessToken` and `credentials.refreshToken` (if offline_access scope and refresh grant) are returned. Store them in the platform secure store (Keychain / Keystore), never AsyncStorage.
## 4. Refresh
Request `offline_access` scope at authorize time and enable refresh token rotation on the application. On reuse detection the whole grant is revoked, so handle that error by sending the user through login again.
## Checklist
- Native app type, never a secret embedded in the binary.
- Callback scheme registered in the OS project AND in Auth0, exact match.
- Tokens in secure storage, rotation on for refresh tokens.