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>
}
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 << ")";
}
}
} 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;
}
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;
}
}
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
}
}
- 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));
}
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);
}
}
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;
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 {
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;
};
};
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)));
}
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) {
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);
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;
}
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);
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)
{
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);
req.getPolicy(), roleId,
req.getRoleSessionName(),
token_claims,
+ req.getPrincipalTags(),
user_id, nullptr);
if (response.assumeRoleResp.retCode < 0) {
return response;
req.getPolicy(), roleId,
req.getRoleSessionName(),
boost::none,
+ boost::none,
user_id, nullptr);
if (response.retCode < 0) {
return response;
boost::none,
boost::none,
boost::none,
+ boost::none,
user_id,
identity); ret < 0) {
return make_tuple(ret, cred);
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,
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;
};
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);
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);
if (struct_v >= 4) {
decode(issued_at, bl);
}
+ if (struct_v >= 5) {
+ decode(principal_tags, bl);
+ }
DECODE_FINISH(bl);
}
};
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; }