I'm trying to set up server-to-server authentication with CloudKit Web Services, but keep getting AUTHENTICATION_FAILED errors. I've tried multiple environment settings and debugging approaches without success.
What I've Tried I created a Swift script to test the connection. Here's the key part that handles the authentication:
// Get current ISO 8601 date let iso8601Formatter = ISO8601DateFormatter() iso8601Formatter.formatOptions = [.withInternetDateTime] let dateString = iso8601Formatter.string(from: Date()) // Create SHA-256 hash of request body let bodyHash = SHA256.hash(data: bodyData).compactMap { String(format: "%02x", $0) }.joined() // Get path from URL let path = request.url?.path ?? "/" // String to sign let method = request.httpMethod ?? "POST" let stringToSign = "\(method):\(path):\(dateString):\(bodyHash)" // Sign the string with EC private key let signature = try createSignature(stringToSign: stringToSign) // Add headers request.setValue(dateString, forHTTPHeaderField: "X-Apple-CloudKit-Request-ISO8601Date") request.setValue(KEY_ID, forHTTPHeaderField: "X-Apple-CloudKit-Request-KeyID") request.setValue(signature, forHTTPHeaderField: "X-Apple-CloudKit-Request-SignatureV1") }
I've made a request to this endpoint:
What's Happening I get a 401 status with this response:
"uuid" : "173179e2-c5a5-4393-ab4f-3cec194edd1c", "serverErrorCode" : "AUTHENTICATION_FAILED", "reason" : "Authentication failed" }
What I've Verified
The key validates correctly and generates signatures The date/time is synchronized with the server The key ID matches what's in CloudKit Dashboard I've tried all three environments: development, Development (capital D), and production The container ID is formatted correctly
Debug Information My debugging reveals:
The EC key is properly formatted (SEC1 format) Signature generation works No time synchronization issues between client and server All environment tests return the same 401 error
Questions
Has anyone encountered similar issues with CloudKit server-to-server authentication? Are there specific container permissions needed for server-to-server keys? Could there be an issue with how the private key is formatted or processed? Are there any known issues with the CloudKit Web Services API that might cause this?
Any help would be greatly appreciated!
The way to set up a CloudKit server-to-server key is detailed in the following sample:
- Server-side CloudKit with node.js (https://cdn.apple-cloudkit.com/cloudkit-catalog/#readme/Server-side-CloudKit-with-node-js).
You can start with going through the process to set up a key that works before applying it to your Swift code. That should help confirm that the key is correct.
If the key works with JS, but not with Swift, it is likely the the data format in your HTTP request has something wrong.
Best,
——
Ziqiao Chen
Worldwide Developer Relations.