anchor.diff:  %% ------------------------------------------------------------------
   %% Internal Function Definitions
   %% ------------------------------------------------------------------
  +
  +generate_signed_header(PrivateKey, Body) ->
  +    HashedBody = chef_authn:hash_string(Body),
  +    ?debugVal(HashedBody),
  +    Sig = base64:encode(public_key:encrypt_private(HashedBody, PrivateKey)),
  +    list_to_binary("Version:1.0;SignedChecksum:" ++ Sig).
  
positive.code: handle_call(_Request, _From, State) ->
      {noreply, ok, State}.
  
  handle_cast(heartbeat, #state{heartbeat_sock=HeartbeatSock, beat_count=Count}=State) ->
      {ok, Hostname} = inet:gethostname(),
      Msg = {[{server, list_to_binary(Hostname)},
              {timestamp, list_to_binary(httpd_util:rfc1123_date())},
              {type, heartbeat}]},
      ?debugVal(Msg),
      % TODO - sign JsonMsg
      JsonMsg = jiffy:encode(Msg),
      %Sig = 'SUPERSECRET',
      %erlzmq:send(HeartbeatSock, Sig, [sndmore]),
      erlzmq:send(HeartbeatSock, JsonMsg),
      {noreply, State#state{beat_count=Count+1}};
  handle_cast(_Msg, State) ->
      {noreply, State}.
  
negative.code:     % expect "tcp://*:port_id"
      {ok, HeartbeatAddress} = application:get_env(pushy, server_heartbeat_socket),
      {ok, HeartbeatSock} = erlzmq:socket(Ctx, pub),
      {ok, PrivateKey} = chef_keyring:get_key(server_private),
      ok = erlzmq:bind(HeartbeatSock, HeartbeatAddress),
      State = #state{heartbeat_sock = HeartbeatSock,
                     heartbeat_interval = Interval,
                     beat_count = 0,
                     private_key = PrivateKey
                    },
      timer:apply_interval(Interval, ?MODULE, heartbeat, []),
      {ok, State}.
  