# Gateways de agentes locais com MDM do macOS

Um gateway de agente local deve ser distribuído como um aplicativo de desktop sensível à segurança, não como um sistema de entrega de segredos compartilhados. O MDM controla o aplicativo assinado, sua versão, seu estado de inicialização e sua remoção. O desenvolvedor controla as credenciais armazenadas em um cofre local e as aprovações que permitem ao agente agir com essas credenciais.

Essa separação vai além de uma administração organizada. Quando a equipe de TI envia chaves de API pelo MDM, cada comprometimento do plano de gerenciamento, da exportação de inventário, do script de distribuição ou do perfil de configuração se torna uma possível exposição de segredos. Quando um agente recebe a própria chave, cada log, transcrição de ferramenta, histórico do shell e limite de prompt passa a fazer parte da superfície de ataque do segredo. Um gateway existe para manter essa credencial fora do processo do agente. Não desfaça esse projeto durante a distribuição.

Este é o modelo operacional que eu usaria para uma frota de Macs gerenciados: distribuir um único pacote de app verificável, iniciá-lo no contexto correto do usuário, mover as versões por anéis, fazer cada desenvolvedor cadastrar suas próprias credenciais localmente e aposentar dispositivos em uma sequência que remova o acesso antes de apagar o hardware.

## O MDM deve distribuir o gateway, não a autoridade do desenvolvedor

O MDM deve saber qual Mac tem o aplicativo aprovado e qual versão está executando. Ele não deve se tornar um cofre para tokens pessoais de API, chaves privadas SSH ou arquivos de credenciais colados.

As pessoas costumam misturar duas coisas diferentes porque ambas são chamadas de «configuração». Instalar um app é configuração da frota. Dar a uma pessoa ou a um agente permissão para chamar uma API de produção é autoridade delegada. A primeira pertence ao MDM. A segunda pertence a um cofre local controlado pelo usuário, com um limite claro de aprovação.

Essa distinção tem uma consequência prática durante a integração. Seu fluxo de MDM pode instalar o gateway antes de o desenvolvedor abrir o editor. O fluxo da primeira execução ainda deve pedir que o desenvolvedor crie ou desbloqueie seu próprio cofre e adicione somente as credenciais que está autorizado a usar. A equipe de TI pode documentar os tipos de credenciais aprovados e as contas de serviço necessárias, mas não deve coletar o material secreto para distribuí-lo novamente depois.

Isso também mantém o desligamento honesto. Remover um app gerenciado não revoga um token de nuvem que foi copiado para um perfil meses atrás. Um cofre local permite que o usuário remova diretamente uma credencial, enquanto o responsável pelo serviço ainda pode revogar o token na origem. Assim, você tem duas formas independentes de encerrar o acesso, em vez de depender de um único script de limpeza frágil.

No Sallyport, essa divisão é intencional: o app mantém chaves de API e SSH em seu cofre local criptografado e executa as ações HTTP ou SSH por conta própria, em vez de passar as credenciais ao agente conectado. O projeto de distribuição deve preservar essa propriedade.

Um registro de MDM adequado para o gateway contém apenas fatos operacionais:

- número de série do dispositivo ou identificador de gerenciamento
- anel de distribuição atribuído e versão do app
- comprovante do pacote e resultado da instalação
- responsável principal pelo suporte e prazo da exceção
- indicação de que o app é obrigatório, opcional ou está aguardando remoção

Não adicione nomes de segredos, valores de tokens, caminhos de chaves privadas ou histórico de aprovações a esse campo de inventário. Esses detalhes expõem contexto sensível ou criam a impressão enganosa de que o MDM consegue reconstruir o acesso de trabalho de um usuário.

## O pacote é o contrato de distribuição

Um pacote instalador assinado é o artefato que torna uma distribuição de frota repetível. Uma imagem de disco compartilhada em um chat, um zip extraído na pasta Downloads ou um script que copia um bundle de app para /Applications não é um contrato de distribuição.

A documentação de distribuição da Apple afirma que os pacotes instalados por gerenciamento de dispositivos precisam conter uma assinatura que o dispositivo possa verificar. Ela também recomenda aplicativos autocontidos, evitando scripts de instalação personalizados para a distribuição comum de apps. É um bom conselho neste caso. Scripts multiplicam os caminhos de falha, executam com privilégios confusos e tendem a sobreviver muito tempo depois que o layout do aplicativo mudou.

