-
-
Notifications
You must be signed in to change notification settings - Fork 362
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lessons learned & ORY Oathkeeper NextGen #441
Comments
Most of the changes are regarding JsonNet. Personally I think it's a win for readability. When I first encountered Go template I was certainly faced a lot of frustrations. I liked the idea of removing I'm little confused between the differences between |
Remote passes the request through as-is, and |
We'll also address this: #265 |
I, personally, don’t want to add UI to Oathkeeper because it’s hard to keep track the changes. Logging: Will you add capability to debug the jsonnet output when request comes to Oathkeeper (log jsonnet output stdout)? Hydrator: Will you allow to use additional info to be used in the mutators (e.g. add additional data to jwt created by id_token)? Allow the hydrator to add extra data and pass to next mutator is a useful feature, I have a use case that need to add extra data (role info) to the jwt created by id_token mutator, so it’s good to have ability to make a http request somewhere (to our authz service in my case) to enrich the RequestContext and then enrich the jwt by using data from RequestContext. |
Yes!
Yes! |
Regarding the custom json error, I had created a thread on the forum some time ago, so I'm pretty happy with this announcement 😀. A while ago, I was thinking of a new authenticator which would work a bit like your In this authenticator you'll tell oathkeeper how to extract the token from the request (http header, query param, post multipart, cookie, ...) and then oathkeeper will query an url set in the configuration (either global or per rules) and will pass the extracted token in the query. The external service will have to respond a 200 OK and a json with the subject in it. This could allow us to implement our own introspection service. |
Hey, Great update, looking forward to Jsonnet instead of Go-templates. remote/remote_json over the specific keta integration makes so much sense too. I'm particularly interested in your non-goal though (sorry!).
I personally wouldn't compare Oathkeeper+Kratos to pomerium, and am glad to see that the scope of these two services is a superset of Pomerium. I think the key differentiator is the Mutator paradigm, i think it's crucial in maintaining different security domains when dealing with application ingress. Anyway, I'm wondering if i can help get there, I have some time to contribute too (with a bit of guidance). I'm specifically interested in the pervasive nature of the beyond-corp definition of front-end infrastructure, and how Kratos and Oathkeeper can achieve that. I like the /sessions/whoami endpoint in Kratos, and i think offloading the session management to a different system significantly lowers the operational overhead for oathkeeper, and given it's on the critical path we need to keep it simple. I'm wondering how you plan on introducing this support in Oathkeeper + Kratos and if you're looking for help? Cheers! |
Most of these changes would not affect how we use Oathkeeper or at least only introduce trivial changes needed to the configuration. I think it sounds like you are heading in a good direction and think that the switch to Jsonnet is welcome! |
Hey thank you for your insightful comment! So this actually is already possible - check out the guide for combining ORY Oathkeeper with ORY Kratos over here: https://www.ory.sh/kratos/docs/guides/zero-trust-iap-proxy-identity-access-proxy |
No worries! I've been following the project for a while now, and finally, have time to play to see what the project(s) can do.
So this is the guide I used to play around with above. The guide works, but it's not clear how i evolve that configuration for what I'm looking for:
I could be missing something here though as I'm still digging. Also, if there's a better place to discuss this, let me know (don't want to clog up this issue unless this is the right place) |
Can't wait to see this happening! If I can add something, I'd like to see error_handlers have computed URL and access to request |
Ah yeah that makes sense, this could be used for We still have two issues left I think:
|
You hit the point!
Yes as often with flexibility comes complexity, so probably the 2 configs will be the good approach:
So somewhat chaining multiple authN (with rules like sufficient/required) and/or authZ (with similar rules)? |
Yeah so right now we don't allow alternatives, so if one authenticator validates bearer token than that's the only one allowed to validate the bearer token. I think we can fix this on a code-level though with some intelligent grouping of authenticators. Maybe it's also just too complicated regarding errors, and we just try it easy for now and introduce more flexibility as people ask for it. |
Should we consider #461 in some way for this diagram? |
Sorry for asking but have the hydrator and new pipeline been implemented in next-gen branch ? |
Not yet
… On 4. Sep 2020, at 10:19, toanguyen ***@***.***> wrote:
Sorry for asking but have the hydrator and new flow been implemented in next-gen branch ?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
We have an application Kavach which supports many to many relationships between organisations and users. And we have some other applications which use Kavach for user info and multi organisation support. We create keto policies where the subject contains kavach user id and not kratos subject. Policy Example:
By using a Hydrator mutator we are adding kavach user id as X-User header but all mutators run after the authorizer. So we are not able to use the remote Authorizer. So that’s why we have to write keto policy check logic in our apps and not in Oathkeeper. Is there any way we can configure the flow of the different Handlers for example we want to run Mutators(specifically Hydrator) before the Authorizer? |
Check out #441 (comment) - would that pipeline solve your woes? |
yeah that pipeline logic will solve our problem. Hydrator will use AuthenticationSession or RequestContext any update on that? |
We'll probably end up with a context object which is mutable by all parts of the pipeline! |
Could we add some flexibility to the whole hydrator mechanism - with making it possible to be before (and after) each step (authentication, authorization and mutation)? For example to rule would be like this:
|
Thank you for the idea! I think we would probably need some smart way of doing this without increasing configuration bloat by too much. Maybe a custom codable pipeline using JsonNet? |
https://github.com/google/cel-go could potentially really help out here |
We're using Oathkeeper more and more where I work (ModusBox), and getting ready to expand that use considerably as part of a centralized IAM setup for hosted customer APIs, and while we can get existing Oathkeeper to do what we need we're particularly interested in some of the JSonnet mechanisms planned for NextGen, both because they're more flexible in ways we'd be able to take advantage of and because we've got a lot of expertise in JSonnet (we used it as the basis for an open source data transformation platform, DataSonnet). I know you don't give out timelines, so I've got a somewhat different question: how can we help, particularly around JSonnet support? We don't have extensive resources to deploy but I could definitely spend a modest portion of my time on features we know we'd use. |
The best option would be to come up with a proposal for JsonNet implementation - particularly around the config schema and how you plan (or not) to keep backwards compatibility. It's been a while since we opened this issue, it's still on our list, but we just don't have anyone dedicated to maintaining larger changes and refactorings in the oathkeeper codebase... |
I could work up a proposal like that. Very loosely, where I'd be inclined to start would be a new mutator under the existing approach that works similar to the new Hydrator proposal in the description. That would be a test bed for incorporating Jsonnet generally, plus provide some useful and flexible new capabilities pretty quickly. I'll see about writing something up with more detail |
I think that makes sense! I was also thinking if we should use JsonNet as a programming language so add some custom builtin functions such as making HTTP calls. However, I'm not sure if that's a good idea really as JsonNet is really not a programming language as it's difficult to test. My idea was a bit like this (pseudo code!):
But yeah I think it will be pretty difficult for people to get into this syntax. An alternative to that would be a JavaScript VM which more or less does the same thing, but here again, the problem is most likely one of testing. To enable testing with this approach, what we would need would be something like this:
But yeah I'm not sure if this overcomplicates things. However, we've seen in the past that people want more and more and more customizations for the individual flows, adding flags and configs everywhere. Maybe this is a better approach? Another alternative would be to use the traefik way of https://github.com/traefik/yaegi which is Go code and probably easier to learn and write than jsonnet. We could still use jsonnet transformations though for some things (e.g. request body modification). |
By the way, if anyone in this thread wants to do this as part of a full time position at Ory - please head over to https://www.ory.sh/jobs - we're actively looking for a FTE maintainer here (just apply for backend or fullstack and say you've seen this comment on oathkeeper issue #744 ) :) |
Just dropping in to connect that a next-generation Oathkeeper would probably be an excellent time to implement a renaming of the project (#804). |
Hi ! Just chiming in about requesting if multiple same-type authenticators would be possible ? So our current workaround was to mutate headers in our reverse proxy (nginx) before it hits oathkeeper so we can match on different authenticators but it's quite cluncky and fragile. Once we've used up all the different authenticators, we can't have any new system to authenticate users. Would it be possible to have authenticators with a user-chosen name as the key and a sub-key as the type. e.g.:
This way, in the rules, I can reference different authenticators depending on the rule (which can match different headers or parameters). Thanks for creating oathkeeper, it's served us well ;) |
Thank you for the feedback! We absolutely want to support multiple handlers in the future, and also make them reusable across the configurations - I think that's a great idea :) |
@achedeuzot It seems like great option/feature for device verification/ authentication before user. |
It may because I'm late to this game but if we're using dlclark/regexp2, lookahead/lookbehind (positive and negative) are supported. The only issue I could find is that we've hard-coded the delimiters for url regexp patterns to be '<','>'. This conflicts with the
and give it a slight face-lift:
This would have little-to-no impact on current regex url patterns (because they're broken anyway). However, there would be a way to fix them by changing the start/end delimiters in the I have a fix (with tests) in my personal fork https://github.com/cmmoran/oathkeeper/tree/fix/regexp-possessive-match-and-lookbehinds I'll create a PR in case there's other folks struggling with this. EDIT: Apparently my initial solution was naive. Using '{','}' as delimiters when "(?<" or "(?>" exist within the pattern works wonderfully; until your pattern contains "(?<" or "(?>" and an "occurence(s)" check: {1}, {2,}, {12,14-19}, etc. I toyed with different possibilities for simplifying this but came up short every time. The only solution that I could come up with was increasing the alphabet available to allow the use of characters that take up more than a single byte. This will require a change to https://github.com/ory/ladon because oathkeeper's regular expression engine uses it. The change to ladon is required to be able to support multi-byte delimiters. For example, in my fork I landed on allowing '<<' and '>>' to be the regex delimiters. Internally (to oathkeeper), I replace '<<' with '«' and '>>' with '»' and in ladon I changed the |
Hey guys, sorry for the off topic, not sure where would be the right place to ask this. Any ideas on when a new release version is coming up? Last version is v0.40.7 feb 29 right? |
First of all, thank you for using ORY Oathkeeper and placing trust in us! This issue's purpose is to discuss structural changes to ORY Oathkeeper.
ORY Oathkeeper is used in production at many companies, handling tons of traffic every day. As such, we naturally receive a lot of bug reports and pull requests. Let's take a look at areas of improvement. Some of these changes will not be backwards compatible, which is why we want you to discuss them with us!
All of the listed changes are breaking changes, which is why it is important to get your feedback! When giving feedback, please keep in mind that we want to build the best product possible for you! This sometimes includes breaking things to move forward :)
Non-Goals
Before we start I want to define some non-goals. One of the non-goals is to implement an "identity-aware" proxy like Pomerium. The reason for that is that we don't want to have user interfaces in Oathkeeper itself. It will be possible (in future versions) to get what Pomerium does (plus a ton more) by combining ORY Oathkeeper and ORY Kratos. If an identity-aware proxy is all that's needed, Pomerium is also probably the better choice!
Support negative lookahead
Neither glob nor regex currently support negative lookahead, but it is quite important to support them as it allows for much easier rule definition. See also https://www.linuxjournal.com/content/bash-extended-globbing
More Proxies
#265
Logging
This release aims to better support debugging by adding a lot of debug logs. We understand that debugging ORY Oathkeeper is time-consuming and frustrating and we want to provide the best tooling possible to fix that!
This is a non-breaking change.
Error Handling
The error handling is quite complex to understand, configure, and debug. The following config is a real-world example:
All it does is return JSON unless the a real user using a browser is making the request, in which case we redirect. We need something better!
These change will not be backwards compatible.
Redirect
One thing we can improve is to decide what to do based on the accept header. If it includes
application/json
, we return JSON (what else would we return?). If it includestext/html
we show an HTML error.To redirect the browser on error, we could define something like:
This works per-route. It might still be cool to redirect based on content-type - maybe we want to redirect to another application/json endpoint?
Todo: Actually the old logic makes more sense because we can have multiple WHENs with an OR. The question is, how likely is it that we have one rule for all eventuality?
Custom HTML Errors
We could allow custom HTML error pages using Go Templates:
The template has access to the error and maybe AuthenticationSession and can return any valid HTML:
Custom JSON Errors
We could allow custom JSON errors using JsonNet:
With a JsonNet file like:
AuthenticationSession
The AuthenticationSession has grown in scope. It contains more and more fields which are sometimes even used as "temporary storage" or something that can be modified over the lifetime of a request. This was not the struct's intention and it's thus time to think of a better way of solving this.
We want to solve that by first renaming
AuthenticationSession
toRequestContext
with the following layout:This context is available in all JsonNet definitions (see sections below) as the global variable
ctx
.Go Templates (Breaking Change)
Go Templates are not great for building JSON. While this is readable
it becomes much less readable and hard to debug - especially with nested objects.
As hinted in other issues (#423) JsonNet is a good alternative here:
With JsonNet one could also extract values from
extra
. Because JsonNet is often loaded from file, we should also be able to specify a file location to load the JsonNet code from:JsonNet has many cool features and no sideeffects or security implications. It supports linting, formatting, and we can even provide a test framework. They're much better and easier to use!
Authenticators
cookie_session
(Breaking Change)Instead of using
extra_form
andsubject_from
with weird JsonPathslet's just use JsonNet
Because we're already changing the config, we also want to improve the config layout for preserving paths and the original HTTP method:
Authorizers
remote_json
This authorizer makes a remote rpc call with a JSON body and expects 403 or 200.
Currently, the config is as follows:
Besides switching to JsonNet support instead of Go Templates, we want to improve the way the request is made
by making it possible to also define custom headers:
remote
This authorizer makes a remote rpc call and pipes through the body. It expects 403 or 200.
Currently, the config is as follows:
Besides switching to JsonNet support instead of Go Templates, we want to improve the way the request is made
by making it possible to also define custom headers:
keto_engine_acp_ory
(Breaking Change)This release will remove the authorizer. You should use
remote_json
instead:Mutators
header
Right now the header mutator is configured with Go Templates like so (example):
This will stay very similar but the value is no longer a Go Template but instead a JsonNet. You can get the above by doing:
cookie
Right now the cookie mutator is configured with Go Templates like so (example):
This will stay very similar but the value is no longer a Go Template but instead a JsonNet. You can get the above by doing:
This allows you to also use more sophisticated means in the future, such as singing the cookie value.
id_token
The
claims
config no longer accepts Go Templates but instead uses JsonNet and loads files from file/https sources:mutator
Will be removed, see Hydration
Hydration
The
hydrator
mutator has been added with the intention of making calls to other services and fetching data (e.g. from Stripe). These don't really mutate the response, but add extra data to the AuthenticationSession.To fix this, the general idea is to add another step to the pipeline called "Hydration". The steps are now:
Instead of using handlers here we think a good idea would be to write JsonNet instead:
The JsonNet gets an extra function called
http_request
which allows us to make an http request somewhere if needed:Alternatively, this also has handlers but I'm not sure if that's actually that useful as we always want to transform the RequestContext.
Caching
Caching is a hard problem and even more so in Ory Oathkeeper. Besides a CVE it has lead to several PRs:
Another interesting thinking is:
So I think this is a sweetspot for this project. Making access control powerful to configure, whlie also very efficient.
The text was updated successfully, but these errors were encountered: