Acesso a procedimentos SQL Server com privilégios mínimos
Conceda operações por roles, entenda ownership chaining e SQL dinâmico e teste acesso efetivo usando uma identidade de aplicação limitada.
Uma aplicação que precisa apenas de um resumo de faturas não necessita alterar todas as tabelas nem modificar o esquema. Conceder db_owner pode eliminar erros de implantação e esconder as dependências reais. Uma superfície pequena de permissões é mais fácil de revisar e manter estável.
Procedimentos armazenados podem oferecer essa fronteira quando seus corpos e relações de propriedade são conhecidos. A pergunta útil não é somente se a identidade conecta, mas quais leituras e gravações ela executa por quais pontos de entrada autorizados.
Conceder a operação por uma role
O exemplo cria uma tabela de prática com emails e um procedimento que retorna somente quantidade e total. Use uma base descartável. GO é separador de lotes do cliente; drivers sem suporte precisam enviar os lotes separadamente.
-- Run in a disposable practice database as its administrator.
CREATE TABLE dbo.PermissionInvoiceDemo (
InvoiceId int PRIMARY KEY,
CustomerEmail nvarchar(200) NOT NULL,
Total decimal(12,2) NOT NULL
);
INSERT dbo.PermissionInvoiceDemo VALUES
(1, N'example1@example.invalid', 40.00),
(2, N'example2@example.invalid', 60.00);
GO
CREATE PROCEDURE dbo.GetInvoiceSummaryDemo
AS
BEGIN
SET NOCOUNT ON;
SELECT COUNT_BIG(*) AS InvoiceCount, SUM(Total) AS InvoiceTotal
FROM dbo.PermissionInvoiceDemo;
END;
GO
CREATE ROLE InvoiceSummaryReaderDemo AUTHORIZATION dbo;
CREATE USER InvoiceReportUserDemo WITHOUT LOGIN;
ALTER ROLE InvoiceSummaryReaderDemo ADD MEMBER InvoiceReportUserDemo;
GRANT EXECUTE ON OBJECT::dbo.GetInvoiceSummaryDemo
TO InvoiceSummaryReaderDemo;
WITHOUT LOGIN cria intencionalmente um usuário para testes locais, não uma conta de conexão da aplicação. Na implantação, crie ou mapeie o usuário real conforme a autenticação existente e inclua-o na role restrita.
A role recebe EXECUTE em um procedimento, sem SELECT geral na tabela. Os objetos compartilham proprietário por meio de dbo e o procedimento usa SQL estático. Com ownership chain intacta, o SQL Server pode autorizar a chamada sem exigir separadamente permissão do chamador sobre a tabela.
O resultado esperado é duas faturas somando 100,00. Emails não são projetados. Isso demonstra uma fronteira de objetos, não uma garantia universal de privacidade: agregados com grupos pequenos também precisam de análise.
Conhecer os limites da fronteira
Um procedimento não é seguro apenas porque o chamador não acessa a tabela diretamente. Nomes de objetos arbitrários, SQL dinâmico sem validação e retornos de todos os tenants podem oferecer capacidades excessivas. Revise o corpo junto com a concessão.
SQL dinâmico não se beneficia da mesma premissa de ownership chain estática. sp_executesql parametrizado trata valores e reduz injeção, mas não concede automaticamente permissões para o comando gerado. Não resolva esse problema promovendo a aplicação a db_owner.
Para acesso dinâmico ou entre fronteiras, considere assinatura de módulo bem delimitada ou um contexto de execução escolhido explicitamente. Assinatura com certificado pode acrescentar permissões específicas durante a execução. A implantação precisa assinar novamente após alterar o módulo. Certificado e capacidade concedida devem permanecer revisáveis.
Evite habilitar TRUSTWORTHY ou ownership chaining amplo entre bases como correção rotineira. Esses ajustes alteram uma fronteira de confiança maior que uma chamada. Projete a operação específica entre bases.
Testar com a identidade limitada
Um teste como sysadmin comprova pouco sobre a aplicação. Esta impersonação controlada executa o resumo e restaura o contexto original mesmo em caso de erro.
EXECUTE AS USER = N'InvoiceReportUserDemo';
BEGIN TRY
EXEC dbo.GetInvoiceSummaryDemo;
END TRY
BEGIN CATCH
REVERT;
THROW;
END CATCH;
REVERT;
Confirme também que ler CustomerEmail diretamente seja negado. Teste operações permitidas e proibidas. GRANTs do catálogo não contam a história inteira: roles, permissões diretas, DENY, propriedade e privilégios superiores influenciam o acesso efetivo.
Separe identidade de implantação da identidade de execução. Implantar pode exigir criar ou alterar procedimentos; requisições comuns não devem receber essa capacidade. Quando uma versão adiciona uma operação, conceda-a deliberadamente em vez de abrir todos os objetos presentes e futuros.
Revise EXECUTE no nível de esquema. Pode servir a um esquema de API gerenciado conscientemente, mas cobre automaticamente procedimentos futuros. Essa é uma decisão de governança, não apenas uma forma curta de escrever permissões.
Mantenha uma verificação significativa nas entregas: operações suportadas funcionam, colunas protegidas não podem ser lidas diretamente e objetos não podem ser alterados. Dessa forma, um aumento acidental de privilégios fica visível antes de virar a configuração normal da aplicação.
Referências técnicas: Microsoft Learn: Database Engine permissions · Microsoft Learn: GRANT object permissions · Microsoft Learn: Sign a procedure with a certificate.