Skip to content
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

rgw: Add External Authentication for S3 #34093

Closed
wants to merge 6 commits into from

Conversation

clwluvw
Copy link
Contributor

@clwluvw clwluvw commented Mar 20, 2020

Ceph external authenticators like Keystone, LDAP, STS, ... doesn't support all RGWUser features and force users to use Keystone, ... servers and can't use their own authentication servers. With this PR anyone can have their own authentication server (Organizations most have) and Ceph Object Storage (S3) can authenticate users with their own authentication server based on needed APIs. Now Remote Users can have SubUser, Permission, is_admin, ... when they come from the server.

Signed-off-by: Seena Fallah seeenafallah@gmail.com

Signed-off-by: Seena Fallah <seenafallah@gmail.com>
Signed-off-by: Seena Fallah <seenafallah@gmail.com>
Signed-off-by: Seena Fallah <seenafallah@gmail.com>
Signed-off-by: Seena Fallah <seenafallah@gmail.com>
S3 can authenticate users with custom authentication servers based on needed APIs.

Signed-off-by: Seena Fallah <seenafallah@gmail.com>
@clwluvw clwluvw force-pushed the external-authentication branch 5 times, most recently from 77f0bc1 to cfffedf Compare March 20, 2020 21:17
@mattbenjamin
Copy link
Contributor

Well, currently remote authentication works fine, but creates a shadow user--not in keystone, but in the RGW database. That can then be a system user, have caps, and so on. I will read further.

@clwluvw
Copy link
Contributor Author

clwluvw commented Mar 20, 2020

@mattbenjamin Really thanks for your attention. Yes in this scenario we have a shadow of external users in RGW database. The main point here is to support SubUser and Permissions and admin users that still are shadows and it acts like Keystone integration.

@clwluvw clwluvw force-pushed the external-authentication branch 4 times, most recently from 56d58ae to 52b6030 Compare March 20, 2020 23:55
@clwluvw clwluvw force-pushed the external-authentication branch 4 times, most recently from 592587b to ab16410 Compare March 21, 2020 13:48
Signed-off-by: Seena Fallah <seenafallah@gmail.com>
@clwluvw
Copy link
Contributor Author

clwluvw commented Mar 21, 2020

jenkins render docs

@ceph-jenkins
Copy link
Collaborator

Doc render available at http://docs.ceph.com/ceph-prs/34093/

@clwluvw
Copy link
Contributor Author

clwluvw commented Mar 24, 2020

@mdw-at-linuxbox It's now ready for your review :)

@clwluvw
Copy link
Contributor Author

clwluvw commented Mar 30, 2020

@mattbenjamin Hi Matt. Can someone else review this PR?

@cbodley
Copy link
Contributor

cbodley commented Mar 30, 2020

why is it necessary or useful to invent a new authentication protocol here?

@clwluvw
Copy link
Contributor Author

clwluvw commented Mar 30, 2020

why is it necessary or useful to invent a new authentication protocol here?

@cbodley To support subuser and other RGWUser features in Remote Authentication. And also anyone have it's own authentication server (Organizations most have) by implementing these APIs.

@cbodley
Copy link
Contributor

cbodley commented Mar 30, 2020

@cbodley To support subuser and other RGWUser features in Remote Authentication.

these are radosgw internals - it's not clear why they should be involved in remote authentication

And also anyone have it's own authentication server (Organizations most have) by implementing these APIs.

most organizations don't write a custom json endpoint to handle their authentication, they rely on integration with existing services though keystone, ldap, or sts

@mattbenjamin
Copy link
Contributor

mattbenjamin commented Jan 10, 2022

@cbodley @mattbenjamin may I kindly bring this one up again and not let it go stale?

It's still a little unfortunate that RADOSGW does not handle users when integrated with OpenStack Keystone. Maybe there are > some pointers to the roadmap that I missed?

Hi @frittentheke, I'm confused; This discussion was about subusers, which is, in part, a mechanism used with Swift interop when the users are RGW local users. RGW (separately) has keystone integration, which permits authentication directly as OpenStack users. What am I missing?

