firebase / firebase/flutterfire
[firebase_app_check]: AppAttestProvider is selected, but generated App Check token appears to use DeviceCheck
- Dominant language
- Dart
- Stars
- 9.3k
- Forks
- 4.1k
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 53
Description
### Is there an existing issue for this?
- [x] I have searched the existing issues.
### Which plugins are affected?
App Check
### Which platforms are affected?
iOS
### Description
I am trying to use Apple App Attest exclusively as the Firebase App Check provider on a physical iOS device.
I explicitly configure the provider as:
await FirebaseAppCheck.instance.activate(
providerApple: const AppleAppAttestProvider(),
);
I am not using appAttestWithDeviceCheckFallback.
The application is running on a physical iPhone in Release mode.
The following are correctly configured:
Apple App Attest capability is enabled in Xcode.
The App Attest entitlement is configured for production.
The application is running on a physical iOS device.
AppleAppAttestProvider is explicitly selected.
There is no DeviceCheck fallback configured.
Native investigation
I added logging to the native FlutterFire implementation to verify which provider is actually being selected.
The native plugin receives:
providerName = appAttest
and the AppCheckProviderWrapper executes:
delegateProvider = AppAttestProvider(app: app)
I also confirmed that the resulting provider is an instance of:
FIRAppAttestProvider
Therefore, it appears that FlutterFire is correctly selecting and instantiating the App Attest provider.
Unexpected result
After activating App Check, I retrieve the token using:
final token = await FirebaseAppCheck.instance.getToken(true);
However, when I decode the returned Firebase App Check JWT, the payload contains:
{
"provider": "device_check_device_identification"
}
This makes it appear that the resulting App Check token is associated with DeviceCheck rather than App Attest.
I also checked the Firebase/Google Cloud logs while requesting the token and could not find an ExchangeAppAttestAttestation operation. Instead, the behavior appears consistent with the DeviceCheck flow.
Expected behavior
Since I explicitly configure:
AppleAppAttestProvider()
I would expect the Firebase App Check token to be generated through the Apple App Attest flow, rather than DeviceCheck.
I would also expect the Firebase App Check token/provider information to indicate that App Attest was used.
Steps to reproduce
Configure Firebase in a Flutter iOS application.
Enable App Check for the Firebase project.
Configure Apple App Attest in the Apple Developer account and Xcode.
Use a physical iOS device.
Run the application in Release mode.
Configure FlutterFire with:
await FirebaseAppCheck.instance.activate(
providerApple: const AppleAppAttestProvider(),
);
Request a token:
final token = await FirebaseAppCheck.instance.getToken(true);
Decode the returned JWT.
Observe that the token contains:
"provider": "device_check_device_identification"
Additional information
I also inspected the FlutterFire native implementation.
The provider selection is definitely reaching the native layer as:
appAttest
and the native implementation creates:
AppAttestProvider(app: app)
Therefore, this does not appear to be a simple Flutter configuration issue or an accidental use of appAttestWithDeviceCheckFallback.
The main question is:
Why does an App Check token appear to be issued using DeviceCheck when AppleAppAttestProvider / FIRAppAttestProvider is explicitly configured and instantiated?
Could this be expected behavior in the underlying Firebase iOS SDK, or could there be an issue in the FlutterFire/native Firebase App Check integration?
Environment
Platform: iOS
Device: Physical iPhone
Build configuration: Release
Apple App Attest: Enabled
App Attest entitlement: Production
FlutterFire provider: AppleAppAttestProvider
DeviceCheck fallback: Not configured
firebase_app_check: 0.4.7
Firebase iOS SDK: 12.18.0
I can provide additional logs, the relevant native FlutterFire source changes, Podfile.lock, or a minimal reproduction project if needed.
### Reproducing the issue
.
### Firebase Core version
4.13.0
### Flutter Version
3.35.7
### Relevant Log Output
```shell
```
### Flutter dependencies
Expand Flutter dependencies snippet
```yaml
Replace this line with the contents of your `flutter pub deps -- --style=compact`.
```
### Additional context and comments
_No response_
Contributor guide
Research direction
Reproduce the report with firebase_app_check 0.4.7 on a physical iOS device, then trace the native provider selection through AppCheckProviderWrapper and AppAttestProvider. Compare the selected provider with the decoded token and Firebase logs, including whether an ExchangeAppAttestAttestation operation occurs. Done means the underlying SDK behavior or FlutterFire integration is identified and the next corrective action is clear.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- dart, firebase, flutter
- Domain
- mobile, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 38/100