I'm developing a react-native app using https://github.com/oblador/react-native-keychain to save and get things from keychain.
The things stored in keychain (and some other things) should be accessible from all our apps. So in xcode under capabilities I have activated an app-group "group.something.test".
I'm using setGenericPassword function of react-native-keychain like this:
await Keychain.setGenericPassword(
'a username',
'a password',
{
service: 'a userId',
accessible: Keychain.ACCESSIBLE.ALWAYS,
accessGroup: 'group.something.test',
accessControl: Keychain.ACCESS_CONTROL.DEVICE_PASSCODE
}
);
In the native module this will store it to the keychain something like this:
SecAccessControlRef sacRef = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
kSecAttrAccessibleAlways,
kSecAccessControlDevicePasscode,
&error);
NSDictionary *attributes = attributes = @{
(__bridge NSString *)kSecClass: (__bridge id)(kSecClassGenericPassword),
(__bridge NSString *)kSecAttrService: service,
(__bridge NSString *)kSecAttrAccount: username,
(__bridge NSString *)kSecValueData: [password dataUsingEncoding:NSUTF8StringEncoding],
(__bridge NSString *)kSecAttrAccessControl] = (__bridge id)sacRef,
(__bridge NSString *)kSecAttrAccessGroup] = accessGroup;
};
...
OSStatus osStatus = SecItemAdd((__bridge CFDictionaryRef) attributes, NULL);
...
And keychain items are retrieved in the following way:
await Keychain.getGenericPassword({ service: 'a userId' });
Which will will run the following native code:
NSDictionary *query = @{
(__bridge NSString *)kSecClass: (__bridge id)(kSecClassGenericPassword),
(__bridge NSString *)kSecAttrService: service,
(__bridge NSString *)kSecReturnAttributes: (__bridge id)kCFBooleanTrue,
(__bridge NSString *)kSecReturnData: (__bridge id)kCFBooleanTrue,
(__bridge NSString *)kSecMatchLimit: (__bridge NSString *)kSecMatchLimitOne,
(__bridge NSString *)kSecUseOperationPrompt:@"Authenticate to retrieve secret"
};
CFTypeRef foundTypeRef = NULL;
OSStatus osStatus = SecItemCopyMatching((__bridge CFDictionaryRef) query, (CFTypeRef*)&foundTypeRef);
This works fine in the first app, I can store and retrieve an item from the keychain.
When I deploy a second app through xcode by just changing Display name and Bundle identifier to something different it also works. I can retrieve the key saved by the first app.
However if I now go back to the first app and try to retrieve the keychain item osStatus is -25308 (errSecInteractionNotAllowed).
If I uninstall the second app, it will start working in the first app again.
What am I doing wrong? Is there something more I need to do in the project settings?
I have also tried with keychain group capability, having the same keychain group as the first index in the keychain groups array, using that id as kSecAttrAccessGroup.