Crie um artefato de versão para cada versão publicada. Dê a ele um nome de arquivo versionado, mantenha seu checksum no registro da versão e exija o mesmo pacote em todos os anéis. Um anel deve testar a exposição ao mesmo build, não uma variação impossível de rastrear montada para cada grupo.

Antes de enviar um pacote ao MDM, verifique tanto o pacote quanto o app instalado em um Mac de teste limpo. Estes comandos oferecem uma verificação mínima útil:

```sh
pkgutil --check-signature Sallyport.pkg
spctl -a -vv -t install Sallyport.pkg
```

O primeiro comando deve identificar um instalador assinado e uma cadeia de assinatura válida. O segundo deve avaliar o pacote para instalação. Depois da distribuição, examine também o bundle do aplicativo:

```sh
codesign --verify --deep --strict --verbose=2 /Applications/Sallyport.app
spctl -a -vv /Applications/Sallyport.app
```

Não trate um status verde do MDM como prova de que o binário correto está pronto. O MDM pode informar que o pacote foi instalado mesmo quando um item de login posterior, um auxiliar em segundo plano, um entitlement ou um requisito da sessão do usuário impede o app de realizar um trabalho útil. A verificação do pacote e o teste funcional respondem a perguntas diferentes.

Mantenha o pacote simples. Ele deve instalar o aplicativo no local esperado, evitar o download de um segundo executável durante o postinstall e evitar a gravação de credenciais ou configurações por usuário. Se um pacote precisa de um script postinstall elaborado para fazer o produto funcionar, pare e avalie se o projeto do aplicativo ou o limite do empacotamento está errado. Você pagará por esse script em cada atualização do macOS e em cada revisão de resposta a incidentes.

O app instalado deve poder ser removido como um app, não como uma investigação forense. A Apple observa que um bundle colocado em /Applications por um pacote pode ser gerenciado e removido individualmente pelo serviço de gerenciamento de dispositivos. Esse é um dos motivos para evitar espalhar arquivos essenciais por diretórios arbitrários.

## Inicie o app na sessão do desenvolvedor

Um gateway que pede aprovação local ou precisa acessar um cofre protegido pelo usuário deve ser executado no contexto do usuário conectado. Um daemon root não substitui esse contexto.

É aqui que as equipes cometem um erro previsível. Elas veem «sempre em execução» e escolhem um LaunchDaemon porque ele é executado antes do login e continua ativo depois que o usuário sai da sessão. Então descobrem que o daemon não consegue exibir de forma adequada um pedido de aprovação do usuário, não consegue usar o chaveiro ou o caminho de autorização biométrica esperados e acumulou mais privilégios do que a tarefa exigia.

A Apple define esse limite com clareza. Um item de início de sessão começa quando o usuário entra e é executado na sessão dele. Um LaunchAgent também é executado para o usuário conectado. Um LaunchDaemon atua no nível do sistema, pode ser executado antes do login e roda como root. A Apple também descreve os itens de início de sessão como apropriados para um app voltado ao usuário que deve permanecer ativo durante a sessão dessa pessoa.

Para um gateway na barra de menus, a escolha normal é um item de início de sessão gerenciado ou o mecanismo de item de início de sessão oferecido pelo próprio aplicativo. Ele deve iniciar depois que o usuário chega à mesa, permanecer visível o suficiente para que o desenvolvedor saiba que está ativo e parar quando o usuário sair. Não esconda um limite de segurança em um processo que os usuários não conseguem inspecionar ou encerrar.

Se o MDM precisar impor o comportamento de inicialização, use a carga de item de início de sessão gerenciado da Apple, em vez de inventar um plist copiado por um script. A carga `com.apple.loginitems.managed` pode especificar o caminho do aplicativo e se ele deve ficar oculto. A referência de gerenciamento de dispositivos da Apple fornece a estrutura da carga e oferece suporte a ela no macOS.

Uma carga representativa tem esta aparência. Substitua os identificadores e o caminho pelos valores da sua versão publicada e gere os UUIDs usando suas ferramentas normais de perfil.

```xml
<dict>
  <key>PayloadType</key>
  <string>com.apple.loginitems.managed</string>
  <key>PayloadIdentifier</key>
  <string>dev.example.agent-gateway.login-item</string>
  <key>PayloadUUID</key>
  <string>REPLACE-WITH-UUID</string>
  <key>PayloadVersion</key>
  <integer>1</integer>
  <key>AutoLaunchedApplicationDictionary-managed</key>
  <array>
    <dict>
      <key>Path</key>
      <string>/Applications/Sallyport.app</string>
      <key>Hide</key>
      <false/>
    </dict>
  </array>
</dict>
```

