]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
rgw/sts: GetCallerIndentity API
authorRaja Sharma <raja@ibm.com>
Thu, 22 May 2025 11:08:00 +0000 (16:38 +0530)
committerRaja Sharma <raja@ibm.com>
Wed, 16 Jul 2025 14:09:47 +0000 (19:39 +0530)
Tracker: https://tracker.ceph.com/issues/72157

Signed-off-by: Raja Sharma <raja@ibm.com>
src/rgw/rgw_auth.cc
src/rgw/rgw_auth.h
src/rgw/rgw_auth_s3.cc
src/rgw/rgw_op_type.h
src/rgw/rgw_rest_s3.cc
src/rgw/rgw_rest_sts.cc
src/rgw/rgw_rest_sts.h

index 0d6c749af050e7d4be5e2e536af3bc7ea70082b8..a2f792ac008a144bfd05beec3c5c794a8cfea0a7 100644 (file)
@@ -1032,11 +1032,20 @@ auto rgw::auth::RemoteApplier::load_acct_info(const DoutPrefixProvider* dpp) con
 
 void rgw::auth::RemoteApplier::modify_request_state(const DoutPrefixProvider* dpp, req_state* s) const
 {
+  string key = "aws:userid";
+  string value = info.acct_user.id;
+  s->env.emplace(key, value);
+
   // copy our identity policies into req_state
   s->iam_identity_policies.insert(s->iam_identity_policies.end(),
                                   policies.begin(), policies.end());
 }
 
+std::optional<rgw::ARN> rgw::auth::RemoteApplier::get_caller_identity() const 
+{
+  return rgw::ARN(owner_acct_user.id, "user", owner_acct_user.tenant, true);
+}
+
 /* rgw::auth::LocalApplier */
 /* static declaration */
 const std::string rgw::auth::LocalApplier::NO_SUBUSER;
@@ -1144,6 +1153,10 @@ auto rgw::auth::LocalApplier::load_acct_info(const DoutPrefixProvider* dpp) cons
 
 void rgw::auth::LocalApplier::modify_request_state(const DoutPrefixProvider* dpp, req_state* s) const
 {
+  string key = "aws:userid";
+  string value = user_info.type == TYPE_ROOT ? user_info.account_id : user_info.user_id.id;
+  s->env.emplace(key, value);
+
   // copy our identity policies into req_state
   s->iam_identity_policies.insert(s->iam_identity_policies.end(),
                                   policies.begin(), policies.end());
index f4e469fb2625a077d4df1e4d26791d85332ca1b6..0630f36d929e24f6b3a730d2b027a06bf7d63591 100644 (file)
@@ -687,9 +687,7 @@ public:
   void write_ops_log_entry(rgw_log_entry& entry) const override;
   uint32_t get_identity_type() const override { return info.acct_type; }
 
-  std::optional<rgw::ARN> get_caller_identity() const override {
-    return std::nullopt;
-  }
+  std::optional<rgw::ARN> get_caller_identity() const override;
 
   std::string get_acct_name() const override { return info.acct_name; }
   std::string get_subuser() const override { return {}; }
@@ -858,7 +856,7 @@ public:
     rgw::Partition partition = rgw::Partition::aws;
     rgw::Service service = rgw::Service::sts;
     std::string acct = role.account->id.empty() ? role.tenant : role.account->id;
-    std::string resource = "assumed-role/" + role.name + "/" + token_attrs.role_session_name;
+    std::string resource = "assumed-role" + role.path + role.name + "/" + token_attrs.role_session_name;
 
     return rgw::ARN(partition, service, "", acct, resource);
   }
