dotnet-opa-wasm icon indicating copy to clipboard operation
dotnet-opa-wasm copied to clipboard

ASP.NET AuthZ Policies based on OPA

Open christophwille opened this issue 4 years ago • 7 comments

Build out https://github.com/christophwille/csharp-opa-wasm/tree/master/spikes/AspNetAuthZwithOpa

Will need a "store" for policies that can be injected. Should account for policies that need different inputs. Should account for policies that need subclasses of OpaPolicy.

christophwille avatar Mar 22 '20 09:03 christophwille

I'm actually doing a spike of doing something like this to integrate with microsoft's new reverse-proxy proxy (yarp). Is this issue and/or this repository still something you're interested in carrying forward?

RichiCoder1 avatar Sep 02 '20 01:09 RichiCoder1

The aforementioned spike actually was the reason I started playing with OPA in C# in the first place. It is also the reason why I opened issues in wasmtime regarding compilation performance & concurrency. I think it is about time I document my current findings:

  • https://github.com/christophwille/csharp-opa-wasm/tree/master/spikes/BenchmarkOpaWasm is the reason why I ended up with the current API design of separating loading from execution. Because loading (the way I implemented it) incurs the costly compilation penalty. Doing it on every API request would simply be darn too slow.
  • What I haven't settled on is caching of those pre-compiled wasms (one reason is the reentrancy I asked for). So today the best way would be to have a pool of named pools of policy instances ("xyz policy", OpaPolicy) that one can draw from at runtime.
  • Logging/Monitoring: haven't decided on that yet. This is one more of those problems where I keep thinking that maybe simply running OPA https://github.com/open-policy-agent/opa side-by-side as a yet another service, stepping up to full Gatekeeper https://github.com/open-policy-agent/gatekeeper or going with https://github.com/open-policy-agent/opa-envoy-plugin is a better option.

The reason I keep hanging on to my approach is because of (the not yet implemented) #3 which would allow me to immediately execute C# code as part of the policy evaluation.

I have an opinion on Yarp (since the first presentation on the MVP summit) as a project really nobody asked for. The xDS APIs of Envoy are simply the go-to API for everyone, including https://github.com/openservicemesh/osm

christophwille avatar Sep 02 '20 05:09 christophwille

https://github.com/christophwille/csharp-opa-wasm/tree/master/spikes/BenchmarkOpaWasm is the reason why I ended up with the current API design of separating loading from execution. Because loading (the way I implemented it) incurs the costly compilation penalty. Doing it on every API request would simply be darn too slow. What I haven't settled on is caching of those pre-compiled wasms (one reason is the reentrancy I asked for). So today the best way would be to have a pool of named pools of policy instances ("xyz policy", OpaPolicy) that one can draw from at runtime.

I was wondering about that! The nature thought I would have is that in-memory via WASM would be faster and more efficient than REST API OPA, but you'd need to efficient managed bundles and VM instances which sounds like no small amount of work.

Logging/Monitoring: haven't decided on that yet. This is one more of those problems where I keep thinking that maybe simply running OPA open-policy-agent/opa side-by-side as a yet another service, stepping up to full Gatekeeper open-policy-agent/gatekeeper or going with open-policy-agent/opa-envoy-plugin is a better option.

I was actually doing a spike to have the AuthZ policy speck CheckRequest, but I was worried it might have to many envoy-isms to feat neatly elsewhere.

The reason I keep hanging on to my approach is because of (the not yet implemented) #3 which would allow me to immediately execute C# code as part of the policy evaluation.

This wasn't to terrible to do for the JavaScript side and (AFAIK) is shouldn't be too terrible to do for C# if you'd like me to take a swing.

I have an opinion on Yarp (since the first presentation on the MVP summit) as a project really nobody asked for. The xDS APIs of Envoy are simply the go-to API for everyone, including openservicemesh/osm

The argument there is more than Envoy is the go-to as technically Yarp could implement the xDS APIs. Well, mostly minus the translation loss since it'd only be able to support clusters & routes right now, and not filters. Would be an interesting alternative too if you could shim other things as you could either have A) C# extensibility via Envoy WASM (which I haven't seen a good swing at) or B) C# extensibility via YARP w/ Envoy/xDS compatibility.

Pardon if any of that sounds like gibberish.

RichiCoder1 avatar Sep 02 '20 06:09 RichiCoder1

I did a comparison of requests to OPA vs local, that's how I found out about the compilation cost (obviously I started out with the naive approach of only caching the policy bytes). Luckily I added the benchmarking project right at the start so I had comparisons for wasmersharp, wasmtime initial port and the various API progressions. But I think the pool of object pools is reasonable.

Regarding my hint on observability (monitoring/perf) - ideally that would tie into the APM solution that is in use, so feeding the AuthZ decisions into eg App Insights together with the request would allow nice request tracing - if you live in the Microsoft world, that is. If you have something k8s-y already in place, then feeding into other systems would be necessary to get the overall picture of a request in your system.

Don't let my snarky comment on YARP get in the way of you building that feature, it is just that in my totally not humble opinion the world doesn't need yet another reverse proxy (when Envoy - in my book - has won).

Regarding #3 - I simply was too lazy yet to take a serious look at that (and busy on things like ILSpy), so yes, help is very much appreciated.

christophwille avatar Sep 02 '20 06:09 christophwille

To document one more thing: the reason I am leaning towards Gatekeeper is that it is used already with AKS https://docs.microsoft.com/en-us/azure/governance/policy/concepts/policy-for-kubernetes

christophwille avatar Sep 02 '20 06:09 christophwille

Don't let my snarky comment on YARP get in the way of you building that feature, it is just that in my totally not humble opinion the world doesn't need yet another reverse proxy (when Envoy - in my book - has won).

Haha, all good. I mostly agree. Interests me though as a more C#-extensibility friendly option until the WASM option matures.

Regarding #3 - I simply was too lazy yet to take a serious look at that (and busy on things like ILSpy), so yes, help is very much appreciated.

I may take a swing at that just to poke at the code base.

To document one more thing: the reason I am leaning towards Gatekeeper is that it is used already with AKS docs.microsoft.com/en-us/azure/governance/policy/concepts/policy-for-kubernetes

Isn't that specifically for Kubernetes Admission?

RichiCoder1 avatar Sep 02 '20 15:09 RichiCoder1

Re:Gatekeeper - yes, that one implementation is specific, but Gatekeeper in general is a great overall policy solution.

christophwille avatar Sep 02 '20 16:09 christophwille