Custom role

Have you considered using a middleware?
I have a middleware that elevates the role for the user once they pass a specific condition:

const res = await next(parent, args, context, info);

if (res && res.value) {
  const adminRole = await strapi
    .query("plugin::users-permissions.role")
    .findOne({ where: { name: "Admin" } })

  if (!adminRole) {
    throw new PolicyError("Admin role not found",
      { errCode: "USER_INFO_REQUEST", })
  }

  if (user.role.id !== adminRole.id) {
    await strapi
      .query("plugin::users-permissions.user")
      .update({ where: { id: user.id }, data: { role: adminRole } })
  }
}

return res;

This is a GraphQL middleware so the next signature is slightly different.