A comprehensive sample application demonstrating Apple's DeviceCheck API, including Device Identification and App Attest features.
This repository contains two main components:
- DeviceCheckApp: iOS test application built with SwiftUI
- DeviceCheckServer: Backend server built with Swift and Vapor
- Xcode 15.0 or later
- iOS 17.0 or later
- Swift 5.9 or later
- Swift 5.9 or later
- macOS 13.0 or later (for development)
Before running the server, you need to configure your Apple credentials:
- 
Open DeviceCheckServer/Sources/App/Constants.swift
- 
Update the following constants: static let bundleID = "com.yourcompany.DeviceCheck" // Your app's bundle ID static let teamID = "YOUR_TEAM_ID" // Your Apple Team ID static let authKeyID = "YOUR_KEY_ID" // Your Auth Key ID 
- 
For production use with Apple's DeviceCheck API: - Generate an authentication key in Apple Developer Portal
- Download the .p8key file
- Place it in the DeviceCheckServerdirectory
- Update authKeyPathin Constants.swift if needed
 
Navigate to the server directory and run:
cd DeviceCheckServer
swift runThe server will start on http://localhost:8080
Health Check:
- GET /- Server info
- GET /health- Health status
Device Identification:
- POST /api/device/query- Query device bits
- POST /api/device/update- Update device bits
- POST /api/device/validate- Validate device
App Attest:
- GET /api/attest/challenge- Get attestation challenge
- POST /api/attest/validate- Validate attestation
- POST /api/attest/assertion- Validate assertion
- Open DeviceCheckApp/DeviceCheck.xcodeprojin Xcode
- Update the bundle identifier to match your Apple Developer account
- Select a physical device (DeviceCheck requires a real device, not simulator)
- Make sure the server is running
- Build and run the app (⌘R)
Note: DeviceCheck APIs only work on physical iOS devices, not in the simulator.
If running the server on a different machine or port, update the endpoint in the iOS app:
- Open DeviceCheckApp/DeviceCheck/Constants.swift
- Update baseURLto point to your server:static let baseURL = "http://your-server-address:8080" 
The Device Identification tab demonstrates Apple's two-bit storage API:
- Query Request: Retrieves the current values of the two bits from Apple's servers
- Update Request: Updates the two bits with new values
- Device Validation: Validates the device against custom criteria
The UI displays the bits as gray rounded squares that show 0 or 1 when populated.
The App Attest tab is a placeholder for App Attest functionality. The server includes endpoints for:
- Challenge generation
- Attestation validation
- Assertion validation
Important: The current implementation runs in demo mode. The server simulates responses from Apple's DeviceCheck API without making actual calls to Apple's servers.
To integrate with Apple's real DeviceCheck API:
- Configure your Apple Developer account credentials
- Implement JWT token generation for Apple API authentication
- Update the controller methods to make actual HTTP requests to Apple's DeviceCheck endpoints
- Add proper CBOR parsing for App Attest attestation and assertion objects
- Implement cryptographic verification of App Attest signatures
- SwiftUI for the user interface
- MVVM architecture with view models
- DeviceCheck framework for device token generation
- App Attest framework for attestation (placeholder)
- Vapor web framework
- Controller-based routing
- Separate controllers for Device Identification and App Attest
- Models for request/response objects
For production deployment:
- Update server configuration in configure.swift
- Configure proper authentication with Apple's API
- Add database persistence for storing device states and public keys
- Implement proper error handling and logging
- Add rate limiting and security measures
- Use HTTPS for all communications
Run server tests:
cd DeviceCheckServer
swift testSee LICENSE.txt for details.
- DeviceCheck is only available on physical iOS devices (iOS 11.0+)
- App Attest requires iOS 14.0 or later
- The two-bit storage is device-specific and persists across app installations
- Proper implementation requires server-side verification with Apple's servers