index 8e243d89ce6ee4f423ce47a425f42927e62f2511..36332f7f35f35284951f8f8b7bdea9f0eb93dfc4 100644 (file)
@@ -472,6 +472,7 @@ static inline int parse_v4_auth_header(const req_info& info,               /* in
 bool is_non_s3_op(RGWOpType op_type)
 {
   switch (op_type) {
+  case RGW_STS_GET_CALLER_IDENTITY:
   case RGW_STS_GET_SESSION_TOKEN:
   case RGW_STS_ASSUME_ROLE:
   case RGW_STS_ASSUME_ROLE_WEB_IDENTITY:
index 01f5a432e92e4905ad2834c013966ac75b85eb01..ca8a71748ecf764b15bd513a3050ed1c6493cb15 100644 (file)
@@ -132,6 +132,7 @@ enum RGWOpType {
   RGW_OP_SYNC_MDLOG_NOTIFY,
   RGW_OP_PERIOD_POST,
   /* sts specific*/
+  RGW_STS_GET_CALLER_IDENTITY,
   RGW_STS_ASSUME_ROLE,
   RGW_STS_GET_SESSION_TOKEN,
   RGW_STS_ASSUME_ROLE_WEB_IDENTITY,
index ac1b1e3f54fe87c1d396967112b3195ac16dc057..5d37827143b8ee062a714a501aca778fde27ec9d 100644 (file)
@@ -6467,6 +6467,7 @@ AWSGeneralAbstractor::get_auth_data_v4(const req_state* const s,
         case RGW_OP_PUT_BUCKET_OBJ_LOCK:
         case RGW_OP_PUT_OBJ_RETENTION:
         case RGW_OP_PUT_OBJ_LEGAL_HOLD:
+        case RGW_STS_GET_CALLER_IDENTITY:
         case RGW_STS_GET_SESSION_TOKEN:
         case RGW_STS_ASSUME_ROLE:
         case RGW_OP_PUT_BUCKET_PUBLIC_ACCESS_BLOCK:
index 0b57f2ea858bafc6a8df83ee3d31c15678c64ed7..f893e727a49e3693624f05a7fc52a06207e89858 100644 (file)
@@ -1055,6 +1055,45 @@ void RGWSTSAssumeRole::execute(optional_yield y)
   }
 }
 
+int RGWSTSGetCallerIdentity::verify_permission(optional_yield y)
+{
+  // https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html
+  // Permissions are not required because the same information is returned when access is denied.
+
+  return 0;
+}
+
+void RGWSTSGetCallerIdentity::execute(optional_yield y)
+{
+  std::string account;
+  std::string userid;
+  std::string arn;
+
+  if (const auto& acc = s->auth.identity->get_account(); acc) {
+    account = acc->id;
+  }
+
+  if(account.empty()) {
+    account = s->user->get_tenant();
+  }
+  if (auto it = s->env.find("aws:userid"); it != s->env.end()) {
+    userid = it->second;
+  }
+
+  auto a = s->auth.identity->get_caller_identity();
+  if(a) {
+    arn = a->to_string();
+  }
+
+  s->formatter->open_object_section_in_ns("GetCallerIdentityResponse", RGW_REST_STS_XMLNS);
+  s->formatter->open_object_section("GetCallerIdentityResult");
+  encode_json("Arn",  arn, s->formatter);
+  encode_json("UserId", userid, s->formatter);
+  encode_json("Account", account, s->formatter);
+  s->formatter->close_section();
+  s->formatter->close_section();
+}
+
 int RGW_Auth_STS::authorize(const DoutPrefixProvider *dpp,
                             rgw::sal::Driver* driver,
                             const rgw::auth::StrategyRegistry& auth_registry,
@@ -1067,7 +1106,8 @@ using op_generator = RGWOp*(*)();
 static const std::unordered_map<std::string_view, op_generator> op_generators = {
   {"AssumeRole", []() -> RGWOp* {return new RGWSTSAssumeRole;}},
   {"GetSessionToken", []() -> RGWOp* {return new RGWSTSGetSessionToken;}},
-  {"AssumeRoleWithWebIdentity", []() -> RGWOp* {return new RGWSTSAssumeRoleWithWebIdentity;}}
+  {"AssumeRoleWithWebIdentity", []() -> RGWOp* {return new RGWSTSAssumeRoleWithWebIdentity;}},
+  {"GetCallerIdentity", []() -> RGWOp* {return new RGWSTSGetCallerIdentity;}}
 };
 
 bool RGWHandler_REST_STS::action_exists(const req_state* s)
index befa93169b4ead0e4077f8d8a96e6ca470177ba8..8a02d5617880a79802ccafdbc4d8cd422da8d4c2 100644 (file)
@@ -203,6 +203,15 @@ public:
   RGWOpType get_type() override { return RGW_STS_GET_SESSION_TOKEN; }
 };
 
+class RGWSTSGetCallerIdentity : public RGWREST_STS {
+public:
+  RGWSTSGetCallerIdentity() = default;
+  void execute(optional_yield y) override;
+  int verify_permission(optional_yield y) override;
+  const char* name() const override { return "get_caller_identity"; }
+  RGWOpType get_type() override { return RGW_STS_GET_CALLER_IDENTITY; }
+};
+
 class RGW_Auth_STS {
 public:
   static int authorize(const DoutPrefixProvider *dpp,