OPA is an authorization engine, with some supporting capabilities, but it's not a complete authorization subsystem.
OPA can be a component of a secure authorization system - low-level policy definition and evaluation - but there are many aspects of an authorization subsystem that OPA doesn't even try to address.
For a start, policy languages like Rego operate at the policy decision level, they have no awareness of any authorization model. If you're implementing anything with high-level authorization semantics - think MLS, Bell-LaPadula, or pretty much anything else that defines a non-trivial authorization model - you essentially have to translate the semantic properties of that system into a low-level policy decisions.
If that translation is done manually, it's highly error prone, which is not a good feature for a security system. Rego doesn't know what a clearance, classification, security compartment, etc. means. It doesn't prevent a policy author from implementing rules that aren't compatible with an authorization model.
Also, for security to be worth anything, there are inevitable cross-cutting concerns with trusted identity and attribute sources. OPA lets you tell it anything you want, but you still have to integrate that with a larger system that doesn't depend on implicit guarantees. E.g., "This is Bob because the invoking service checked it and says so" might be fine for an e-commerce site, but not for many more secure environments. Same goes for attributes other than identity. Doing all of this in secure ways is the cause of much of the complexity I mentioned.