Security - Use Active Directory or SQL Server and Why? - sql-server

My company is currently planning to reconfigure security and we are currently arguing over which way to go, storing everything in Active Directory or in SQL Server?
So setting up Active Directory groups and use it to create a read and a read/write group and just move users in and out of these security groups and manage security for SQL Server from Active Directory or use SQL Server and move all users into security and create groups in SQL Server and manage the
security from there?

AD is the way to go in my opinion, for a number of reasons.
Security doesn't just cover access to databases. It covers access to files, folders etc. Anything in SQL is irrelevant to the question 'Should they have access to this spreadsheet?'. AD is the way to go there. Why not integrate everything into the same mechanism?
AD is more flexible than SQL. An AD Group can contain other AD groups. If you have an AD group called e.g. 'Power Traders' then the Power Traders are added to that group. There would also be groups which give access to individual securables (files, folders, databases, apps etc); 'Power Traders' would be added to those groups and inherit the access to the individual things. If another job also needs access to one of these, that job group can be added to the necessary individual group.
If an individual needs access to something outside his normal job, just add them to the individual groups necessary.
A full solution would actually have multiple levels of groups. How many would be down to the company and how it wishes to organise itself.

Related

Azure SQL Databases Admin Permissions

We are looking at moving a number of applications from on prem SQL Servers upto Azure as a Paas offering, what would be the best way to grant the Database team access to these databases? They'll be under one tenant but spread across a couple of subscriptions and multiple resource groups.
Moving forward i'd also like for them to have permissions automatically for any new SQL database added to any resource group within our tenant.
Little bit confused on the best approach?
Thanks in advance
Dave
You need to perform below mentioned tasks to achieve your requirement.
create an Azure Active Directory user
create an Azure Active Directory group and assign the user group
add an Azure Active Directory user/group as an Azure SQL
Administrator
add Azure Active Directory users to Azure SQL Database
Follow this third-party tutorial to implement the same.
Additionally, you can have Database-level role for each user for more safety of the data. Please check this official document from Microsoft.

Sharing SSRS reports with my organization

We are currently trying to make use of SSRS within my organization and I want to know how other organizations share these reports with the broader organization without having to give every individual rights to the SQL databases on the SQL server.
We have considered creating Active directory groups and then adding those groups as registered users under the databases but are having push back from IT related to possible data breaches when numerous users have access to a database.
If the groups only have read-only access then I don't know how much extra risk there would be.
What have other organizations done to allow individuals access to data without having to give individual access to each user?
There are two levels of permissions here - the permission to access the report and the permission to access the data.
You can setup data sources in SSRS as shared data source - and provide credentials that are stored securely in SSRS to access the data source. That can be a SQL account or Windows account (with windows account - you may need to set the account that runs SSRS to allow delegation).
When you build your report - setup the report to use a shared data source, the same name as the shared data source created in SSRS and make sure you do not allow overwriting the data sources in your project. When you then publish the report - the report will be published to use the shared data source and will not overwrite the one that already exists.
Now - you can create your AD groups and use those groups to grant access to the folder/report in SSRS. The users who have access to the reports will be able to run the reports but will not have direct access to the database system.

Windows Authentication - Restrict SQL Server Backend Access

