In the end our solution was trivial (?): We'd pass the final assembled prompt (there was some templating) as a payload to a wrapper-prompt, basically asking the LLM to summarize and evaluate the "user prompt" on how well it fit our criteria.
If it didn't match the criteria, it was rejected. Since it was a piece of text embedded in a larger text, it seemed secure against injection. In any case, we haven't found a way to break it yet.
I strongly believe the LLMs should be all-featured, and agnostic of opinions / beliefs / value systems. This way we get capable "low level" tools which we can then tune for specific purpose downstream.