OIDC can't be set up for the hardcoded clients
Describe the bug
I'm using Kanidm for OIDC. It doesn't allow changing the secret to a custom value for security reasons. (You can only read it or regenerate it)
Even if I were to user another IdP, it is a good security practice to use my own secrets instead of the exact same as every other self-hosted installation.
That clashes with OCIS as the desktop and mobile clients all have hardcoded secrets. There should be some way to change them (and also the client id).
Steps to reproduce
- Setup OIDC
- Have it working in the web UI
- Apps don't work
- Not find any config to change the secret in the apps
Expected behavior
- Be able to set up the secret (and client id) in the apps
Actual behavior
- Secret and client id are hardcoded
Duplicate of #2445
Duplicate of #2445
The issue is about the Web UI? I have successfully set that up. Kanidm does support that flow.
I'm talking about the desktop and mobile clients. Kanidm does also support the flow they use (except for the custom urls, but that isn't an issue with OCIS), but it does not support manually setting the secret for security reasons.
For better compatibility (and also higher security for who wishes) one should be able to change the secret that is used by clients to connect to OIDC.
https://github.com/kanidm/kanidm/issues/2802#issuecomment-2141059519
As this seems to be the intended behavior I can change it to a feature request.
Your request is already possible. We offer to build custom clients via a subscription. There you can change these values.
Ah okay, that comes with the Enterprise plan, right?
The scope for this request was only for my personal deployment, that would be 15,67€ per user per month or 391,75€ per month considering the minimum user quota.
For me and a few family members, just to get a properly secure OIDC implementation.
That is a bit unfortunate. Thanks for the swift response though.
@FilipeRamalho
I strongly disagree with framing public client id and secret as „insecure“ . We are doing PSKE auth flow which is considered secure.
What was not mentioned before is, that our clients can also do Dynamic Client Registration (DCR) in combination with capable Identity Providers like keycloak.
There is zero configuration needed for DCR and every client gets its own id.
Wait, it's just the same PKCE auth flow like for the web ui?
Because you explicitly were using a secret for the apps and not for the UI I thought it was a normal Authorization flow.
Kanidm does support that, that is what I used for the web UI. I will try that.
It is not working. I set it up using the public client setup and I get token errors, although I think I know the main problem.
Yes, it's all PKCE, but it doesn't seem to be the same client type.
https://github.com/owncloud/ocis/blob/42e1d39daf9c1edece65b88d07474f35b2b6c266/deployments/examples/ocis_keycloak/config/keycloak/clients/web.json#L22 OCIS web is a public client, kanidm works fine with it.
https://github.com/owncloud/ocis/blob/42e1d39daf9c1edece65b88d07474f35b2b6c266/deployments/examples/ocis_keycloak/config/keycloak/clients/desktop_client.json#L21 OCIS Desktop is set up as a confidential client. Kanidm will work with it, but the user cannot set the secret.
In both cases PKCE is used by default by kanidm. But in the latter case kanidm does not allow to set the secret.
As far as I understand it, it is not a problem to publish the secret of a confidential client if you use PKCE? That's actually a new concept to me, but it kind of makes sense?
Though I don't quite understand the advantage if you publish the secret. Why not just use PKCE instead of PKCE on top of the normal flow?
I kinda understand doing the normal flow and tacking PKCE on top of it so it's even more secure, but doesn't it just fallback to the same "level of security" of PKCE if you publish the secret?
From a quick research most sources seem to recommend PKCE as supplementary for confidential clients and not as a replacement. That does indicate to me that the secret still should not be shared.
So it seems the implementation here isn't insecure because of the shared secret, but maybe redundant?
I'm sorry if I'm being annoying with this, I'm trying to understand at which door I need to knock about this. For me it seems like the kanidm implementation is fine (except for custom urls), but that OCIS is going a very specific way to use PKCE that kanidm doesn't support.
I just came across this issue, and have a fundamental question regarding the OIDC implementation:
In my understanding of the spec (in particular Section 2.1 of RFC6749) the ownCloud desktop and mobile client are public clients, and as such should not use a client_secret.
Although I agree that a public client_"secret" is not unsafe in principle when combined with PKCE, I don't see the advantage compared to Authorization Code Flow with PKCE, as @FilipeRamalho already mentioned.
I would be pleased if you could explain why you have chosen this OAuth Flow for the ownCloud clients.
@TheOneRing @dragotin could you clarify?
We have to make a difference between the specs and real world implementations (and consider the history). Also the implementation is a living thing which changed over time and will continue to change.
From my pov client_secret and PKCE can be seen independent of each other (in fact the PKCE spec is not even talking about client secret).
And this is also how things got implemented over time: there is client id + client secret and there is PKCE. The defaults require a secret because many IdPs require bot to be set - at least in the past years.
Things might change now and we need to change as well and find a setup which fits for most IdPs.
Hope this explains things - if not please ping again. THX
@DeepDiver1975 Thanks for the explanation, that explains how it came to be.
But it doesn't quite explain why it still makes sense to have a public secret. If it were just the normal auth flow, that would be unsafe, thankfully that isn't the case, but with PKCE it's just redundant.
A private secret and PKCE make totally sense and can seen as independent as you say. But a public secret can't be seen as independent from the PKCE flow, because on its own it's unsafe, only through the PKCE it's safe.
I would even understand a default secret, albeit I don't think that is a good idea, at least I should be able to set a private secret and all would be great (well almost see below).
In the meanwhile I did experiment around and
- Through some manual interventions on a test server I was able to set a secret in kanidm (only did it for test purposes)
- Then I hit some issues with auto-provision, which surprised me as I already oAuth working over the web. I had to set some other environment variables and that got fixed.
- After that I still had an issue where the client_id had uppercase letters, which kanidm did accept on setup, but on the uri that ocis opens on the browser kanidm didn't like that, so I had to change the letters to lowercase for my test (This is an issue on kanidm's side, I think)
- Then the changing port on the localhost server also caused issues (also issue on kanidm side)
So I had those two kanidm issues left, which I was able to fix on each attempt by changing the URI, with those fixes kanidm did it's job and redirected to ocis, which then still didn't work.
I had a final ocis issue, from the logs it seems like the app successfully gets the redirect and the token, but when accessing the endpoints it does not transmit the token correctly. (It was in the header, so it definitely had the token)
At that point I had two kanidm side issues, this issue and now an issue with ocis accessing the endpoints.
I assumed those issues are from kanidm as I haven't checked the specs, maybe that is the expected behavior by spec (so only lowercase letters in uri and no changing ports), but with so many issues on so many sides I didn't want waste even more time finding out whose fault it is.
So I gave up and set up Nextcloud, they use the Backend for Frontend approach, so I only set up one client on kanidm and it just works.
Well .... The clients are all compiled which means no user can change the default client id and secret. Under the assumption that a secret is needed the default secret can only be public. 🤷
Anyway have fun with nextcloud 👋
@DeepDiver1975 I mean yes, the default would still be public, which is why I I said don't think it would be a good idea.
But I could imagine that is easier to do that as the alternative would be a quite big breaking change? Though that isn't for me to worry about :P If you think this is sth. that should be fixed, it's up for you to decide how to go about it without bothering too many, which is a very important consideration for a project this size. 😅
@DeepDiver1975 Thanks for the clarification!
There is one thing I don't quite understand, though: You write that the client secret is used for compatibility reasons with older IdPs. But doesn't that mean that such (legacy) IdPs (which require a client secret) are necessarily incompatible with the ownCloud web app?
This ticket is stunning. The OIDC implementation that ownCloud uses is fundamentally broken: the clients are not authenticating in a way that anyone considers rational, and which is incompatible with many identity providers. ownCloud's response here is nothing short of absolutely wild, from suggesting small home users pay an enterprise subscription to rationalizing the why it's not broken "because of the history".
Anyways, I'm also going to look elsewhere, for my personal and professional use.