So, I developed systems with CI a long time ago, and my answer would be that it depends on what you're doing.
The first suggestion, what I use, is to return the user's privacy at the time of login and save it in session, as the CI enables by the user data. I do with all the data that I use constantly, such as email, login, nickname, language and permission.
function mountSessionUser($userData) {
//força o carregamento da instância do CI
$CI = & get_instance();
$CI->session->set_userdata(['user-data' => json_encode($userData)]);
}
Then, if it exists:
$usuario = $CI->session->userdata('user-data');
It means that the user is logged in and you will have all the data of him that did in the login, without consulting the bank.
Now, about the main point of the question, which is about the relationship with the database outside the models. I use yes, no problem, but I always mentor my team the way we choose to use it in the project.
Coherent data to be read from the database to render a page must always be in the model or already preloaded, such as the user name example. Other functions, however, that are not linked to data that will be shown or that perform parallel or common tasks to the whole system may, in my view, be in the yes libraries. An example of this is the two libraries I use to manage users.
Within the model I keep the queries responsible for rendering user listings, user friends, and so on. But the password change function, which in this case can be done via site and via API, stays in the user management library, called several times in the application, not only in the user controller.