It could be that you have minimum TTL set to something non-default and it's caching it for that time period instead of whatever's in your Cache-Control header. I think that's unlikely both because you probably already thought of it and because it appears the distribution respects Cache-Control: no-cache (and it wouldn't if minimum TTL was non-default).
More likely, cloudfront is just evicting your items after a while:
If an object in an edge location isn't frequently requested, CloudFront might evict the object—remove the object before its expiration date—to make room for objects that are more popular.
- from this article
As for web-sniffer.net, you'll notice that it sends a Cache-Control: no-cache header, which will make cloudfront fetch from origin.