I dug down into the gem and then into the simple_auth gem that ims-lti now relies on to verify the signature of the request.
The IMS::LTI::Services::MessageAuthenticator initialization parses the params object into options and parsed_params.
The course level navigation results in an @options that looks like this:
{:consumer_key=>"lti-example-dev", :signature_method=>"HMAC-SHA1", :timestamp=>"1498094063", :nonce=>"sTtZphI5tfJarJfZQksP1Bdm6nILujuMntjpVk10bc", :version=>"1.0", :callback=>"about:blank"}
The content item selection results in an @options that looks like this:
{:consumer_key=>"lti-example-dev", :signature_method=>"HMAC-SHA1", :timestamp=>"1498094088", :nonce=>"TTNKN94qqjX8vmehAIlsod7GhXLkQpRqy52FxYamG4", :version=>"1.0"}
The primary difference is that the content item selection does not have a callback.
However, when I did into the simple_oauth gem and look at the "signature_base" that is used to generate the signature, both requests contain an "oauth_callback". I think that somewhere in one of the gems that value is being added in. It passes in the case of the course level launch because it was part of the original request and thus part of the signature. In the content item selection there is no oauth_callback value and so the signatures are different and the request fails.