@frittentheke
Copy link
Contributor

frittentheke commented Jan 12, 2022

@cbodley @mattbenjamin may I kindly bring this one up again and not let it go stale?
It's still a little unfortunate that RADOSGW does not handle users when integrated with OpenStack Keystone. Maybe there are > some pointers to the roadmap that I missed?

Hi @frittentheke, I'm confused; This discussion was about subusers, which is, in part, a mechanism used with Swift interop when the users are RGW local users. RGW (separately) has keystone integration, which permits authentication directly as OpenStack users. What am I missing?

Yeah @mattbenjamin sorry my statement was indeed confusing.

I was referring to support for OpenStack Keystone "users" as subusers for buckets. Currently RGW only uses the the project_id from the keystone authentication:

This actually renders bucket policies with rules for different Keystone users non-functional as they are all reduced to their project.

I once asked on the ML about this as well https://lists.ceph.io/hyperkitty/list/ceph-users@ceph.io/message/S2TV7GVFJTWPYA6NVRXDL2JXYUIQGMIN/ and I simply thought a generic implementation for external authentication could enable such a richer integration as it apparently also has support for subusers.

@frittentheke
Copy link
Contributor

@mattbenjamin would you kindly take another look at this PR or even my question on the ML (https://lists.ceph.io/hyperkitty/list/ceph-users@ceph.io/message/S2TV7GVFJTWPYA6NVRXDL2JXYUIQGMIN/) about the keystone auth integration?

I am just so darn confused that currently only the project id is taken from Keystone which is then rendering all nice features such as Ceph subusers or any further access control useless. Are you potentially working on extending the integration in #43898 ?

@frittentheke frittentheke mentioned this pull request Feb 14, 2022
15 tasks
@djgalloway djgalloway changed the base branch from master to main July 9, 2022 00:00
@djgalloway djgalloway requested a review from a team as a code owner July 9, 2022 00:00
Copy link
Contributor

@anthonyeleven anthonyeleven left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for the delay, we're working to do better.
I've requested some documentation changes. I must defer to the RGW code folks regarding the code and API bits.

users with all RGW User features like SubUser, Tenant, Permissions.
The only thing you should obey is to implement these APIs so we can get needed
data from your sever.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest something like

It is possible to use an external authentication server for the Ceph Object Gateway (RGW), providing
all user features including subuser, tenant, and permissions. The external server must implement that API as below.

External Authentication APIs
============================

In your authentication server you should implement these APIs so we can get our needed data
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/In your/The/
s/you//
s/our//

}
}

``access_key_id``: This is a access key which is used in request.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe something like

This is the access key used in requests
This is the request signature computed with the user secret / signing key.

``user_id``: user id for RGW User

``tenant``: Optional. If user has tenant.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional, only needed if the user has tenants.


``tenant``: Optional. If user has tenant.

``user_name``: display name in RGW User
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RGW user display name

