I am new to golang and currently trying to build a multi-tenant application. In my application each tenants have their own database. My requirement is that I need to switch database connection per tenant request, how can this be accomplished in golang. I prefer postgresql for this project.
I can have a map of database connection to tenant, but not sure if this is a good practice.
Your help and suggestion is highly appreciated
I've handled a similar kind of requirement in Rails. Probably you can use the same approach in go-lang also.
I will have one master DB, which will hold just the tenant information. Like tenant name and db_name.
And I've got a rack middleware which will switch DB based on a subdomain(I'm using the subdomain to identify the tenant).
For example, Your master DB can have table tenants and an example record might probably look like this:
{
id: 1,
name: 'XYZ',
db_name: 'xyz'
}
and when your application receives a request with subdomain xyz, Your middleware should switch to xyz DB.
its a better solutions to create an schema instead of an entire database and on each request change the schema of the request identifying the tenant.other solutions is to create a database and reopen a connection on each request after the tenant recognition on the middleware
Related
Good afternoon,
I am writing a front-end for a research database that holds sensitive health information. My institution has a policy that user actions be logged by the SQL server so that they can perform audits on the server log files in the event of a breach.
Because of this policy, I cannot connect Django to the db as a system user (otherwise, all users of the front-end actions would be logged by the server as the Django system user instead as the actual user individually).
Is there a way to connect to the DB using per user credentials so that actions performed on the front end will be logged as that user on the db server? I have been able to find a lot of information about using multiple databases, but nothing about per user authentication of those databases.
Thank you in advanced!
I don't think you can do that, the user that connect to the database need to have access to all the tables.
I had a similar issue when I wanted to use Django models outside Django and restrict access to certain models for certain users.
I ended up using SQLAlchemy and its automap feature on the existing Django database. Then you can connect to the database using your SQL users.
However, if you don't mind all the users accessing all the tables and are only concerned about the logs, maybe you can use a different settings.py or at least a different DATABASES configuration for each user?
I was able to accomplish this by giving the SQL user the IMPERSONATE permission and performing EXECUTE AS prior to the DB queries that I needed to have logged in models.py.
cursor = self.connection.cursor()
try:
cursor.execute("EXECUTE AS " + get_current_user()
except DatabaseError as e:
cursor.close()
raise e
Which is the better way to set up access on some databases that my web apps query. I can only think of one pro for one and one con for the other, so I need some other input before making a final decision.
Option 1 – 10 apps, 10 databases, 1 Service Accounts for each app (User does not have direct access)
All query requests go through the Service Account to the database. The con I can think of is that there is no record of who sent the request, just that the SA accessed the db with a request.
Option 2 – 10 apps, 10 databases, User has direct access (no Service Account)
All query requests from the app go directly to the db and each request is logged, identifying who sent the request from what app. This setup could be locked down further by allowing the specific app access only to db/tables/columns that it needs to complete the request/query. The obvious pro is there would be no anonymous requests; all requests could be traced back to the requester and not just to a SA.
If by Service Account you refer to a functional account or database account for the application. This is the way to go. If you need to log who did the request your application should have user authentication and do the logging of the request.
The other alternative of a database account per user is not scalable and if you have to provide a database id for each user, which the user will be using to connect, it also has security implications.
By having the application between the user and the database you isolate the database from the outside and the only access is what the applications permits.
We have a requirement that user account can provide username/password for database. This means that after user account is loaded, the user should use his own database connection for persistence.
How do I configure that in Spring Data?
Which database?
Which ORM implementation?
Spring has the AbstractRoutingDataSource, which lets you change the DataSource at runtime.
You could also use a delegation pattern, where the web server connects as a limited user, and then changes role to a different user if their authentication is successful. See How to run SQL SET statements against db at start of connection/session using Hibernate? and Switch role after connecting to database
You'll probably need to disable caching in your ORM too.
Just had a query that can WSO2 Identity Server be integrated with both LDAP and DB at the same time. To elaborate my query more, say we have a group of users defined in LDAP and another group of users defined in DB and I want Identity Server to act authorization gateway for both of these groups. Is it possible?
Also, while integrating with DB WSO2 adds its own tables in our existing DB. Is there any way we can add custom attributes(claims) support in DB without altering the WSO2 tables?
WSO2 Identity Server supports only one active user realm at a given time. But if your requirement is to use WSO2 IS as an authorization gateway which connects to a LDAP server as well to a DB for populating claims, etc then it is possible to use XACML support in WSO2 IS with a custom PIP(policy information point). In that case, you can connect to the LDAP server as the primary user store and write a custom PIP to connect to the DB to read the required claims.
Following two posts on PIPs will be helpful.
[1] - http://xacmlinfo.com/2011/12/18/understanding-pip/
[2] - http://blog.facilelogin.com/2011/04/xacml-policy-information-point.html
Answering the second query, with the default configuration in the JDBC mode, WSO2 IS uses its own set of tables for maintaining its user store. But if required, you can write your own user store implementation which connects to your database.
I spent a long time yesterday to configure for my CouchDB instance in order to create a little app and letting CouchDB manage authentication and authorizations for me.
So I ended up with something like that :
On top of everything I've got a server admin, who basically is god on my CouchBD instance.
Then I created a database named "mydatabase" (for example) and added the role "mydatabase_dba" as admin and also the role "mydatabase_user" as reader.
I also created a database named "_users" which contains all the database admins and users with their roles and also a design document named "_auth" which manages authorizations.
Only the server admin is admin of this database, and I added users with role "mydatabase_dba" as readers. Then, for those of you who knows about it, I modified the "validate_doc_update" field o the "_auth" document so that users with role "mydatabase_dba" can only deals with users with role "mydatabase_user".
So, to summarize at this point :
server admin is still god
users with role "mydatabase_user" can connect to "mydatabase" but they are just readers
users with role "mydatabase_dba" are admins of "mydatabase"
users with role "mydatabase_dba" can connect to database "_users" where they are readers
users with role "mydatabase_dba" can only manage users of role "mydatabase_user" in "_users"
Hope this is clear :D
What I can do now is create an application that will not manage users itself, but let users connect to CouchDB directly (transparently).
The problem come when it deals with users creation/update/deletion.
Because only users with role "mydatabase_dba" can access to the "_users" database and work on users with roles "mydatabase_user", I need at some point to connect to CouchDB as this db admin.
I have two solutions :
Create a user interface into my app that will let the admin connect and do what he has to do
or
Make some more code and let the app do it automatically, this is the solution I prefer, but the problem is : I have to store the admin credentials...
Sorry for the long introduction but I had to describe the landscape first :)
I created a post yesterday about how I could secure the connection between my app and the CouchDB instance : here
The solution I was given is to use HTTP over SSL (/TLS) to secure the communication. I'm okay with that, but now I have another concern, maybe I'm paranoid, but because my app will need to connect as "mydatabase_dba", I have to store its credential somewhere.
But how to store them securely ? As said in my previous post, even if I store the hashed password instead of the plain text password, if an attacker access my app source code, he'll have my admin credentials...
An application should never have an administrative rights. It should only be given the bare minim rights it needs to function. If the application needs some administrative rights, make sure it has as few as possible. Other than that, most of the time these credentials are stored in plain text in some file that only your application can access.
Never commit this text file into your source code manager (Subversion, Git, etc.)! Placing the file into a running system must be a step in the installation procedure.