4

So I read through the example which Apple gave us (CloudKit catalog) and I noticed that everytime you want to write or read you need to put your API token into the script.

Now Javascript is clientbased which means every user can read the API token and can read and write into my containers?!

This code would be in one of the Javascript files

CloudKit.configure({
locale: 'en-us',

containers: [{

// Change this to a container identifier you own.
containerIdentifier: 'com.example.apple-samplecode.cloudkit-catalog',

apiTokenAuth: {
  // And generate a web token through CloudKit Dashboard.
  apiToken: '<insert your token here>',

  persist: true, // Sets a cookie.

  signInButton: {
    id: 'apple-sign-in-button',
    theme: 'black' // Other options: 'white', 'white-with-outline'.
  },

  signOutButton: {
    id: 'apple-sign-out-button',
    theme: 'black'
  }
},

environment: 'development'
}]
});

Now the question is: am I missing something or is the solution to user a server-to-server communication over Node?

ph1psG
  • 568
  • 5
  • 24

2 Answers2

5

Here's my understanding:

API Tokens are not really meant to be private, and can't be since they're designed to be used in client-side JavaScript. Even if you tried to obfuscate the token in your code, it would be easily discovered by examining the URLs that are called during the sign in process.

The important thing to understand is that they can't do much by themselves. They allow a user to sign in to your container, and then the signed in user can read and write their own data—the same things they'd have access to if they signed in to iCloud on their iPhone or Mac and used your app there.

There's not much of a security concern because even if they take your token and write their own JavaScript, they're only messing with their own data. That said, you can use the "Allowed Origins" option to make this harder to do. (I put it that way because they could conceivably use a browser extension or something to alter the JS on your site. In general it seems wise to treat a user's CloudKit data as untrusted, even when it's coming from the API.)

Server to Server Keys are very different, and have a private key that is of course meant to be private. In that scenario anyone with the private key has read and write access to your public database. As the name implies, this is not something you'd use directly from JavaScript—you'd write your own server-side code that contacts the CloudKit API directly.

Unfortunately, while Apple has a nice red warning when you create a private Server to Server key, they don't seem to offer any security guidance on API Tokens. I'm 99% confident that this is because it's not a concern, and working on getting confirmation for that last 1%.

robotspacer
  • 2,732
  • 2
  • 28
  • 50
1

The init.js runs at client side, in the browser, you can easily notice that from the code:

<script>
        window.addEventListener('cloudkitloaded',CKCatalog.init);
</script>

This will disclose the API token to the user ...
But you can always mitigate the risk of dangerous usage on the API token by:

  • Set "Allowed Origins" of the API token to only the domain of your site;
  • Set "Sign In Callback" to your URL only;
  • etc

In short, running in client side will disclose your API token, while it is still OK if you take actions to prevent dangerous usage of your token.

marknote
  • 1,058
  • 8
  • 10