.set_default("")
.set_description("URL to external authentication server to get user secret")
.set_long_description(
"To cache user access key and secret key we use to send GET request to this URL"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we send a GET

.set_description("URL to external authentication server to get user secret")
.set_long_description(
"To cache user access key and secret key we use to send GET request to this URL"
"in pattern of URL/?access_key_id=ACCESS_KEY_ID and need response in format of"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the pattern of
and need a response in the format

.set_default(10000)
.set_description("external authentication access key cache size")
.set_long_description(
"Max number of access keys that will be cached. Access Key that is not cached "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Access keys that are not cached require the


Option("rgw_s3_external_authentication_verify_ssl", Option::TYPE_BOOL, Option::LEVEL_ADVANCED)
.set_default(true)
.set_description("Should RGW verify the external authentication server SSL certificate."),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.set_description("Should RGW verify the external authentication server's SSL certificate?"),


Option("rgw_s3_auth_use_external_authentication", Option::TYPE_BOOL, Option::LEVEL_ADVANCED)
.set_default(false)
.set_description("Should external authentication be used to authenticate users."),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

? instead of .

@mattbenjamin
Copy link
Contributor

I don't know if we should be doing what this PR intends, but it seems to be doing several things. I'm most suspicious of "remote authentication for S3." RGW already has Keystone authentication. I think the oldest part of this change involves changing the Keystone integration, so we also need to fully understand that. But what sort of remote authentication protocol standard does the "remote authentication for S3 " represent? Why can't integration with established OpenID::connect- and Oauth2-enabled IDPs satisfy the requirement, esp. given their intrinsic support for dynamic authz of different kinds?

@clwluvw
Copy link
Contributor Author

clwluvw commented Jul 11, 2022

@mattbenjamin Well, the idea was to have a general rest API for external authentication. In this case, it won't be limited to any authentication systems (like keystone, ...) and on the server-side (authentication server) anyone can have its own implementation and prepare the APIs needed by RGW to sync and could use all the RGW User's feature!
eg. in keystone there is no subuser support (#33210) - but with this idea, there is no need to have a Keystone for the authenticator and RGW can connect to any Authentication server implements the needed APIs.

@mattbenjamin
Copy link
Contributor

mattbenjamin commented Jul 11, 2022

@mattbenjamin Well, the idea was to have a general rest API for external authentication. In this case, it won't be limited to any authentication systems (like keystone, ...) and on the server-side (authentication server) anyone can have its own implementation and prepare the APIs needed by RGW to sync and could use all the RGW User's feature! eg. in keystone there is no subuser support (#33210) - but with this idea, there is no need to have a Keystone for the authenticator and RGW can connect to any Authentication server implements the needed APIs.

It would be my contention that it's not consistent with RGW's role to define a sui generis remote authentication protocol. To repeat a question from above, why is it not possible to build on OpenID::connect() or Oauth2--these are established standards with a lot of flexibility and basically well-known security properties?

@frittentheke
Copy link
Contributor

It would be my contention that it's not consistent with RGW's role to define a sui generis remote authentication protocol. To repeat a question from above, why is it not possible to build on OpenID::connect() or Oauth2--these are established standards with a lot of flexibility and basically well-known security properties?

I second your thinking here. While looking at OIDC or SAML to allow RGW to consume an existing authentication setup one cannot ignore that OpenStack Keystone is quite a common auth target for RGW, but it currently does not provide those kind of "standard" interfaces. The federation feature (https://docs.openstack.org/keystone/latest/admin/federation/introduction.html) works to integrate Keystone with existing authentication systems. And if those exists in the form of a versatile implementation like Keycloak those could then also be used as auth source by RGW.

But, with only Keystone and it's built-in auth, which is natively supported by RGW the case looks different.
While OAuth 2.0 is being worked on (https://blueprints.launchpad.net/keystone/+spec/oauth2-client-credentials-ext, https://blueprints.launchpad.net/keystone/+spec/enhance-oauth2-interoperability) this is not yet available widespread.

Also the question is if the proper claims and metadata can be provided to a potential client RGW yet. So enabling features like subusers, groups and whatever RGW supports to use in its bucket policies. Also the mapping from and to the world of EC2 credentials to serve S3 adds some more complexity.

What I am saying is that just having a standard and very common auth protocol like OAuth 2.0, only helps if that's what your clients use. If you "only" want to integrate one established system like Keystone or the whole of OpenStack services with RGW, RGW might have to have a more plug and play integration into that ecosystem. And while that exists in the form of keystone_auth (which lacks in functionality, see #34093 (comment)), it's reasonable to think about having a more generic integration available which then allows for a simple far end to exist on the Keystone side.

If you allow for a comparison, look at what Kubernetes does with its webhook auth: https://kubernetes.io/docs/reference/access-authn-authz/webhook/. That also does allow of any arbitrary system to provide auth to Kubernetes, while they certainly also support OIDC ... if you already have that for your clients.

@mattbenjamin
Copy link
Contributor

mattbenjamin commented Jul 11, 2022

It would be my contention that it's not consistent with RGW's role to define a sui generis remote authentication protocol. To repeat a question from above, why is it not possible to build on OpenID::connect() or Oauth2--these are established standards with a lot of flexibility and basically well-known security properties?

I second your thinking here.

> > But, with only Keystone and it's built-in auth, which is natively supported by RGW the case looks different. While OAuth 2.0 is being worked on (https://blueprints.launchpad.net/keystone/+spec/oauth2-client-credentials-ext, https://blueprints.launchpad.net/keystone/+spec/enhance-oauth2-interoperability) this is not yet available widespread. > > Also the question is if the proper claims and metadata can be provided to a potential client RGW yet. So enabling features like subusers, groups and whatever RGW supports to use in its bucket policies. Also the mapping from and to the world of EC2 credentials to serve S3 adds some more complexity. > > What I am saying is that just having a standard and very common auth protocol like OAuth 2.0, only helps if that's what your clients use.

@frittenthek you're clearly very informed--can you clarify just a bit further what you're actually recommending with respect to the current PR? is there a gap in our keystone support that we need to fill (e.g., exposing subusers), and if so, do you support the subuser change being proposed by @clwluvw ? and am I correct to read you as rejecting the "generic auth protocol" part of this--I'm reading that as your take, in spite of the caveats you mentioned; Please correct me if that's incorrect.

thanks!

Matt

@frittentheke
Copy link
Contributor

frittentheke commented Jul 12, 2022

But, with only Keystone and it's built-in auth, which is natively supported by RGW the case looks different. While OAuth 2.0 is being worked on (https://blueprints.launchpad.net/keystone/+spec/oauth2-client-credentials-ext, https://blueprints.launchpad.net/keystone/+spec/enhance-oauth2-interoperability) this is not yet available widespread.

Also the question is if the proper claims and metadata can be provided to a potential client RGW yet. So enabling features like subusers, groups and whatever RGW supports to use in its bucket policies. Also the mapping from and to the world of EC2 credentials to serve S3 adds some more complexity. What I am saying is that just having a standard and very common auth protocol like OAuth 2.0, only helps if that's what your clients use.

@frittentheke you're clearly very informed--can you clarify just a bit further what you're actually recommending with respect to the current PR?

Certainly @mattbenjamin . First of all I second your thought of questioning why RGW should support more than the likely most common OIDC + OAuth2 to talk to an external and existing authentication system. It certainly is well established and has lots of flexibility, the issue arises in the case of OpenStack Keystone being the "only" authentication system and it not yet being an OAuth2 authentication server itself. Currently Keystone only provides SAML when serving as an IdP (https://docs.openstack.org/keystone/latest/admin/federation/configure_federation.html#keystone-as-idp). And SAML while also being a standard (even if it's on its way out ...) , does not get us anywhere with RGW.

See maybe https://softiron.com/blog/integrating-rados-gateway-with-an-external-oidc-provider/ as an example how an OIDC provider is expected and, getting back to Keystone by itself is not yet capable of providing this. This is being worked on, see https://review.opendev.org/q/topic:bp%252Foauth2-client-credentials-ext, with different integrations than RGW in mind so far though, so I am unsure if this covers everything to work as an OIDC provider to RGW. It's not about authenticating, but providing the right data for authorization.

One would much more likely go the path of having something like Keycloak be the hub of all authentication and authorization and doing any sort of data fetching, field mapping and token exchange there. But in a setup where a flexible OIDC provider such as Keycloak exists, both, Keystone and RGW would just be be clients to it. But quintessentially this asks for third component, the commonly used authentication system, to be setup and there is lots of complexity in implementing and integrating this.
See last questions about my reasoning in regards to a much much simpler "interface" to get external auth to RGW.

is there a gap in our keystone support that we need to fill (e.g., exposing subusers), and if so, do you support the subuser change being proposed by @clwluvw ?

Yes there is a (or maybe more) gap. Currently at the very least the lack of sub-users. If you look at my first point of my post to the ML at https://lists.ceph.io/hyperkitty/list/ceph-users@ceph.io/message/S2TV7GVFJTWPYA6NVRXDL2JXYUIQGMIN/

currently only the project_id is used by RGW's keystone auth. This means I can only use the granularity of "projects" for my bucket policies rendering them virtually useless. I have to grant all of the users of a project access rights to my bucket. I'd much rather have users like "s3-gitlab" and grant only that user access to a particular bucket, but not all of them.

There already was PR #33210 also by @clwluvw implementing this, but unfortunately this went stale during review 😞 . If Ceph wants to keep and maintain specific integration to Keystone auth, it would be awesome to pick up on that one (again).

and am I correct to read you as rejecting the "generic auth protocol" part of this--I'm reading that as your take, in spite of the caveats you mentioned; Please correct me if that's incorrect.

No - I was, sorry about the amount of words I used.

Having OIDC as generic integration for auth is great and a must have and I also strongly agree to not even attempt to create a similar feature rich protocol. But as said above it's not always applicable to expect only OIDC on the other end, depending on the environment people want to integrate RGW with.
Looking at K8s and their webhook auth (https://kubernetes.io/docs/reference/access-authn-authz/webhook/) I then came to the conclusion that having a really simple and generic method to connect RGW with just about anything I can put a webhook responder in front off does make sense. So actually I like the idea of having this generic external authentication.

Thinking this through this would require at least a first actual use-case, so an integration. Keystone or rather the adapter in fron of the keystone auth could be one. But talking about introducing this generic auth and then deprecating the well established and widely used Keystone auth in RGW in favor of a new piece of software might be too much of a stretch.

@github-actions
Copy link

This pull request has been automatically marked as stale because it has not had any activity for 60 days. It will be closed if no further activity occurs for another 30 days.
If you are a maintainer or core committer, please follow-up on this pull request to identify what steps should be taken by the author to move this proposed change forward.
If you are the author of this pull request, thank you for your proposed contribution. If you believe this change is still appropriate, please ensure that any feedback has been addressed and ask for a code review.

@github-actions github-actions bot added the stale label Sep 10, 2022
@frittentheke
Copy link
Contributor

I don't consider this stale.

@github-actions github-actions bot removed the stale label Sep 27, 2022
@mmgaggle
Copy link
Member

@frittentheke It would seem that adding support for AssumeRoleWithSAML, and combining it with keystone-as-idp (SAML) would be a viable option, would it not?

@frittentheke
Copy link
Contributor

frittentheke commented Oct 14, 2022

@mmgaggle Sorry about the late response.

@frittentheke It would seem that adding support for AssumeRoleWithSAML, and combining it with keystone-as-idp (SAML) would be a viable option, would it not?

This sounds like it's going in the right direction of reusing existing capabilities ....

but is this really lightweight enough to have this as the standard auth integration of RGW to an OpenStack cloud?
SAML is not really common (anymore) and OIDC and OAuth 2.0 with all sort of additions and flows are taking over.

Could you explain how the config and dataflows would look like then?

@github-actions
Copy link

This pull request has been automatically marked as stale because it has not had any activity for 60 days. It will be closed if no further activity occurs for another 30 days.
If you are a maintainer or core committer, please follow-up on this pull request to identify what steps should be taken by the author to move this proposed change forward.
If you are the author of this pull request, thank you for your proposed contribution. If you believe this change is still appropriate, please ensure that any feedback has been addressed and ask for a code review.

@github-actions github-actions bot added the stale label Dec 13, 2022
@frittentheke
Copy link
Contributor

@mmgaggle would you mind diving into your idea a little more?

@github-actions github-actions bot removed the stale label Dec 13, 2022
@github-actions
Copy link

This pull request has been automatically marked as stale because it has not had any activity for 60 days. It will be closed if no further activity occurs for another 30 days.
If you are a maintainer or core committer, please follow-up on this pull request to identify what steps should be taken by the author to move this proposed change forward.
If you are the author of this pull request, thank you for your proposed contribution. If you believe this change is still appropriate, please ensure that any feedback has been addressed and ask for a code review.

@github-actions github-actions bot added the stale label Feb 11, 2023
@github-actions
Copy link

This pull request has been automatically closed because there has been no activity for 90 days. Please feel free to reopen this pull request (or open a new one) if the proposed change is still appropriate. Thank you for your contribution!

@github-actions github-actions bot closed this Mar 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
8 participants