{"action":"created","issue":{"url":"https://api.github.com/repos/sethvargo/chef-api/issues/32","labels_url":"https://api.github.com/repos/sethvargo/chef-api/issues/32/labels{/name}","comments_url":"https://api.github.com/repos/sethvargo/chef-api/issues/32/comments","events_url":"https://api.github.com/repos/sethvargo/chef-api/issues/32/events","html_url":"https://github.com/sethvargo/chef-api/issues/32","id":55209773,"number":32,"title":"Frequent \"Invalid signature for user or client\"","user":{"login":"phene","id":166528,"avatar_url":"https://avatars.githubusercontent.com/u/166528?v=3","gravatar_id":"","url":"https://api.github.com/users/phene","html_url":"https://github.com/phene","followers_url":"https://api.github.com/users/phene/followers","following_url":"https://api.github.com/users/phene/following{/other_user}","gists_url":"https://api.github.com/users/phene/gists{/gist_id}","starred_url":"https://api.github.com/users/phene/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/phene/subscriptions","organizations_url":"https://api.github.com/users/phene/orgs","repos_url":"https://api.github.com/users/phene/repos","events_url":"https://api.github.com/users/phene/events{/privacy}","received_events_url":"https://api.github.com/users/phene/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":10,"created_at":"2015-01-22T21:15:16Z","updated_at":"2015-07-13T04:19:40Z","closed_at":"2015-01-22T21:56:07Z","body":"I cannot reproduce it consistently, but I frequently get transient errors for the api key when connecting to the chef server.  I've verified that I'm using the correct key, and there are no time sync issues between the servers."},"comment":{"url":"https://api.github.com/repos/sethvargo/chef-api/issues/comments/120805618","html_url":"https://github.com/sethvargo/chef-api/issues/32#issuecomment-120805618","issue_url":"https://api.github.com/repos/sethvargo/chef-api/issues/32","id":120805618,"user":{"login":"spuder","id":242382,"avatar_url":"https://avatars.githubusercontent.com/u/242382?v=3","gravatar_id":"","url":"https://api.github.com/users/spuder","html_url":"https://github.com/spuder","followers_url":"https://api.github.com/users/spuder/followers","following_url":"https://api.github.com/users/spuder/following{/other_user}","gists_url":"https://api.github.com/users/spuder/gists{/gist_id}","starred_url":"https://api.github.com/users/spuder/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/spuder/subscriptions","organizations_url":"https://api.github.com/users/spuder/orgs","repos_url":"https://api.github.com/users/spuder/repos","events_url":"https://api.github.com/users/spuder/events{/privacy}","received_events_url":"https://api.github.com/users/spuder/received_events","type":"User","site_admin":false},"created_at":"2015-07-13T04:19:40Z","updated_at":"2015-07-13T04:19:40Z","body":"I can reproduce this rather consistently and I have captured tcp dumps of both successful and unsuccessful api calls. While I do suspect this is a bug in chef server, because it only affects api calls with this ruby gem, I'm posting my data here instead of https://github.com/chef/chef-server/issues/5 since \r\n\r\n**Symptoms:**\r\n\r\n- Fails about 5 to 10 times out of 50 attempts. \r\n- When the ruby script fails, running knife commands in a separate terminal will also fail for a few seconds. (I've never had a knife command fail otherwise)\r\n- Fails more often on longer \"fetches\" (like getting cookbook versions)\r\n\r\nI don't consider myself a developer, but here is some ruby which reproduces the problem quite nicely. \r\n\r\nsausage.rb\r\n```ruby\r\nrequire 'chef-api'\r\ninclude ChefAPI::Resource\r\n\r\nsausage = ChefAPI::Connection.new(\r\n  endpoint: 'https://api.opscode.com/organizations/spuder',\r\n  client:   'spuder',\r\n  key:      '~/.chef/sausage.pem'\r\n)\r\n\r\n@aCookbook   = 'elasticsearch'\r\n@theEnvironments = sausage.environments.list\r\n@aDatabagItem = 'foo'\r\n\r\n@cookbooks = Hash.new({ value: 0 })\r\n@cookbookAttribHash = Hash.new({ value: 0 })\r\n\r\ndef cookbookVersions(organization)\r\n  @theEnvironments.each do |anEnvironment|\r\n    cookbook_version = organization.environments.fetch(anEnvironment).cookbook_versions[@aCookbook]\r\n    @cookbooks[anEnvironment] = { label: anEnvironment, value: cookbook_version }\r\n  end\r\n  return @cookbooks.values\r\nend\r\n\r\ndef environmentAttributes(organization)\r\n  @theEnvironments.each do |anEnvironment|\r\n    if organization.environments.fetch(anEnvironment).default_attributes[@aCookbook]\r\n      cookbook_version = organization.environments.fetch(anEnvironment).default_attributes[@aCookbook]['foo']\r\n      @cookbookAttribHash[anEnvironment] = { label: anEnvironment, value: cookbook_version }\r\n    else\r\n      @cookbookAttribHash[anEnvironment] = { label: anEnvironment, value: nil }\r\n    end\r\n  end\r\n  return @cookbookAttribHash.values\r\nend\r\n\r\n\r\nputs cookbookVersions(sausage)\r\nputs environmentAttributes(sausage)\r\n\r\n```\r\n\r\nYou can replace the organization, key and client information, then test like so: \r\n\r\n    F=0; for i in {1..50}; do echo \"Executing run $i\"; ruby sausage.rb; if [ $? !=0 ];then F=$((F+1));fi; done; echo \"Failed $F times\"\r\n\r\nIn my last test, I had 14 failures out of 50 attempts. \r\n\r\nHere is what good output should look like. \r\nThe first 9 rows show the version of 'elasticsearch' in each of my environments\r\nThe second 9 rows show the value of a default attribute in an environment. \r\n\r\n```bash\r\nfoo@bar-MBP:$ ruby sausage.rb\r\n{:label=>\"_default\", :value=>nil}\r\n{:label=>\"datacenter01\", :value=>nil}\r\n{:label=>\"datacenter02\", :value=>\"<= 1.1.1\"}\r\n{:label=>\"datacenter03\", :value=>\"~> 2.2.2\"}\r\n{:label=>\"datacenter04\", :value=>\"~> 9.9.9\"}\r\n{:label=>\"datacenter05\", :value=>nil}\r\n{:label=>\"datacenter06\", :value=>nil}\r\n{:label=>\"datacenter07\", :value=>nil}\r\n{:label=>\"datacenter08\", :value=>nil}\r\n{:label=>\"_default\", :value=>nil}\r\n{:label=>\"datacenter01\", :value=>nil}\r\n{:label=>\"datacenter02\", :value=>nil}\r\n{:label=>\"datacenter03\", :value=>nil}\r\n{:label=>\"datacenter04\", :value=>nil}\r\n{:label=>\"datacenter05\", :value=>nil}\r\n{:label=>\"datacenter06\", :value=>20160808.2}\r\n{:label=>\"datacenter07\", :value=>nil}\r\n{:label=>\"datacenter08\", :value=>nil}\r\n```\r\n\r\nA failure will output the following\r\n\r\n```bash\r\n\r\nfoo@bar-MBP:$ ruby sausage.rb\r\n{:label=>\"_default\", :value=>nil}\r\n{:label=>\"datacenter01\", :value=>nil}\r\n{:label=>\"datacenter02\", :value=>\"<= 1.1.1\"}\r\n{:label=>\"datacenter03\", :value=>\"~> 2.2.2\"}\r\n{:label=>\"datacenter04\", :value=>\"~> 9.9.9\"}\r\n{:label=>\"datacenter05\", :value=>nil}\r\n{:label=>\"datacenter06\", :value=>nil}\r\n{:label=>\"datacenter07\", :value=>nil}\r\n{:label=>\"datacenter08\", :value=>nil}\r\n/Users/foo/.rvm/gems/ruby-2.2.0/gems/chef-api-0.5.0/lib/chef-api/connection.rb:413:in `error': The Chef Server requires authorization. Please ensure you have specified the correct client name and private key. If this error continues, please verify the given client has the proper permissions on the Chef Server. (ChefAPI::Error::HTTPUnauthorizedRequest)\r\n\r\n    {\"error\":[\"Invalid signature for user or client 'spuder'\"]}\r\n\tfrom /Users/foo/.rvm/gems/ruby-2.2.0/gems/chef-api-0.5.0/lib/chef-api/connection.rb:282:in `block in request'\r\n\tfrom /Users/foo/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/net/http.rb:853:in `start'\r\n\tfrom /Users/foo/.rvm/gems/ruby-2.2.0/gems/chef-api-0.5.0/lib/chef-api/connection.rb:268:in `request'\r\n\tfrom /Users/foo/.rvm/gems/ruby-2.2.0/gems/chef-api-0.5.0/lib/chef-api/connection.rb:106:in `get'\r\n\tfrom /Users/foo/.rvm/gems/ruby-2.2.0/gems/chef-api-0.5.0/lib/chef-api/resources/base.rb:252:in `fetch'\r\n\tfrom sausage.rb:30:in `block in environmentAttributes'\r\n\tfrom sausage.rb:28:in `each'\r\n\tfrom sausage.rb:28:in `environmentAttributes'\r\n\tfrom sausage.rb:42:in `<main>'\r\n```\r\n\r\nI have captured wireshark dumps and filtered to just a couple hundred packets that show success and failure scenarios. Unfortunately, chef appears to be preferring ECDHE, which from my research uses perfect forward secrecy, and is impossible to decrypt, even with my chef private and public keys. (If anyone knows a way to get decrypted tcp dumps with chef, please let me know). \r\n\r\n    Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)\r\n\r\nHere are the wireshark dumps. Two are on my home network, and two are while tethered to my cellphone 4g connection. \r\n\r\nhttps://dl.dropboxusercontent.com/u/460997/chef-bug/good-sausage-filtered.pcapng\r\nhttps://dl.dropboxusercontent.com/u/460997/chef-bug/good-sausage-4g-filtered.pcapng\r\nhttps://dl.dropboxusercontent.com/u/460997/chef-bug/bad-sausage-filtered.pcapng\r\nhttps://dl.dropboxusercontent.com/u/460997/chef-bug/bad-sausage-4g-filtered.pcapng\r\n\r\nInteresting data points\r\n- Every tcp dump has packets that arrived out of order, and also dropped packets\r\n- There are a lot of \"Server Hello\" transactions which seems to indicate the gem is opening a new connection for every api call. (I haven't worked much with API's and development to know if that is normal.)\r\n\r\n\r\n\r\n**Environment**\r\nMac Yosemite\r\nChef Development Kit Version: 0.3.5\r\nHosted chef (with 0 nodes, 1 user,  ~ 8 environments, 2 organizations)\r\n"}}