MongoDB - limit access to other databases using a connectionString - mongodb

I want to create multiple databases, say db_1, db_2, etc. I have a single user called dashboard.
Now, I have a dashboard, and I want to limit access to the dbs, i.e. I want to use a connectionString such that the user dashboard only has access to db_1 and another connectionString such that the user dashboard only has access to db_2.
For example, if I were to use mongosh "mongodb+srv://dashboard:MY_PASSWORD#IP_ADDRESS/db1?tls=true&authSource=admin&replicaSet=IP_ADDRESS", you can the change the database to db2 if you want to. But I want to prevent that - that connection should only have access to db1
This can be accomplished by creating different users with limits on what they read, but I was hoping this could be done via a single user.

You can do something like you are wanting if the user dashboard is a user on each individual database, and not in the more "global" admin database.
The authSource=admin in your query string tells MongoDB which database to use to authenticate, and since you are pointing to admin it will always use the same user, the one in the admin database.
If two users have the same name but are created in different databases, they are two separate users. If you want to have a single user with permissions on multiple databases, create a single user with a role for each applicable database.
https://www.mongodb.com/docs/manual/core/security-users/#authentication-database
So you'd need to create a separate dashboard user in each database.
The docs and steps here maybe helpful:
https://www.mongodb.com/docs/manual/tutorial/create-users/#create-additional-users-for-your-deployment

Related

How to use postgresql roles to connect a database?

We saw PostgreSQL roles in class this year. Our teacher told us that it is more secure to use different roles with custom rights for every table or even column if necessary.
We have a project in which we have to use PostgreSQL to build a website with restricted access for connected users, who can be of different types (admin, employee, client). To follow the teacher's recommendations, we created different roles with different rights (one for each type of user).
We decided to use Go for our back end (with token auth) but I can't figure it out how to use our roles, which are more groups than users. I read in the doc that you "open" the connection to the DB once for all but to do so you have to give a PostgreSQL role. I didn't find a way to change the connected role without closing and reopening the DB. If I run the application without changing connected roles, how can PostgreSQL control if a user has the right to access tables he needs for the requests.
You can change roles on the fly in PostgreSQL. If you are logged in as nobody, and nobody is a member of role cleve, you can become role admins with
SET ROLE cleve;
But using that during authentication is problematic, because there is nothing that keeps the user from running the statement
RESET ROLE;
to become nobody again and then impersonating somebody else.
Typically, there are two ways how you can use the role system to leverage database permissions:
You have a personalized database user for every user of the application.
That is of course only feasible if the set of users is fairly constant and limited.
Then the individual users have no permissions at all, and there are certain roles like admin, reader, accountant and so on. The login roles are assigned permissions by becoming members of one or more of these roles, and they inherit their permissions.
You don't have personalized database users.
Then you only have one login role per set of permissions, say accountant, admin, viewer and so on.
The application has to decide as which user it should connect before establishing the database connection. If you need database queries for this decision, you perform those as a nobody database user with very limited permissions. For example, it may call a function that verifies a user-supplied password.
You can use the set role command to change the role while the session is open.

Allow a DB User to access a single Database

I'm new to google cloud.
I created a Google Cloud SQL Instance.
Added multiple DBs and few users.
How can I restrict an user to single database ?
and
How can I restrict an user to single database with ReadOnly permission ?
Take a look at this post in regards to restricting access to only one database for a user; and here you can find more information related to "Read Only" access using MySQL.

MongoDB single/central authSource vs multiple/distributed authSource

When securing a Mongo instance, you can add user credentials and roles into the built-in "admin" database or into any number of other custom databases that you may add to the instance.
It seems to me that having all the credentials and roles stored centrally in the "admin" database would make sense from a management point of view (easy to locate, everything in one place, don't need to connect to multiple databases to find all users, predictability, etc), so why would you use a custom database as the "authSource"? The docs don't explain why you would use "admin" over a custom database or vice versa.
So my question is:
Is it best practice to store all users and roles in the "admin" database or in each custom database to which that user will be connecting? Why?

MongoDB should I put users in admin db or local db

Is there any best practice in MongoDB as to where I should put my database users?
I've just set up a local MongoDB server and I've added users in the admin database and granted them access to "their" (by their I mean the only database the users have access to) database.
Do you think it would be better to just put the users in "their" database and not in the admin database?
Regardless of the user's authentication database, Mongo always stores user information in admin.
MongoDB stores all user information, including name, password, and the user's authentication database, in the system.users collection in the admin database.
See centralized-user-data and system-users-collection.
When you create a user and grant that user access to a single database (aka their authentication database) then that information can only be stored in the admin database.
So, it's not really a question of "best practice"; storing user details in admin is MongoDB's choice, as implemented by their user management commands.
Update in response to this comment:
Ok, so the users are always located in the admin db, but I may also add "duplicates" to the other dbs? Maybe the question should be whether there any advantage in adding users to the other "non admin" dbs?
If you intend to have a single user with access to multiple databases then create a single user with roles in each of those databases rather than creating that user multiple times i.e. once in each of those databases. For example:
use admin;
db.createUser({user:'userName', pwd:'passwordValue', roles:[
{role:'readWrite', db:'DatabaseA'},
{role:'readWrite', db:'DatabaseB'}
]});

Mongodb - how to add database user through spring application

I want to implement database authentication in mongodb.
In order to do that, I found out that I need to first create an admin user and then create separate users for each of my database through mongodb client shell (manually or using a javascript file).
I was wondering if it is possible to add user to the individual databases from the spring application itself but did not get any useful pointers to do this. Is it that this approach is wrong because if this possible the application will always be able to access the database because it itself is creating the user, but external access will still be blocked.
Please let me know how this can be achieved or if it is an incorrect approach.
After you add a normal user via the MongoShell, you can then connect via your application and create either normal users, or read only users.
Note that a normal user can also add users, so the users your application adds may need to be down as read only users depending on your use case and needs.
In the MongoShell, adding a read only user can be done via
use myAppDB
db.addUser("JohnSmith", "CheddarCheese", true)