]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw/sts: code to use session tags in AssumeRoleWithWebIdentity call,
authorPritha Srivastava <prsrivas@redhat.com>
Wed, 10 Mar 2021 06:54:49 +0000 (12:24 +0530)
committerPritha Srivastava <prsrivas@redhat.com>
Thu, 18 Aug 2022 08:08:57 +0000 (13:38 +0530)
as aws:PrincipalTags in an IAM policy's Condition element.

The incoming session tags in AssumeRoleWithWebIdentity call
are passed along with the session credentials (temporary creds)
as aws:PrincipalTags, and those can be used as Condition element
of an IAM Policy.

Signed-off-by: Pritha Srivastava <prsrivas@redhat.com>
(cherry picked from commit 6b2d3da84c0960260d06433906deda218a2cc43e)

src/rgw/rgw_auth.cc
src/rgw/rgw_auth.h
src/rgw/rgw_auth_s3.h
src/rgw/rgw_rest_s3.cc
src/rgw/rgw_rest_sts.cc
src/rgw/rgw_sts.cc
src/rgw/rgw_sts.h

index e5492c36425f72786f1f4d56f815b0fcae37d016..e7c25cf8749290600ef63a1deca9b71c080aa2bd 100644 (file)
@@ -794,11 +794,11 @@ void rgw::auth::LocalApplier::write_ops_log_entry(rgw_log_entry& entry) const
 }
 
 void rgw::auth::RoleApplier::to_str(std::ostream& out) const {
-  out << "rgw::auth::LocalApplier(role name =" << role.name;
+  out << "rgw::auth::RoleApplier(role name =" << role.name;
   for (auto& policy: role.role_policies) {
     out << ", role policy =" << policy;
   }
-  out << ", token policy =" << token_policy;
+  out << ", token policy =" << token_attrs.token_policy;
   out << ")";
 }
 
