Convite de API com parâmetro group_names retorna 403 para usuário dono do grupo, a menos que seja admin

Resumo

Um usuário não administrador que é dono de um grupo no Discourse consegue convidar novos membros com a atribuição desse grupo com sucesso por meio do diálogo de convite da interface web. A ação idêntica via API REST (/invites.json, chave de API com escopo Global, Api-Username correto) retorna 403 invalid_access — mas apenas quando group_names/group_ids está incluído no payload. Criticamente, conceder ao usuário o status de Moderador não corrige a chamada da API — apenas a concessão de Admin total resolve, embora Moderador seja suficiente para todos os outros cenários testados (interface web, convite de API sem grupo).

Ambiente

  • Versão do Discourse: 2026.7.1
  • Tipo de chave de API: Escopo Global, CheriArchives = o nome de usuário exato do usuário de teste

Passos para reproduzir

  1. Crie um usuário não administrador e não moderador (<userid>), tornando-o dono do grupo <group_name>.
  2. Na interface web, como <userid>: convidar sem grupo → sucesso. Convidar com a atribuição de <group_name> → sucesso.
  3. Via API, como <userid> (chave de escopo Global, Api-Username=<userid>):
    • POST /invites.json sem group_names → sucesso.
    • POST /invites.json com group_names=<group_name> (o mesmo grupo do qual ele é dono) → 403 invalid_access.
  4. Promova <userid> a Moderador. Repita a chamada de API com grupo da etapa 3 → ainda 403 invalid_access.
  5. Promova <userid> a Admin. Repita a chamada de API com grupo da etapa 3, mesma chave, mesmo payload → sucesso.

Comportamento esperado

Como a propriedade do grupo sozinha é uma permissão suficiente para um usuário não membro da equipe atribuir esse grupo em um convite via interface web, a API — autenticada como o mesmo usuário via Api-Username — deveria respeitar a mesma permissão. No mínimo, Moderador (que é membro da equipe) não deveria se comportar de forma idêntica a um usuário sem privilégios aqui; o fato de Moderador falhar de forma idêntica à ausência de papel, e apenas Admin ter sucesso, sugere que o caminho de código da API verifica especificamente user.admin? em vez da propriedade do grupo ou mesmo do status geral de membro da equipe (user.staff?, que é verdadeiro para moderadores).

Comportamento real

A API retorna 403 para qualquer convite com grupo, a menos que o usuário atuante seja um Admin total. A propriedade do grupo (verificado funcionando via interface web) e o status de Moderador/membro da equipe (verificado via teste de promoção direta) são ambos insuficientes para o caminho da API, apesar de qualquer um deles ser suficiente através da interface web ou para o caso de API sem grupo.

Pergunta para a equipe do Discourse

O caminho de código de convite com grupo autenticado via API requer explicitamente user.admin?, em vez de verificar a propriedade do grupo ou user.staff? da mesma forma que o caminho autenticado por sessão/interface web faz? Se sim, isso é intencional (restrição específica da API não documentada) ou é um bug onde a verificação do guardião da API diverge da verificação do guardião da web para esta ação?

Ficarei feliz em fornecer logs completos de requisição/resposta (chave redigida) mediante solicitação.