3

I'm having trouble getting this to work. I keep getting the following error:

[Error: No key provided to sign]

Here is my config code:

CloudKit.configure({
  services: {
    fetch: fetch
  },
  containers: [{
    containerIdentifier: 'iCloud.io.shakd.Command-Center',
    environment: 'development',
    serverToServerKeyAuth: {
        keyID: "MyKeyId",
        privateKeyFile: "./eckey.pem",
        privateKeyPassPhrase: "MyPassPhrase"
    }

  }]
})

Also, what is the privateKeyPassPhrase? Is it the code that was generated in the terminal?

shakked
  • 783
  • 8
  • 24

2 Answers2

3

Apple's sample code at CloudKit Catalog: An Introduction to CloudKit (Cocoa and JavaScript), shows that the required syntax for privateKeyFile is to prepend __dirname (the directory of the executing Node script) to the eckey.pem file. From config.js:

serverToServerKeyAuth: {
    keyID: '<insert key ID>',
    privateKeyFile: __dirname + '/eckey.pem'
}

The second critical piece of information is that after configuring CloudKit, you have to explicitly sign in using setUpAuth(). From index.js:

var container = CloudKit.getDefaultContainer();
var database = container.publicCloudDatabase; // We'll only make calls to the public database.

// Sign in using the keyID and public key file.
container.setUpAuth().then(function (userInfo) {
    println("userInfo", userInfo);
    return database.performQuery({ recordType: 'Test' });
}).then(function (response) {
    println("Queried Records", response.records);
}).catch(function (error) {
    console.warn(error);
});

After making these two changes in my JavaScript code, my script was authenticated for reading and writing to my CloudKit database.

cyanware
  • 163
  • 7
1

You only need privateKeyPassPhrase if your privateKeyFile is encrypted with a pass phrase.

The error

[Error: No key provided to sign] 

comes straight from node's crypto module.

Looks like your eckey.pem file doesn't contain a private key. You can try the following to verify:

var fs = require('fs');
var crypto = require('crypto');
var privateKey = fs.readFileSync('./eckey.pem', 'utf8');
var signer = crypto.createSign('RSA-SHA256');
signer.update('message');
console.log(signer.sign(privateKey, 'base64'));

If that works, then your configuration should be:

CloudKit.configure({
  services: {
    fetch: fetch
  },
  containers: [{
    containerIdentifier: 'iCloud.io.shakd.Command-Center',
    environment: 'development',
    serverToServerKeyAuth: {
        //that looks suspicious, please use the real keyID
        keyID: "MyKeyId",
        privateKeyFile: "./eckey.pem"
    }
  }]
})
Max Gunther
  • 296
  • 2
  • 5
  • 1
    What do you mean by, "if that works"? Thanks. I got some encrypted output, but still get the error no key provided to sign. – malhal Jan 18 '17 at 14:36