The Problem
Good Morning! I work on an application team that supports a few applications which utilize SQL Server for data storage. Recently, our Database Support team decided that SQL Authentication was no longer permissible (for security and logging reasons) and so my team was forced to convert all connections to Windows Authentication including several dedicated Service IDs that our applications had been utilizing for data retrieval.
First, let me say there most certainly are advantages to moving to Windows Authentication, I am not trying to dispute that. But this change has raised a huge problem for us... by switching our Service IDs to Windows Authentication we have now opened up our back-end databases to every internal business user with front-end application access.
MS Access is pushed out to every user desktop and a few superusers even have access to SSMS. At this point we are relying entirely on user ignorance to prevent internal users from accessing the back-end database directly. And given that certain roles have elevated DML rights, this presents a possibility for some nasty data consequences.
This new enterprise standard has left my team stuck between a rock and a hard place at this point so we looking for any database, account or architecture solution that would allow us to restrict user access to front-end only.
Questions
Has anyone else run into this problem? Is there an architectural solution we are missing that would allow us to eliminate SQL Authentication without exposing our databases?
Does anyone know of a way to restrict access to a SQL Server database to only certain connection methods? I'm wondering if there is a way to designate a specific ID (or role) as only allowing a connection through a front end (and eliminate ODBC connections entirely).
Does anyone have any clever workarounds?
-------------EDIT---------------
A couple people brought up a good point about role access so I wanted to clarify our former and current solution... Previously, all role access was managed on the front-end and data retrieval was handled entirely by private system SQL Authenticated IDs to which end users had no visibility.
When we were forced to eliminate these SQL Auth IDs, we created a similar role-based setup on the back-end database as existed on the front end. Active Directory Groups were created to house different groups of users and these groups were assigned specific role privileges in the database. So currently access is limited by role as much as feasible.
The problem is that even the lowest privileged roles have INSERT, UPDATE and DELETE access to some tables (access which is normally controlled through code). So while we were able to mitigate risk somewhat by utilizing database roles, we still have areas where a user can bypass front end protections by logging directly into the database.
EDIT: Question clarification makes this answer obsolete, but leaving it for reference since some comments discuss it.
Assuming you mean that you have to (based on your architecture) allow access to the DB to each windows user account, one options is to use database roles.
You disable public access to your database, then define a set of database roles, depending on your use cases. Each role is granted permissions such that members of that role are able to manipulate the data they need and or work with the objects they need. Users are then mapped into the roles they require. When connecting to your database, the user will be granted permissions according to the roles they are members of.
For example, we have a role in one of our databases named MyAppUser (our name is actually related to the app which uses the db), which is designed for end users to read and insert data only. These can be created simply as follows:
CREATE ROLE [MyAppUser]
The role is granted just the permissions it to the relevant schemas or tables (assume all our "public" tables are in dbo schema for now).
GRANT SELECT ON SCHEMA::[dbo] TO [MyAppUser]
GRANT INSERT ON SCHEMA::[dbo] TO [MyAppUser]
GRANT DELETE ON SCHEMA::[dbo] TO [MyAppUser]
Each user who should have this public read-write access is then mapped into the relevant role.
ALTER ROLE [MyAppUser] ADD MEMBER [UserName]
This separates users and roles / permissions within your database and allows you to have a single point of entry to control who has access to what in your databases.
By having the "View Definition" permission denied by default (to end users), they won't be able to "explore" the database / view table definitions etc using access, or even SSMS.
NB: SSMS provides wizards for managing and viewing permissions and memberships which are very handy for getting things initially setup / tested / fiddled around with.

Creating users with or without schemas?

