Pular para o conteúdo

Papéis e permissões

Descreva o que as pessoas podem fazer com papéis, atribua-os a usuários, grupos, clients ou realms e confira-os na sua API pelo access token.

Um papel é um conjunto nomeado de permissões — billing-admin, editor, support-agent — que o Authio grava nos access tokens de todos que o têm. A sua API lê o token e decide; o Authio nunca chama o seu código para perguntar.

Os papéis pertencem à sua conta. O lugar onde um papel é atribuído decide quem o recebe e em qual claim ele chega: direto a um usuário, por um grupo, a todos que entram por um client ou a todos de um realm.

Como um papel é montado

Um papel carrega uma lista de claims. O tipo de cada claim é uma permissão (invoice, documents, reports) e o valor é um método que o papel libera nela (read, write, approve). Um papel que deixa ler e escrever faturas carrega duas claims do tipo invoice, com os valores read e write.

ParteRegras
NomeAté 256 caracteres, único na conta sem diferenciar maiúsculas. default-system e admin-system são reservados à plataforma.
DescriçãoAté 500 caracteres, exibida só no console.
ClaimsUma permissão de até 256 caracteres e um método de até 1.024. Nomes que o protocolo escreve, como sub, aud ou scope, são recusados.
StatusUm papel inativo fica de fora de todo token e não pode ser atribuído.

Papéis globais e exclusivos

Um papel criado em Papéis globais pode ser atribuído em qualquer lugar da conta. Um papel criado a partir de um realm, de um client, de um usuário ou de um grupo é exclusivo desse dono: só o dono, e o que vive dentro dele, pode recebê-lo. Um papel exclusivo de um client, por exemplo, só chega aos tokens que esse client emite. O dono é definido na criação e nunca muda.

Crie um papel

  1. Abra a lista de papéis

    No console, abra Permissões › Papéis globais e escolha Novo papel. Para um papel exclusivo de um realm, de um client, de um usuário ou de um grupo, comece pela página desse registro.

  2. Dê um nome e adicione as permissões

    Dê um nome e uma descrição e adicione uma claim por permissão e método: tipo invoice com valor read, tipo invoice com valor write.

  3. Atribua o papel

    Um papel não faz nada até alguém tê-lo. A próxima seção mostra as quatro formas de atribuir um.

Atribua papéis

Há quatro formas de dar um papel a alguém, e elas se somam: a pessoa tem todo papel que chega a ela por qualquer uma delas.

Atribuído aOnde no consoleQuem recebeClaim
Um usuárioO passo Permissões da edição do usuário, em UsuáriosAquela pessoauser_resource_access
Um grupoGruposTodos os membros, nos tokens emitidos pelo client do grupouser_resource_access
Um clientPapéis concedidos, na aba Acesso do clientTodos que entram por aquele clientclient_resource_access
Um realmPapéis concedidos, na aba Acesso e regras do realmTodos do realmrealm_resource_access

Grupos

Um grupo é um conjunto nomeado de usuários de um client que entrega os papéis dele a todos os membros de uma vez. Crie-o em Grupos com Novo grupo — escolha o realm e o client, dê um nome e escolha os papéis que ele concede — e adicione os membros pela página do grupo. Qualquer usuário do realm pode entrar num grupo de um dos clients desse realm.

  • Os papéis são lidos pela filiação a cada emissão de token, nunca copiados para o usuário: tirar alguém do grupo leva os papéis embora a partir do próximo token.
  • Salvar os papéis de um grupo substitui os que ele concedia antes; eles não se somam.
  • Um grupo inativo mantém os membros e não concede nada.
  • Grupos pertencem a um client e não se aninham.

Papéis no access token

Os papéis só chegam ao access token quando ele recebeu o escopo roles. roles é um escopo padrão: quando está habilitado no client, é concedido mesmo que a requisição de autorização não o peça. O ID token nunca traz papéis.

Cada origem tem uma claim própria. Cada claim mapeia o nome do papel para as permissões dele, e cada permissão para os métodos que o papel libera:

Payload do access tokenJSON
{
  "iss": "https://authio.api.hyperio.tech/realms/acme",
  "sub": "6f1c2e7a-4b8d-4f0e-9a51-3c2d7e8b9f10",
  "aud": "https://api.acme.com",
  "azp": "acme-web",
  "scope": "openid profile roles",
  "user_resource_access": {
    "billing-admin": { "invoice": ["read", "write"] }
  },
  "client_resource_access": {
    "member": { "invoice": ["read"], "reports": ["read"] }
  },
  "realm_resource_access": {
    "employee": { "directory": ["read"] }
  },
  "exp": 1791372600
}
ClaimTraz
user_resource_accessOs papéis atribuídos direto à pessoa e os dos grupos de que ela participa no client que emitiu o token.
client_resource_accessOs papéis que o client emissor concede a todos que entram por ele.
realm_resource_accessOs papéis que o realm concede a todos que estão nele.

Uma claim fica de fora quando estaria vazia. Papéis inativos, e papéis retidos por uma suspensão em vigor, saem das três.

Credenciais de máquina funcionam do mesmo jeito, numa claim própria: os papéis de um consumer chegam em consumer_resource_access. Veja Máquina a máquina.

Confira permissões na sua API

Valide o token primeiro — assinatura, emissor, audiência e validade, como mostra Servidores de recurso. Depois faça a união das três claims e de todos os papéis nelas: uma permissão concedida por qualquer papel que a pessoa tenha está concedida.

Confira permissões, não nomes de papel

O nome de um papel é um rótulo que um administrador pode mudar. Código que testa billing-admin quebra numa renomeação; código que testa invoice e write, não.
permissions.tsTypeScript
import type { JWTPayload } from 'jose'

type ResourceAccess = Record<string, Record<string, string[]>>

const ROLE_CLAIMS = [
  'user_resource_access',
  'client_resource_access',
  'realm_resource_access',
] as const

export function can(payload: JWTPayload, permission: string, method: string) {
  return ROLE_CLAIMS.some((claim) =>
    Object.values((payload[claim] ?? {}) as ResourceAccess).some((granted) =>
      granted[permission]?.includes(method),
    ),
  )
}

No ASP.NET Core, coloque a conferência numa policy. MapInboundClaims = false mantém os nomes das claims exatamente como o Authio os escreve:

Program.csC#
using Microsoft.AspNetCore.Authentication.JwtBearer;

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.Authority = "https://authio.api.hyperio.tech/realms/acme";
        options.Audience = "https://api.acme.com";
        options.MapInboundClaims = false;
    });

builder.Services.AddAuthorization(options =>
    options.AddPolicy("invoices.write", policy =>
        policy.RequireAssertion(context => context.User.Can("invoice", "write"))));

var app = builder.Build();

app.MapPost("/invoices", () => Results.Ok())
    .RequireAuthorization("invoices.write");

app.Run();

Quando uma mudança vale

Os papéis são copiados para o token quando ele é emitido. Conceder, remover ou desativar um papel chega à pessoa no próximo token — num refresh ou num novo login — e nunca num token já emitido.

Um access token emitido antes da mudança mantém os papéis antigos até expirar, então a duração do access token é o tempo que uma permissão removida continua valendo. Encurte-a no client se as remoções precisarem valer antes.

Próximos passos

Cookies de analytics

Gostaríamos de medir como o console é usado, com o Google Analytics, para enxergar em quais telas as pessoas travam. Isso grava um cookie que reconhece este navegador na sua próxima visita.

Recusar não muda mais nada. Os cookies que mantêm você conectado e lembram o seu idioma e o seu tema são necessários para o console funcionar, e ficam de qualquer forma. Ler a Política de Privacidade