As has been suggested, you can use dynamic management views to identify login and IP addresses during the logon coupled with a logon trigger to restrict non-prod apps from accessing prod databases. Before I did this (again, as others have suggested), I would consider alternatives using:
- Firewall rules to prevent non-prod boxes from reaching prod boxes
- Ensuring the prod password does not match a non-prod account (especially good for keeping prod passwords out of things like source control or developers who may not necessarily need prod access)
With that said, here's a database-driven solution that let's you control the restrictions through a table that can live anywhere you want on the server.
CREATE TABLE SampleDB.dbo.LoginRestrictions (
RestrictionId INT NOT NULL PRIMARY KEY,
LoginName VARCHAR(500) NOT NULL,
IpAddress VARCHAR(50) NOT NULL,
Notes VARCHAR(500) NULL
)
INSERT SampleDB.dbo.LoginRestrictions VALUES
('app1', '10.1.1.125', 'Deny app1 from QA'),
('app1', '10.1.1.%', 'Deny app1 from DEV') -- Notice '%' so you can match general subnets
-- ... Any other rules
Then, you can create a logon trigger that if a user login (can be a SQL account s in these cases, but you can also use domain logins to restrict any domain accounts if you wish). Also notice that the trigger uses LIKE
so you can leverage wildcards in the IP addresses in case you can match by subnets.
CREATE TRIGGER tg_Logon_Blocker
ON ALL SERVER FOR LOGON AS
BEGIN
SET NOCOUNT ON
-- Rollback if restricted
IF EXISTS (
SELECT *
FROM SampleDB.dbo.LoginRestrictions R
INNER JOIN sys.server_principals P
ON P.name = R.LoginName
INNER JOIN sys.dm_exec_connections c
ON c.session_id = @@SPID
AND c.client_net_address LIKE R.IpAddress
WHERE p.name = ORIGINAL_LOGIN()
)
ROLLBACK
END
GO