Let's say I want to create simple database, for a simple book store application. I think i should have minimum two users: admin, which has privileges to create, modify and drop objects and user, having just select and insert privileges.
I am a little confused here. Should I create a user account with normal schema or with empty schema? Should the user has privileges to select and query from admin schema which contains tables or it is a user schema that should contain these tables?
There are many different ways to approach this sort of problem. So a great deal depends on your application architecture.
You would generally create one database account that owns the database objects-- tables, packages, views, etc. Let's call this account BOOKSTORE_OWNER. This account would generally be locked so that no one could log in as BOOKSTORE_OWNER other during periodic builds.
Beyond that starting point, however, there are a host of reasonable ways to deal with authentication and authorization. If you wanted to let the database handle both, you would create two roles-- BOOKSTORE_USER and BOOKSTORE_ADMIN. Those roles would be given appropriate privileges on the objects owned by BOOKSTORE_OWNER. You would then create a database user for every person that can use the application and grant the appropriate role to each new user. So if you're an admin and I'm a user, the database account dygi would be created and granted the BOOKSTORE_ADMIN role while the database account Justin would be created and granted the BOOKSTORE_USER role.
This approach worked quite well when people were building client-server applications. If you are using a three-tier application, on the other hand, you want the middle tier connection pool to use the same credentials to connect to the database rather than having each user have their own database connections. The simplest way to accomplish this is to create a single BOOKSTORE_APP database account, grant that account all the privileges of the BOOKSTORE_ADMIN and BOOKSTORE_USER role, and then let the application implement the logic to figure out which front end user has what privileges. This would generally entail a USER, PRIVILEGE, and USER_PRIVILEGE table in the BOOKSTORE_OWNER schema. This approach can work quite well. The downside, though, is that every application has to build its own logic for managing privileges which can get quite complex over time. It also can make it somewhat difficult to report on what privileges users have or to ensure that a user's privileges are kept up to date when users leave the organization or move to a new role.
Oracle in particular addresses many of these challenges by allowing proxy authentication. This allows you to mix the benefits of the client-server approach where every user has their own database account that leverages Oracle's existing privilege management infrastructure with the connection pooling benefits of using a shared database account. This works very well but only works with Oracle and then only with certain protocols (OCI and JDBC) so it is not terribly popular.
Of course, beyond these basics, you can get into quite a bit of complexity. You may want to have enterprise users where Oracle doesn't maintain the password but instead allows the user to authenticate against an external LDAP directory. You may want to manage privileges with LDAP roles rather than with rows in application-specific tables. You may want to integrate with various middle-tier single sign-on (SSO) solutions.

SQL Server Login Configuration and Automation

What's a good way to manage and maintain SQL Server logins, server roles, and individual access rights across multiple databases that exist in multiple environments? What are your best practices?
Some info about my situation:
SQL Server 2005
We have N amount of "client" databases with identical schemas (in theory, at least)
We have a central "admin" database that references each client database and can hold configuration values
This "admin/client" pattern is duplicated across multiple environments (dev/qa/stage/prod)
Some users, like testers, need different rights based on evironment
We frequently have to pull client db backups from one environment to restore on another for development or testing purposes
We keep our stored procedures and scripts in source control and deploy in a build cycle
Right now my organization is chaotic and we don't follow good security practices. We have no formal DBA. However, if we got any more complex it would be a constant hassle to maintain it all the time. I could see migrating to a new server or recovering from disaster being extremely time consuming if we where to attempt configuring it directly through the management studio IDE.
First, to make restoring a database to a different server easier, make sure that your logins all have the same SID on all of your servers by using the sp_help_revlogin stored procedure from Microsoft to script the login on the first server you create it on and then use the script to create the login on your other servers. This keeps the database user mapped to the login correctly when you restore the database.
Having different permissions at the database level depending on the environment is going to be a hassle to a point no matter how you role this out. I have a stored procedure in master that gets called on my Dev Server as a part of my restore process that performs the additional GRANT's on the database to give the developers access to make changes. That's the best I have been able to come up with to solve similar problems.
A way to make the rights easier would be to create rolls in the database called Dev, QA, Test, Prod and grant the correct rights to those roles. Then as you restore the databases to each environment just drop the developers in the correct role.
We use active directory groups and enforce windows authenticated logins. From within SQL Server we can then define access based on the AD group the user is in by creating a single SQL Server login per AD group. Not sure if this is any better or worse than DB roles, but it means the roles are managed outside each database.
Propagating access to databases is then either a manual operation or a short SQL script to ensure the logins in the database point to a valid SQL Server login (which in turn is an AD group).
Generally this works well for the general case. We can use DB roles then to assign the builtin roles (e.g, db_datareader) to each AD group
Rarely someone needs some specific access to a database outside this model. We either end up opening it up to the group as a whole if it's not going to be invasive or critical or we'll end up creating a per-user account that has to be managed separately. We endevour to keep these to an absolute minimum, and clean them up every now and then so they're not abused/forgotten about.

Resources