From: Pritha Srivastava Date: Mon, 11 May 2020 17:52:02 +0000 (+0530) Subject: rgw: adding user related web token claims to ops log X-Git-Tag: v15.2.9~43^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=b858196d3d89554bdfd9681a1d735ee5a4faca7f;p=ceph.git rgw: adding user related web token claims to ops log for auditing purposes. Fixes: https://tracker.ceph.com/issues/45989 Signed-off-by: Pritha Srivastava (cherry picked from commit bb6a68ec14f07c17fdf68243aaec35c17d5e01bf) --- diff --git a/src/rgw/rgw_auth.cc b/src/rgw/rgw_auth.cc index 22d8ccd0d49e..60b01d8588ef 100644 --- a/src/rgw/rgw_auth.cc +++ b/src/rgw/rgw_auth.cc @@ -742,6 +742,11 @@ void rgw::auth::RoleApplier::modify_request_state(const DoutPrefixProvider *dpp, string condition = "aws:userid"; string value = role.id + ":" + role_session_name; s->env.emplace(condition, value); + + s->token_claims.emplace_back("sts"); + for (auto& it : token_claims) { + s->token_claims.emplace_back(it); + } } rgw::auth::Engine::result_t diff --git a/src/rgw/rgw_auth.h b/src/rgw/rgw_auth.h index e9a243dbb716..3d841213a492 100644 --- a/src/rgw/rgw_auth.h +++ b/src/rgw/rgw_auth.h @@ -638,6 +638,7 @@ protected: const rgw_user user_id; string token_policy; string role_session_name; + std::vector token_claims; public: @@ -645,11 +646,13 @@ public: const Role& role, const rgw_user& user_id, const string& token_policy, - const string& role_session_name) + const string& role_session_name, + const std::vector& token_claims) : role(role), user_id(user_id), token_policy(token_policy), - role_session_name(role_session_name) {} + role_session_name(role_session_name), + token_claims(token_claims) {} uint32_t get_perms_from_aclspec(const DoutPrefixProvider* dpp, const aclspec_t& aclspec) const override { return 0; @@ -678,7 +681,8 @@ public: const rgw::auth::RoleApplier::Role& role_name, const rgw_user& user_id, const std::string& token_policy, - const std::string& role_session) const = 0; + const std::string& role_session, + const std::vector& token_claims) const = 0; }; }; diff --git a/src/rgw/rgw_auth_s3.h b/src/rgw/rgw_auth_s3.h index 0809ee854eb8..0baad3401dd4 100644 --- a/src/rgw/rgw_auth_s3.h +++ b/src/rgw/rgw_auth_s3.h @@ -68,9 +68,10 @@ class STSAuthStrategy : public rgw::auth::Strategy, const rgw::auth::RoleApplier::Role& role, const rgw_user& user_id, const std::string& token_policy, - const std::string& role_session_name) const override { + const std::string& role_session_name, + const std::vector& token_claims) const override { auto apl = rgw::auth::add_sysreq(cct, ctl, s, - rgw::auth::RoleApplier(cct, role, user_id, token_policy, role_session_name)); + rgw::auth::RoleApplier(cct, role, user_id, token_policy, role_session_name, token_claims)); return aplptr_t(new decltype(apl)(std::move(apl))); } diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 7ce379b0dda6..48115804fc9a 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -1747,6 +1747,9 @@ struct req_state : DoutPrefixProvider { /// optional coroutine context optional_yield yield{null_yield}; + //token claims from STS token for ops log (can be used for Keystone token also) + std::vector token_claims; + req_state(CephContext* _cct, RGWEnv* e, rgw::sal::RGWUser* u, uint64_t id); ~req_state(); diff --git a/src/rgw/rgw_log.cc b/src/rgw/rgw_log.cc index a0f677644704..4955715c163c 100644 --- a/src/rgw/rgw_log.cc +++ b/src/rgw/rgw_log.cc @@ -274,6 +274,19 @@ void rgw_format_ops_log_entry(struct rgw_log_entry& entry, Formatter *formatter) formatter->close_section(); } formatter->dump_string("trans_id", entry.trans_id); + if (entry.token_claims.size() > 0) { + if (entry.token_claims[0] == "sts") { + formatter->open_object_section("sts_token_claims"); + for (const auto& iter: entry.token_claims) { + auto pos = iter.find(":"); + if (pos != string::npos) { + formatter->dump_string(iter.substr(0, pos), iter.substr(pos + 1)); + } + } + formatter->close_section(); + } + } + formatter->close_section(); } @@ -394,6 +407,10 @@ int rgw_log_op(RGWRados *store, RGWREST* const rest, struct req_state *s, entry.op = op_name; + if (! s->token_claims.empty()) { + entry.token_claims = std::move(s->token_claims); + } + /* custom header logging */ if (rest) { if (rest->log_x_headers()) { diff --git a/src/rgw/rgw_log.h b/src/rgw/rgw_log.h index e8ac71cc053a..1de5227939a1 100644 --- a/src/rgw/rgw_log.h +++ b/src/rgw/rgw_log.h @@ -35,9 +35,10 @@ struct rgw_log_entry { string bucket_id; headers_map x_headers; string trans_id; + std::vector token_claims; void encode(bufferlist &bl) const { - ENCODE_START(10, 5, bl); + ENCODE_START(11, 5, bl); encode(object_owner.id, bl); encode(bucket_owner.id, bl); encode(bucket, bl); @@ -61,10 +62,11 @@ struct rgw_log_entry { encode(bucket_owner, bl); encode(x_headers, bl); encode(trans_id, bl); + encode(token_claims, bl); ENCODE_FINISH(bl); } void decode(bufferlist::const_iterator &p) { - DECODE_START_LEGACY_COMPAT_LEN(10, 5, 5, p); + DECODE_START_LEGACY_COMPAT_LEN(11, 5, 5, p); decode(object_owner.id, p); if (struct_v > 3) decode(bucket_owner.id, p); @@ -113,6 +115,9 @@ struct rgw_log_entry { if (struct_v >= 10) { decode(trans_id, p); } + if (struct_v >= 11) { + decode(token_claims, p); + } DECODE_FINISH(p); } void dump(ceph::Formatter *f) const; diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index d3ac614fc7f0..857e515742bd 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -5942,7 +5942,7 @@ 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); + auto apl = role_apl_factory->create_apl_role(cct, s, r, user_id, token.policy, token.role_session, token.token_claims); 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; diff --git a/src/rgw/rgw_sts.cc b/src/rgw/rgw_sts.cc index ca813c244b61..9b28eca67802 100644 --- a/src/rgw/rgw_sts.cc +++ b/src/rgw/rgw_sts.cc @@ -45,6 +45,7 @@ int Credentials::generateCredentials(CephContext* cct, const boost::optional& policy, const boost::optional& roleId, const boost::optional& role_session, + const boost::optional> token_claims, boost::optional user, rgw::auth::Identity* identity) { @@ -108,6 +109,10 @@ int Credentials::generateCredentials(CephContext* cct, token.user = u; } + if (token_claims) { + token.token_claims = std::move(*token_claims); + } + if (identity) { token.acct_name = identity->get_acct_name(); token.perm_mask = identity->get_perm_mask(); @@ -295,6 +300,7 @@ AssumeRoleWithWebIdentityResponse STSService::assumeRoleWithWebIdentity(AssumeRo { AssumeRoleWithWebIdentityResponse response; response.assumeRoleResp.packedPolicySize = 0; + std::vector token_claims; if (req.getProviderId().empty()) { response.providerId = req.getIss(); @@ -302,6 +308,10 @@ AssumeRoleWithWebIdentityResponse STSService::assumeRoleWithWebIdentity(AssumeRo response.aud = req.getAud(); response.sub = req.getSub(); + token_claims.emplace_back(string("iss") + ":" + req.getIss()); + token_claims.emplace_back(string("aud") + ":" + req.getAud()); + token_claims.emplace_back(string("sub") + ":" + req.getSub()); + //Get the role info which is being assumed boost::optional r_arn = rgw::ARN::parse(req.getRoleARN()); if (r_arn == boost::none) { @@ -338,6 +348,7 @@ AssumeRoleWithWebIdentityResponse STSService::assumeRoleWithWebIdentity(AssumeRo response.assumeRoleResp.retCode = response.assumeRoleResp.creds.generateCredentials(cct, req.getDuration(), req.getPolicy(), roleId, req.getRoleSessionName(), + token_claims, user_id, nullptr); if (response.assumeRoleResp.retCode < 0) { return response; @@ -384,6 +395,7 @@ AssumeRoleResponse STSService::assumeRole(AssumeRoleRequest& req) response.retCode = response.creds.generateCredentials(cct, req.getDuration(), req.getPolicy(), roleId, req.getRoleSessionName(), + boost::none, user_id, nullptr); if (response.retCode < 0) { return response; @@ -422,6 +434,7 @@ GetSessionTokenResponse STSService::getSessionToken(GetSessionTokenRequest& req) boost::none, boost::none, boost::none, + boost::none, user_id, identity); ret < 0) { return make_tuple(ret, cred); diff --git a/src/rgw/rgw_sts.h b/src/rgw/rgw_sts.h index fa8cc70295da..37519210efba 100644 --- a/src/rgw/rgw_sts.h +++ b/src/rgw/rgw_sts.h @@ -129,11 +129,12 @@ struct SessionToken { bool is_admin; uint32_t acct_type; string role_session; + std::vector token_claims; SessionToken() {} void encode(bufferlist& bl) const { - ENCODE_START(2, 1, bl); + ENCODE_START(3, 1, bl); encode(access_key_id, bl); encode(secret_access_key, bl); encode(expiration, bl); @@ -145,11 +146,12 @@ struct SessionToken { encode(is_admin, bl); encode(acct_type, bl); encode(role_session, bl); + encode(token_claims, bl); ENCODE_FINISH(bl); } void decode(bufferlist::const_iterator& bl) { - DECODE_START(2, bl); + DECODE_START(3, bl); decode(access_key_id, bl); decode(secret_access_key, bl); decode(expiration, bl); @@ -163,6 +165,9 @@ struct SessionToken { if (struct_v >= 2) { decode(role_session, bl); } + if (struct_v >= 3) { + decode(token_claims, bl); + } DECODE_FINISH(bl); } }; @@ -181,6 +186,7 @@ public: const boost::optional& policy, const boost::optional& roleId, const boost::optional& role_session, + const boost::optional > token_claims, boost::optional user, rgw::auth::Identity* identity); const string& getAccessKeyId() const { return accessKeyId; }