From my POV, all of the trust is split between the contract that verifies the proofs and the contract that uses the verified data. Assuming those are functional, a rogue gateway can only censor (deny) your data. This is a problem when you’re not in the direct control of the choice of gateway, however this can be alleviated by having multiple gateways. It seems relatively straightforward to ensure verifier correctness.
To support trustless gateways, EIP-3668 should be upgraded to support a new callback-originating revert that indicates the next endpoint should be used: eg. contract → revert OffchainLookup() → endpoint #1 → callback() → revert OffchainNext() → endpoint #2… This allows a verifier to reject a bunk proof without aborting the CCIP-Read session. As long as (1) gateway is functioning, you only experience increased latency. There also should be requirement to shuffle the endpoint set. AFAICT, all of the power is currently held by the gateway and expressed via the response status code.
I think the default is to be extremely skeptical of any contract that uses gateway data. You must see the source code to validate what’s between the verifier and the final callback. This implies that the best solutions (gateway + L1 verifier + L1 resolver + L2 storage) should be monolithic in the sense they provide a complete ENS solution. Having many adhoc contracts that use the same gateway is a lot of surface area.
I say L1+L2 because I think the best solutions are of this type until we have ZK solutions, since a storage proof is useless without DA and L2s will likely be the second best fine-grained persistent storage after Ethereum itself.
Related to my post about MerkleResolver and your stuff with IPFS using stored signatures, I think there’s lots of unexplored territory in terms of how data is stored on L2 and what trade-offs can be made to reduce proof and gateway complexity. Although a general gateway should have slot-level resolution to support arbitrary contracts, keyed bytearrays are probably all you need for ENS. Additionally, it’s probably better to have a complex storage contract that maintains a bunch of internal checks, than a dumb storage contract that relies on a swiss-cheese proofs.