]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
rgw/iam: add support to service principals in bucket policy
authorYuval Lifshitz <ylifshit@ibm.com>
Thu, 13 Mar 2025 17:34:07 +0000 (17:34 +0000)
committerYuval Lifshitz <ylifshit@ibm.com>
Wed, 26 Mar 2025 15:21:32 +0000 (15:21 +0000)
Fixes: https://tracker.ceph.com/issues/70086
Signed-off-by: Yuval Lifshitz <ylifshit@ibm.com>
src/rgw/rgw_auth.h
src/rgw/rgw_basic_types.cc
src/rgw/rgw_basic_types.h
src/rgw/rgw_bucket_logging.h
src/rgw/rgw_iam_policy.cc

index 2568558a289d04fd8a9debf40201b7b2328e82dc..6632a38e6a61bd15c9754b480f3f25816d4dab5f 100644 (file)
@@ -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<RGWAccountInfo>& get_account() const override {
+    static constexpr std::optional<RGWAccountInfo> no_account;
+    return no_account;
+  }
+
+  bool is_root() const override {
+    return false;
+  }
+};
+
 /* The anonymous abstract engine. */
 class AnonymousEngine : public Engine {
   CephContext* const cct;
index f82694683a05fb96efcaec0cda82892962593048..e489a1391e6249b2c5036e297559ad8246e2c6c3 100644 (file)
@@ -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()) {
index d09f06a4a98f38761498e3994fca2b26c32005ac..93321e85c5c978ad02f1f3344bc7662203c5d254 100644 (file)
@@ -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);
   }
index cbdb8b55f8827cbba9ac598b241cc925c2076677..d4c2e28b4752445988fbf6cffd4865e14016b0a4 100644 (file)
@@ -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<rgw_bucket>;
 
 constexpr unsigned MAX_BUCKET_LOGGING_BUFFER = 1000;
index bcd89d7f87733b3e96e752e24ae6782716cbbe26..caf9150edf5f314ba41bd1039aef0fd44d8f49d5 100644 (file)
@@ -584,6 +584,8 @@ boost::optional<Principal> 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)