A falha evitada aqui é simples, mas cara: o pacote instala, o app aparece em /Applications e o desenvolvedor presume que o gateway está protegendo seu agente. Na realidade, ele nunca foi iniciado depois do login, então o shim MCP não consegue concluir uma solicitação ou o usuário nunca vê o cartão de aprovação. Suas verificações de inscrição devem testar um login real de usuário, não apenas a instalação pelo agente do MDM.

Um LaunchDaemon ainda tem usos legítimos, mas mantenha-o fora do caminho do cofre. Use-o somente quando puder explicar por que o trabalho precisa ser executado sem uma sessão gráfica e por que root é necessário. «Queríamos que fosse confiável» não é uma resposta. Um aplicativo na sessão do usuário pode ser confiável sem fingir que é um serviço da máquina.

## Os anéis de atualização devem testar o trabalho real dos desenvolvedores

Os anéis de atualização funcionam quando cada um responde a uma pergunta operacional diferente. Eles falham quando se tornam uma maneira educada de adiar todas as atualizações para sempre.

Comece com um pequeno anel interno. Coloque nele as pessoas que empacotam o app, administram a configuração do MDM e solucionam problemas nas estações dos desenvolvedores. A tarefa delas é detectar falhas de instalação, problemas de inicialização, pedidos inesperados de permissão e caminhos de atualização a partir da versão anterior em produção.

O anel seguinte deve incluir desenvolvedores que usam ferramentas e padrões de acesso diferentes. Inclua alguém que use APIs HTTP por meio de um agente, alguém que use SSH, alguém que mude de rede com frequência e alguém que trabalhe com uma conta gerenciada comum, sem privilégios de administrador local. Você está procurando diferenças no uso real, não reunindo entusiastas que perdoariam qualquer aresta mal acabada.

Produção é o anel em que a versão se torna o padrão. Mantenha um pequeno grupo de retenção emergencial apenas por um motivo específico, com responsável e data de expiração. «Essa pessoa está ocupada» não é uma política de distribuição. É assim que versões sem suporte se tornam permanentes.

Trate a distribuição como uma máquina de estados, não como um ritual de calendário:

1. Instale o pacote assinado no anel interno e confirme a avaliação do pacote e do aplicativo.
2. Peça a cada usuário de teste que saia e entre novamente, depois confirme que o gateway inicia na sessão dele.
3. Execute ações reais e inofensivas pelo caminho do agente, incluindo uma solicitação HTTP e um comando SSH quando esses canais estiverem no escopo.
4. Avance o pacote idêntico para o anel piloto depois de revisar falhas, chamados de suporte e necessidades de reversão.
5. Promova para produção somente depois que o caminho de atualização da versão anterior funcionar, não apenas a instalação do zero.

Não defina sucesso como «o console do MDM diz que está instalado». Defina-o como uma cadeia de eventos observáveis: o comprovante do pacote está presente, o app assinado passa pela avaliação, o app inicia após o login, o desenvolvedor consegue desbloquear o próprio cofre, o agente alcança o shim local e uma ação permitida retorna um resultado.

Defina a reversão antes da distribuição. Para uma atualização comum, reverter deve significar redistribuir o pacote assinado anterior, restaurar a atribuição da versão anterior como obrigatória e verificar se o aplicativo antigo consegue ler o estado local com segurança. Não deve significar pedir aos desenvolvedores que arrastem aplicativos entre pastas enquanto o suporte tenta adivinhar qual build eles têm.

O gerenciamento declarativo de apps e pacotes da Apple pode definir pacotes como obrigatórios ou opcionais em Macs supervisionados compatíveis, e o gerenciamento declarativo de apps tem precedência sobre um comando de instalação sobreposto. Não envie dois mecanismos de gerenciamento para o mesmo destino esperando que o dispositivo escolha o que você queria. Escolha o método controlador em cada anel e registre-o.

## Um cofre separado muda a integração e a recuperação

Um cofre por desenvolvedor transforma a primeira execução em um procedimento de segurança, não em uma falha de automação. O usuário precisa decidir quais credenciais pertencem àquele Mac, e o dispositivo precisa provar que o usuário consegue desbloqueá-las.

