From: Yuval Lifshitz Date: Thu, 13 Mar 2025 17:34:07 +0000 (+0000) Subject: rgw/iam: add support to service principals in bucket policy X-Git-Tag: v20.3.0~206^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=7869df8cfdfe38af90fcefd4b87e37eb980b94e3;p=ceph.git rgw/iam: add support to service principals in bucket policy Fixes: https://tracker.ceph.com/issues/70086 Signed-off-by: Yuval Lifshitz --- diff --git a/src/rgw/rgw_auth.h b/src/rgw/rgw_auth.h index 2568558a289d..6632a38e6a61 100644 --- a/src/rgw/rgw_auth.h +++ b/src/rgw/rgw_auth.h @@ -842,6 +842,67 @@ public: }; }; +class ServiceIdentity : public Identity { + const std::string service_id; +public: + ServiceIdentity(const std::string& s) : service_id(s) {} + virtual ~ServiceIdentity() = default; + + ACLOwner get_aclowner() const override { + return {}; + } + + uint32_t get_perms_from_aclspec(const DoutPrefixProvider* dpp, const aclspec_t& aclspec) const override { + return RGW_PERM_NONE; + } + + bool is_admin_of(const rgw_owner& o) const override { + return false; + } + + bool is_owner_of(const rgw_owner& o) const override { + return false; + } + + uint32_t get_perm_mask() const override { + return RGW_PERM_NONE; + } + + virtual void to_str(std::ostream& out) const override { + out << "rgw::auth::ServiceIdentity(id=" << service_id << ")"; + } + + bool is_identity(const Principal& p) const override { + return p.is_service() && p.get_service() == service_id; + } + + uint32_t get_identity_type() const override { + return TYPE_RGW; + } + + std::string get_acct_name() const override { + return {}; + } + + std::string get_subuser() const override { + return {}; + } + + const std::string& get_tenant() const override { + static const std::string no_tenant; + return no_tenant; + } + + const std::optional& get_account() const override { + static constexpr std::optional no_account; + return no_account; + } + + bool is_root() const override { + return false; + } +}; + /* The anonymous abstract engine. */ class AnonymousEngine : public Engine { CephContext* const cct; diff --git a/src/rgw/rgw_basic_types.cc b/src/rgw/rgw_basic_types.cc index f82694683a05..e489a1391e62 100644 --- a/src/rgw/rgw_basic_types.cc +++ b/src/rgw/rgw_basic_types.cc @@ -170,6 +170,9 @@ ostream& operator <<(ostream& m, const Principal& p) { if (p.is_wildcard()) { return m << "*"; } + if (p.is_service()) { + return m << p.get_service(); + } m << "arn:aws:iam:" << p.get_account() << ":"; if (p.is_account()) { diff --git a/src/rgw/rgw_basic_types.h b/src/rgw/rgw_basic_types.h index d09f06a4a98f..93321e85c5c9 100644 --- a/src/rgw/rgw_basic_types.h +++ b/src/rgw/rgw_basic_types.h @@ -143,10 +143,11 @@ extern void decode_json_obj(rgw_placement_rule& v, JSONObj *obj); namespace rgw { namespace auth { class Principal { - enum types { User, Role, Account, Wildcard, OidcProvider, AssumedRole }; + enum types { User, Role, Account, Wildcard, OidcProvider, AssumedRole, Service }; types t; rgw_user u; std::string idp_url; + std::string service_id; explicit Principal(types t) : t(t) {} @@ -183,6 +184,12 @@ public: return Principal(AssumedRole, std::move(t), std::move(u)); } + static Principal service(std::string&& s) { + auto p = Principal(Service); + p.service_id = std::move(s); + return p; + } + bool is_wildcard() const { return t == Wildcard; } @@ -207,6 +214,10 @@ public: return t == AssumedRole; } + bool is_service() const { + return t == Service; + } + const std::string& get_account() const { return u.tenant; } @@ -227,6 +238,10 @@ public: return u.id; } + const std::string& get_service() const { + return service_id; + } + bool operator ==(const Principal& o) const { return (t == o.t) && (u == o.u); } diff --git a/src/rgw/rgw_bucket_logging.h b/src/rgw/rgw_bucket_logging.h index cbdb8b55f882..d4c2e28b4752 100644 --- a/src/rgw/rgw_bucket_logging.h +++ b/src/rgw/rgw_bucket_logging.h @@ -139,6 +139,8 @@ struct configuration { }; WRITE_CLASS_ENCODER(configuration) +static const std::string service_principal = "logging.s3.amazonaws.com"; + using source_buckets = std::set; constexpr unsigned MAX_BUCKET_LOGGING_BUFFER = 1000; diff --git a/src/rgw/rgw_iam_policy.cc b/src/rgw/rgw_iam_policy.cc index bcd89d7f8773..caf9150edf5f 100644 --- a/src/rgw/rgw_iam_policy.cc +++ b/src/rgw/rgw_iam_policy.cc @@ -584,6 +584,8 @@ boost::optional ParseState::parse_principal(string&& s, "for an assumed role, " "`arn:aws:iam::tenant:user/user-name` for a user, " "`arn:aws:iam::tenant:oidc-provider/idp-url` for OIDC.", s); + } else if (w->id == TokenID::Service) { + return Principal::service(std::move(s)); } if (errmsg)