Glad you got it working. I will try and explain each below
<Step>
<Name>verify-api-key</Name>
<Condition>request.verb != "OPTIONS"</Condition>
</Step>
The above it to execute the policy and if the condition evaluates to true, it executes the policy
<FaultRules/>
<DefaultFaultRule name="all">
<AlwaysEnforce>true</AlwaysEnforce>
<Step>
<Name>Add-CORS</Name>
</Step>
</DefaultFaultRule><br>
Any exception thrown by a policy in Apigee raises a fault (you can think it like an exception). To catch those you need to use the FaultRules to execute like catch block. Check this link for more info. DefaultFaultRule are the ones that executes after the FaultRules are executed.
<Flow name="OptionsPreFlight">
<Request/>
<Response>
<Step>
<Name>AM-AddCORS</Name>
</Step>
</Response>
<Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition>
</Flow><br>
is a Conditional flow that executes on a Condition. In the above block, it gets called with the Preflight OPTIONS call occur. And when that occurs, it sets the CORS headers in the response
<RouteRule name="NoRoute">
<Condition>request.verb == "OPTIONS" AND request.header.origin != null AND request.header.Access-Control-Request-Method != null</Condition>
</RouteRule><br>
RouteRule is used to determine the target endpoint where the request needs to be sent to. For the OPTIONS call, we dont need to send to a backend target. So we set it with no target endpoints. Compare this routerule with the default RouteRule you have in your proxy. For more info on Route Rules, check this link
In your case, when you passed an invalid API KEY, Apigee raised a fault and it went to the FaultRule,DefaultFaultRule section. And in that section, since the response did not include the CORS headers, the portal was not able to render the response. Hence we had to include the CORS Assign Message policy to the FaultRule as well.
hope the blocks and the explanation clarifies