Esse é exatamente o objetivo. O gateway de agente local pode receber uma solicitação do Claude Code ou de outro agente compatível com MCP, mas o agente nunca deve receber a credencial em texto simples nem um marcador falso que possa usar indevidamente depois. O gateway deve executar a ação HTTP ou SSH e retornar o resultado.

No Sallyport, a sequência fixa de decisões é útil porque evita uma linguagem de políticas que cada equipe precisaria aprender e auditar. Um cofre bloqueado nega todas as ações. Um novo processo de agente recebe autorização de sessão por padrão, e uma credencial marcada para aprovação por chamada pede autorização sempre que é usada. Esses controles são diferentes, portanto treine os desenvolvedores para usá-los em situações diferentes.

Use o bloqueio do cofre quando o laptop estiver sem supervisão ou quando o desenvolvedor terminar o trabalho. Use a autorização de sessão para identificar uma nova execução do agente antes que ela receba liberdade ampla. Use a aprovação por chamada para credenciais em que cada uso mereça atenção humana, como um token de administração de produção ou uma identidade SSH sensível.

Não diga aos desenvolvedores para colocar todas as credenciais sob aprovação por chamada apenas porque isso parece mais seguro. Pedidos repetidos treinam as pessoas a aprovar sem ler. Coloque o atrito onde uma solicitação equivocada teria impacto e deixe as credenciais comuns de desenvolvimento e baixo risco sob o limite da sessão. A fadiga de aprovação é uma falha de projeto, não uma prova de que sua equipe leva a segurança a sério.

A recuperação exige limites igualmente claros. A equipe de TI pode reinstalar o app do gateway e reparar seu estado de inicialização gerenciado. Ela não pode nem deve restaurar o conteúdo do cofre de um desenvolvedor a partir de um registro do MDM. Se um Mac for substituído, o desenvolvedor deve obter credenciais novas pelo sistema de origem ou seguir o processo aprovado de migração de credenciais da organização. Isso pode ser inconveniente. Ainda é mais seguro do que tratar um banco de dados de gerenciamento de frota como backup de tokens de produção.

Documente a tabela de responsabilidades antes da distribuição:

| Evento | Desenvolvedor | TI ou equipe de endpoints | Responsável pelo serviço |
| --- | --- | --- | --- |
| Configuração de um Mac novo | Desbloqueia o cofre e adiciona credenciais autorizadas | Instala o app e a configuração de login | Concede a credencial inicial |
| Comportamento inesperado do agente | Revoga a sessão e bloqueia o cofre | Confirma o estado do dispositivo e do app | Revoga a credencial se necessário |
| Falha na atualização do app | Relata o comportamento visível e a versão | Corrige a atribuição do pacote ou reverte a versão | Normalmente nenhuma ação |
| Substituição do dispositivo | Obtém uma credencial nova ou migração aprovada | Aposenta o Mac antigo e distribui o novo | Alterna ou reemite o acesso |

Essa tabela evita o pior chamado de suporte da distribuição: um desenvolvedor diz «meu agente perdeu o acesso», o suporte de endpoints responde «o app está instalado» e o responsável pelo serviço presume que alguém restaurou um segredo que ninguém deveria possuir.

## Inventário e evidências de ações respondem a perguntas diferentes

O inventário do MDM informa se o aplicativo gerenciado chegou a um dispositivo. Ele não consegue estabelecer o que um agente de IA solicitou depois da instalação, qual autoridade aprovou a solicitação ou qual chamada de API foi executada.

Mantenha esses registros separados e relacione-os quando necessário. O registro do MDM deve fornecer a identidade do hardware, o estado de gerenciamento, a versão atribuída do app, o horário da instalação e o status da remoção. O rastro de auditoria do gateway deve fornecer a sessão, a ação individual e o resultado da verificação. Se você juntar tudo em uma planilha, acabará expondo detalhes operacionais demais à equipe de endpoints ou privando os responsáveis pela resposta a incidentes das evidências necessárias.

O Sallyport registra as execuções dos agentes em um diário de Sessões e as ações individuais em um diário de Atividade, ambos projetados a partir de um único log de auditoria criptografado e encadeado por hash. O comando `sp audit verify` verifica a cadeia offline sobre o texto cifrado e não precisa da chave do cofre. Assim, um investigador pode verificar se o registro foi alterado sem abrir os segredos do usuário.

Use um procedimento simples de coleta para um incidente ou uma revisão de versão:

```sh
sp audit verify
```

Um resultado útil tem uma indicação clara de aprovação ou falha, seguida do intervalo verificado, por exemplo:

