Os 3 tipos de autorização no SAP RAP: DCL, Global e Instance — como e quando usar cada um
Segurança em camadas, não em um único ponto
Quem está começando no RAP costuma tratar autorização como uma coisa só — "checar se o usuário pode". Mas o RAP estratifica a proteção do Business Object em camadas independentes, e cada uma responde a uma pergunta diferente. Misturá-las (ou usar a errada) gera tanto buracos de segurança quanto código que nem ativa.
São três os mecanismos principais: CDS Access Control (DCL) para leitura, Global Authorization para "esse usuário pode em geral?" e Instance Authorization para "esse usuário pode neste registro específico?". A documentação oficial separa claramente: autorizações de leitura ficam na entidade CDS; autorizações de modificação ficam na Behavior Definition (SAP Help — Authorization Control).
Este guia mostra o que cada camada faz, quando usar e quando não usar cada uma, com exemplos de código e as armadilhas que mais derrubam desenvolvedores.
O essencial em 4 linhas
DCL (CDS Access Control): filtra quais linhas o usuário lê. Declarativo, aplicado pelo kernel em todo
SELECT— inclusive nas leituras do próprio RAP.Global Authorization: "esse usuário pode executar a operação em geral?" Avaliada 1x por requisição, sem olhar dados. Perfeita para
createe regras por perfil.Instance Authorization: "esse usuário pode neste registro?" Avaliada por chave, olha o valor da instância. Para
update/deletecontextuais. Não vale paracreatepuro.As três se complementam — e ainda há Precheck (validar payload) e Feature Control (habilitar botões), que não são segurança.
Quais são as três camadas de autorização do RAP?
O RAP protege o Business Object em três frentes, cada uma num lugar diferente do stack. A leitura é controlada na entidade CDS via DCL; a modificação é controlada na Behavior Definition, em dois níveis de granularidade (global e por instância). Numa requisição OData típica, as três convergem antes de qualquer dado voltar ao usuário.
Camada | Pergunta que responde | Onde se define | Aplica-se a |
|---|---|---|---|
CDS Access Control (DCL) | Quais linhas este usuário pode ler? | Data Control Language ( | Leitura (SELECT em CDS, inclusive RAP READ) |
Global Authorization | Este usuário pode executar esta operação em geral? | BDEF: | Create, Update, Delete, ações estáticas e de instância |
Instance Authorization | Pode executar nesta instância específica? | BDEF: | Update, Delete, Instance Actions, Create-by-association |
Regra mental: se a pergunta é sobre quais dados aparecem, é DCL. Se é sobre poder fazer uma operação, é Behavior Definition — global quando só depende do usuário, instance quando depende do conteúdo do registro.
Como funciona o CDS Access Control (DCL)?
O DCL é um mecanismo declarativo que adiciona implicitamente cláusulas WHERE a toda leitura ABAP SQL sobre a entidade CDS protegida. Segundo a SAP Help — ABAP CDS Access Control, uma CDS role não é atribuída a usuários: ela é avaliada para cada usuário a cada acesso. Por isso também é chamada de mapping role.
Um ponto que pega iniciantes: o filtro vale também para as leituras feitas pelo próprio RAP (a operação READ flui pela entidade CDS), não só para Open SQL "de fora". Ou seja, configurou o DCL certo, e a query OData do Fiori já volta filtrada.
Quando usar
Sempre que uma entidade expuser dados sensíveis e o filtro puder ser expresso declarativamente (por empresa, organização de vendas, centro, país).
Quando o filtro depende de valores de autorização PFCG do usuário — ex.: ver só as vendas das organizações para as quais ele tem o objeto clássico.
Quando a regra deve valer uniformemente em qualquer consumidor: OData, EML, ABAP SQL, analytics.
Quando NÃO usar
Para verificar se o usuário pode executar uma ação (create/update/delete) — isso é trabalho da Global/Instance Authorization.
Para start authorization (entrar na app) — use
AUTHORITY-CHECKclássico no início.Em entidades puramente técnicas (config, value helps internos) — desligue com a annotation apropriada.
Exemplo: DCL com condição PFCG
A condição mapeia um objeto de autorização clássico para os campos da view. A ordem dos elementos à esquerda deve casar com a ordem dos campos mapeados à direita — é posicional (SAP Help — pfcg_condition):
@MappingRole: true
@EndUserText.label: 'Access Control for Sales Order'
define role ZI_SalesOrder {
grant
select on ZI_SalesOrder
where
(SalesOrderType) = aspect pfcg_auth( V_VBAK_AAT, AUART, ACTVT = '03' )
and
(OrganizationDivision, SalesOrganization, DistributionChannel)
= aspect pfcg_auth( V_VBAK_VKO, SPART, VKORG, VTWEG, ACTVT = '03' );
}Em runtime, ao rodar SELECT * FROM zi_salesorder, o kernel injeta um WHERE derivado das autorizações PFCG do usuário. Linhas sem ACTVT='03' simplesmente não voltam — o handler nem precisa saber que o filtro existe.
Ligando e desligando o controle
A annotation @AccessControl.authorizationCheck define o comportamento. Aqui mora uma confusão comum, então preste atenção aos valores reais (SAP Help — view entity annotations):
Valor | Efeito |
|---|---|
| Padrão. Exige DCL e avalia o controle de acesso. |
| Apenas suprime o aviso de "nenhuma role existe". NÃO desliga o controle. |
| Desliga de fato o controle de acesso (útil para entidades técnicas). |
| (view entities) Só pode ser lida com |
Correção de um mito comum: #NOT_REQUIRED não abre vazamento de dados — ele só silencia o aviso de role ausente; a checagem continua valendo se houver role. Quem realmente desliga o controle é #NOT_ALLOWED. Use-o apenas em entidades sem dado sensível.
Para ignorar o DCL pontualmente em código técnico bem auditado (um job de fim de mês, por exemplo), existe o WITH PRIVILEGED ACCESS (SAP Help — SELECT data_source):
SELECT * FROM zi_salesorder WITH PRIVILEGED ACCESS
INTO TABLE @DATA(all_orders).Cuidado: ele afeta só a entidade onde está, não as alcançadas por associações, e nunca deve aparecer em handler exposto ao usuário final.
O que é Global Authorization e quando usá-la?
Global Authorization é uma verificação declarada na Behavior Definition e implementada num método FOR GLOBAL AUTHORIZATION. Ela é chamada uma única vez por requisição e responde se o usuário pode executar a operação independentemente dos dados (SAP Help — Implementing Global Authorization). Cobre create, update, delete, ações estáticas e de instância, e create-by-association.
Quando usar
A verificação depende apenas do usuário — papel PFCG, time, sistema.
Você quer bloquear cedo, antes de qualquer acesso ao buffer transacional ou ao banco.
Regras como "somente o perfil X cria pedidos" ou "a static action
bulkApproveexige o objeto Z".
Quando NÃO usar
A regra precisa olhar valores da instância (status, criador, valor) → use Instance Authorization.
A regra é só sobre leitura de linhas → use DCL.
Você só quer habilitar/desabilitar um botão sem semântica de segurança → use Feature Control.
Declaração na BDEF e implementação
Na Behavior Definition, marque a entidade com authorization master ( global ). O método handler recebe quais autorizações foram requisitadas e devolve o veredito por operação:
define behavior for ZI_Travel alias Travel
persistent table ztravel
lock master
authorization master ( global ) " <<< declara GLOBAL
etag master last_changed_at
{
create;
update;
delete;
field ( readonly ) travel_uuid, created_by, created_at, last_changed_at;
static action ( authorization : global ) bulkApprove parameter zbulk_param;
}METHOD get_global_authorizations.
" ---------- CREATE ----------
IF requested_authorizations-%create = if_abap_behv=>mk-on.
AUTHORITY-CHECK OBJECT 'ZAUTH_OBJ'
ID 'ACTVT' FIELD '01'.
result-%create = COND #(
WHEN sy-subrc = 0 THEN if_abap_behv=>auth-allowed
ELSE if_abap_behv=>auth-unauthorized ).
ENDIF.
" ---------- UPDATE (inclui Edit no draft) ----------
IF requested_authorizations-%update = if_abap_behv=>mk-on OR
requested_authorizations-%action-Edit = if_abap_behv=>mk-on.
AUTHORITY-CHECK OBJECT 'ZAUTH_OBJ'
ID 'ACTVT' FIELD '02'.
result-%update = COND #( WHEN sy-subrc = 0 THEN if_abap_behv=>auth-allowed
ELSE if_abap_behv=>auth-unauthorized ).
result-%action-Edit = result-%update.
ENDIF.
ENDMETHOD.Detalhe que muda o comportamento: se a operação tem authorization:global e o método retorna auth-unauthorized, o handler da operação (CREATE/UPDATE/DELETE) nem é invocado — a requisição é rejeitada antes. O nome get_global_authorizations é convenção, não obrigatório.
Como funciona a Instance Authorization?
Instance Authorization também é declarada na BDEF, mas implementada em FOR INSTANCE AUTHORIZATION. Ela recebe as chaves das instâncias que serão modificadas e decide por instância (SAP Help — Implementing Instance Authorization). Aplica-se a update, delete, instance actions e create-by-association.
Instance Authorization não vale para create puro: não existe instância para checar. O create é coberto pela Global. A exceção é o create-by-association, onde a instância-pai já existe e pode ser avaliada.
Quando usar
A regra depende de dados da instância: "só o criador atualiza", "status RELEASED não deleta", "moeda especial exige autorização extra".
Você precisa de granularidade fina: dois registros, mesmo usuário, decisões diferentes.
Quando NÃO usar
A regra é puramente baseada no usuário → use Global (mais barata, sem ler o buffer).
Precisa validar valores de entrada antes de entrarem no buffer → use RAP Precheck.
Regra de visibilidade de linhas → use DCL.
Declaração combinada e implementação
Para ativar as duas avaliações, declare authorization master ( global, instance ). O handler de instância lê os registros afetados e decide caso a caso:
define behavior for ZI_Travel alias Travel
persistent table ztravel
lock master
authorization master ( global, instance ) " <<< AMBAS
{
create;
update;
delete;
association _Booking { create ( authorization : instance ); }
action ( authorization : instance ) acceptTravel result [1] $self;
}METHOD get_instance_authorizations.
" 1) Lê as instâncias afetadas EM LOCAL MODE
READ ENTITIES OF ZI_Travel IN LOCAL MODE
ENTITY Travel
ALL FIELDS WITH CORRESPONDING #( keys )
RESULT DATA(travels).
CHECK travels IS NOT INITIAL.
LOOP AT travels INTO DATA(travel).
DATA(update_granted) = abap_false.
IF requested_authorizations-%update = if_abap_behv=>mk-on.
" Regra de negócio: só o criador OU gestor da BU
IF travel-created_by = sy-uname.
update_granted = abap_true.
ELSE.
AUTHORITY-CHECK OBJECT 'ZTRAVEL_BU'
ID 'BUKRS' FIELD travel-company_code
ID 'ACTVT' FIELD '02'.
update_granted = xsdbool( sy-subrc = 0 ).
ENDIF.
" Bloqueio extra: status RELEASED é imutável
IF travel-overall_status = 'A'.
update_granted = abap_false.
ENDIF.
ENDIF.
APPEND VALUE #(
%tky = travel-%tky
%update = COND #( WHEN update_granted = abap_true
THEN if_abap_behv=>auth-allowed
ELSE if_abap_behv=>auth-unauthorized )
) TO result.
ENDLOOP.
ENDMETHOD.Por que IN LOCAL MODE? Porque essa adição acessa o BO direto, sem verificar access control (DCL), authorization control, feature control nem prechecks. Sem ela, ler a própria entidade dispararia de novo a verificação de autorização — que chamaria o handler outra vez, num laço de recursão. É um requisito, não um detalhe estético.
Como sobrescrever a autorização por operação?
Quando o master é instance mas uma operação específica deve usar lógica global (ou vice-versa), você sobrescreve por operação. Cada override recebe um único valor — global, instance, update (reutiliza a checagem do update) ou none (SAP Help — Authorization Definition):
authorization master ( instance )
{
update; " usa instance (master)
delete ( authorization : global ); " força global nesta operação
static action ( authorization : global ) bulkApprove;
action ( authorization : none ) calcTotals; " fora da checagem
}Para rodar as duas checagens (global + instance) numa operação de instância, a forma documentada é declarar authorization master ( global, instance ) no nível da entidade — aí as operações de instância passam pelas duas. Evite assumir uma forma combinada por operação como action ( authorization : global, instance ) sem testar no seu sistema; ela não é confirmada na documentação.
DCL vs Global vs Instance: comparativo lado a lado
As três diferem em camada, estilo, granularidade e custo. A Instance é a mais cara porque precisa ler o buffer; a Global é a mais barata porque roda uma vez e não toca em dado. O DCL fica fora dessa conta — é um predicado SQL que o kernel resolve na origem.
Aspecto | CDS Access Control (DCL) | Global Authorization | Instance Authorization |
|---|---|---|---|
Camada | Leitura (SQL) | Modificação | Modificação |
Estilo | Declarativo (DCL) | Procedural (ABAP) | Procedural (ABAP) |
Granularidade | Por linha | Por operação | Por instância (chave) |
Custo | Baixo (predicado SQL) | Muito baixo (1x/request) | Médio (lê o buffer) |
Acesso ao dado | Filtra na origem | Não recebe instância | Recebe |
Operações | SELECT / READ | Create, Update, Delete, Actions | Update, Delete, Instance Actions, Create-by-assoc |
Onde declarar |
|
|
|
Handler | (kernel) |
|
|
Como combinar as três num cenário real?
Imagine uma app de viagens corporativas com quatro regras: (1) o usuário só vê viagens da própria empresa; (2) só o perfil ZTRAVEL_AGENT cria; (3) só o criador ou um gestor da BU atualiza, e viagens RELEASED são imutáveis; (4) delete só com perfil de gestor e status OPEN. Cada regra cai naturalmente numa camada.
// Camada 1 — DCL (leitura por empresa)
@MappingRole: true
define role ZI_Travel {
grant select on ZI_Travel
where (company_code) = aspect pfcg_auth( ZTRAVEL_BU, BUKRS, ACTVT = '03' );
}* Camada 2 — Global (create por perfil)
METHOD get_global_authorizations.
IF requested_authorizations-%create = if_abap_behv=>mk-on.
AUTHORITY-CHECK OBJECT 'ZTRAVEL_BU'
ID 'BUKRS' DUMMY
ID 'ACTVT' FIELD '01'.
result-%create = COND #( WHEN sy-subrc = 0
THEN if_abap_behv=>auth-allowed ELSE if_abap_behv=>auth-unauthorized ).
ENDIF.
ENDMETHOD.
* Camada 3 e 4 — Instance (update/delete contextuais): get_instance_authorizationsO ganho de integridade: mesmo que alguém chame a OData direto via Postman, as camadas convergem para impedir leitura indevida, criação sem perfil, atualização fora da regra e delete em estado errado. E tudo isso reflete automaticamente no Fiori Elements, com os botões certos desabilitados. Para a base do BO em si, vale revisitar os BDEF Derived Types (%tky, %cid, %control), que aparecem nesses handlers.
E o RAP Precheck e o Feature Control?
Nem tudo que parece autorização é autorização. Dois mecanismos costumam ser confundidos com as três camadas, mas têm papéis distintos — e tratá-los como segurança é um erro clássico.
RAP Precheck: valida dados de entrada antes de eles entrarem no buffer transacional (ex.: "booking fee não pode ser negativo"). Trabalha junto com a autorização, não no lugar dela.
Feature Control: habilita ou desabilita campos, ações e operações dinamicamente na UI (botão cinza). Não é mecanismo de segurança — se a regra é crítica, duplique-a na camada de autorização.
Quais são as armadilhas mais comuns?
A maioria dos bugs de autorização no RAP vem de poucos enganos recorrentes. Conhecê-los antecipadamente economiza horas de depuração — e evita ativações que falham em strict mode.
Esquecer
IN LOCAL MODEemget_instance_authorizations→ recursão da verificação.Usar Instance Authorization para create → não funciona; não há instância. Use Global.
Confundir Feature Control com Authorization → Feature Control só mexe em botão; não protege nada por si só.
Não definir
result-%updateem todos os caminhos → deixe sempre explícitoauth-allowedouauth-unauthorized, nunca confie no valor inicial.Inverter a ordem dos campos no
pfcg_auth→ o mapeamento é posicional; a ordem à esquerda precisa casar com a da direita.Strict mode (
strict ( 2 )) exige que o handler trate todas as operações declaradas — senão a ativação falha.
Novidade que vale acompanhar (release 2508): o ABAP Cloud passou a permitir autorização dedicada para create-by-association, em vez de herdar automaticamente a checagem de update do pai. E lembre: em cenários unmanaged non-draft, o framework não chama o método de instance authorization — planeje a proteção de acordo.
Perguntas frequentes
DCL substitui a Global/Instance Authorization?
Não. DCL controla leitura (quais linhas aparecem); Global e Instance controlam modificação (se a operação pode rodar). São camadas complementares. A documentação oficial separa explicitamente: leitura na entidade CDS, modificação na Behavior Definition. Use as três juntas para proteção completa do BO.
Global ou Instance Authorization: qual escolher?
Depende do que a regra olha. Se ela depende só do usuário (perfil, time), use Global — é avaliada uma vez e não lê dados. Se depende de valores do registro (status, criador, valor), use Instance — ela recebe as chaves e decide por instância. Create puro é sempre Global, pois não há instância para checar.
Por que minha leitura interna entra em loop na instance authorization?
Porque você leu a entidade sem IN LOCAL MODE. Essa adição acessa o BO sem verificar access control, authorization, feature control nem prechecks; sem ela, ler a própria entidade dispara de novo o handler de autorização, criando recursão. Sempre use READ ENTITIES ... IN LOCAL MODE dentro do método.
Feature Control não é suficiente para segurança?
Não. Feature Control apenas habilita ou desabilita elementos na UI — um usuário pode contornar via chamada OData direta. Ele melhora a experiência, mas não protege. Se a regra é crítica, implemente-a também em Global ou Instance Authorization, que rodam no servidor independentemente da UI.
O que significa WITH PRIVILEGED ACCESS?
É uma adição ao ABAP SQL que desliga o controle de acesso CDS para aquela leitura. Serve para código técnico bem auditado (jobs, integrações) que precisa enxergar tudo. Afeta só a entidade onde está, não as alcançadas por associações, e nunca deve aparecer em handler exposto ao usuário final.
Conclusão
Autorização no RAP não é um interruptor único — são camadas que respondem a perguntas diferentes. DCL decide o que o usuário vê; Global decide se ele pode em geral; Instance decide se ele pode naquele registro. Acerte a camada e o código fica simples; erre, e você abre buracos ou luta contra o framework.
O resumo de 30 segundos: filtro de linha é DCL; regra por perfil é Global; regra por conteúdo do registro é Instance; validação de payload é Precheck; e botão na tela é Feature Control — que não é segurança. Combine as quatro primeiras nas situações certas e o seu Business Object fica protegido em qualquer porta de entrada.
Referências oficiais
Comentários 0
Ainda sem comentários
Seja o primeiro a comentar este artigo.
Entre na conversa
Faça login para deixar seu comentário neste artigo.