Prioritize user privacy and data security in your app. Discuss best practices for data handling, user consent, and security measures to protect user information.

All subtopics
Posts under Privacy & Security topic

Post

Replies

Boosts

Views

Created

SPF verification fails for long records (3+ DNS TXT strings) in Private Email Relay
Hi, we are experiencing a specific issue with the Private Email Relay service. Our domain e.glassesdirect.co.uk consistently fails SPF verification while our other domains pass. The Pattern: We've noticed that domains with SPF records fitting in 1-2 TXT strings pass, but this specific domain (~750 chars, 3 TXT strings) fails. Technical Details: Team ID: SM2J7LWD33 Domain: e.glassesdirect.co.uk SPF Record length: ~750 characters Third-party tools (MxToolbox) confirm the record is valid. We suspect Apple's verification parser might be failing to handle concatenated TXT strings or hitting a size limit. Could any Apple engineers confirm if there is a character limit or a bug in handling multi-part TXT records?
0
0
191
Apr ’26
Cannot set nested subdomains in web auth configuration
For my api I have a domain scheme of env.service.example.com. I am trying to setup sign in with apple, however, when trying to set my return urls, the env subdomain is stripped, making the return url incorrect. For example, when I try to set https://env.service.example.com/ it is changed to https://service.example.com/ when submitted. Is there any way around this issue?
0
0
132
Apr ’26
[KeyChain Framework] KeyChain Item is accessible post App Transfer without rebuilding the KeyChain
We have utilised the KeyChain Framework for Adding items into KeyChain. We have Generated KeyPair using 'SecKeyGeneratePair' API as below (OSStatus)generateAssymetricKeyPair:(NSUInteger)bitSize{ OSStatus sanityCheck = noErr; SecKeyRef publicKeyRef = NULL; SecKeyRef privateKeyRef = NULL; NSString *appGrpIdentifier = @"group.com.sample.xyz" // Set the private key attributes. NSDictionary *privateKeyAttr = @{(id)kSecAttrIsPermanent: @YES, (id)kSecAttrApplicationTag: [TAG_ASSYMETRIC_PRIVATE_KEY dataUsingEncoding:NSUTF8StringEncoding], (id)kSecAttrCanEncrypt:@NO, (id)kSecAttrCanDecrypt:@YES, (id)kSecAttrAccessGroup: appGrpIdentifier }; // Set the public key attributes. NSDictionary *publicKeyAttr = @{(id)kSecAttrIsPermanent: @YES, (id)kSecAttrApplicationTag: [TAG_ASSYMETRIC_PUBLIC_KEY dataUsingEncoding:NSUTF8StringEncoding], (id)kSecAttrCanEncrypt:@YES, (id)kSecAttrCanDecrypt:@NO, (id)kSecAttrAccessGroup: appGrpIdentifier }; // Set top level attributes for the keypair. NSDictionary *keyPairAttr = @{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeRSA, (id)kSecAttrKeySizeInBits: @(bitSize), (id)kSecClass: (id)kSecClassKey, (id)kSecPrivateKeyAttrs: privateKeyAttr, (id)kSecPublicKeyAttrs: publicKeyAttr, // MOBSF-WARNING-SUPPRESS: (id)kSecAttrAccessible: (id)kSecAttrAccessibleAfterFirstUnlock, // mobsf-ignore: ios_keychain_weak_accessibility_value // MOBSF-SUPPRESS-END (id)kSecAttrAccessGroup: appGrpIdentifier }; // Generate Assymetric keys sanityCheck = SecKeyGeneratePair((CFDictionaryRef)keyPairAttr, &publicKeyRef, &privateKeyRef); if(sanityCheck == errSecSuccess){ NSLog(@"[DB_ENCRYPTION] <ALA_INFO> [OS-CCF] CALLED Assymetric keys are generated"); } else{ NSLog(@"[DB_ENCRYPTION] <ALA_ERROR> [OS-CCF] CALLED Error while generating asymetric keys : %d", (int)sanityCheck); } if (publicKeyRef) { CFRelease(publicKeyRef); } if (privateKeyRef) { CFRelease(privateKeyRef); } return sanityCheck; } KeyPair is added into the KeyChain (BOOL)saveSymetricKeyToKeychain:(NSData *)symmetricKeyData keyIdentifier:(NSString *)keyIdentifier { NSString *appGrpIdentifier = [KeychainGroupManager getAppGroupIdentifier]; NSDictionary *query = @{ (__bridge id)kSecClass: (__bridge id)kSecClassKey, (__bridge id)kSecAttrApplicationTag: keyIdentifier, (__bridge id)kSecValueData: symmetricKeyData, (__bridge id)kSecAttrKeyClass: (__bridge id)kSecAttrKeyClassSymmetric, // MOBSF-WARNING-SUPPRESS: (__bridge id)kSecAttrAccessible: (__bridge id)kSecAttrAccessibleAfterFirstUnlock, // mobsf-ignore: ios_keychain_weak_accessibility_value // MOBSF-SUPPRESS-END (__bridge id)kSecAttrAccessGroup: appGrpIdentifier }; // Now add the key to the Keychain status = SecItemAdd((__bridge CFDictionaryRef)query, NULL); if (status == errSecSuccess) { NSLog(@"[DB_ENCRYPTION] Key successfully stored in the Keychain"); return YES; } else { NSLog(@"<ALA_ERROR> [DB_ENCRYPTION] Error storing key in the Keychain: %d", (int)status); return NO; } } Post App Transfer, we are able to retrieve the Public & Private Key Reference without rebuilding the keychain Query:- Is this attribute "kSecAttrAccessGroup" helping us to retrieve the KeyChain items without having to rebuild on App Transfer to New Apple Account as described in this set of guidelines. Could you please explain in detail on this. https://developer.apple.com/help/app-store-connect/transfer-an-app/overview-of-app-transfer Keychain sharing continues to work only until the app is updated. Therefore, you must rebuild the keychain when submitting updates. If your keychain group is defined in the Xcode project, replace it with a group created by the recipient, incorporating their Team ID for continued keychain sharing. After the update, users must re-login once as the app cannot retrieve the authentication token from the keychain.
1
0
122
Apr ’26
[Apple Sign-In] How to handle missing transfer_sub and the 60-day migration limit during App Transfer?
Hello everyone, We are currently preparing for an App Transfer to a new Apple Developer account due to a corporate merger. We are trying to figure out the best way to handle Apple Sign-In user migration and would love to get some advice on our proposed fallback plan. 📌 Current Situation We need to transfer our app's ownership to a new corporate entity. The app heavily relies on Apple Sign-In. The Issue: We did not collect the transfer_sub values during our initial development phase. Although we started collecting them recently, we will not have them for all existing users by the time the transfer happens. 🚨 The Risk (The 60-Day Rule) Based on Apple's documentation, even if we provide the transfer_sub, users must log into the app within 60 days of the transfer to successfully migrate their accounts. This means that users who log in after 60 days, or those whose transfer_sub is missing, will fail the Apple migration process. They will be treated as "new users" and will lose access to their existing account data. 💡 Our Proposed Custom Recovery Flow Since we cannot rely entirely on Apple's automated migration, we are planning to build a custom internal account recovery process to prevent user drop-off: A user (who failed the migration or logged in after 60 days) attempts to use Apple Sign-In on the transferred app. Since the existing account isn't linked, Apple generates a new identifier (sub), and the user enters the new sign-up flow. During the sign-up process, we enforce a mandatory identity verification step (e.g., SMS phone number verification). We query our existing user database using this verified information. If a matching existing user is found: We interrupt the sign-up process and display a prompt: "An existing account was found. We will link your account." We then update our database by mapping the new Apple sub value to their existing account record, allowing them to log in seamlessly. ❓ My Questions App Review Risk: Could this manual mapping approach—overwriting the Apple sub on an existing account based on internal identity verification—violate any Apple guidelines or result in an App Store rejection? Shared Experiences: Has anyone dealt with missing transfer_sub values or the 60-day migration limit during an App Transfer? How did you mitigate user loss? Best Practices: Are there any alternative, safer, or more recommended workarounds for this scenario?
0
0
179
Apr ’26
ASAuthorizationProviderExtensionAuthorizationRequest.complete(httpAuthorizationHeaders:) custom header not reaching endpoint
I’m implementing a macOS Platform SSO extension using ASAuthorizationProviderExtensionAuthorizationRequest. In beginAuthorization, I intercept an OAuth authorize request and call: request.complete(httpAuthorizationHeaders: [ "x-psso-attestation": signedJWT ]) I also tested: request.complete(httpAuthorizationHeaders: [ "Authorization": "Bearer test-value" ]) From extension logs, I can confirm the request is intercepted correctly and the header dictionary passed into complete(httpAuthorizationHeaders:) contains the expected values. However: the header is not visible in browser devtools the header does not appear at the server / reverse proxy So the question is: Does complete(httpAuthorizationHeaders:) support arbitrary custom headers, or only a restricted set of authorization-related headers ? Is there something that I might be missing ? And if custom headers are not supported, is there any supported way for a Platform SSO extension to attach a normal HTTP header to the continued outbound request ?
1
0
344
Apr ’26
DCDevice last_update_time issue
We are currently experiencing an unexpected issue with the DeviceCheck query_two_bits endpoint. According to the official documentation (Accessing and Modifying Per-Device Data), the last_update_time field should represent the month and year when the bits were last modified. The Issue: For several specific device tokens, our server is receiving a last_update_time value that is set in the future. Current Date: April 2026 Returned last_update_time: 2026-12 (December 2026) Here is a response: { "body": "{\"bit0\":false,\"bit1\":true,\"last_update_time\":\"2026-12\"}", "headers": { "Server": ["Apple"], "Date": ["Thu, 02 Apr 2026 06:05:23 GMT"], "Content-Type": ["application/json; charset=UTF-8"], "Transfer-Encoding": ["chunked"], "Connection": ["keep-alive"], "X-Apple-Request-UUID": ["53e16c38-d9f7-4d58-a354-ce07a4eaa35b"], "X-Responding-Instance": ["af-bit-store-56b5b6b478-k8hnh"], "Strict-Transport-Security": ["max-age=31536000; includeSubdomains"], "X-Frame-Options": ["SAMEORIGIN"], "X-Content-Type-Options": ["nosniff"], "X-XSS-Protection": ["1; mode=block"] }, "statusCode": "OK", "statusCodeValue": 200 } Technical Details: Endpoint: https://api.development.devicecheck.apple.com/v1/query_two_bits (also occurring in Production) Response Body Example: JSON { "bit0": true, "bit1": false, "last_update_time": "2026-12" } Observations: This occurs even when our server has not sent an update_two_bits request for that specific device in the current month. Questions: Is there a known issue with the timestamp synchronization or regional database propagation for DeviceCheck? Does the last_update_time field ever represent an expiration date or any value other than the "last modified" month? Best regards,
1
0
146
Apr ’26
DeviceCheck query_two_bits returns last_update_time in the future — what could cause this?
Hi everyone, I'm integrating Apple's DeviceCheck API into my app and have run into a strange issue that I can't find documented anywhere. The Problem When I call Apple's DeviceCheck query endpoint (POST https://api.devicecheck.apple.com/v1/query_two_bits), the response occasionally returns a last_update_time value that is in the future — ahead of the current server time. Example response: { "bit0": true, "bit1": false, "last_update_time": "2026-05" // future month, not yet reached } What I've Checked My server's system clock is correctly synced via NTP The JWT token I generate uses the current timestamp for the iat field This doesn't happen on every device — only on some specific devices The issue is reproducible on the same device across multiple calls Questions Is last_update_time sourced from the device's local clock at the time update_two_bits was called? Or is it stamped server-side by Apple? Could a device with an incorrectly set system clock (set to the future) cause Apple's servers to record a future last_update_time? Is there a recommended way to validate or sanitize last_update_time on the server side to handle this edge case? Has anyone else encountered this behavior? Any known workarounds? Any insight would be greatly appreciated. Thanks!
1
0
140
Apr ’26
Production-Grade Implementation Guidance: DCError Matrices, Retry Strategies, and Simulator Testing for App Attest APIs
Hi there, We're implementing Apple's DeviceCheck App Attest for production iOS authentication. The public documentation defines DCError cases but doesn't specify which errors are expected per API method or recommend retry/remediation strategies. We need Apple's guidance to implement robust, production-aligned error handling before rollout. 1. Error Surface per API Method Question: Can you confirm the complete, officially expected set of DCError values for each method? We understand the following errors are possible across App Attest APIs: invalidKey invalidInput featureUnsupported serverUnavailable unknownSystemFailure Specifically, please confirm which errors can occur for: DCAppAttestService.generateKey() DCAppAttestService.attestKey(_:clientData:) DCAppAttestService.generateAssertion(keyID:clientData:) Are there any additional undocumented or edge-case errors we should handle? 2. Retry Strategy & Remediation Matrix Question: For each API method and error code, please help us with proposal around which errorCode is retriable, whats the remediation pre retry, retry cap and backoff strategy: Kindly also help with errors that are not covered here: Specific sub-questions: invalidKey handling: When this error occurs: Should the app delete the key and call generateKey again? Or should it fail the entire flow? serverUnavailable handling: Should we retry immediately, or wait before retrying? Is exponential backoff recommended? What's the recommended max retry count? Backoff strategy: Which errors (if any) qualify for exponential backoff? Recommended base delay, max delay, and jitter approach? When should we give up and fail the request? unknownSystemFailure: Is this retriable or should we fail? Any known causes or mitigations? 3. Simulator Testing Questions: Simulator API behavior: Can App Attest APIs be called normally on iOS Simulator? If not, is there a way to simulate for testing. Do they complete successfully with simulated attestations, or do they fail? Thanks, Nirekshitha
0
0
331
Apr ’26
SFAuthorizationPluginView
I’ve developed an authorization plug-in with a mechanism that runs an SFAuthorizationPluginView subclass and I’m facing a couple issues: - Glitch after successful login After setting kAuthorizationResultAllow in the context the user is successfully logged in and brought to the desktop but the login controls remain onscreen for a few seconds after login is complete, resulting in them being visible at the same time as the dock, menu bar and desktop.
 I’ve also tried what’s mentioned here https://developer.apple.com/forums/thread/780212 but without any luck. It’s also worth mentioning that the deinit() in my SFAuthorizationPluginView subclass never gets called when the plugin it’s loaded at the login stage but it does get called the plugin is used to re-authenticate the user after they locked their screen. - update() doesn't trigger the plugin to call view(for:) I’m trying to update the UI elements out of my control (like buttons and user avatar images) in order to have them placed at the proper position on the screen after a resize of my inner NSView. To do that I call update() but it appears that does not trigger the plugin to call view(for:) and update system UI elements placement. Is this the expected behavior? - setButton not working as expected 
I’m trying to disable the login button by calling the setButton(_:enabled:) passing a SFButtonTypeLogin as inButtonType, as suggested here: https://developer.apple.com/forums/thread/777432. When the method is called at the login screen it has no effect on the button (the one with the forward-arrow icon) but when it’s called by the plugin loaded at the ‘unlock screen’ stage it successfully disable the ‘OK’ button. - Certificate issue When trying to run a network request from the plugin loaded in the ‘unlock screen’ scenario, I always get this type of error: The certificate for this server is invalid. You might be connecting to a server that is pretending to be <<server_url>> which could put your confidential information at risk Everything works as expected when the plugin is loaded either at login screen or for authorizing an operation that requires admin privileges while the user is logged in.
3
0
483
Apr ’26
launch ASWebAuthenticationSession from single sign on extenstion
I need to launch ASWebAuthenticationSession from single sign on extension, but its not launching it might issue with anchoring window, I have create custom windo and passing it in presentanchor(for session) function, custom window is launching but ASWebAuthenticationSession browser is not launching Note - flow is like this Apple PSSO register window lauched OIDC login will happen via ASWebAuthenticationSession to get accesstoken which will use in device registration but ASWebAuthenticationSession is not launching, I am using custom scheme as redirect URI iskeywindow for custom window is always false what is right approach to achieve the goal
1
0
197
Apr ’26
iPhone 16 Datasheet
I am trying to find a datasheet containing information such as "Key Exchange / Key Agreement / Key Establishment Protocols Used", "Digital Signature Algorithms Used", "Hash Algorithms Used", etc. Any information would greatly appreciated.
1
0
109
Mar ’26
Exploring Secure Enclave–backed biometric authorization between macOS and iPhone using public APIs (FaceBridge prototype)
Hi everyone, I’ve been working on an experimental prototype called FaceBridge that explores whether Secure Enclave–backed biometric authorization can be delegated between macOS and iPhone using only public Apple APIs. The goal of the project was to better understand the architectural boundaries of cross-device trust and approval flows that resemble Apple’s built-in Touch ID / Continuity authorization experiences. FaceBridge implements a local authorization pipeline where: macOS generates a signed authorization request the request is delivered to a trusted nearby iPhone over BLE / Network framework the iPhone verifies sender identity Face ID approval is requested using LocalAuthentication the iPhone signs the approval response using Secure Enclave–backed keys macOS validates the response and unlocks a protected action Security properties currently implemented: • Secure Enclave–backed signing identities per device • cryptographic device pairing and trust persistence • replay protection using nonce + timestamp binding • structured authorization request/response envelopes • signed responder identity verification • trusted-device registry model • local encrypted transport over BLE and local network This is intentionally not attempting to intercept or replace system-level Touch ID dialogs (App Store installs, Keychain prompts, loginwindow, etc.), but instead explores what is possible within application-level authorization boundaries using public APIs only. The project is open source: https://github.com/wesleysfavarin/facebridge Technical architecture write-up: https://medium.com/@wesleysfavarin/facebridge I’m particularly interested in feedback around: • recommended Secure Enclave identity lifecycle patterns • best practices for cross-device trust persistence • LocalAuthentication usage in delegated approval scenarios • whether similar authorization models are expected to become more formally supported across Apple platforms in the future Thanks in advance for any guidance or suggestions.
1
0
258
Mar ’26
TEAM ID Prefix Keychain Access
Thanks all for reading my post. A bit of context: We just finished an app transfer to our developer account. We successfully signed and generated the new release. We are already able to roll it out in testflight were we found an issue. We store valuable data in the Keychain like Authentication tokens, once the new app is installed over the old one we are experiencing a loss of all data as the keychain become "untrusted". This is worst case scenario for us because all users will immediately lose the access to the app and hence the whole system. Questions: Is there a way to solve this issue, something like migration of the Keychain data? We came to know the standard migration path: Release a version that copies items from the old access groups to a new group based on com.apple.security.application-groups (App Groups). Wait for most users to update and run the migration. Then perform the App ID prefix change. Is this still the best method? Any improvements or new tools available since the 2022 DTS post? The problem with this is that the app is already on our account and that might need to rollback the transfer. Right? How long should we realistically wait for user migration before making the prefix change? Is there a way to measure migration completion? Thank you in advance!
1
0
183
Mar ’26
Sign in with Apple Web: invalid_client on token exchange with real authorization code, but invalid_grant with dummy code
We are integrating Sign in with Apple for our web application and have been stuck on an invalid_client error during the token exchange step. The Problem The authorization step works fine — the user authenticates on Apple's page and a valid authorization code is returned to our callback URL. However, when we exchange that code at https://appleid.apple.com/auth/token, it returns: {"error": "invalid_client"} The Puzzling Part When we send a dummy/expired authorization code with the exact same client_id and client_secret, Apple returns: {"error": "invalid_grant", "error_description": "The code has expired or has been revoked."} This confirms that our client credentials (client_id + client_secret JWT) are valid and accepted by Apple. The invalid_client error only occurs when a real, freshly-issued authorization code is used. Configuration Service ID configured with Sign in with Apple enabled Primary App ID with Sign in with Apple capability enabled Domain verified, Return URL registered Key created with Sign in with Apple enabled, linked to the correct Primary App ID Client Secret JWT Generated per Apple's documentation: Header: alg: ES256, kid set to our Key ID Claims: iss: Team ID iat: current timestamp exp: iat + 6 months (within Apple's limit) aud: https://appleid.apple.com sub: Service ID (matches the client_id used in authorization) Signed with: the .p8 private key associated with the Key Token Exchange Request POST https://appleid.apple.com/auth/tokenContent-Type: application/x-www-form-urlencodedclient_id=client_secret=code=grant_type=authorization_coderedirect_uri= What We've Tried Standalone test endpoint — built a minimal endpoint (no framework) that does the token exchange via server-side curl. Same invalid_client. Multiple Service IDs — created and tried 3 different Service IDs. All produce the same error with real codes. Multiple Keys — tried 2 different keys. Same error. Verified redirect_uri matches exactly between the authorization request and token request. Verified client_id matches exactly between the authorization URL and token request. Used client_secret_post (credentials in body, not Basic auth header). Freshness — code is used immediately upon receipt (within seconds), well before the 5-minute expiry. Filed a Developer Support case — was directed to Forums. Summary Scenario code Result Dummy/expired code abc123 invalid_grant (credentials accepted) Real fresh code from Apple callback invalid_client This pattern suggests something goes wrong specifically when Apple validates the authorization code against the client — even though the client credentials themselves are accepted in isolation. Has anyone encountered this behavior? Is there a known configuration issue that could cause invalid_client only with valid authorization codes? Any guidance would be greatly appreciated.
0
0
275
Mar ’26
TKTokenDriverConfiguration becomes permanently unusable after ctkd process restart
Background We're building a macOS application that acts as a CryptoTokenKit software token. The architecture follows the documented pattern: a container app (a long-running agent process) manages token registration and identity updates via TKTokenDriverConfiguration, and a separate appex extension process handles the actual signing operations for client sessions. What we're doing At agent startup, the container app calls [TKTokenDriverConfiguration driverConfigurations] to obtain our token driver, then registers a token instance ID: NSDictionary<TKTokenDriverClassID, TKTokenDriverConfiguration *> *driverConfigurations = [TKTokenDriverConfiguration driverConfigurations]; TKTokenDriverConfiguration driver = / first value from driverConfigurations */; [driver addTokenConfigurationForTokenInstanceID:@"setoken"]; When the agent renews a certificate, it pushes updated TKTokenKeychainItem objects to ctkd by setting keychainItems on the TKTokenConfiguration: TKTokenConfiguration *tokenCfg = driver.tokenConfigurations[@"setoken"]; tokenCfg.keychainItems = updatedItems; This works correctly during normal operation. The failure When ctkd is restarted (e.g., killall ctkd, or the system restarts the daemon), all subsequent calls through the existing TKTokenDriverConfiguration reference silently fail. Specifically: [TKTokenDriverConfiguration driverConfigurations] returns the same stale object - it does not establish a new connection to the newly-started ctkd process. There is no error, no exception, and no indication the returned object is invalid. driver.tokenConfigurations[@"setoken"] still returns a non-nil value reflecting the pre-restart state - so any nil check intended to detect "token not registered with ctkd" does not fire. [driver addTokenConfigurationForTokenInstanceID:@"setoken"] appears to succeed (no error) but the token is not actually registered with the new ctkd instance. Setting tokenCfg.keychainItems = updatedItems appears to succeed but the new ctkd instance has no knowledge of the update. The only reliable recovery we've found is restarting the container app process itself, at which point [TKTokenDriverConfiguration driverConfigurations] returns a fresh object connected to the new ctkd instance. What we've investigated There is no public API on TKTokenDriverConfiguration to invalidate or refresh the internal XPC connection to ctkd TKTokenWatcher can observe token insertions/removals, but we found no documented way to use it to detect a ctkd process restart specifically The NSXPCConnection invalidation handler pattern is not accessible through the TKTokenDriverConfiguration abstraction Moving credential management into the appex extension. Since the appex extension is recreated when the ctkd process restarts, we are able to update keychainItems from the extension. However, this comes with it's own set of problems: the extension is ephemeral and using the keychain APIs directly from the extension is not well documented and does not appear to be a supported pattern. Questions Is there a supported API to detect that ctkd has restarted and that the existing TKTokenDriverConfiguration reference is no longer valid? Is there a supported way to obtain a fresh TKTokenDriverConfiguration without restarting the container app? Should the container app be re-architected to avoid holding long-lived TKTokenDriverConfiguration references?
4
0
355
Mar ’26
password to unlock login keychain in 26.4?
I lived with knowledge that one needs to provide his login password to unlock the login keychain. This does not seem to be entirely true after upgrading Tahoe to 26.4. For example, on 26.3: Go to ~/Library/Keychains Copy login.keychain-db to different name, say test.keychain-db. Double-click on test.keychain-db -> this should open Keychain Access with test in Custom keychains section, it will appear locked. Select test keychain and press Cmd+L to unlock it. When prompted, provide your login password. Result: the keychain is unlocked. When I preform above sequence of steps on 26.4 I am not able to unlock the copied keychain (the original login keychain appears implicitly unlocked).
2
0
332
Mar ’26
Endpoint Security entitlement for open-source behavioral monitoring tool
Hi, I’m building a macOS tool that analyzes process behavior to detect autonomous / AI-like activity locally (process trees, file access patterns, and network usage). The system is fully user-space and runs locally in real time. I’m planning to use the Endpoint Security Framework for process and file event monitoring. This is an open-source project (non-enterprise), developed by a solo developer. My question: What are the realistic chances of getting Endpoint Security entitlements approved for this type of project? Are there specific requirements or common reasons for rejection I should be aware of? Thanks, sivan-rnd
2
0
214
Mar ’26
TkSmartCard transmitRequest persistently returning Cryptotokenkit error -2 on iOS/iPadOS
We are using the CryptoTokenKit framework, specifically the classes TKSmartCardSlotManager, TKSmartCardSlot, and TKSmartCard, to communicate with smart cards through external USB readers on iOS and iPadOS. In most cases, we are able to detect readers via TKSmartCardSlotManager, and send APDU commands using transmitRequest method, with the following code (where self->_slot and self->_card are previously created TkSmartCardSlot and TkSmartCard, respectively): #import <CryptoTokenKit/CryptoTokenKit.h> - (NSData *)sendCardCommand:(NSData *)command { if (!self->_card || !self->_card.valid || self->_slot.state != TKSmartCardSlotStateValidCard) return nil; NSMutableData *res = [[NSMutableData alloc] init]; NSError *sessionError = nil; [self->_card inSessionWithError:&sessionError executeBlock:^BOOL(NSError **error) { dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); try { [self->_card transmitRequest:command reply:^(NSData * _Nullable response, NSError* _Nullable apduError) { if (apduError != nil) self->_error = apduError; else [res appendData: response]; dispatch_semaphore_signal(semaphore); }]; } catch (NSException *exception) { dispatch_semaphore_signal(semaphore); } dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); if (res.length == 0) return NO; return YES; }]; return res; } However, with certain other USB smart card readers, we occasionally encounter APDU communication failures when calling transmitRequest (for instance, with a HID Global OMNIKEY 5422), which returns the following error: "Domain: CryptoTokenKit Code: -2". Once a failure occurs and transmitRequest starts returning this error, all subsequent calls to transmitRequest fail with the same error. This persists even when: A different smart card is inserted The same card is reinserted A different USB reader (previously working correctly) is connected The TKSmartCard object is recreated via makeSmartCard The slot state changes (observed via KVO) All internal objects (TKSmartCard, TKSmartCardSlot) are reset in the application At this point, the system appears to be stuck in a non-recoverable state which affects all readers and cards, including those that were previously functioning correctly. The only way to recover from this state is terminating and restarting the application which is running the code. After restarting the app, everything works normally again. We have created a bug report: FB22339746. The issue has been reproduced on iOS 26.4 and 18.5. Also on iPadOS 18.1. Anyone has already faced a similar issue? Could it be related to some internal state of TKSmartCardSlotManager?
2
0
294
Mar ’26
SPF verification fails for long records (3+ DNS TXT strings) in Private Email Relay
Hi, we are experiencing a specific issue with the Private Email Relay service. Our domain e.glassesdirect.co.uk consistently fails SPF verification while our other domains pass. The Pattern: We've noticed that domains with SPF records fitting in 1-2 TXT strings pass, but this specific domain (~750 chars, 3 TXT strings) fails. Technical Details: Team ID: SM2J7LWD33 Domain: e.glassesdirect.co.uk SPF Record length: ~750 characters Third-party tools (MxToolbox) confirm the record is valid. We suspect Apple's verification parser might be failing to handle concatenated TXT strings or hitting a size limit. Could any Apple engineers confirm if there is a character limit or a bug in handling multi-part TXT records?
Replies
0
Boosts
0
Views
191
Activity
Apr ’26
Cannot set nested subdomains in web auth configuration
For my api I have a domain scheme of env.service.example.com. I am trying to setup sign in with apple, however, when trying to set my return urls, the env subdomain is stripped, making the return url incorrect. For example, when I try to set https://env.service.example.com/ it is changed to https://service.example.com/ when submitted. Is there any way around this issue?
Replies
0
Boosts
0
Views
132
Activity
Apr ’26
[KeyChain Framework] KeyChain Item is accessible post App Transfer without rebuilding the KeyChain
We have utilised the KeyChain Framework for Adding items into KeyChain. We have Generated KeyPair using 'SecKeyGeneratePair' API as below (OSStatus)generateAssymetricKeyPair:(NSUInteger)bitSize{ OSStatus sanityCheck = noErr; SecKeyRef publicKeyRef = NULL; SecKeyRef privateKeyRef = NULL; NSString *appGrpIdentifier = @"group.com.sample.xyz" // Set the private key attributes. NSDictionary *privateKeyAttr = @{(id)kSecAttrIsPermanent: @YES, (id)kSecAttrApplicationTag: [TAG_ASSYMETRIC_PRIVATE_KEY dataUsingEncoding:NSUTF8StringEncoding], (id)kSecAttrCanEncrypt:@NO, (id)kSecAttrCanDecrypt:@YES, (id)kSecAttrAccessGroup: appGrpIdentifier }; // Set the public key attributes. NSDictionary *publicKeyAttr = @{(id)kSecAttrIsPermanent: @YES, (id)kSecAttrApplicationTag: [TAG_ASSYMETRIC_PUBLIC_KEY dataUsingEncoding:NSUTF8StringEncoding], (id)kSecAttrCanEncrypt:@YES, (id)kSecAttrCanDecrypt:@NO, (id)kSecAttrAccessGroup: appGrpIdentifier }; // Set top level attributes for the keypair. NSDictionary *keyPairAttr = @{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeRSA, (id)kSecAttrKeySizeInBits: @(bitSize), (id)kSecClass: (id)kSecClassKey, (id)kSecPrivateKeyAttrs: privateKeyAttr, (id)kSecPublicKeyAttrs: publicKeyAttr, // MOBSF-WARNING-SUPPRESS: (id)kSecAttrAccessible: (id)kSecAttrAccessibleAfterFirstUnlock, // mobsf-ignore: ios_keychain_weak_accessibility_value // MOBSF-SUPPRESS-END (id)kSecAttrAccessGroup: appGrpIdentifier }; // Generate Assymetric keys sanityCheck = SecKeyGeneratePair((CFDictionaryRef)keyPairAttr, &publicKeyRef, &privateKeyRef); if(sanityCheck == errSecSuccess){ NSLog(@"[DB_ENCRYPTION] <ALA_INFO> [OS-CCF] CALLED Assymetric keys are generated"); } else{ NSLog(@"[DB_ENCRYPTION] <ALA_ERROR> [OS-CCF] CALLED Error while generating asymetric keys : %d", (int)sanityCheck); } if (publicKeyRef) { CFRelease(publicKeyRef); } if (privateKeyRef) { CFRelease(privateKeyRef); } return sanityCheck; } KeyPair is added into the KeyChain (BOOL)saveSymetricKeyToKeychain:(NSData *)symmetricKeyData keyIdentifier:(NSString *)keyIdentifier { NSString *appGrpIdentifier = [KeychainGroupManager getAppGroupIdentifier]; NSDictionary *query = @{ (__bridge id)kSecClass: (__bridge id)kSecClassKey, (__bridge id)kSecAttrApplicationTag: keyIdentifier, (__bridge id)kSecValueData: symmetricKeyData, (__bridge id)kSecAttrKeyClass: (__bridge id)kSecAttrKeyClassSymmetric, // MOBSF-WARNING-SUPPRESS: (__bridge id)kSecAttrAccessible: (__bridge id)kSecAttrAccessibleAfterFirstUnlock, // mobsf-ignore: ios_keychain_weak_accessibility_value // MOBSF-SUPPRESS-END (__bridge id)kSecAttrAccessGroup: appGrpIdentifier }; // Now add the key to the Keychain status = SecItemAdd((__bridge CFDictionaryRef)query, NULL); if (status == errSecSuccess) { NSLog(@"[DB_ENCRYPTION] Key successfully stored in the Keychain"); return YES; } else { NSLog(@"<ALA_ERROR> [DB_ENCRYPTION] Error storing key in the Keychain: %d", (int)status); return NO; } } Post App Transfer, we are able to retrieve the Public & Private Key Reference without rebuilding the keychain Query:- Is this attribute "kSecAttrAccessGroup" helping us to retrieve the KeyChain items without having to rebuild on App Transfer to New Apple Account as described in this set of guidelines. Could you please explain in detail on this. https://developer.apple.com/help/app-store-connect/transfer-an-app/overview-of-app-transfer Keychain sharing continues to work only until the app is updated. Therefore, you must rebuild the keychain when submitting updates. If your keychain group is defined in the Xcode project, replace it with a group created by the recipient, incorporating their Team ID for continued keychain sharing. After the update, users must re-login once as the app cannot retrieve the authentication token from the keychain.
Replies
1
Boosts
0
Views
122
Activity
Apr ’26
[Apple Sign-In] How to handle missing transfer_sub and the 60-day migration limit during App Transfer?
Hello everyone, We are currently preparing for an App Transfer to a new Apple Developer account due to a corporate merger. We are trying to figure out the best way to handle Apple Sign-In user migration and would love to get some advice on our proposed fallback plan. 📌 Current Situation We need to transfer our app's ownership to a new corporate entity. The app heavily relies on Apple Sign-In. The Issue: We did not collect the transfer_sub values during our initial development phase. Although we started collecting them recently, we will not have them for all existing users by the time the transfer happens. 🚨 The Risk (The 60-Day Rule) Based on Apple's documentation, even if we provide the transfer_sub, users must log into the app within 60 days of the transfer to successfully migrate their accounts. This means that users who log in after 60 days, or those whose transfer_sub is missing, will fail the Apple migration process. They will be treated as "new users" and will lose access to their existing account data. 💡 Our Proposed Custom Recovery Flow Since we cannot rely entirely on Apple's automated migration, we are planning to build a custom internal account recovery process to prevent user drop-off: A user (who failed the migration or logged in after 60 days) attempts to use Apple Sign-In on the transferred app. Since the existing account isn't linked, Apple generates a new identifier (sub), and the user enters the new sign-up flow. During the sign-up process, we enforce a mandatory identity verification step (e.g., SMS phone number verification). We query our existing user database using this verified information. If a matching existing user is found: We interrupt the sign-up process and display a prompt: "An existing account was found. We will link your account." We then update our database by mapping the new Apple sub value to their existing account record, allowing them to log in seamlessly. ❓ My Questions App Review Risk: Could this manual mapping approach—overwriting the Apple sub on an existing account based on internal identity verification—violate any Apple guidelines or result in an App Store rejection? Shared Experiences: Has anyone dealt with missing transfer_sub values or the 60-day migration limit during an App Transfer? How did you mitigate user loss? Best Practices: Are there any alternative, safer, or more recommended workarounds for this scenario?
Replies
0
Boosts
0
Views
179
Activity
Apr ’26
ASAuthorizationProviderExtensionAuthorizationRequest.complete(httpAuthorizationHeaders:) custom header not reaching endpoint
I’m implementing a macOS Platform SSO extension using ASAuthorizationProviderExtensionAuthorizationRequest. In beginAuthorization, I intercept an OAuth authorize request and call: request.complete(httpAuthorizationHeaders: [ "x-psso-attestation": signedJWT ]) I also tested: request.complete(httpAuthorizationHeaders: [ "Authorization": "Bearer test-value" ]) From extension logs, I can confirm the request is intercepted correctly and the header dictionary passed into complete(httpAuthorizationHeaders:) contains the expected values. However: the header is not visible in browser devtools the header does not appear at the server / reverse proxy So the question is: Does complete(httpAuthorizationHeaders:) support arbitrary custom headers, or only a restricted set of authorization-related headers ? Is there something that I might be missing ? And if custom headers are not supported, is there any supported way for a Platform SSO extension to attach a normal HTTP header to the continued outbound request ?
Replies
1
Boosts
0
Views
344
Activity
Apr ’26
DCDevice last_update_time issue
We are currently experiencing an unexpected issue with the DeviceCheck query_two_bits endpoint. According to the official documentation (Accessing and Modifying Per-Device Data), the last_update_time field should represent the month and year when the bits were last modified. The Issue: For several specific device tokens, our server is receiving a last_update_time value that is set in the future. Current Date: April 2026 Returned last_update_time: 2026-12 (December 2026) Here is a response: { "body": "{\"bit0\":false,\"bit1\":true,\"last_update_time\":\"2026-12\"}", "headers": { "Server": ["Apple"], "Date": ["Thu, 02 Apr 2026 06:05:23 GMT"], "Content-Type": ["application/json; charset=UTF-8"], "Transfer-Encoding": ["chunked"], "Connection": ["keep-alive"], "X-Apple-Request-UUID": ["53e16c38-d9f7-4d58-a354-ce07a4eaa35b"], "X-Responding-Instance": ["af-bit-store-56b5b6b478-k8hnh"], "Strict-Transport-Security": ["max-age=31536000; includeSubdomains"], "X-Frame-Options": ["SAMEORIGIN"], "X-Content-Type-Options": ["nosniff"], "X-XSS-Protection": ["1; mode=block"] }, "statusCode": "OK", "statusCodeValue": 200 } Technical Details: Endpoint: https://api.development.devicecheck.apple.com/v1/query_two_bits (also occurring in Production) Response Body Example: JSON { "bit0": true, "bit1": false, "last_update_time": "2026-12" } Observations: This occurs even when our server has not sent an update_two_bits request for that specific device in the current month. Questions: Is there a known issue with the timestamp synchronization or regional database propagation for DeviceCheck? Does the last_update_time field ever represent an expiration date or any value other than the "last modified" month? Best regards,
Replies
1
Boosts
0
Views
146
Activity
Apr ’26
DeviceCheck query_two_bits returns last_update_time in the future — what could cause this?
Hi everyone, I'm integrating Apple's DeviceCheck API into my app and have run into a strange issue that I can't find documented anywhere. The Problem When I call Apple's DeviceCheck query endpoint (POST https://api.devicecheck.apple.com/v1/query_two_bits), the response occasionally returns a last_update_time value that is in the future — ahead of the current server time. Example response: { "bit0": true, "bit1": false, "last_update_time": "2026-05" // future month, not yet reached } What I've Checked My server's system clock is correctly synced via NTP The JWT token I generate uses the current timestamp for the iat field This doesn't happen on every device — only on some specific devices The issue is reproducible on the same device across multiple calls Questions Is last_update_time sourced from the device's local clock at the time update_two_bits was called? Or is it stamped server-side by Apple? Could a device with an incorrectly set system clock (set to the future) cause Apple's servers to record a future last_update_time? Is there a recommended way to validate or sanitize last_update_time on the server side to handle this edge case? Has anyone else encountered this behavior? Any known workarounds? Any insight would be greatly appreciated. Thanks!
Replies
1
Boosts
0
Views
140
Activity
Apr ’26
Production-Grade Implementation Guidance: DCError Matrices, Retry Strategies, and Simulator Testing for App Attest APIs
Hi there, We're implementing Apple's DeviceCheck App Attest for production iOS authentication. The public documentation defines DCError cases but doesn't specify which errors are expected per API method or recommend retry/remediation strategies. We need Apple's guidance to implement robust, production-aligned error handling before rollout. 1. Error Surface per API Method Question: Can you confirm the complete, officially expected set of DCError values for each method? We understand the following errors are possible across App Attest APIs: invalidKey invalidInput featureUnsupported serverUnavailable unknownSystemFailure Specifically, please confirm which errors can occur for: DCAppAttestService.generateKey() DCAppAttestService.attestKey(_:clientData:) DCAppAttestService.generateAssertion(keyID:clientData:) Are there any additional undocumented or edge-case errors we should handle? 2. Retry Strategy & Remediation Matrix Question: For each API method and error code, please help us with proposal around which errorCode is retriable, whats the remediation pre retry, retry cap and backoff strategy: Kindly also help with errors that are not covered here: Specific sub-questions: invalidKey handling: When this error occurs: Should the app delete the key and call generateKey again? Or should it fail the entire flow? serverUnavailable handling: Should we retry immediately, or wait before retrying? Is exponential backoff recommended? What's the recommended max retry count? Backoff strategy: Which errors (if any) qualify for exponential backoff? Recommended base delay, max delay, and jitter approach? When should we give up and fail the request? unknownSystemFailure: Is this retriable or should we fail? Any known causes or mitigations? 3. Simulator Testing Questions: Simulator API behavior: Can App Attest APIs be called normally on iOS Simulator? If not, is there a way to simulate for testing. Do they complete successfully with simulated attestations, or do they fail? Thanks, Nirekshitha
Replies
0
Boosts
0
Views
331
Activity
Apr ’26
SFAuthorizationPluginView
I’ve developed an authorization plug-in with a mechanism that runs an SFAuthorizationPluginView subclass and I’m facing a couple issues: - Glitch after successful login After setting kAuthorizationResultAllow in the context the user is successfully logged in and brought to the desktop but the login controls remain onscreen for a few seconds after login is complete, resulting in them being visible at the same time as the dock, menu bar and desktop.
 I’ve also tried what’s mentioned here https://developer.apple.com/forums/thread/780212 but without any luck. It’s also worth mentioning that the deinit() in my SFAuthorizationPluginView subclass never gets called when the plugin it’s loaded at the login stage but it does get called the plugin is used to re-authenticate the user after they locked their screen. - update() doesn't trigger the plugin to call view(for:) I’m trying to update the UI elements out of my control (like buttons and user avatar images) in order to have them placed at the proper position on the screen after a resize of my inner NSView. To do that I call update() but it appears that does not trigger the plugin to call view(for:) and update system UI elements placement. Is this the expected behavior? - setButton not working as expected 
I’m trying to disable the login button by calling the setButton(_:enabled:) passing a SFButtonTypeLogin as inButtonType, as suggested here: https://developer.apple.com/forums/thread/777432. When the method is called at the login screen it has no effect on the button (the one with the forward-arrow icon) but when it’s called by the plugin loaded at the ‘unlock screen’ stage it successfully disable the ‘OK’ button. - Certificate issue When trying to run a network request from the plugin loaded in the ‘unlock screen’ scenario, I always get this type of error: The certificate for this server is invalid. You might be connecting to a server that is pretending to be <<server_url>> which could put your confidential information at risk Everything works as expected when the plugin is loaded either at login screen or for authorizing an operation that requires admin privileges while the user is logged in.
Replies
3
Boosts
0
Views
483
Activity
Apr ’26
launch ASWebAuthenticationSession from single sign on extenstion
I need to launch ASWebAuthenticationSession from single sign on extension, but its not launching it might issue with anchoring window, I have create custom windo and passing it in presentanchor(for session) function, custom window is launching but ASWebAuthenticationSession browser is not launching Note - flow is like this Apple PSSO register window lauched OIDC login will happen via ASWebAuthenticationSession to get accesstoken which will use in device registration but ASWebAuthenticationSession is not launching, I am using custom scheme as redirect URI iskeywindow for custom window is always false what is right approach to achieve the goal
Replies
1
Boosts
0
Views
197
Activity
Apr ’26
iPhone 16 Datasheet
I am trying to find a datasheet containing information such as "Key Exchange / Key Agreement / Key Establishment Protocols Used", "Digital Signature Algorithms Used", "Hash Algorithms Used", etc. Any information would greatly appreciated.
Replies
1
Boosts
0
Views
109
Activity
Mar ’26
Exploring Secure Enclave–backed biometric authorization between macOS and iPhone using public APIs (FaceBridge prototype)
Hi everyone, I’ve been working on an experimental prototype called FaceBridge that explores whether Secure Enclave–backed biometric authorization can be delegated between macOS and iPhone using only public Apple APIs. The goal of the project was to better understand the architectural boundaries of cross-device trust and approval flows that resemble Apple’s built-in Touch ID / Continuity authorization experiences. FaceBridge implements a local authorization pipeline where: macOS generates a signed authorization request the request is delivered to a trusted nearby iPhone over BLE / Network framework the iPhone verifies sender identity Face ID approval is requested using LocalAuthentication the iPhone signs the approval response using Secure Enclave–backed keys macOS validates the response and unlocks a protected action Security properties currently implemented: • Secure Enclave–backed signing identities per device • cryptographic device pairing and trust persistence • replay protection using nonce + timestamp binding • structured authorization request/response envelopes • signed responder identity verification • trusted-device registry model • local encrypted transport over BLE and local network This is intentionally not attempting to intercept or replace system-level Touch ID dialogs (App Store installs, Keychain prompts, loginwindow, etc.), but instead explores what is possible within application-level authorization boundaries using public APIs only. The project is open source: https://github.com/wesleysfavarin/facebridge Technical architecture write-up: https://medium.com/@wesleysfavarin/facebridge I’m particularly interested in feedback around: • recommended Secure Enclave identity lifecycle patterns • best practices for cross-device trust persistence • LocalAuthentication usage in delegated approval scenarios • whether similar authorization models are expected to become more formally supported across Apple platforms in the future Thanks in advance for any guidance or suggestions.
Replies
1
Boosts
0
Views
258
Activity
Mar ’26
TEAM ID Prefix Keychain Access
Thanks all for reading my post. A bit of context: We just finished an app transfer to our developer account. We successfully signed and generated the new release. We are already able to roll it out in testflight were we found an issue. We store valuable data in the Keychain like Authentication tokens, once the new app is installed over the old one we are experiencing a loss of all data as the keychain become "untrusted". This is worst case scenario for us because all users will immediately lose the access to the app and hence the whole system. Questions: Is there a way to solve this issue, something like migration of the Keychain data? We came to know the standard migration path: Release a version that copies items from the old access groups to a new group based on com.apple.security.application-groups (App Groups). Wait for most users to update and run the migration. Then perform the App ID prefix change. Is this still the best method? Any improvements or new tools available since the 2022 DTS post? The problem with this is that the app is already on our account and that might need to rollback the transfer. Right? How long should we realistically wait for user migration before making the prefix change? Is there a way to measure migration completion? Thank you in advance!
Replies
1
Boosts
0
Views
183
Activity
Mar ’26
Sign in with Apple Web: invalid_client on token exchange with real authorization code, but invalid_grant with dummy code
We are integrating Sign in with Apple for our web application and have been stuck on an invalid_client error during the token exchange step. The Problem The authorization step works fine — the user authenticates on Apple's page and a valid authorization code is returned to our callback URL. However, when we exchange that code at https://appleid.apple.com/auth/token, it returns: {"error": "invalid_client"} The Puzzling Part When we send a dummy/expired authorization code with the exact same client_id and client_secret, Apple returns: {"error": "invalid_grant", "error_description": "The code has expired or has been revoked."} This confirms that our client credentials (client_id + client_secret JWT) are valid and accepted by Apple. The invalid_client error only occurs when a real, freshly-issued authorization code is used. Configuration Service ID configured with Sign in with Apple enabled Primary App ID with Sign in with Apple capability enabled Domain verified, Return URL registered Key created with Sign in with Apple enabled, linked to the correct Primary App ID Client Secret JWT Generated per Apple's documentation: Header: alg: ES256, kid set to our Key ID Claims: iss: Team ID iat: current timestamp exp: iat + 6 months (within Apple's limit) aud: https://appleid.apple.com sub: Service ID (matches the client_id used in authorization) Signed with: the .p8 private key associated with the Key Token Exchange Request POST https://appleid.apple.com/auth/tokenContent-Type: application/x-www-form-urlencodedclient_id=client_secret=code=grant_type=authorization_coderedirect_uri= What We've Tried Standalone test endpoint — built a minimal endpoint (no framework) that does the token exchange via server-side curl. Same invalid_client. Multiple Service IDs — created and tried 3 different Service IDs. All produce the same error with real codes. Multiple Keys — tried 2 different keys. Same error. Verified redirect_uri matches exactly between the authorization request and token request. Verified client_id matches exactly between the authorization URL and token request. Used client_secret_post (credentials in body, not Basic auth header). Freshness — code is used immediately upon receipt (within seconds), well before the 5-minute expiry. Filed a Developer Support case — was directed to Forums. Summary Scenario code Result Dummy/expired code abc123 invalid_grant (credentials accepted) Real fresh code from Apple callback invalid_client This pattern suggests something goes wrong specifically when Apple validates the authorization code against the client — even though the client credentials themselves are accepted in isolation. Has anyone encountered this behavior? Is there a known configuration issue that could cause invalid_client only with valid authorization codes? Any guidance would be greatly appreciated.
Replies
0
Boosts
0
Views
275
Activity
Mar ’26
TKTokenDriverConfiguration becomes permanently unusable after ctkd process restart
Background We're building a macOS application that acts as a CryptoTokenKit software token. The architecture follows the documented pattern: a container app (a long-running agent process) manages token registration and identity updates via TKTokenDriverConfiguration, and a separate appex extension process handles the actual signing operations for client sessions. What we're doing At agent startup, the container app calls [TKTokenDriverConfiguration driverConfigurations] to obtain our token driver, then registers a token instance ID: NSDictionary<TKTokenDriverClassID, TKTokenDriverConfiguration *> *driverConfigurations = [TKTokenDriverConfiguration driverConfigurations]; TKTokenDriverConfiguration driver = / first value from driverConfigurations */; [driver addTokenConfigurationForTokenInstanceID:@"setoken"]; When the agent renews a certificate, it pushes updated TKTokenKeychainItem objects to ctkd by setting keychainItems on the TKTokenConfiguration: TKTokenConfiguration *tokenCfg = driver.tokenConfigurations[@"setoken"]; tokenCfg.keychainItems = updatedItems; This works correctly during normal operation. The failure When ctkd is restarted (e.g., killall ctkd, or the system restarts the daemon), all subsequent calls through the existing TKTokenDriverConfiguration reference silently fail. Specifically: [TKTokenDriverConfiguration driverConfigurations] returns the same stale object - it does not establish a new connection to the newly-started ctkd process. There is no error, no exception, and no indication the returned object is invalid. driver.tokenConfigurations[@"setoken"] still returns a non-nil value reflecting the pre-restart state - so any nil check intended to detect "token not registered with ctkd" does not fire. [driver addTokenConfigurationForTokenInstanceID:@"setoken"] appears to succeed (no error) but the token is not actually registered with the new ctkd instance. Setting tokenCfg.keychainItems = updatedItems appears to succeed but the new ctkd instance has no knowledge of the update. The only reliable recovery we've found is restarting the container app process itself, at which point [TKTokenDriverConfiguration driverConfigurations] returns a fresh object connected to the new ctkd instance. What we've investigated There is no public API on TKTokenDriverConfiguration to invalidate or refresh the internal XPC connection to ctkd TKTokenWatcher can observe token insertions/removals, but we found no documented way to use it to detect a ctkd process restart specifically The NSXPCConnection invalidation handler pattern is not accessible through the TKTokenDriverConfiguration abstraction Moving credential management into the appex extension. Since the appex extension is recreated when the ctkd process restarts, we are able to update keychainItems from the extension. However, this comes with it's own set of problems: the extension is ephemeral and using the keychain APIs directly from the extension is not well documented and does not appear to be a supported pattern. Questions Is there a supported API to detect that ctkd has restarted and that the existing TKTokenDriverConfiguration reference is no longer valid? Is there a supported way to obtain a fresh TKTokenDriverConfiguration without restarting the container app? Should the container app be re-architected to avoid holding long-lived TKTokenDriverConfiguration references?
Replies
4
Boosts
0
Views
355
Activity
Mar ’26
Feedback Hub Error When Forgot Password
I am not able to use Feedback because the app can not reset my password.
Replies
1
Boosts
0
Views
188
Activity
Mar ’26
password to unlock login keychain in 26.4?
I lived with knowledge that one needs to provide his login password to unlock the login keychain. This does not seem to be entirely true after upgrading Tahoe to 26.4. For example, on 26.3: Go to ~/Library/Keychains Copy login.keychain-db to different name, say test.keychain-db. Double-click on test.keychain-db -> this should open Keychain Access with test in Custom keychains section, it will appear locked. Select test keychain and press Cmd+L to unlock it. When prompted, provide your login password. Result: the keychain is unlocked. When I preform above sequence of steps on 26.4 I am not able to unlock the copied keychain (the original login keychain appears implicitly unlocked).
Replies
2
Boosts
0
Views
332
Activity
Mar ’26
Endpoint Security entitlement for open-source behavioral monitoring tool
Hi, I’m building a macOS tool that analyzes process behavior to detect autonomous / AI-like activity locally (process trees, file access patterns, and network usage). The system is fully user-space and runs locally in real time. I’m planning to use the Endpoint Security Framework for process and file event monitoring. This is an open-source project (non-enterprise), developed by a solo developer. My question: What are the realistic chances of getting Endpoint Security entitlements approved for this type of project? Are there specific requirements or common reasons for rejection I should be aware of? Thanks, sivan-rnd
Replies
2
Boosts
0
Views
214
Activity
Mar ’26
TkSmartCard transmitRequest persistently returning Cryptotokenkit error -2 on iOS/iPadOS
We are using the CryptoTokenKit framework, specifically the classes TKSmartCardSlotManager, TKSmartCardSlot, and TKSmartCard, to communicate with smart cards through external USB readers on iOS and iPadOS. In most cases, we are able to detect readers via TKSmartCardSlotManager, and send APDU commands using transmitRequest method, with the following code (where self->_slot and self->_card are previously created TkSmartCardSlot and TkSmartCard, respectively): #import <CryptoTokenKit/CryptoTokenKit.h> - (NSData *)sendCardCommand:(NSData *)command { if (!self->_card || !self->_card.valid || self->_slot.state != TKSmartCardSlotStateValidCard) return nil; NSMutableData *res = [[NSMutableData alloc] init]; NSError *sessionError = nil; [self->_card inSessionWithError:&sessionError executeBlock:^BOOL(NSError **error) { dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); try { [self->_card transmitRequest:command reply:^(NSData * _Nullable response, NSError* _Nullable apduError) { if (apduError != nil) self->_error = apduError; else [res appendData: response]; dispatch_semaphore_signal(semaphore); }]; } catch (NSException *exception) { dispatch_semaphore_signal(semaphore); } dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); if (res.length == 0) return NO; return YES; }]; return res; } However, with certain other USB smart card readers, we occasionally encounter APDU communication failures when calling transmitRequest (for instance, with a HID Global OMNIKEY 5422), which returns the following error: "Domain: CryptoTokenKit Code: -2". Once a failure occurs and transmitRequest starts returning this error, all subsequent calls to transmitRequest fail with the same error. This persists even when: A different smart card is inserted The same card is reinserted A different USB reader (previously working correctly) is connected The TKSmartCard object is recreated via makeSmartCard The slot state changes (observed via KVO) All internal objects (TKSmartCard, TKSmartCardSlot) are reset in the application At this point, the system appears to be stuck in a non-recoverable state which affects all readers and cards, including those that were previously functioning correctly. The only way to recover from this state is terminating and restarting the application which is running the code. After restarting the app, everything works normally again. We have created a bug report: FB22339746. The issue has been reproduced on iOS 26.4 and 18.5. Also on iPadOS 18.1. Anyone has already faced a similar issue? Could it be related to some internal state of TKSmartCardSlotManager?
Replies
2
Boosts
0
Views
294
Activity
Mar ’26