```text
Audit chain: valid
Records checked: 184
First record: 2026-07-01T14:22:09Z
Last record: 2026-07-22T09:15:44Z
```

Os campos exatos dependem da versão instalada do comando, portanto salve a saída bruta junto com a versão do app e o identificador do dispositivo. Não copie o conteúdo do cofre de um desenvolvedor, a transcrição do prompt do agente ou um histórico de terminal não relacionado só porque está coletando um resultado de auditoria.

Essa separação também melhora o suporte de rotina. Se o console do MDM mostrar a versão esperada, mas o desenvolvedor disser que uma ação foi negada, examine o estado local do gateway e o caminho de aprovação. Se o registro de auditoria mostrar uma ação, mas o MDM não tiver um registro atual de instalação, investigue um registro de dispositivo obsoleto, um Mac recém-aposentado ou uma instalação não gerenciada. Cada sistema tem uma função limitada. Deixe-o cumprir bem essa função.

## A aposentadoria do dispositivo começa pelo acesso, não pelo apagamento

Quando um Mac muda de mãos, é perdido ou deixa a empresa, encerre sua relação de acesso antes de apagá-lo ou liberá-lo da propriedade organizacional. Apagar limpa o disco. Isso não prova que as credenciais de nuvem, as sessões ativas do agente ou as atribuições do dispositivo foram tratadas corretamente.

Para uma devolução corporativa normal, siga esta ordem:

1. Identifique o dispositivo, seu último usuário atribuído, seu registro no MDM e se ele ainda faz check-in.
2. Revogue as sessões ativas do gateway e peça ao responsável pelo serviço que alterne ou revogue as credenciais que ainda possam ser úteis em outro lugar.
3. Remova o aplicativo gerenciado ou marque-o para remoção se o Mac permanecer online tempo suficiente para receber o comando.
4. Preserve o mínimo necessário de evidências de gerenciamento e auditoria conforme suas regras de retenção.
5. Apague o Mac pelo fluxo aprovado de devolução ou redistribuição da organização.

Não libere o Mac do Apple Business Manager apenas porque um funcionário saiu. A liberação é uma decisão de propriedade para hardware vendido, perdido sem possibilidade realista de recuperação ou que deixou de pertencer ao seu controle. A Apple alerta que a liberação é irreversível pelo caminho usual de atribuição, impede futuras atribuições de MDM e exige apagamento e restauração depois da liberação. Ela também alerta para não liberar um dispositivo enviado para reparo, pois uma substituição pode não retornar ao Apple Business Manager.

Para um Mac corporativo redistribuído, mantenha a inscrição organizacional, apague-o e inscreva o próximo usuário pelo fluxo padrão. Para um dispositivo pessoal sob um modelo de inscrição do usuário, remova o gerenciamento conforme a política acordada, confirme quais apps e configurações gerenciados desaparecerão e peça ao desenvolvedor que remova as próprias credenciais antes da transferência. A Apple observa que a desinscrição pode remover apps e conteúdo gerenciados, enquanto apps e configurações pessoais permanecem em dispositivos inscritos pelo usuário.

Um Mac perdido exige um caminho mais rápido. Revogue primeiro as credenciais e as sessões, pois a máquina pode nunca voltar a ficar online. Depois, use os controles de gerenciamento do dispositivo e o processo de revogação do responsável pelo serviço. Esperar que um comando de remoção do app chegue ao dispositivo não é contenção.

## A distribuição funciona quando permanece sem surpresas

A melhor distribuição de um gateway local produz pouco drama porque cada limite é explícito. A equipe de MDM envia um app assinado e controla seu ciclo de vida. O desenvolvedor mantém as credenciais em um cofre local e consegue ver quando um agente solicita autoridade. O responsável pelo serviço concede e revoga o acesso na origem. O rastro de auditoria registra as ações sem se transformar em um despejo de segredos.

Comece pelo teste que expõe as suposições mais problemáticas: inscreva um Mac gerenciado limpo, faça login como um desenvolvedor comum, instale o pacote de produção pelo MDM, saia e entre novamente, adicione localmente uma credencial não crítica, execute uma ação inofensiva do agente, verifique seu registro de auditoria, remova o app e repita tudo a partir de uma inscrição nova. Se essa sequência exigir trabalho manual não documentado, um script root oculto ou um arquivo de credenciais copiado, corrija a distribuição antes de adicionar mais cem dispositivos.
