I have developed framework and want to use this framework in authplugin which added on same project in different target
That plugin target is working fine without framework, once I am adding framework the authplugin is not working
Auth-plugin I am using to change in screen-saver plist
General
RSS for tagPrioritize user privacy and data security in your app. Discuss best practices for data handling, user consent, and security measures to protect user information.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I have a sandboxed Mac app which I can grant access to a folder using an NSOpenPanel. Once it’s been granted access it can enumerate the contents of the folder just fine. If I rename the folder while the app is open and then make the app enumerate the folder’s contents again, though, it seems to have lost access.
What’s the recommended way to have an app’s sandbox “track” files as they’re moved around the filesystem? (NSDocument handles this for you, from what I can tell.) I’ve managed to hack something together with a combination of Dispatch sources and security-scoped bookmarks, but it feels like there must be an easier solution …
I need to open p12 file from other iOS applications to import private key to my application. My app is set up to be able to open nay file with following plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>Files</string>
<key>LSHandlerRank</key>
<string>Default</string>
<key>LSItemContentTypes</key>
<array>
<string>public.item</string>
<string>public.data</string>
<string>public.content</string>
</array>
</dict>
</array>
</dict>
</plist>
But my don't appear in share dialog from Files or Mail app for example. There are however other third party apps that can accept this file. Some of them use Share extension which I don't have, but some of them don't have it as far as I can understand. At least they don't present any UI and open apps directly.
Also I've tried to specify com.rsa.pkcs-12 UTI directly but it didn't help. Also noticed that *.crt files have similar behaviour.
Am I missing something about this specific file type?
I'm seeing some odd behavior which may be a bug. I've broken it down to a least common denominator to reproduce it. But maybe I'm doing something wrong.
I am opening a file read-write. I'm then mapping the file read-only and private:
void* pointer = mmap(NULL, 17, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);
I then unmap the memory and close the file. After the close, eslogger shows me this:
{"close":{"modified":false,[...],"was_mapped_writable":false}}
Which makes sense.
I then change the mmap statement to:
void* pointer = mmap(NULL, 17, PROT_READ, MAP_FILE | MAP_SHARED, fd, 0);
I run the new code and and the close looks like:
{"close":{"modified":false, [....], "was_mapped_writable":true}}
Which also makes sense.
I then run the original again (ie, with MAP_PRIVATE vs. MAP_SHARED) and the close looks like:
{"close":{"modified":false,"was_mapped_writable":true,[...]}
Which doesn't appear to be correct.
Now if I just open and close the file (again, read-write) and don't mmap anything the close still shows:
{"close":{ [...], "was_mapped_writable":true,"modified":false}}
And the same is true if I open the file read-only.
It will remain that way until I delete the file. If I recreate the file and try again, everything is good until I map it MAP_SHARED.
I tried this with macOS 13.6.7 and macOS 15.0.1.
I work for Brave, a browser with ~80M users. We want to introduce a new system for automatic updates called Omaha 4 (O4). It's the same system that powers automatic updates in Chrome.
O4 runs as a separate application on users' systems. For Chrome, this works as follows: An app called GoogleUpdater.app regularly checks for updates in the background. When a new version is found, then GoogleUpdater.app installs it into Chrome's installation directory /Applications/Google Chrome.app.
But consider what this means: A separate application, GoogleUpdater.app, is able to modify Google Chrome.app.
This is especially surprising because, for example, the built-in Terminal.app is not able to modify Google Chrome.app. Here's how you can check this for yourself:
(Re-)install Chrome with its DMG installer.
Run the following command in Terminal: mkdir /Applications/Google\ Chrome.app/test. This works.
Undo the command: rm -rf /Applications/Google\ Chrome.app/test
Start Chrome and close it again.
mkdir /Applications/Google\ Chrome.app/test now fails with "Operation not permitted".
(These steps assume that Terminal does not have Full Disk Access and System Integrity Protection is enabled.)
In other words, once Chrome was started at least once, another application (Terminal in this case) is no longer allowed to modify it.
But at the same time, GoogleUpdater.app is able to modify Chrome. It regularly applies updates to the browser. For each update, this process begins with an mkdir call similarly to the one shown above.
How is this possible? What is it in macOS that lets GoogleUpdater.app modify Chrome, but not another app such as Terminal? Note that Terminal is not sandboxed.
I've checked that it's not related to codesigning or notarization issues. In our case, the main application (Brave) and the updater (BraveUpdater) are signed and notarized with the same certificate and have equivalent requirements, entitlements and provisioning profiles as Chrome and GoogleUpdater.
The error that shows up in the Console for the disallowed mkdir call is:
kernel (Sandbox)
System Policy: mkdir(8917) deny(1) file-write-create /Applications/Google Chrome.app/foo
(It's a similar error when BraveUpdater tries to install a new version into /Applications/Brave Browser.app.)
The error goes away when I disable System Integrity Protection. But of course, we cannot ask users to do that.
Any help would be greatly appreciated.
Hi,
We're encountering an intermittent issue where certain users are unexpectedly logged out of our app and unable to log in again.
We believe we've narrrowed down the issue to the Keychain due to the following reasons:
We use a keychain item to determine if the member is logged in or not. Failure to retrieve the value leads the app to believe the member is logged out.
API error logs on the server show 3 missing values in fields that are each populated from items stored in the keychain.
Additional Notes:
The issue is hard to reproduce and seems to affect only a subset of users.
In some cases, uninstalling and reinstalling the app temporarily resolves the problem, but the issue recurs after a period of time.
The behavior appears to have coincided with the release of iOS 18.
We’re using the “kSecAttrAccessibleWhenUnlocked” accessibility attribute. Given that our app doesn’t perform background operations, we wouldn’t expect this to be an issue. We’re also considering changing this to "kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly" to see if this might resolve the issue.
We're the keychain-swift library to interact with the keychain.
We are currently adding extensive logging around our keychain implementation to confirm our findings but are looking for any additional input.
Questions:
Has anyone encountered similar keychain behavior on iOS 18?
Are there known changes or stability issues with the keychain in iOS 18 that might lead to such intermittent “item not found” errors?
Any recommended workarounds or troubleshooting steps that could help isolate the problem further?
Thanks for any help you can provide.
I've tried all kinds of ways to get a SecKeyRef from the .p8 file I downloaded from my App Store Connect account. The key itself looks OK, as openssl gives this result:
openssl asn1parse -in 359UpAdminKey.p8
0:d=0 hl=3 l= 147 cons: SEQUENCE
3:d=1 hl=2 l= 1 prim: INTEGER :00
6:d=1 hl=2 l= 19 cons: SEQUENCE
8:d=2 hl=2 l= 7 prim: OBJECT :id-ecPublicKey
17:d=2 hl=2 l= 8 prim: OBJECT :prime256v1
27:d=1 hl=2 l= 121 prim: OCTET STRING [HEX DUMP]:30...
My method for creating the key is:
'- (SecKeyRef)privateKeyFromP8:(NSURL *)p8FileURL error:(NSError **)error {
// Read the .p8 file
NSData *p8Data = [NSData dataWithContentsOfURL:p8FileURL options:0 error:error];
if (!p8Data) {
return NULL;
}
// Convert P8 to base64 string, removing header/footer
NSString *p8String = [[NSString alloc] initWithData:p8Data encoding:NSUTF8StringEncoding];
NSArray *lines = [p8String componentsSeparatedByString:@"\n"];
NSMutableString *base64String = [NSMutableString string];
for (NSString *line in lines) {
if (![line containsString:@"PRIVATE KEY"]) {
[base64String appendString:line];
}
}
// Decode base64 to raw key data
NSData *keyData = [[NSData alloc] initWithBase64EncodedString:base64String options:0];
if (!keyData) {
if (error) {
*error = [NSError errorWithDomain:@"P8ImportError"
code:1
userInfo:@{NSLocalizedDescriptionKey: @"Failed to decode base64 data"}];
}
return NULL;
}
// Set up key parameters
NSDictionary *attributes = @{
(__bridge NSString *)kSecAttrKeyType: (__bridge NSString *)kSecAttrKeyTypeECSECPrimeRandom,
(__bridge NSString *)kSecAttrKeyClass: (__bridge NSString *)kSecAttrKeyClassPrivate,
(__bridge NSString *)kSecAttrKeySizeInBits: @256
};
// Create SecKeyRef from the raw key data
CFErrorRef keyError = NULL;
SecKeyRef privateKey = SecKeyCreateWithData((__bridge CFDataRef)p8Data,
(__bridge CFDictionaryRef)attributes,
&keyError);
if (!privateKey && keyError) {
*error = (__bridge_transfer NSError *)keyError;
NSError *bridgeError = (__bridge NSError *)keyError;
if (error) {
*error = bridgeError; // Pass the bridged error back to the caller
}
NSLog(@"Key Error: %@", bridgeError.localizedDescription);
}
return privateKey;
}
`
I get this error from SecKeyCreateWithData
The operation couldn’t be completed. (OSStatus error -50 - EC private key creation from data failed)
Filed a DTS incident, but they won't be back until after the New Year.
I've tried all kinds of things. Various AI chatbots, etc. Nothing seems to be working. I'm sure the problem is something elementary, but have spent hours on this with no luck.
Help, please.
I am using the CryptoKit SecureEnclave enum to generate Secure Enclave keys. I've got a couple of questions:
What is the lifetime of these keys?
When I don't store them somewhere, how does the Secure Enclave know they are gone? Do backups impact these keys? I.e. can I lose access to the key when I restore a backup?
Do these keys count to the total storage capacity of the Secure Enclave?
If I recall correctly, the Secure Enclave has a limited storage capacity. Do the SecureEnclave key instances count towards this storage capacity?
What is the dataRepresentation and how can I use this?
I'd like to store the Secure Enclave (preferably not in the Keychain due to its limitations). Is it "okay" to store this elsewhere, for instance in a file or in the UserDefaults?
Can the dataRepresentation be used in other apps?
If I had the capability of extracting the dataRepresentation as an attacker, could I then rebuild that key in my malicious app, as the key can be rebuilt with the Secure Enclave on the same device, or are there measures in place to prevent this (sandbox, bundle id, etc.)
Hello!
I do know apple does not support electron, but I do not think this is an electron related issue, rather something I am doing wrong. I'd be curious to find out why the keychain login is happenning after my app has been signed with the bundleid, entitlements, and provision profile.
Before using the provision profile I did not have this issue, but it is needed for assessments feature.
I'm trying to ship an Electron / macOS desktop app that must run inside Automatic Assessment Configuration. The build signs and notarizes successfully, and assessment mode itself starts on Apple-arm64 machines, but every single launch shows the system dialog that asks to allow access to the "login" keychain. The dialog appears on totally fresh user accounts, so it's not tied to anything I store there.
It has happened ever since I have added the provision profile to the electron builder to finally test assessment out.
entitlements.inherit.plist keys
<key>com.apple.security.cs.allow-jit</key> <true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key> <true/>
entitlements.plist keys:
<key>com.apple.security.cs.allow-jit</key> <true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key> <true/>
<key>com.apple.developer.automatic-assessment-configuration</key> <true/>
I'm honestly not sure whether the keychain is expected, but I have tried a lot of entitlement combinations to get rid of It. Electron builder is doing the signing, and we manually use the notary tool to notarize but probably irrelevant.
mac: {
notarize: false,
target: 'dir',
entitlements: 'buildResources/entitlements.mac.plist',
provisioningProfile: 'buildResources/xyu.provisionprofile',
entitlementsInherit: 'buildResources/entitlements.mac.inherit.plist',
Any lead is welcome!
Topic:
Privacy & Security
SubTopic:
General
Tags:
Automatic Assessment Configuration
Assessment
Security
Entitlements
Hi,
When calling generateAssertion on DCAppAttestService.shared, it gives invalidKey error when there was an update for an offloaded app.
The offloading and reinstall always works fine if it is the same version on app store that was offloaded from device,
but if there is an update and the app tries to reuse the keyID from previous installation for generateAssertion, attestation service rejects the key with error code 3 (invalid key) for a significant portion of our user.
In our internal testing it failed for more than a third of the update attempts.
STEPS TO REPRODUCE:
install v1 from app store
generate key using DCAppAttestService.shared.generateKey
Attest this key using DCAppAttestService.shared.attestKey
Send the attestation objection to our server and verify with apple servers
Generate assertions for network calls to backend using DCAppAttestService.shared.generateAssertion with keyID from step 2
Device offloads the app (manually triggered by user, or automatically by iOS)
A new version v2 is published to App Store
Use tries to open the app
Latest version is download from the App Store
App tries to use the keyID from step 2 to generate assertions
DCAppAttestService throws invalidKey error (Error Domain=com.apple.devicecheck.error Code=3)
Step 7 is critical here, if there is no new version of the app, the reinstalled v1 can reuse the key from step 2 without any issues
Is this behaviour expected?
Is there any way we can make sure the key is preserved between offloaded app updates?
Thanks
Our desktop app for macos will be released in 2 channels
appstore
dmg package on our official website for users to download and install
Now when we debug with passkey, we find that the package name of the appstore can normally arouse passkey, but the package name of the non-App Store can not arouse the passkey interface
I need your help. Thank you
Topic:
Privacy & Security
SubTopic:
General
Tags:
Bundle ID
macOS
Passkeys in iCloud Keychain
Authentication Services
I'd like to implement unit tests that exercise keys made available via a persistent token interface. However, when attempting to list available tokens by passing kSecAttrAccessGroupToken as the kSecAttrAccessGroup to SecItemCopyMatching from a unit test, -34018 is returned. It succeeds without the kSecAttrAccessGroup, which makes sense given the unit test binary does not have com.apple.token Keychain Group. The Xcode UI indicates "Capabilities are not supported" for the unit test binary when attempting to add a Keychain Sharing capability to enable use of persistent tokens. This feels like a dead end but begs the question is there any way to implement unit tests to exercise a persistent token interface? It seems like the only path may be write unit tests that drive an independent app that handles the interactions with the persistent token.
Hello,
I have encountered several challenges related to System Integrity Protection (SIP) state detection and code signing requirements. I would like to seek clarification and guidance on the proper approach to programmatically determine the SIP state.
Here are the issues I’ve encountered:
XPC Code Signing Check APIs:
APIs like setCodeSigningRequirement and setConnectionCodeSigningRequirement do not work when SIP disabled and that's ok given what SIP is.
LaunchCodeRequirement API:
When using Process.launchRequirement, the LaunchCodeRequirement API does not function anymore when SIP disabled.
The IsSIPProtected requirement behaves in a way that is not clearly documented -- it appears to only apply to pre-installed Apple apps.
Legacy APIs:
Older APIs like SecCodeCheckValidity are likely to be non-functional, though I haven’t had the chance to validate this yet.
Private API Concerns:
So to mitigate those limitations I prefer my app to not even try to connect to untrusted XPC or launch untrusted Processes when SIP is disabled. The only way to determine SIP state I could find is a low-level C function csr_get_active_config. However, this function is not declared in any publicly available header file, indicating that it is a private API.
Since private APIs cannot be used in App Store-distributed apps and are best avoided for Developer ID-signed apps, this does not seem like a viable solution.
Given these limitations, what is the recommended and proper approach to programmatically determine the SIP state in a macOS application?
Any insights or guidance would be greatly appreciated.
Thank you!
Topic:
Privacy & Security
SubTopic:
General
Hi there,
I'm trying to use SFAuthorizationPluginView in order to show some fields in the login screen, have the user click the arrow, then continue to show more fields as a second step of authentication. How can I accomplish this?
Register multiple SecurityAgentPlugins each with their own mechanism and nib?
Some how get MacOS to call my SFAuthorizationPluginView::view() and return a new view?
Manually remove text boxes and put in new ones when button is pressed
I don't believe 1 works, for the second mechanism ended up calling the first mechanism's view's view()
Cheers,
-Ken
For security reasons, my application needs to prohibit external devices. If it is determined that the current phone is connected to any external devices, including non MFI authenticated devices, the app will exit. Please tell me how to do it? Thanks for your help.
I'm trying to develop a GUI app on macOS that takes control of the screen so that user must perform certain actions before regaining control of the desktop. I don't want the user to be able to kill the process (for example via an "assassin" shell script that looks for the process and terminates it with kill).
Based on this post it is not possible to create an unkillable process on macOS.
I'm wondering, however, if it's possible to run the GUI process in root (or with other escalated privileges) such that the logged in user cannot kill it. So it's killable, but you need privileges above what the logged in user has (assuming they are not root). I'm not worried about a root user being able to kill it.
Such an app would run in a managed context. I've played around with Service Background Tasks, but so far haven't found what I'm looking for.
I'm hoping someone (especially from Apple) might be able to tell me if this goal is even achievable with macOS Sequoia (and beyond).
Hello,
I have an application which uses a helper[1] to download[2] files. When files download is a DMG and user mounts the image to run the application from this DMG it doesn't pass Gatekeeper. It presents the "Application XYZ.app can't be opened.".
Same file downloaded via Safari shows a different dialog, the "XYZ.app is an app downloaded from the internet. Are you sure you want to open it?"
In the system log I see this line:
exec of /Volumes/SampleApp/SampleApp.app/Contents/MacOS/SampleApp denied since it was quarantined by Download\x20Helper and created without user consent, qtn-flags was 0x00000187
The application is running sandboxed and hardened, the main application has com.apple.security.files.downloads.read-write entitlement. Everything is signed by DeveloperID and passes all checks[3].
I tried to check the responsible process[4] of the helper. Then trivial stuff like download folder access in System Settings/Privacy & Security/Files & Folders. Everything seems to be fine.
For what it worths the value of quarantine attribute is following:
com.apple.quarantine: 0087;6723b80e;My App;
The Safari downloaded one posses:
com.apple.quarantine: 0083;6723b9fa;Safari;02162070-2561-42BE-B30B-19A0E94FE7CA
Also tried a few more ways and got to 0081 with Edge and 0082 with a sample app with similar setup. Not sure if that has any meaning.
What could I be doing wrong that Gatekeeper right away refuses to run the application from DMG instead of showing the dialog like in other cases?
[1] The executable is in application bundle located in Contents/Helpers/DownloadHelper.app in the main application bundle.
[2] Nothing fancy, curl + regular POSIX file operations
[3] codesign, syspolicy_check, spctl
[4] launchctl procinfo pid
I have 2 basic questions related to Launch Constraints:
[Q1] Are Launch Constraints supposed to work when SIP is disabled?
From what I'm observing, when SIP is disabled, Launch Constraints (e.g. Launch Constraint Parent Process) are not enforced. I can understand that. But it's a bit confusing considering that the stack diagram in the WWDC 2023 session is placing the 'Environment Constraints' block under SIP, not above.
Also the documentation only mentions SIP for the 'is-sip-protected' fact.
[Q2] Is the SpawnConstraint key in legacy launchd plist files (i.e. inside /Library/Launch(Agents|Daemons)) officially supported?
From what I'm seeing, it seems to be working when SIP is enabled. But the WWDC session and the documentation don't really talk about this case.
Attempting to DECRYPT a cipher message using the Apple API SecKeyCreateDecryptedData(privateKey, .rsaEncryptionOAEPSHA256, encryptedMessage). Decryption ALWAYS fails for every algorithm.
SecKeyCreateDecryptedDataWithParameters Error: `Domain=NSOSStatusErrorDomain Code=-50 "algid:encrypt:RSA:OAEP:SHA256: algorithm not supported by the key <SecKeyRef:('com.yubico.Authenticator.TokenExtension:5621CDF8560D4C412030886584EC4C9E394CC376DD9738B0CCBB51924FC26EB6') 0x3007fd150>" UserInfo={numberOfErrorsDeep=0, NSDescription=algid:encrypt:RSA:OAEP:SHA256: algorithm not supported by the key <SecKeyRef:('com.yubico.Authenticator.TokenExtension:5621CDF8560D4C412030886584EC4C9E394CC376DD9738B0CCBB51924FC26EB6') 0x3007fd150>}`
Decryption failed: SecKeyCreateDecryptedData returned nil.
Error: One or more parameters passed to a function were not valid.
When checking with SecKeyIsAlgorithmSupported(privateKey, .decrypt, <ANYalgorithm>) all algorithms fail. Btw - The privateKey does support decryption when retrieving the attributes.
Important to know:
The private key is a reference to an external private key placed in the iOS Keychain via a 3rd party CryptoTokenKit Extension app. When I perform, the SecKeyCreateSignature(...) and pass in the SAME privateKey reference, the OS automatically calls the 3rd party app to perform a successful signing with the private key that reside on a YubiKey.
Here's my code for obtaining the private key reference from an Identity:
func getKeyPairFromIdentity() -> (privateKey: SecKey, publicKey: SecKey)? {
let query = NSDictionary(
dictionary: [
kSecClass as String: kSecClassIdentity,
kSecAttrTokenID as String: self.tokenID!,
kSecReturnRef as String: kCFBooleanTrue as Any
]
)
var identityRef: CFTypeRef?
let status = SecItemCopyMatching(query, &identityRef)
if status == errSecSuccess, let identity = identityRef {
var privateKeyRef: SecKey?
let keyStatus = SecIdentityCopyPrivateKey(identity as! SecIdentity, &privateKeyRef)
if keyStatus == errSecSuccess, let privateKey = privateKeyRef {
let publicKey = SecKeyCopyPublicKey(privateKey)
if let publicKey = publicKey {
print("Private and public keys extracted successfully.")
return (privateKey, publicKey)
} else {
print("Failed to extract public key from private key.")
return nil
}
} else {
print("SecIdentityCopyPrivateKey: Private key not found error: \(keyStatus)")
return nil
}
} else {
print("SecIdentity not found or error: \(status)")
return nil
}
}
Hi everyone,
I’d like to clarify something regarding the behavior of Team IDs after an app transfer between Apple Developer accounts.
I have an app update that enforces a force update for all users. My plan is to release this update under the current developer account, and then proceed with transferring the app to a different developer account shortly afterward.
My concern is: once the transfer is complete, will users who download the same app version (released before the transfer) be logged out due to a change in Team ID? Specifically, does the transferred app continue to use the original Team ID (used to sign the last submitted build), or does the Team ID change immediately upon transfer — affecting Keychain access?
Any insights or confirmation on this would be greatly appreciated. Thanks!
Topic:
Privacy & Security
SubTopic:
General