-
Notifications
You must be signed in to change notification settings - Fork 971
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
API Authentication #385
Comments
Do you plan on doing that with OAuth2? So that a third party acts on behalf of on of your users? Best example is probably a "create your facbook photo backup app" where Facebook asks the user "are you ok with giving all your photos to this app?"? |
I get that part of OAuth, it would be an option but my API allows third parties to perform actions on behalf of users in their system but who aren't registered in my system. (My system supports "alliances" between companies, they can make reservations in each others systems but they all have their own "user system") So the third party system would needs to be able to retrieve "public" data (which is just freely available, no auth necessary), but also perform actions for users who aren't registered with my system. |
Ok so in those cases it's not really about third parties consuming your users' data but instead using your app like a database of sorts? So the developer / your customer (who you call third party) stores stuff in your application. So not on behalf of someone but on behalf of themselves, right? So basically, after registration, you want to be able to show in a UI: "Yo this is your API Key use it to make calls against my backend and store e.g. the orders people in your coffee shop placed". Am I understanding that correctly? |
Yes but keeping with the coffee shop trend, I am also a coffee shop. There are 20 different coffee shops in the area and they all sell different kinds of coffee, so clients can come to my coffee shop and buy 1 kind of coffee from me but also buy a few from others. (the clients that buy through me all have an account registered in Kratos) |
This is too abstract for me :D What I'm trying to drill down on is if you have users in kratos and want third parties to act on behalf of those users in your kratos, or if you have users in kratos and they just interact with your system like they would with a website but through an API. |
Okay so... I think the 2nd option. Clients that come to my coffee shop have an account which they use to place orders. (aka they can use my website and sign in through my website and place an order for themselves) |
Ok, I see - that makes sense. So what you want is have a token (not a cookie) that is bound to the "client" registered in your Kratos? |
Yes, but part of my question is if having a token that is generated once secure enough? |
Typically yes - the session cookie is nothing different. Most API Keys are permanent (think GitHub Personal Access Tokens for example). Since you can revoke the token easily (blacklist) there is no need for a refresh dance. Most if not all mobile apps allow you to sign in once and re-use the issued token for along period of time, typically the lifetime of your account! |
Okay great, I do see it a lot so would make sense. And what about the 1st option from before? How could we implement the "perform actions on behalf of a user"? (best to clarify this even though I might not need it, I can possibly implement it so that the full "API Authentication" would be available) |
This would be achieved by combining ORY Hydra with ORY Kratos which enables OAuth2 and OpenID Connect, which are the protocols that should be used here. By the way, don't confuse "hard to implement" with "secure". OAuth2 and OpenID Connect are very hard to get right because it is so damn difficult to implement them. That's why we're building ORY Kratos :)
Yeah so I think the flow starts a bit different than what we use now. So instead of going through a browser flow where we make the init request and redirect to the UI we would probably just make the init request and expect a JSON response with details on how to proceed. Those details would probably contain the CSRF Token and probably more or less the payloads we have right now (forms/fields etc). The client then renders that data as a form (e.g. in your mobile or native app or your CLI with input prompts) and when filled out sends it using an API request to the endpoint specified e.g. in the The response, since it's an application/json request, would then include the session token and would not, as it is the case for browsers, initiate an HTTP redirect. |
Alternatively we could create a session/fork feature which would allow a user to fork his/her session. This would then create an API token that the user can use to authenticate in systems that work with kratos. This would be more along the lines of the "Github Personal Access Token" as opposed to my previous comment which focuses on login for applications that don't have a browser (native mobile apps, native desktop apps written in C, ...). |
Looks good, but here and for the "perform actions on behalf of a user" part, should we have options about how long that session is valid? And what if a user logs in again because the token wasn't saved? I guess we would have to invalidate that previous session somehow?
I'm guessing we can add this as an extra option comparable to the profile? Where users can create and revoke API tokens at any point? Maybe with a name and/or description? |
I'd like to propose the following:
What do you think about this? Should anything be different? |
Thank you for all the input! I'm now going to be working on this. The general idea would be to simply return a session identifier (can be used as a Bearer Token). It has the same properties as a session cookie but instead of it being a cookie, it's a pass-by-reference string that you can use against e.g. The bearer token will behave exactly like a session cookie. It's valid for the same amount of time like the session cookie. It will be refreshed similarly to the session cookie (#615). It will keep track of the same properties like the session cookie (user agents, IPs, used at, ...). |
A primary limitation of this approach is that social sign in will not be working with this method due to the fact that OAuth2 is a inherent browser protocol. This implies that we'll have new API endpoints
which will support the For the password strategy we are going to add two new API endpoints as well
which will be able to perform login and registration without a browser involved. This will come in very handy when working with mobile clients who have some serious limitations when it comes to cookie handling, browser handling, and so on. The result of the authentication process will be a Session Token which can be sent in the HTTP Authorization Header and will yield the same result as calling e.g. There's still thinking needed around what the registration endpoint will return when the Similarly we also haven't figured out yet how to implement the advanced flows (e.g. changing ones password) given that they need a fresh re-auth session and can't use cookies to store state between requests. |
If the solution is to combine Kratos and Hydra, just curious why not use the Code Grant + PKCE flow? This is the recommended flow for oidc mobile clients. AppAuth is one oidc client library to implement such flow in iOS and Android apps. |
Code Grant + PKCE is useful for third party sign in (e.g. "Sign in with Google") but rarely used in first party applications. We'll support OAuth2 Auth Code + PKCE at some point via Hydra though for those who want to use this in first party scenarios or who want to provide social sign in. |
@aeneasr I came upon this thread while looking for a Personal Access Token feature. We have a need to support authentication from our CLI triggered by a CI system like Github Actions, CircleCI, Jenkins, etc. Obviously username/password works for this, but personal access tokens allow our users to generate tokens specifically for these use cases and manage expiration/rotation more explicitly. It looks like you mentioned you were working on this, but the feature doesn't seem to be in the PR you cited. Did I miss that feature somewhere, or would that warrant another issue to track and implement? |
Hey David, we have API auth but it is scoped to user credentials for now. Personal API Tokens are usually something you generate after a user signed in / has a valid session. These tokens might also have their own subject ID. There are currently no real plans to add Personal API Tokens, but adding them should be easy actually as the implementation is pretty much trivial! So we could think about an RFC / design draft |
Thanks @aeneasr – that would be helpful! It'd be great to allow logged in users to create, rotate, revoke, and even name these tokens, and ideally the login/auth flows from our application can treat these tokens just like a password to maintain a uniform integration experience. |
Can you maybe create a new issue for that to move the discussion there @davidthor ? Thanks a lot 👍 |
There's also more to it like permissions, when the token was used last, ... The question also is if this is really something Kratos should solve or if this is another component entirely. |
Is your feature request related to a problem? Please describe.
I'm currently trying to give a third party access to my API (authenticated with Kratos, authorization through Keto and Oathkeeper as a gateway).
The documentation describes that “Self-Service User Login and User Registration for API Clients” will be addressed in a future release.
I'd like to discuss how we could implement this. Because the current system uses cookies which doesn't really work for API clients, storing them isn't great because then the third party API wouldn't be stateless and including them in a request just isn't reliable for me.
Describe the solution you'd like
An auth method which is easy for a developer to implement when trying to connect to my API (not specifically mine of course but anyone who is using Kratos to protect an API and a third party needs access to it).
Describe alternatives you've considered
This is what I'd like to discuss, I might be able to PR the solution we find. We have a few "standard" options, but other creative options we can discuss:
1. JWT Tokens
Tokens which contain information about the API.
Pretty secure, easy to implement
2. oAuth
Does this in an okay way but what if someone doesn't use oAuth and how would this work for authorization? (I'm not an expert on oAuth so more clarification on this would be great)
Very secure, hard to implement
3. Basic Auth
Not really an option IMO due to the lack of security. But could use the technology to send over encrypted keys for example.
Not secure, easy to implement
4. Certificates
Sending data across with certificates could be an option we could explore.
Unsure
Most of the time the third party would already have an account but it's possible that they don't so how do we differ "APIs keys" from being connected to an account or not being connected to an account.
The text was updated successfully, but these errors were encountered: