]> git.apps.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>
Wed, 1 Sep 2021 10:26:17 +0000 (15:56 +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>
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 b7d48d603f7ee4bcded65560e210072ecd358c85..af23c23d71c9cd7aac5a30b84b037b3e48d4eece 100644 (file)
@@ -785,11 +785,11 @@ void rgw::auth::LocalApplier::load_acct_info(const DoutPrefixProvider* dpp, RGWU
 }
 
 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 << ")";
 }
 
@@ -805,7 +805,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;
       }
@@ -813,12 +813,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;
       }
     }
@@ -829,7 +829,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
@@ -846,9 +846,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));
@@ -860,15 +860,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 fc84a79b5bbe3fed92ff487cc6bbe1acf379e907..82403fad8d4ab1e1d9b9ea592719c6d05b4aca70 100644 (file)
@@ -686,29 +686,26 @@ public:
     std::string name;
     std::string tenant;
     std::vector<std::string> role_policies;
-  } role;
+  };
+  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;
-  std::string token_policy;
-  std::string role_session_name;
-  std::vector<std::string> token_claims;
-  std::string token_issued_at;
+  Role role;
+  TokenAttrs token_attrs;
 
 public:
 
   RoleApplier(CephContext* const cct,
                const Role& role,
-               const rgw_user& user_id,
-               const std::string& token_policy,
-               const std::string& role_session_name,
-               const std::vector<std::string>& token_claims,
-               const std::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;
@@ -717,7 +714,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 {
@@ -736,11 +733,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<std::string>& token_claims,
-                                      const std::string& token_issued_at) const = 0;
+                                      const rgw::auth::RoleApplier::TokenAttrs& token_attrs) const = 0;
     };
 };
 
index 5de9e46a5ac13e0101aad064b2ab1071b6d9c207..5ad1516f369a114f528ddc489b894891d1169692 100644 (file)
@@ -65,13 +65,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, store, 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 7a8fb8f45b1b7f587afc9d37f63e057dc1705f77..b7ee647e727d65258d582c390ce40181bde5331a 100644 (file)
@@ -6084,6 +6084,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()) {
     std::unique_ptr<rgw::sal::RGWRole> role = store->get_role(token.roleId);
     if (role->get_by_id(dpp, y) < 0) {
@@ -6100,8 +6101,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;
   }
 
   user = store->get_user(token.user);
@@ -6119,7 +6118,13 @@ rgw::auth::s3::STSEngine::authenticate(
                                             get_creds_info(token));
     return result_t::grant(std::move(apl), completer_factory(token.secret_access_key));
   } 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 44810d71265680b15cf6f3bf392a3537b4b5a09a..388fffd6ab4cdcbdbfee673c93d3df6e56a3feda 100644 (file)
@@ -637,7 +637,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 6cccaf03265f18abcd74b3ae0ac609158ce92605..edfb2ae39c012b0a50091193d5e211919c470076 100644 (file)
@@ -44,10 +44,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)
 {
@@ -131,6 +132,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);
 
@@ -385,6 +389,7 @@ AssumeRoleWithWebIdentityResponse STSService::assumeRoleWithWebIdentity(AssumeRo
                                                                                       req.getPolicy(), roleId,
                                                                                       req.getRoleSessionName(),
                                                                                       token_claims,
+                                                                                      req.getPrincipalTags(),
                                                                                       user_id, nullptr);
   if (response.assumeRoleResp.retCode < 0) {
     return response;
@@ -435,6 +440,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;
@@ -474,6 +480,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 6be5633488af5f35295f06117d6b60486b345dc3..d67cd49975415a2c83ec5e079a9c5e7ad4c94c33 100644 (file)
@@ -50,6 +50,7 @@ class AssumeRoleWithWebIdentityRequest : public AssumeRoleRequestBase {
   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 std::string& duration,
@@ -59,13 +60,15 @@ public:
                       const std::string& roleSessionName,
                       const std::string& iss,
                       const std::string& sub,
-                      const std::string& aud)
+                      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) {}
+      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;
 };
 
@@ -135,11 +138,12 @@ struct SessionToken {
   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);
   }
 };
@@ -195,7 +203,8 @@ public:
                           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::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 std::string& getAccessKeyId() const { return accessKeyId; }