title: How do I kill the popup?
body: <p>If you edit the following code to have valid certificate paths and a url that requires client certificates and then compile it with <code>clang++ -lcurl curl.cpp</code> on OS X (I'm using El Cap, but I think Mavericks or later behave the same way), and run the executable, you get a popup (shown below) from OS X asking if you want to allow the executable to use a private key in your keychain. This is annoying to users that know what's going on (internally curl on OS X uses the OS X security framework to load the client cert) but it's frightening for users who don't know what's happening because they think that the program is trying to access a private key in their keychain (as an aside this is an example of terrible UX from Apple as the popup message is a complete red herring). </p>
  
  <p>The curl command line tool doesn't produce a popup, so either there is a lower level API I could use or it's because the executable is signed. The real program I'm trying to add this feature to is often distributed as source code so signing the executable isn't an ideal approach, as I can't distribute the signing keys or they'll be revoked. Does anyone know how I can prevent the popup programmatically? </p>
  
  <p><a href="https://i.stack.imgur.com/wKFYf.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/wKFYf.png" alt="Popup with warning text: a wants to sign using key &quot;privateKey&quot; in your keychain. The authenticity of &quot;a&quot; cannot be verified. Do you want to allow access to this item? and buttons for Allow, Deny, and Always Allow"></a></p>
  
  <pre><code>#include &lt;curl/curl.h&gt;
  #include &lt;string&gt;
  
  using namespace std;
  
  static size_t receiveResponseBytes(void *buffer, size_t size, size_t nmemb, void *userData) {
    string *responseData = (string *) userData;
    responseData-&gt;append((const char *) buffer, size * nmemb);
    return size * nmemb;
  }
  
  void prepareCurlPOST(CURL *curl, string &amp;bodyJsonString, string *responseData, struct curl_slist **chunk) {
    curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
    curl_easy_setopt(curl, CURLOPT_URL, "https://example.dev/v1/check.json");
    curl_easy_setopt(curl, CURLOPT_HTTPGET, 0);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, bodyJsonString.c_str());
    curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, bodyJsonString.length());
    *chunk = curl_slist_append(NULL, "Content-Type: application/json");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, *chunk);
    curl_easy_setopt(curl, CURLOPT_SSLCERT, "/path/to/client_cert.p12");
    curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "P12");
    curl_easy_setopt(curl, CURLOPT_SSLCERTPASSWD, "1234");
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, receiveResponseBytes);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, responseData);
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 180);
    curl_easy_setopt(curl, CURLOPT_CAINFO, "/path/to/ca.crt");
  }
  
  int main(){
    CURL* curl = curl_easy_init();
    struct curl_slist *chunk = NULL;
    string responseData;
    long responseCode;
    string bodyJsonString = "{\"version\": 1}";
    prepareCurlPOST(curl, bodyJsonString, &amp;responseData, &amp;chunk);
    fprintf(stderr,"%s\n",curl_easy_strerror(curl_easy_perform(curl)));
    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &amp;responseCode);
    if (responseCode != 200) {
      fprintf(stderr, "HTTP %d %s\n", (int) responseCode, responseData.c_str());
    }
    curl_slist_free_all(chunk);
    curl_easy_cleanup(curl);
  }
  </code></pre>