@@ -814,7 +814,7 @@ bool rgw::auth::RoleApplier::is_identity(const idset_t& ids) const {
       }
     } else if (p.is_assumed_role()) {
       string tenant = p.get_tenant();
-      string role_session = role.name + "/" + role_session_name; //role/role-session
+      string role_session = role.name + "/" + token_attrs.role_session_name; //role/role-session
       if (role.tenant == tenant && role_session == p.get_role_session()) {
         return true;
       }
@@ -822,12 +822,12 @@ bool rgw::auth::RoleApplier::is_identity(const idset_t& ids) const {
       string id = p.get_id();
       string tenant = p.get_tenant();
       string oidc_id;
-      if (user_id.ns.empty()) {
-        oidc_id = user_id.id;
+      if (token_attrs.user_id.ns.empty()) {
+        oidc_id = token_attrs.user_id.id;
       } else {
-        oidc_id = user_id.ns + "$" + user_id.id;
+        oidc_id = token_attrs.user_id.ns + "$" + token_attrs.user_id.id;
       }
-      if (oidc_id == id && user_id.tenant == tenant) {
+      if (oidc_id == id && token_attrs.user_id.tenant == tenant) {
         return true;
       }
     }
@@ -838,7 +838,7 @@ bool rgw::auth::RoleApplier::is_identity(const idset_t& ids) const {
 void rgw::auth::RoleApplier::load_acct_info(const DoutPrefixProvider* dpp, RGWUserInfo& user_info) const /* out */
 {
   /* Load the user id */
-  user_info.user_id = this->user_id;
+  user_info.user_id = this->token_attrs.user_id;
 }
 
 void rgw::auth::RoleApplier::modify_request_state(const DoutPrefixProvider *dpp, req_state* s) const
@@ -855,9 +855,9 @@ void rgw::auth::RoleApplier::modify_request_state(const DoutPrefixProvider *dpp,
     }
   }
 
-  if (!this->token_policy.empty()) {
+  if (!this->token_attrs.token_policy.empty()) {
     try {
-      string policy = this->token_policy;
+      string policy = this->token_attrs.token_policy;
       bufferlist bl = bufferlist::static_from_string(policy);
       const rgw::IAM::Policy p(s->cct, role.tenant, bl);
       s->session_policies.push_back(std::move(p));
@@ -869,15 +869,19 @@ void rgw::auth::RoleApplier::modify_request_state(const DoutPrefixProvider *dpp,
   }
 
   string condition = "aws:userid";
-  string value = role.id + ":" + role_session_name;
+  string value = role.id + ":" + token_attrs.role_session_name;
   s->env.emplace(condition, value);
 
-  s->env.emplace("aws:TokenIssueTime", token_issued_at);
+  s->env.emplace("aws:TokenIssueTime", token_attrs.token_issued_at);
+
+  for (auto& m : token_attrs.principal_tags) {
+    s->env.emplace(m.first, m.second);
+  }
 
   s->token_claims.emplace_back("sts");
   s->token_claims.emplace_back("role_name:" + role.tenant + "$" + role.name);
-  s->token_claims.emplace_back("role_session:" + role_session_name);
-  for (auto& it : token_claims) {
+  s->token_claims.emplace_back("role_session:" + token_attrs.role_session_name);
+  for (auto& it : token_attrs.token_claims) {
     s->token_claims.emplace_back(it);
   }
 }
index 1614259815e07966480e58918767607cb6a37cb4..c0df09818f7af95c3b7a8592f051eec583135df0 100644 (file)
@@ -702,33 +702,30 @@ public:
 class RoleApplier : public IdentityApplier {
 public:
   struct Role {
-    string id;
-    string name;
-    string tenant;
-    vector<string> role_policies;
-  } role;
+    std::string id;
+    std::string name;
+    std::string tenant;
+    std::vector<std::string> role_policies;
+  };
+  struct TokenAttrs {
+    rgw_user user_id;
+    std::string token_policy;
+    std::string role_session_name;
+    std::vector<std::string> token_claims;
+    std::string token_issued_at;
+    std::vector<std::pair<std::string, std::string>> principal_tags;
+  };
 protected:
-  const rgw_user user_id;
-  string token_policy;
-  string role_session_name;
-  std::vector<string> token_claims;
-  string token_issued_at;
+  Role role;
+  TokenAttrs token_attrs;
 
 public:
 
   RoleApplier(CephContext* const cct,
                const Role& role,
-               const rgw_user& user_id,
-               const string& token_policy,
-               const string& role_session_name,
-               const std::vector<string>& token_claims,
-               const string& token_issued_at)
+               const TokenAttrs& token_attrs)
     : role(role),
-      user_id(user_id),
-      token_policy(token_policy),
-      role_session_name(role_session_name),
-      token_claims(token_claims),
-      token_issued_at(token_issued_at) {}
+      token_attrs(token_attrs) {}
 
   uint32_t get_perms_from_aclspec(const DoutPrefixProvider* dpp, const aclspec_t& aclspec) const override {
     return 0;
@@ -737,7 +734,7 @@ public:
     return false;
   }
   bool is_owner_of(const rgw_user& uid) const override {
-    return (this->user_id.id == uid.id && this->user_id.tenant == uid.tenant && this->user_id.ns == uid.ns);
+    return (this->token_attrs.user_id.id == uid.id && this->token_attrs.user_id.tenant == uid.tenant && this->token_attrs.user_id.ns == uid.ns);
   }
   bool is_identity(const idset_t& ids) const override;
   uint32_t get_perm_mask() const override {
@@ -756,11 +753,7 @@ public:
     virtual aplptr_t create_apl_role( CephContext* cct,
                                       const req_state* s,
                                       const rgw::auth::RoleApplier::Role& role,
-                                      const rgw_user& user_id,
-                                      const std::string& token_policy,
-                                      const std::string& role_session,
-                                      const std::vector<string>& token_claims,
-                                      const std::string& token_issued_at) const = 0;
+                                      const rgw::auth::RoleApplier::TokenAttrs& token_attrs) const = 0;
     };
 };
 
index cc1dbf90b0e5e4719ff7fd342db541722bae2812..0a1390a1eecfeed5a66970874ff6040eabce32be 100644 (file)
@@ -66,13 +66,9 @@ class STSAuthStrategy : public rgw::auth::Strategy,
   aplptr_t create_apl_role(CephContext* const cct,
                             const req_state* const s,
                             const rgw::auth::RoleApplier::Role& role,
-                            const rgw_user& user_id,
-                            const std::string& token_policy,
-                            const std::string& role_session_name,
-                            const std::vector<string>& token_claims,
-                            const std::string& token_issued_at) const override {
+                            const rgw::auth::RoleApplier::TokenAttrs& token_attrs) const override {
     auto apl = rgw::auth::add_sysreq(cct, ctl, s,
-      rgw::auth::RoleApplier(cct, role, user_id, token_policy, role_session_name, token_claims, token_issued_at));
+      rgw::auth::RoleApplier(cct, role, token_attrs));
     return aplptr_t(new decltype(apl)(std::move(apl)));
   }
 
index 8945e929fcb083a1ab295f89813f0f63b5913b7d..948ffb81b4d51fe7dc7df0424cbb8eef53f81fd4 100644 (file)
@@ -5921,6 +5921,7 @@ rgw::auth::s3::STSEngine::authenticate(
   rgw_user user_id;
   string role_id;
   rgw::auth::RoleApplier::Role r;
+  rgw::auth::RoleApplier::TokenAttrs t_attrs;
   if (! token.roleId.empty()) {
     RGWRole role(s->cct, ctl, token.roleId);
     if (role.get_by_id(dpp, y) < 0) {
@@ -5937,8 +5938,6 @@ rgw::auth::s3::STSEngine::authenticate(
         r.role_policies.push_back(std::move(perm_policy));
       }
     }
-    // This is mostly needed to assign the owner of a bucket during its creation
-    user_id = token.user;
   }
 
   if (! token.user.empty() && token.acct_type != TYPE_ROLE) {
@@ -5955,7 +5954,13 @@ rgw::auth::s3::STSEngine::authenticate(
                                             get_creds_info(token));
     return result_t::grant(std::move(apl), completer_factory(boost::none));
   } else if (token.acct_type == TYPE_ROLE) {
-    auto apl = role_apl_factory->create_apl_role(cct, s, r, user_id, token.policy, token.role_session, token.token_claims, token.issued_at);
+    t_attrs.user_id = std::move(token.user); // This is mostly needed to assign the owner of a bucket during its creation
+    t_attrs.token_policy = std::move(token.policy);
+    t_attrs.role_session_name = std::move(token.role_session);
+    t_attrs.token_claims = std::move(token.token_claims);
+    t_attrs.token_issued_at = std::move(token.issued_at);
+    t_attrs.principal_tags = std::move(token.principal_tags);
+    auto apl = role_apl_factory->create_apl_role(cct, s, r, t_attrs);
     return result_t::grant(std::move(apl), completer_factory(token.secret_access_key));
   } else { // This is for all local users of type TYPE_RGW or TYPE_NONE
     string subuser;
index e84e7271419a6630a57f409a0c19526692d7dadb..0d8532e973f908c9c4197725f7ff1bd9635cb162 100644 (file)
@@ -595,7 +595,7 @@ void RGWSTSAssumeRoleWithWebIdentity::execute(optional_yield y)
   }
 
   STS::AssumeRoleWithWebIdentityRequest req(s->cct, duration, providerId, policy, roleArn,
-                        roleSessionName, iss, sub, aud);
+                        roleSessionName, iss, sub, aud, s->principal_tags);
   STS::AssumeRoleWithWebIdentityResponse response = sts.assumeRoleWithWebIdentity(req);
   op_ret = std::move(response.assumeRoleResp.retCode);
 
index bb125cdc60b31dd010657dd2570f3051a90715be..f46d100354f0fa578c80c3f0a5e64fc3ebd08bde 100644 (file)
@@ -42,10 +42,11 @@ void Credentials::dump(Formatter *f) const
 
 int Credentials::generateCredentials(CephContext* cct,
                           const uint64_t& duration,
-                          const boost::optional<string>& policy,
-                          const boost::optional<string>& roleId,
-                          const boost::optional<string>& role_session,
-                          const boost::optional<std::vector<string>> token_claims,
+                          const boost::optional<std::string>& policy,
+                          const boost::optional<std::string>& roleId,
+                          const boost::optional<std::string>& role_session,
+                          const boost::optional<std::vector<std::string>>& token_claims,
+                          const boost::optional<std::vector<std::pair<std::string,std::string>>>& session_princ_tags,
                           boost::optional<rgw_user> user,
                           rgw::auth::Identity* identity)
 {
@@ -129,6 +130,9 @@ int Credentials::generateCredentials(CephContext* cct,
     token.role_session = role_session.get();
   }
 
+  if (session_princ_tags) {
+    token.principal_tags = std::move(*session_princ_tags);
+  }
   buffer::list input, enc_output;
   encode(token, input);
 
@@ -384,6 +388,7 @@ AssumeRoleWithWebIdentityResponse STSService::assumeRoleWithWebIdentity(AssumeRo
                                                                                       req.getPolicy(), roleId,
                                                                                       req.getRoleSessionName(),
                                                                                       token_claims,
+                                                                                      req.getPrincipalTags(),
                                                                                       user_id, nullptr);
   if (response.assumeRoleResp.retCode < 0) {
     return response;
@@ -434,6 +439,7 @@ AssumeRoleResponse STSService::assumeRole(const DoutPrefixProvider *dpp,
                                               req.getPolicy(), roleId,
                                               req.getRoleSessionName(),
                                               boost::none,
+                                              boost::none,
                                               user_id, nullptr);
   if (response.retCode < 0) {
     return response;
@@ -473,6 +479,7 @@ GetSessionTokenResponse STSService::getSessionToken(GetSessionTokenRequest& req)
                                       boost::none,
                                       boost::none,
                                       boost::none,
+                                      boost::none,
                                       user_id,
                                       identity); ret < 0) {
     return make_tuple(ret, cred);
index 14c783c1cde014c4cd4f0dfd84426c4f356eaa78..aca9e24d10dd1cd20752e5c40d32fb836d94da0c 100644 (file)
@@ -45,27 +45,30 @@ public:
 class AssumeRoleWithWebIdentityRequest : public AssumeRoleRequestBase {
   static constexpr uint64_t MIN_PROVIDER_ID_LEN = 4;
   static constexpr uint64_t MAX_PROVIDER_ID_LEN = 2048;
-  string providerId;
-  string iamPolicy;
-  string iss;
-  string sub;
-  string aud;
+  std::string providerId;
+  std::string iamPolicy;
+  std::string iss;
+  std::string sub;
+  std::string aud;
+  std::vector<std::pair<std::string,std::string>> session_princ_tags;
 public:
   AssumeRoleWithWebIdentityRequest( CephContext* cct,
-                      const string& duration,
-                      const string& providerId,
-                      const string& iamPolicy,
-                      const string& roleArn,
-                      const string& roleSessionName,
-                      const string& iss,
-                      const string& sub,
-                      const string& aud)
+                      const std::string& duration,
+                      const std::string& providerId,
+                      const std::string& iamPolicy,
+                      const std::string& roleArn,
+                      const std::string& roleSessionName,
+                      const std::string& iss,
+                      const std::string& sub,
+                      const std::string& aud,
+                      std::vector<std::pair<std::string,std::string>> session_princ_tags)
     : AssumeRoleRequestBase(cct, duration, iamPolicy, roleArn, roleSessionName),
-      providerId(providerId), iss(iss), sub(sub), aud(aud) {}
-  const string& getProviderId() const { return providerId; }
-  const string& getIss() const { return iss; }
-  const string& getAud() const { return aud; }
-  const string& getSub() const { return sub; }
+      providerId(providerId), iss(iss), sub(sub), aud(aud), session_princ_tags(session_princ_tags) {}
+  const std::string& getProviderId() const { return providerId; }
+  const std::string& getIss() const { return iss; }
+  const std::string& getAud() const { return aud; }
+  const std::string& getSub() const { return sub; }
+  const std::vector<std::pair<std::string,std::string>>& getPrincipalTags() const { return session_princ_tags; }
   int validate_input() const;
 };
 
@@ -132,14 +135,15 @@ struct SessionToken {
   uint32_t perm_mask;
   bool is_admin;
   uint32_t acct_type;
-  string role_session;
-  std::vector<string> token_claims;
-  string issued_at;
+  std::string role_session;
+  std::vector<std::string> token_claims;
+  std::string issued_at;
+  std::vector<std::pair<std::string,std::string>> principal_tags;
 
   SessionToken() {}
 
   void encode(bufferlist& bl) const {
-    ENCODE_START(4, 1, bl);
+    ENCODE_START(5, 1, bl);
     encode(access_key_id, bl);
     encode(secret_access_key, bl);
     encode(expiration, bl);
@@ -153,11 +157,12 @@ struct SessionToken {
     encode(role_session, bl);
     encode(token_claims, bl);
     encode(issued_at, bl);
+    encode(principal_tags, bl);
     ENCODE_FINISH(bl);
   }
 
   void decode(bufferlist::const_iterator& bl) {
-    DECODE_START(4, bl);
+    DECODE_START(5, bl);
     decode(access_key_id, bl);
     decode(secret_access_key, bl);
     decode(expiration, bl);
@@ -177,6 +182,9 @@ struct SessionToken {
     if (struct_v >= 4) {
       decode(issued_at, bl);
     }
+    if (struct_v >= 5) {
+      decode(principal_tags, bl);
+    }
     DECODE_FINISH(bl);
   }
 };
@@ -192,10 +200,11 @@ class Credentials {
 public:
   int generateCredentials(CephContext* cct,
                           const uint64_t& duration,
-                          const boost::optional<string>& policy,
-                          const boost::optional<string>& roleId,
-                          const boost::optional<string>& role_session,
-                          const boost::optional<std::vector<string> > token_claims,
+                          const boost::optional<std::string>& policy,
+                          const boost::optional<std::string>& roleId,
+                          const boost::optional<std::string>& role_session,
+                          const boost::optional<std::vector<std::string>>& token_claims,
+                          const boost::optional<std::vector<std::pair<std::string,std::string>>>& session_princ_tags,
                           boost::optional<rgw_user> user,
                           rgw::auth::Identity* identity);
   const string& getAccessKeyId() const { return accessKeyId; }