I am trying to provide my database, [TestDB], the ability to execute sql server jobs via certificate signing (while having [TestDB] trustworthy bit set to OFF). My current implementation attempt (below), allows [TestDB] to successfully read from MSDB..SYSJOBS_VIEW via certificate, but FAILS to execute MSDB..SP_START_JOB using the same methodology - i get an error "...the specified @job_name ('HELLO') does not exist."Your mission, should you choose to accept, is to get MSDB..SP_START_JOB to work with a certificate. MUCH Thanks in advance!Using SQL Server 2005, you can immediately reproduce this problem by running the code below. Just copy/paste/run it directly. For your convenience, I've added code to remove the created objects which are commented out at the very end.PRINT '1. Create Database [TestDB]'--=======================================================================================CREATE DATABASE [TestDB];GOUSE [TestDB];CREATE LOGIN [testdb_owner] WITH PASSWORD=N'123', DEFAULT_DATABASE=[master], DEFAULT_LANGUAGE=[us_english], CHECK_EXPIRATION=ON, CHECK_POLICY=ONCREATE USER [testdb_owner] FROM LOGIN [testdb_owner]--make user db_ownerEXEC sp_addrolemember N'db_owner', N'testdb_owner'GOCREATE PROCEDURE dbo.SELECT_ALL_JOBSAS select * from msdb.dbo.sysjobs_viewGOCREATE PROCEDURE dbo.START_HELLO_JOBAS EXEC MSDB.DBO.sp_start_job @JOB_NAME = 'Hello'GO--End of create [TestDB]--=======================================================================================PRINT '2. Create/Install Certificate on [TestDB]'--=======================================================================================USE [TestDB];CREATE CERTIFICATE [TestJobCertificate]ENCRYPTION BY PASSWORD = '123' --password of the private keyWITH SUBJECT = 'Certificate to view and execute jobs',START_DATE = '20110101', EXPIRY_DATE = '20990101'; BACKUP CERTIFICATE [TestJobCertificate]TO FILE = 'D:\TestJobCertificate.CER'WITH PRIVATE KEY (FILE = 'D:\TestJobCertificate.PVK', ENCRYPTION BY PASSWORD = '123', DECRYPTION BY PASSWORD = '123');GO--Create the certificate userCREATE USER TestJobCertificateUser FROM CERTIFICATE [TestJobCertificate]GO--sign stored proc with certificateADD SIGNATURE TO OBJECT::[SELECT_ALL_JOBS]BY CERTIFICATE [TestJobCertificate] WITH PASSWORD = '123'; --password of the private keyGRANT EXECUTE ON SELECT_ALL_JOBS TO TestJobCertificateUser --sign stored proc with certificateADD SIGNATURE TO OBJECT::[START_HELLO_JOB]BY CERTIFICATE [TestJobCertificate] WITH PASSWORD = '123'; --password of the private keyGRANT EXECUTE ON START_HELLO_JOB TO TestJobCertificateUser--=======================================================================================GOPRINT '3. Create/Install Certificate on [MSDB]'--=======================================================================================USE [MSDB];GO--Create 'HELLO' JOB--=============================================================================DECLARE @jobId BINARY(16)EXEC msdb.dbo.sp_add_job @job_name=N'Hello', @enabled=1, @category_name=N'[Uncategorized (Local)]', @owner_login_name=N'sa', @job_id = @jobId OUTPUTEXEC msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'Hello', @step_id=1, @os_run_priority=0, @subsystem=N'TSQL', @command=N'select ''HELLO''', @database_name=N'msdb', @flags=0EXEC msdb.dbo.sp_add_jobserver @job_name=N'Hello' --=============================================================================--CREATE CERTIFICATE FROM FILECREATE CERTIFICATE [TestJobCertificate]FROM FILE = 'D:\TestJobCertificate.CER'WITH PRIVATE KEY (FILE = 'D:\TestJobCertificate.PVK', ENCRYPTION BY PASSWORD = '123', DECRYPTION BY PASSWORD = '123');--Create the certificate userCREATE USER TestJobCertificateUser FROM CERTIFICATE [TestJobCertificate]GO--GRANT NECESSARY PERMISSIONS REQUIRED TO VIEW/EXECUTE JOBS--THIS DATABASE ROLE IS REQUIRED IN ORDER FOR THE CERTIFICATE USER TO START JOBS HE DOES NOT OWNEXEC sp_addrolemember N'SQLAgentOperatorRole', N'TestJobCertificateUser'GO--ADDITIONAL PERMISSIONS FOR TESTINGGRANT EXECUTE ON MSDB.DBO.sp_verify_job_identifiers TO [TestJobCertificateUser]GRANT SELECT ON MSDB..SYSJOBS_VIEW TO [TestJobCertificateUser]GRANT SELECT ON MSDB..SYSJOBS TO [TestJobCertificateUser]GRANT EXECUTE ON MSDB.DBO.sp_start_job TO [TestJobCertificateUser]GOPRINT 'SETUP IS NOW COMPLETE AT THIS POINT...'--=====================================================PRINT '4. Testing Impersonation...'--=====================================================USE [TestDB];GOexecute as login = 'testdb_owner'select suser_name() as [context]--this stmt will execute fine and return all records from msdb.dbo.sysjobs_view via the certificateexec SELECT_ALL_JOBSPRINT 'the following stmt will throw an error:'PRINT 'Msg 14262, Level 16, State 1, Procedure sp_verify_job_identifiers, Line 67'PRINT 'The specified @job_name (''HELLO'') does not exist.'PRINT 'however, if you run under the context of ''sa'', it will execute fine (but that defeats the purpose of certificate signing)'PRINT 'MSDB.DBO.sp_verify_job_identifiers, is where the error gets raised. sp_verify_job_identifiers attempts to select from msdb.dbo.sysjobs_view where (name = @job_name); 'PRINT 'however no rows are returned, hence error # 14262 gets raised. On the other hand, when you selected from msdb.dbo.sysjobs_view through the stored proc, SELECT_ALL_JOBS, that is signed by the certificate, the rows DO get returned.'PRINT '------------------------'exec START_HELLO_JOBPRINT '------------------------'revert;--CLEANUP CODE/*USE [MSDB];GODROP USER [TestJobCertificateUser]DROP CERTIFICATE [TestJobCertificate]EXEC msdb.dbo.sp_delete_job @job_name='Hello'GODROP Login [testdb_owner]DROP DATABASE [TestDB]--Delete certificate and private key from file*/

