appAttest
Docs

Other platforms

AppAttest ships official bridges for React Native, Capacitor, and Flutter, plus a CocoaPods option for native Swift. They wrap the same SDK and expose the same shape — start, waitForReady, read a secret, observe state — idiomatic to each runtime.

The account, secret, Apple Developer Console, and entitlements steps are identical across every platform. Do steps 1–4 of the Quickstart first; this page only covers the per-platform install and read delta.

App Attest is an Apple capability, so these bridges gate and deliver secrets on the iOS side of your cross-platform app. There is no Android or web attestation path — on those targets the SDK is unavailable and your code should fall back accordingly.

Secrets are write-only on every platform: you set or overwrite a value in the dashboard, but the dashboard can never show a stored value back.

React Native

npm install @appattest/react-native
cd ios && pod install
import { AppAttest, useSecret } from '@appattest/react-native';

// Once, at app launch:
AppAttest.start();

// In a component — re-renders when secrets land:
function ApiView() {
  const openaiKey = useSecret('OPENAI_API_KEY');
  return openaiKey ? <Ready /> : <Loading />;
}

// Outside components:
await AppAttest.waitForReady();
const key = await AppAttest.getSecret('OPENAI_API_KEY'); // string | null
const all = await AppAttest.getAllSecrets();             // Record<string, string>

Observe lifecycle state with the useAppAttestState() hook.

Capacitor

npm install @appattest/capacitor
npx cap sync
import { AppAttest } from '@appattest/capacitor';

// Once, at app launch:
AppAttest.start();

// Anywhere:
await AppAttest.waitForReady();
const key = await AppAttest.getSecret('OPENAI_API_KEY'); // string | null
const all = await AppAttest.getAllSecrets();

Observe state with await AppAttest.getState() and AppAttest.addStateListener(...).

Flutter

# pubspec.yaml
dependencies:
  appattest_flutter: ^0.1.0
flutter pub get
cd ios && pod install
import 'package:appattest_flutter/appattest_flutter.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  AppAttest.start();
  runApp(const MyApp());
}

// Anywhere:
await AppAttest.waitForReady();
final key = await AppAttest.secret('OPENAI_API_KEY'); // String?
final all = await AppAttest.allSecrets();             // Map<String, String>

Observe state with AppAttest.stateStream.

Swift via CocoaPods

If you use CocoaPods instead of Swift Package Manager:

pod 'AppAttest'

Then use the SDK exactly as in the Quickstart. The Objective-C facade is available as pod 'AppAttestObjC' for bridge writers and Objective-C consumers; native Swift apps should depend on AppAttest. The bridges pull the iOS pods in automatically — you don’t add them yourself.

Testing without a device

App Attest needs real hardware. For simulator builds, previews, and tests, enable local stubs (one debug mode, stripped from release builds):

  • React Native / Capacitor: AppAttest.setDebugMode('local', { stubs: { OPENAI_API_KEY: 'sk-test-stub' } })
  • Flutter: AppAttest.setDebugMode(DebugMode.local, { 'OPENAI_API_KEY': 'sk-test-stub' })

Errors

Every bridge surfaces the same stable error codes: subscription_required, credits_required, attestation_rejected, service_unavailable, network, debug_mode_release_blocked, invalid_argument. Gate your UI on the observed state rather than catching on the read path.

What’s next

For AI agents — this page is available as markdown:
View markdown