Remote Config in context of an Authorization Plugin on macOS
Description
I am trying to use Firebase’s Remote Config in the context of an Authorization Plugin & launchd daemon on macOS to implement feature flag support. When I try to fetch remote Firebase settings, I get a -34018 indicating that there is an error with access to the keychain on the Mac.
As auth plugin & launchd daemon does not run in user context but runs in system context, and does not have access to Data Protection Keychain on macOS, is it possible to use Firebase within the context of an Authorization Plugin & launchd daemon (specifically Remote config FF) and what is the recommended approach?
We got this message after submitting in support section of Firebase:
Per consultation with our engineer, it is possible to use Firebase within the context of an Authorization Plugin with regards to Remote Config
Details: Firebase/RemoteConfig ~> 9.4 macOS deployment target: 12.0 Swift version: 5
Reproducing the issue
No response
Firebase SDK Version
9.4
Xcode Version
15.2
Installation Method
CocoaPods
Firebase Product(s)
Remote Config
Targeted Platforms
macOS
Relevant Log Output
Error Domain=com. google. remoteconfig. ErrorDomain Code=8003 "Failed to get installations token. Error: Error Domain=com. firebase. installations Code=0 "Underlying error: The operation couldn't be completed. SecItemAdd (-34018) " UserInfo=‹NSLocalizedFailureReason=Underlvingerror:The operation couldn't be completed. SecItemAdd (-34018), NSUnderIvingError=0x600000c71320 (Error Domain=com.qul. kevchain. ErrorDomain Code=0 "SecItemAdd (-34918)" UserInfo={NSLocalizedFailureReason=SecItemAdd(-34918)}})."UserInfo=(NSLocalizedDescription=Failedtogetinstallationstoken.Error:ErrorDomain=com.firebase.installationsCode=0"Underlyingerror:The operation couldn't be completed. SecItemAdd (-34918)" UserInfo=(NSLocalizedFailureReason=Underlying error: The operation couldn't be completed. SecItemAdd (-34018), NSUnderlyingError=0×600000c71320 {Error Domain=com. gul.keychain. ErrorDomain Code=0
"SecItemAdd (-34018) " UserInfo={NSLocalizedFailureReason=SecItemAdd (-34018))}).)
If using Swift Package Manager, the project's Package.resolved
Expand Package.resolved snippet
Replace this line with the contents of your Package.resolved.
If using CocoaPods, the project's Podfile.lock
Expand Podfile.lock snippet
PODS:
- Firebase/Analytics (9.4.0):
- Firebase/Core
- Firebase/Core (9.4.0):
- Firebase/CoreOnly
- FirebaseAnalytics (~> 9.4.0)
- Firebase/CoreOnly (9.4.0):
- FirebaseCore (= 9.4.0)
- Firebase/RemoteConfig (9.4.0):
- Firebase/CoreOnly
- FirebaseRemoteConfig (~> 9.4.0)
- FirebaseABTesting (9.6.0):
- FirebaseCore (~> 9.0)
- FirebaseAnalytics (9.4.0):
- FirebaseAnalytics/AdIdSupport (= 9.4.0)
- FirebaseCore (~> 9.0)
- FirebaseInstallations (~> 9.0)
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
- GoogleUtilities/MethodSwizzler (~> 7.7)
- GoogleUtilities/Network (~> 7.7)
- "GoogleUtilities/NSData+zlib (~> 7.7)"
- nanopb (< 2.30910.0, >= 2.30908.0)
- FirebaseAnalytics/AdIdSupport (9.4.0):
- FirebaseCore (~> 9.0)
- FirebaseInstallations (~> 9.0)
- GoogleAppMeasurement (= 9.4.0)
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
- GoogleUtilities/MethodSwizzler (~> 7.7)
- GoogleUtilities/Network (~> 7.7)
- "GoogleUtilities/NSData+zlib (~> 7.7)"
- nanopb (< 2.30910.0, >= 2.30908.0)
- FirebaseCore (9.4.0):
- FirebaseCoreDiagnostics (~> 9.0)
- FirebaseCoreInternal (~> 9.0)
- GoogleUtilities/Environment (~> 7.7)
- GoogleUtilities/Logger (~> 7.7)
- FirebaseCoreDiagnostics (9.6.0):
- GoogleDataTransport (< 10.0.0, >= 9.1.4)
- GoogleUtilities/Environment (~> 7.7)
- GoogleUtilities/Logger (~> 7.7)
- nanopb (< 2.30910.0, >= 2.30908.0)
- FirebaseCoreInternal (9.6.0):
- "GoogleUtilities/NSData+zlib (~> 7.7)"
- FirebaseInstallations (9.6.0):
- FirebaseCore (~> 9.0)
- GoogleUtilities/Environment (~> 7.7)
- GoogleUtilities/UserDefaults (~> 7.7)
- PromisesObjC (~> 2.1)
- FirebaseRemoteConfig (9.4.0):
- FirebaseABTesting (~> 9.0)
- FirebaseCore (~> 9.0)
- FirebaseInstallations (~> 9.0)
- GoogleUtilities/Environment (~> 7.7)
- "GoogleUtilities/NSData+zlib (~> 7.7)"
- GoogleAppMeasurement (9.4.0):
- GoogleAppMeasurement/AdIdSupport (= 9.4.0)
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
- GoogleUtilities/MethodSwizzler (~> 7.7)
- GoogleUtilities/Network (~> 7.7)
- "GoogleUtilities/NSData+zlib (~> 7.7)"
- nanopb (< 2.30910.0, >= 2.30908.0)
- GoogleAppMeasurement/AdIdSupport (9.4.0):
- GoogleAppMeasurement/WithoutAdIdSupport (= 9.4.0)
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
- GoogleUtilities/MethodSwizzler (~> 7.7)
- GoogleUtilities/Network (~> 7.7)
- "GoogleUtilities/NSData+zlib (~> 7.7)"
- nanopb (< 2.30910.0, >= 2.30908.0)
- GoogleAppMeasurement/WithoutAdIdSupport (9.4.0):
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
- GoogleUtilities/MethodSwizzler (~> 7.7)
- GoogleUtilities/Network (~> 7.7)
- "GoogleUtilities/NSData+zlib (~> 7.7)"
- nanopb (< 2.30910.0, >= 2.30908.0)
- GoogleDataTransport (9.3.0):
- GoogleUtilities/Environment (~> 7.7)
- nanopb (< 2.30910.0, >= 2.30908.0)
- PromisesObjC (< 3.0, >= 1.2)
- GoogleUtilities/AppDelegateSwizzler (7.12.0):
- GoogleUtilities/Environment
- GoogleUtilities/Logger
- GoogleUtilities/Network
- GoogleUtilities/Environment (7.12.0):
- PromisesObjC (< 3.0, >= 1.2)
- GoogleUtilities/Logger (7.12.0):
- GoogleUtilities/Environment
- GoogleUtilities/MethodSwizzler (7.12.0):
- GoogleUtilities/Logger
- GoogleUtilities/Network (7.12.0):
- GoogleUtilities/Logger
- "GoogleUtilities/NSData+zlib"
- GoogleUtilities/Reachability
- "GoogleUtilities/NSData+zlib (7.12.0)"
- GoogleUtilities/Reachability (7.12.0):
- GoogleUtilities/Logger
- GoogleUtilities/UserDefaults (7.12.0):
- GoogleUtilities/Logger
- nanopb (2.30909.1):
- nanopb/decode (= 2.30909.1)
- nanopb/encode (= 2.30909.1)
- nanopb/decode (2.30909.1)
- nanopb/encode (2.30909.1)
- OktaConfig/Complete (2.2.8):
- OktaConfig/Core
- OktaConfig/FirebaseConfig
- OktaConfig/Core (2.2.8)
- OktaConfig/FirebaseConfig (2.2.8):
- Firebase/RemoteConfig (~> 9.4)
- OktaConfig/Core
- PromisesObjC (2.3.1)
DEPENDENCIES:
- Firebase/Analytics (= 9.4)
- Firebase/RemoteConfig (= 9.4)
- OktaConfig/Complete (from `.`)
SPEC REPOS:
trunk:
- Firebase
- FirebaseABTesting
- FirebaseAnalytics
- FirebaseCore
- FirebaseCoreDiagnostics
- FirebaseCoreInternal
- FirebaseInstallations
- FirebaseRemoteConfig
- GoogleAppMeasurement
- GoogleDataTransport
- GoogleUtilities
- nanopb
- PromisesObjC
EXTERNAL SOURCES:
OktaConfig:
:path: "."
SPEC CHECKSUMS:
Firebase: 7703fc4022824b6d6db1bf7bea58d13b8e17ec46
FirebaseABTesting: 61826730ce9eee8781ba99a2b3420e9bce148dc9
FirebaseAnalytics: a1a24e72b7ba7f47045a4633f1abb545c07bd29c
FirebaseCore: 9a2b10270a854731c4d4d8a97d0aa8380ec3458d
FirebaseCoreDiagnostics: 99a495094b10a57eeb3ae8efa1665700ad0bdaa6
FirebaseCoreInternal: bca76517fe1ed381e989f5e7d8abb0da8d85bed3
FirebaseInstallations: 0a115432c4e223c5ab20b0dbbe4cbefa793a0e8e
FirebaseRemoteConfig: 6d9982bc64548a6e3c1b497b9fa53938ad135f2d
GoogleAppMeasurement: 5d69e04287fc2c10cc43724bfa4bf31fc12c3dff
GoogleDataTransport: 57c22343ab29bc686febbf7cbb13bad167c2d8fe
GoogleUtilities: 0759d1a57ebb953965c2dfe0ba4c82e95ccc2e34
nanopb: d4d75c12cd1316f4a64e3c6963f879ecd4b5e0d5
OktaConfig: e2a6952c9abb7a68f4ecb99fc27eea08f626c7da
PromisesObjC: c50d2056b5253dadbd6c2bea79b0674bd5a52fa4
PODFILE CHECKSUM: cc159b7fbfd491491f9758aed96efd45964f5dcc
COCOAPODS: 1.12.1
I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.
cc @paulb777 @ncooke3
Remote Config depends on Firebase Installations which accesses the keychain and by default, Authorization plugins cannot access the keychain.
There are some possible workarounds on stackoverflow like https://stackoverflow.com/a/45002093/556617. Does that help?
I think the main problem here is that launchd daemons(and Authorization plugin in particular) are not able to use data protection keychain APIs and therefore we see entitlement level error from Security framework(more info here)
@paulb777 , do you think it is possible to have some public APIs to disable keychain usage for Firebase Installations and use in-memory cache?
I think it could be possible, although a solution may impact performance and behavior of subsequent app sessions.
We don't currently have this investigation prioritized, but would consider a pull request.
I also encountered this problem, who can provide a solution? Waiting online