As I've thought about my app’s use case a bit more, I'm beginning to think I don't even need a passkey. I’m not 100% sure about this, though.
All of this thinking is in the context of my app and server using Apple App Attestation to ensure it’s the only thing making requests.
My app needs to interact with its server to provide some background processing for the user that I can't rely on iOS to provide: it needs to wake up at a specified time, do some small network calls to a third party that can take some time to complete (waiting for the other end), and then, depending on the result of those network calls, notify the user. (I had initially coded this using the the available iOS APIs, and found them unreliable. I then used OneSignal to schedule background push notifications that were more reliable, but iOS wouldn't let my app wake long enough to complete the network requests. This, coupled with OneSignal changes, led me to making my own server). By pushing the scheduling and network calls to my server, I didn't have to rely on iOS.
But now the server has to differentiate users and store a per-user auth token for the third-party server. That made me think I needed passkeys to safely identify each user.
But now I'm thinking perhaps not. During onboarding, my app can request an identifying token from the server (much like the auth token it gets after a successful passkey ceremony). It then sends that on all subsequent requests. Stored in iCloud Keychain, that should allow them to connect their other devices to the same account, right?
I think this is secure, in that no unauthorized person should be able to access a given user’s account on my server. There may be a risk that the user loses access to their account state on the server, if they ever lose that auth token. But in this application, the server state is fairly easy to re-create from scratch, I think.
Thoughts?
• App Attestation ensures all requests come only from my app.
• Server generates a user-identifying token, app stores it in iCloud Keychain.
• App sends that token with all user-centric requests.
At no point does the user have to concern themselves with creating or remembering a user account, or even using passkeys.
(I do hate that I’ll be discarding all that lovely passkey work I did, but I’ll need it on another project soon enough).
Post
Replies
Boosts
Views
Activity
I have the exact same issue. It seems the address information is stored in more than one place. If I look at my account membership details, it shows the new address. But the banner shown during the compliance flow shows my old addresses under two entities, my LLC and my Personal one.
I went through ADP tech support (sent them an email) to see if they could update it.
But then I went ahead and proceeded with the compliance steps, and it pre-populated the address form with the correct address, so maybe it will work for you too.
I should clarify: My app will use only passkeys for signin. No username/password. I kinda don’t want usernames to be visible to the user at all, but I suppose they're necessary to allow different users to use the same device.
I'm watching the video now, looking for those options. I have some other feedback too:
Avoiding Typing Wherever Possible
In the example where you want to log into your account on your friend’s PC, the flow requires you to type in your username first. I don't know if that's a WebAuthn requirement, or something that site implemented, but I think a better experience would be for there to be a "Log in as Someone Else" button that presents the QR code without requiring me to type something (it can be very hard to type on some devices). The QR code can identify the relying party, device, and challenge to whatever other device is used for authentication. That latter device can then provide the username and signed challenge to the server (presenting the owner with options for different usernames), which can complete the loop with the PC.
Before I learned about passkeys, I built a similar flow for CNC machines that have awful user interfaces.
Streamlining
Ah, it looks like .preferImmediatelyAvailableCredentials might help me!
The only thing I think I might like to have is a "Create Account" button on the OS sign-in form that calls back my delegate so I can lead the user through creating an(other) account.
When I try to just sign in without any credentials, it presents a QR code. That is, when it doesn't report an error that the app site association is bad (seems to alternate with subsequent attempts).
No response at all. I shut this project down a few months ago, but I think the way I solved it was to remove the header from the Bridging header, and keep the code that depended on it as Obj-C.
It's an awful view, and both the FBs I filed have been ignored.
I found a solution. It turns out that SwiftUI is creating its standard suite of menus (which I argue is incorrect for an LSUIElement app). So to my app’s SwiftUI main Window, I add the following modifier:
.commands
{
CommandGroup(replacing: .appTermination)
{
}
}
This removes the Quit menu item altogether. It might be better to call NSMenu.removeAllItems() in my app delegate, but from what I read online, SwiftUI will restore the menus, and so you have to observe NSApp.mainMenu for changes.
Once again, Apple has offered very narrow use-case solutions in SwiftUI, without more generalized support.
I'm running into this issue now, too. I disabled SIP and manually edited the TCC.db, removing all trace of my app's bundle ID (since tccutil said it couldn't find it), and it still shows up in System Settings -> Privacy & Security -> Accessibility. Double entries for each of two old apps. It must also be recorded somewhere else. Apple needs to be much more transparent about how this stuff works.
I'm trying to use Combine on macOS to get notified of change to app group UserDefaults when made from another process. I've had no end of trouble doing this. There are half a dozen guides online for how to do this in Swift, and I got it working within a single process (with the caveat that the change dictionary always has nil values).
But making a change from another process (e.g. with defaults write) does not result in my KVO or Combine sub getting called (both do get the initial value).
Now, I'm calling .observe() and .publisher(for:) on my UserDefaults object. Apple’s example for block-based KVO calls observe() on self. where self is an NSObject observer subclass, and it observes a key path through its reference to the object with the changing property. Does that matter?
I decided to try DistributedNotificationCenter. It also does not fire when another process sends a notification.
What solved it for me (on Xcode 15, not sure if this works on earlier versions) was to set the shown destinations. I'm not really sure why this option exists.
Still happens in Xcode 15b6
This answer fixed it for me: https://stackoverflow.com/a/75602571/251914
To reiterate, there is a pressing need to be able to install beta macOS versions for development and testing. Ideally, there would be complete integration with Xcode, allowing me to write in, say 13.4, targeting 14(b1), Run, have it launch in the 14 VM, and connect the debugger. It's the only practical way to develop for unreleased macOS versions. iOS has the simulator. But macOS has either dual-booting, or buying a second Mac. Neither is practical.
I'd be okay with it being a special VM built into Xcode, and not something that would work on Parallels, for example, although I'm sure that restricts a lot of other use cases.
@eskimo, is there a way to build my macOS app locally and then copy it over to a VM to at least try to run it?
I don't have any, despite trying to create them manually on the portal or implicitly via Xcode.
Ah, sorry I wasn't clear before. Yes, the LLC is an Organization, and I am the account holder (I created this account), as shown in the Membership Details: