RE: https://mastodon.social/@pfandrade/116035886020550720

So can we actually use CloudKit's public database to store user-specific and/or sensitive data without it being widely available? So it's more like a traditional database an app can build functionality on?

Can anyone confirm this?

If that's the case, I've totally misunderstood the public database for years. I have always considered it suitable only for sample data and other data meant to be broadly accessible without auth.

@simonbs @pfandrade I'm pretty sure anything stored in CloudKit for any bundle ID can be retrieved on a Mac with System Integrity Protection turned off. Security by obscurity only
@stroughtonsmith @pfandrade I'm concerned if that's the case when security roles don't list a record (e.g. the PushToken in the screenshot) for the "_world" and “_icloud” roles. In that case, I'd expect records of that type only to be accessible by the creator and anyone authorizing with a server-to-server key.
@stroughtonsmith @simonbs if it is _world readable then everyone can read (has nothing to do with SIP).

@stroughtonsmith @simonbs @pfandrade that’s a bit pessimistic, isn’t it

CK has a bunch of crypto protections, especially for data in private db if people have Advanced Data Protection enabled

It is even end to end encrypted… sometimes, under certain conditions, which are opaque to you as a developer 🙈

https://canopy-docs.justtact.com/documentation/canopy/icloud-advanced-data-protection

Documentation

@simonbs Not that I know of, anyone can see it, it's publicly readable, even people without iCloud can read it. You can only limit writing. So I wouldn't recommend storing sensitive data. You can use it for other data. I store about 3 million records my users can read from. Nothing sensitive, just regular data anyone has access to.

@dvrzan This is also my understanding but then I started looking into the security roles. Have you played around with those?

If the "_world" and “_icloud" users don't have a role for a record (for example, the PushToken role), I don't think the world can see it, only the creator of the record and anyone authorizing with a server-to-server key.

@simonbs @dvrzan What happened when you queried it?
@dvrzan @simonbs this is incorrect. Remove the _world readable (which is the default) from a record type and it’s no longer readable by default. You could, for example, make it readable only for _icloud (authenticated users) or create your own security role and add it only to the users you want.

@pfandrade @simonbs

Oh so it is configurable and you could limit access if you wanted to. TIL, thank you!
But I think my main point still stands though. Once a client is authorized to read from the Public DB, that data is client-visible by design. It’s encrypted in transit, but any authorized user can inspect responses or replay queries from the app. So even updating the access control doesn't make it suitable to store sensitive data there.

@dvrzan @pfandrade If I understand correctly, you're both right.

All data in the public DB that's allowed by the user's security role will be visible, but if data is only readable/writable to the creator, it'll only be accessible to a single user, even if it's within the public database.

@simonbs @dvrzan @pfandrade yep correct! That’s the conclusion I also came to when working more with CloudKit a while ago. You can definitely have data in the public database that’s only readable by the user who created it.
@simonbs Do you know, @_tim______ ?
@gregggreg @_tim______ I wish I did 😄
@simonbs @_tim______ Haha, I'm asking Tim if he knows the answer. He used to work on CloudKit.

@simonbs @pfandrade you can set up public database to have various restrictions, as others explain

I thought a lot about public vs private CloudKit DB when working on @tact

The main distinction for me is, who owns the data

Private db: user owns data, I as developer literally have no way to access it. Also it’s counted towards the user’s iCloud storage quota

Public db: I as developer own the data, and my app has storage quota not tied to any user