8 min de leitura

A identidade de processo no macOS precisa de mais do que um Team ID

Um modelo prático de identidade de processo no macOS com Team ID, identificador de assinatura, requisitos designados, caminhos e tratamento rigoroso de compilações sem assinatura.

A identidade de processo no macOS precisa de mais do que um Team ID

Um Team ID não basta para decidir qual processo do macOS pode usar um segredo. Ele identifica uma equipe de desenvolvedores Apple, não um executável específico criado por essa equipe. Se você autorizar apenas um Team ID, todo app, auxiliar, utilitário de teste e binário futuro adequadamente assinado por essa equipe poderá herdar o mesmo acesso.

Uma identidade de autorização defensável combina a autoridade de assinatura com o identificador de assinatura, registra um requisito que sobrevive a atualizações legítimas e avalia essa identidade no processo que está realmente fazendo a solicitação. O caminho do executável continua importante no cartão de aprovação e no registro de auditoria, mas não deve decidir a autorização. Compilações de desenvolvimento sem assinatura e com assinatura ad hoc precisam de um caminho separado e visivelmente mais fraco, não de uma exceção silenciosa.

Essa distinção importa mais na fronteira com um segredo. Uma assinatura de código pode informar quem assinou um processo e qual nome de programa o assinante declarou. Ela não informa se o processo merece uma senha de banco de dados, se a solicitação atual faz sentido ou se outro programa do mesmo desenvolvedor deve receber a mesma concessão. A identidade é um dado da autorização, não seu substituto.

O Team ID identifica um assinante, não um programa

O Team ID responde a uma pergunta útil, mas ampla: qual equipe de desenvolvedores Apple emitiu a identidade de assinatura usada por este código? Para certificados de desenvolvedor emitidos pela Apple, a linguagem de requisitos expõe o Team ID pelo campo de unidade organizacional do certificado folha. As ferramentas também podem mostrar um valor TeamIdentifier nos detalhes da assinatura.

Execute isto no executável exato, não apenas no pacote externo do app:

codesign -dvvv /Applications/Example.app/Contents/MacOS/Example 2>&1

A parte útil da saída tem esta forma:

Executable=/Applications/Example.app/Contents/MacOS/Example
Identifier=dev.example.agent
Authority=Developer ID Application: Example Developer (A1B2C3D4E5)
Authority=Developer ID Certification Authority
Authority=Apple Root CA
TeamIdentifier=A1B2C3D4E5

Um Team ID válido define o escopo do assinante. Ele exclui binários assinados por outras equipes, impedindo que um desenvolvedor sem relação declare o mesmo identificador de assinatura e passe na sua verificação. A Apple destaca exatamente isso na documentação de SigningIdentifier: vários assinantes podem declarar um identificador de assinatura, por isso uma verificação segura de código que não é da Apple também precisa de uma restrição de TeamIdentifier e de uma categoria de validação adequada.

O inverso é a armadilha. Uma equipe pode assinar muitos produtos sem relação entre si e muitos componentes de um único produto. Um app, seu auxiliar privilegiado, um item de início de sessão, uma ferramenta de linha de comando, um serviço XPC e um diagnóstico interno podem compartilhar o Team ID. Um serviço de assinatura comprometido poderia produzir mais um binário dentro desse escopo. Pertencer à equipe não distingue nenhum deles.

Por isso, Team ID == equipe aprovada é amplo demais para uso com segredos. É como conceder acesso a todos os funcionários de uma empresa porque os crachás foram emitidos pela mesma entidade. A entidade emissora importa, mas o nome no crachá também importa.

Há casos restritos em que usar somente o Team ID é intencional. Uma ferramenta de desenvolvedor pode permitir que qualquer componente assinado pela equipe do próprio usuário acesse um recurso local descartável. Essa é uma política de confiança na equipe, não uma identidade de processo, e o texto da aprovação deve dizer isso. Não a armazene em um campo chamado application para depois esquecer quanta autoridade ela concede.

O identificador de assinatura separa programas dentro de uma equipe

O identificador de assinatura fornece a dimensão de programa que falta ao Team ID. O codesign o exibe como Identifier. Em um app empacotado, ele costuma ser o identificador do pacote, mas a Apple deixa claro que essa equivalência não é obrigatória. Quem assina escolhe o valor, e executáveis de linha de comando podem ter identificadores sem serem pacotes de app.

Unir Team ID e identificador de assinatura produz uma identidade mínima muito melhor:

team_id = A1B2C3D4E5
signing_identifier = dev.example.agent

O par significa "o programa chamado dev.example.agent, assinado pela equipe A1B2C3D4E5". Outra equipe pode copiar o identificador, mas não consegue satisfazer a restrição de equipe. Outro programa da equipe aprovada deve ter um identificador diferente e, portanto, não deve corresponder.

Esse "deve" tem peso na última frase. Uma equipe controla seus próprios identificadores e pode reutilizá-los. Uma configuração descuidada de compilação pode atribuir o identificador do app principal a um auxiliar incorporado. Um assinante malicioso ou comprometido poderia copiar o valor aprovado. O par restringe a autoridade sob a premissa de que o assinante protege tanto suas credenciais de assinatura quanto seu espaço de nomes de identificadores.

Mesmo assim, essa é a fronteira normal para uma identidade de terceiros estável entre atualizações no macOS. Hashes de código são mais específicos, mas cada versão legítima os altera. Impressões digitais de certificados também são âncoras de continuidade incômodas, pois certificados expiram e são substituídos. Team ID mais identificador de assinatura expressa a continuidade que a maioria dos apps deseja: aceitar versões futuras deste programa vindas deste assinante, sem aceitar todo o catálogo do assinante.

Inspecione cada executável que pode se conectar. Não deduza o identificador de um auxiliar a partir do app que o contém. A Apple TN3127 usa um app e sua ferramenta de linha de comando incorporada para mostrar o mesmo ponto: eles compartilham um Team ID, mas têm identificadores de assinatura de código diferentes, e a Apple chama essa separação de boa prática. Se o auxiliar inicia a solicitação, a identidade dele é a que importa na fronteira.

Os identificadores também exigem tratamento byte a byte. A documentação atual de SigningIdentifier da Apple diz que a comparação não faz normalização Unicode. Armazene e compare o valor retornado pelo Code Signing Services como uma string opaca ou sequência de bytes. Convertê-lo para minúsculas, normalizá-lo ou recriá-lo a partir de CFBundleIdentifier cria um segundo sistema de identidade com regras diferentes.

O requisito designado registra uma identidade estável entre atualizações

Um requisito designado, geralmente abreviado como DR, é a expressão nativa do macOS para decidir se o código visto agora é o mesmo código visto antes. Ele combina o identificador de assinatura com restrições sobre a autoridade de assinatura. Isso se aproxima mais do objeto de autorização necessário do que qualquer um dos campos isoladamente.

A Apple TN3127 descreve um DR como a forma de o código declarar como outra parte pode reconhecê-lo novamente. O teste prático da nota técnica é uma atualização: a versão 1.3 deve satisfazer a identidade registrada para a versão 1.2, embora seus bytes tenham mudado. Ao mesmo tempo, outro produto deve falhar. Essa é exatamente a tensão que uma concessão durável de segredo precisa resolver.

Exiba o DR com:

codesign -d -r- /Applications/Example.app/Contents/MacOS/Example 2>&1

Um resultado Developer ID tem esta forma geral, com os detalhes do certificado variando conforme o caminho de assinatura:

Executable=/Applications/Example.app/Contents/MacOS/Example
designated => anchor apple generic and identifier "dev.example.agent" and certificate leaf[subject.OU] = "A1B2C3D4E5"

Não analise essa string exibida em campos próprios para tentar reproduzir o avaliador da Apple. A TN3125 alerta que as estruturas de assinatura mudam e orienta desenvolvedores a usar codesign ou Code Signing Services para validação. Use SecCodeCopyDesignatedRequirement para obter um requisito e SecCodeCheckValidity, ou as APIs atuais de requisitos de processo, para avaliar o código. Deixe a plataforma compilar e comparar sua própria forma de requisito.

Daí surge um ponto sutil: o DR do próprio código é uma declaração, não uma decisão de autorização. O assinante pode fornecer um DR explícito, e o Code Signing Services pode sintetizar um quando nenhum estiver incorporado. Seu sistema ainda decide qual requisito registrar e se o escopo dele é adequado à concessão. Ler um DR e anunciar "confiável" confunde material de identidade com política.

Para software Developer ID comum, registrar o DR validado no momento da aprovação é um padrão seguro. Armazene também o Team ID exibido e o identificador de assinatura como campos de auditoria para que uma pessoa entenda a decisão. Em chamadas posteriores, avalie o processo ativo em relação ao requisito armazenado, em vez de comparar por igualdade textual uma string de DR recém-impressa. Objetos de requisito expressam comportamento, e expressões equivalentes não precisam ter a mesma formatação.

Mudanças de distribuição exigem tratamento deliberado. A TN3127 observa que os DRs padrão para variantes da Mac App Store e do Developer ID não são automaticamente compatíveis, embora o Xcode possa usar requisitos personalizados para conectar formas de distribuição planejadas. Não amplie seu verificador durante uma mudança de canal. Trate o novo requisito como uma mudança de identidade, mostre-o ao usuário e exija nova aprovação, a menos que você tenha criado e testado um requisito explícito de compatibilidade.

Caminhos de executável dão contexto, não prova

Um caminho de executável informa ao operador onde o macOS encontrou a imagem. Isso é um excelente contexto para uma aprovação e uma evidência fraca de continuidade. Arquivos mudam de lugar, a translocação de apps pode alterar locais, usuários mantêm várias versões e gerenciadores de pacotes instalam caminhos versionados. Por outro lado, um invasor capaz de substituir um arquivo em um caminho gravável aprovado pode herdar uma concessão baseada apenas no caminho.

A conhecida lista de permissões por caminho falha nos dois sentidos. Ela rejeita o mesmo programa assinado após uma mudança inofensiva e aceita bytes diferentes depois de uma substituição hostil. Adicionar verificações de proprietário e modo reduz parte do risco de substituição, mas não transforma um nome de caminho em identidade criptográfica.

Mantenha o caminho para três funções:

  • Mostrar ao usuário qual instalação iniciou a solicitação.
  • Registrar contexto suficiente para investigar uma chamada inesperada.
  • Aplicar uma restrição opcional de localização depois que a identidade pela assinatura for confirmada.

Esse último uso pode ser razoável em ambientes gerenciados. Você pode exigir um DR aprovado e também que o executável esteja sob um diretório de implantação pertencente a root. Nesse caso, o caminho limita onde um programa já identificado pode ser executado. Ele nunca corrige uma assinatura ausente ou inválida.

Resolva e registre o executável realmente associado ao processo em execução. Não confie em uma string fornecida pelo cliente, como argv[0], um diretório de trabalho, um caminho de pacote em uma solicitação ou uma variável de ambiente. Tudo isso são declarações de quem solicita. Mesmo um caminho canonizado pode sofrer uma corrida se você inspecionar um arquivo e depois autorizar um processo apenas com base no nome salvo.

Quando a plataforma os fornece, mantenho nos dados de auditoria tanto o caminho original observado quanto um caminho resolvido, pois links simbólicos e wrappers de inicialização explicam muitas surpresas. Nenhum dos dois valores entra na tupla de identidade durável. Se uma organização optar por restringir o caminho, armazene isso em um campo location_constraint separado para que revisores vejam que é uma política adicionada à identidade.

Avalie quem chama agora, não um nome de caminho

Verifique evidências sem acessar o cofre
O registro de auditoria encadeado por hash é verificado offline sobre texto cifrado com `sp audit verify`.

A verificação de autorização precisa estar vinculada ao processo que faz a conexão. Verificar um arquivo no momento da instalação, salvar seu caminho e confiar no que for executado ali depois deixa uma brecha entre a verificação e o uso. Verificar o arquivo atual nesse caminho quando chega uma solicitação ainda pode inspecionar uma substituição, em vez da imagem que já está sendo executada.

O Code Signing Services do macOS distingue código estático no disco de código dinâmico associado a um processo em execução. A Apple documenta SecCodeCopyGuestWithAttributes para obter um objeto de código de código convidado, geralmente pelo PID, e SecCodeCheckValidityWithProcessRequirement para verificar um processo em execução contra um requisito. A API mais recente de requisitos leves pode deixar explícitas as restrições pretendidas de TeamIdentifier e SigningIdentifier. Use a API compatível com seu alvo de implantação, em vez de extrair a saída de codesign em produção.

Um fluxo de conexão confiável se parece com isto:

  1. Obtenha a identidade de processo fornecida pelo kernel na fronteira IPC, como o token de auditoria anexado a uma conexão aceita. Não aceite um PID informado no corpo da solicitação.
  2. Resolva esse processo ativo para um objeto de código dinâmico e valide sua assinatura com a API da plataforma.
  3. Avalie o requisito armazenado, ou as restrições armazenadas de assinante e identificador, no mesmo objeto de código.
  4. Registre no histórico de decisão o caminho, PID, identidade de início do processo quando disponível, informações da assinatura e resultado da validação.
  5. Vincule a aprovação à conexão ou ao tempo de vida do processo e descarte-a quando esse tempo terminar.

Um PID isolado não é um identificador durável porque o kernel reutiliza IDs de processo. Se o verificador lê um PID, espera e depois o consulta novamente, pode inspecionar outro processo. Um token de auditoria carrega mais identidade de processo que um inteiro fornecido pelo cliente, e a verificação com escopo de conexão reduz a janela. A API exata depende de sua fronteira ser XPC, socket de domínio Unix ou outro mecanismo IPC, mas a regra não muda: derive o sujeito a partir da visão que o sistema operacional tem do par.

Valide antes de exibir a identidade. Caso contrário, um cartão de aprovação pode mostrar campos extraídos de uma assinatura malformada ou inválida como se o macOS os tivesse confirmado. O cartão deve distinguir assinatura Developer ID válida de havia texto de identificador. Se a validação falhar, não recorra a uma correspondência de caminho sob a mesma aprovação.

Árvores de processos merecem uma decisão explícita. Se um agente assinado inicia /bin/sh e o shell se conecta diretamente, o par é o shell. Percorrer automaticamente até um ancestral e emprestar a identidade do pai pode autorizar filhos substituídos ou descendentes sem relação. Se sua arquitetura quiser autorizar quem iniciou o processo, vincule uma capacidade à conexão original autenticada e passe-a por um canal controlado. Não tente redescobrir a intenção subindo pelos PIDs dos pais.

Também por isso a autorização deve expirar quando o processo aprovado termina. Uma identidade salva pode respaldar aprovações futuras, mas uma concessão de sessão não deve ficar solta e se prender para sempre a qualquer processo correspondente. Separe "reconhecemos este programa" de "esta execução está aprovada agora".

Compilações sem assinatura e ad hoc precisam de política separada

Código sem assinatura não tem requisito designado. Código assinado ad hoc tem um DR vinculado àquela versão específica, então uma recompilação muda a identidade. A Apple TN3127 diz que o macOS não consegue acompanhar com confiabilidade nenhuma dessas formas entre versões. Um intermediário de segredos deve preservar essa limitação em vez de encobri-la com uma exceção de diretório.

Para segredos de produção, falhe de forma fechada quando quem chama não tiver uma assinatura válida e estável entre atualizações. Essa é a regra mais clara e mais fácil de explicar. Desenvolvedores podem assinar compilações locais com uma identidade Apple Development ou uma identidade de assinatura privada, cuja confiança e requisitos a organização administra. O incômodo costuma ser menor do que a ambiguidade criada por uma exceção permanente para código sem assinatura.

O desenvolvimento local às vezes precisa de um modo mais fraco. Torne-o opcional, chame-o de aprovação de desenvolvimento e limite o alcance do dano. Um desenho razoável vincula a aprovação ao tempo de vida do processo atual e ao hash exato do código, destaca sem assinatura ou ad hoc, exclui conjuntos de segredos de produção e pede novamente após cada recompilação. A repetição do aviso não é um defeito. Ela reflete que o executável já não tem uma continuidade que o macOS possa provar.

Não use estes substitutos populares:

  • Um caminho sob o diretório pessoal do usuário, porque o mesmo usuário pode substituí-lo.
  • Um nome de arquivo ou identificador de pacote lido de metadados, porque código sem assinatura pode declarar qualquer valor.
  • A assinatura do processo pai, porque o filho é o par que usa a autoridade.
  • Uma aprovação geral de terminal, porque terminais iniciam programas arbitrários.
  • Um hash armazenado como identidade permanente, porque toda recompilação legítima exige migração manual.

Um hash pode restringir com segurança uma exceção temporária. Ele diz "estes bytes exatos nesta execução", não "este é o mesmo programa após uma atualização". Mantenha essa diferença semântica visível no armazenamento e na interface.

Trate um Team ID ausente como um estado a classificar, não como nulo que ignora a comparação. Código de plataforma assinado pela Apple, código assinado de forma independente, código ad hoc e código sem assinatura não cabem todos na mesma tupla. Defina quais categorias seu produto aceita e teste cada uma. Uma verificação if team != expected com um ramo permissivo para valor vazio causou bugs de autorização suficientes para merecer um teste unitário dedicado.

Armazene um registro de identidade que explique seu próprio escopo

Troque a entrega de segredos por ações
Sallyport injeta as credenciais e devolve apenas o resultado ao processo de agente autorizado.

Um registro durável deve preservar o requisito que a máquina pode avaliar, os fatos legíveis da assinatura, a categoria de código e qualquer condição de localização aprovada separadamente. Ele também deve registrar o escopo da concessão. Uma pessoa que revise o banco de dados seis meses depois precisa conseguir saber se a aprovação cobria uma execução, versões assinadas futuras ou todos os programas de uma equipe.

Este exemplo usa valores de preenchimento e um blob serializado de requisito representado como base64. O blob deve vir do Code Signing Services, não da compilação de uma string fornecida pelo cliente:

{
  "schema": 1,
  "code_category": "developer_id",
  "team_id": "A1B2C3D4E5",
  "signing_identifier": "dev.example.agent",
  "designated_requirement": "BASE64_PLATFORM_REQUIREMENT",
  "approval_scope": "matching_identity_per_session",
  "location_constraint": null,
  "observed_path": "/Applications/Example.app/Contents/MacOS/Example"
}

O algoritmo de correspondência deve ser simples. Primeiro, classifique quem chama e valide sua assinatura ativa. Para uma identidade assinada, avalie o requisito armazenado em relação ao processo ativo. Confirme que o Team ID retornado e o identificador de assinatura correspondem aos campos de auditoria. Uma divergência indica estado corrompido ou bug, não motivo para ampliar o acesso. Depois, aplique qualquer restrição de localização. Por fim, consulte o escopo da concessão e qualquer requisito de aprovação por segredo.

O pseudocódigo facilita revisar o comportamento em caso de falha:

caller = peer_from_kernel(connection)
code = dynamic_code(caller)
result = validate(code)

if result.category not in accepted_categories:
    deny("unsupported code category")

identity = evaluate(stored_requirement, code)
if identity != satisfied:
    deny("process identity changed")

if facts(code) != stored_audit_facts:
    deny("identity record inconsistent")

if location_constraint and not location_allowed(code, location_constraint):
    deny("approved program ran from an unapproved location")

authorize_for(connection_lifetime, requested_secret)

Observe o que o algoritmo não faz. Ele não aceita apenas um Team ID, não compara um caminho antes de verificar a assinatura, não procura processos pais em busca de uma identidade mais favorável e não converte silenciosamente quem chama sem assinatura em uma concessão de desenvolvimento. Cada falha gera um motivo que usuário e auditor conseguem entender.

Planeje a migração de identidade como uma operação, não como exceção. Uma transferência de equipe, mudança de identificador de assinatura, mudança de canal de distribuição ou troca de assinatura ad hoc por Developer ID pode alterar legitimamente o requisito. Apresente os fatos antigos e novos lado a lado, exija que uma pessoa autorizada aprove a transição e mantenha ambos os registros no histórico de auditoria. Nunca sobrescreva a identidade antiga e faça chamadas passadas parecerem ter vindo da nova.

Teste com cenários adversariais. Assine dois executáveis com a mesma equipe e identificadores diferentes. Apenas um deve passar. Assine outro com o identificador aprovado sob uma equipe diferente. Ele deve falhar. Copie o executável aprovado para outro caminho. A identidade deve passar, salvo se uma condição de localização disser o contrário. Substitua o arquivo depois de iniciá-lo e confirme que o verificador avalia o par ativo. Recompile um alvo ad hoc e confirme que a aprovação temporária não sobrevive.

A identidade não responde se a ação é permitida

Interrompa uma execução aprovada na hora
O diário de sessões permite revogar um agente em execução quando sua identidade ou comportamento parecer incorreto.

Uma correspondência correta de processo identifica apenas o sujeito de uma solicitação. Ela não prova que o sujeito pode usar todos os segredos, chamar todos os hosts ou manter acesso para sempre. Mantenha identidade de processo, aprovação de sessão e aprovação de ação como decisões separadas, mesmo que uma interface as apresente juntas.

Essa separação evita uma escalada comum. Um usuário aprova um agente de programação assinado para ler um token de desenvolvimento, o sistema armazena a identidade do agente e uma implementação posterior passa a tratar esse registro como aprovação para todas as credenciais. Nada no Team ID, identificador de assinatura ou DR carrega a fronteira original do recurso. A identidade permaneceu estável enquanto a autorização se ampliava silenciosamente.

Deixe explícita a tupla de autorização: sujeito, ação, recurso, condições e duração. Para um gateway de segredos, ela pode ser assim:

subject: requirement R42 satisfied by this live process
action: perform an HTTP request with injected bearer credentials
resource: issue-tracker-development
conditions: vault unlocked and session approved
lifetime: this connection, with per-call approval if the secret requires it

O campo de sujeito se refere ao registro de identidade do processo. Os outros campos vêm da operação solicitada e dos controles ao redor dela. Essa estrutura também atende a um agente que usa HTTP e SSH sem fingir que o reconhecimento de processo autoriza automaticamente os dois canais.

Permissões podem informar uma política especializada, mas não devem virar uma pontuação improvisada de reputação. Uma permissão é uma declaração assinada que o macOS interpreta para recursos específicos do sistema. Sua presença não torna o programa mais seguro em geral, e sua ausência não enfraquece uma correspondência de Team ID mais identificador. Verifique uma permissão específica apenas quando seu projeto de autorização lhe atribuir um significado preciso.

A notarização e o Gatekeeper também respondem a perguntas diferentes. A aceitação deles pode contribuir para validar a categoria de código e a confiança na distribuição, mas nenhum dos dois identifica um programa dentro de uma equipe de desenvolvedores nem concede acesso ao seu segredo. Executar spctl -a -vv -t exec durante o diagnóstico pode explicar se o Gatekeeper aceita um arquivo. Não substitua sua verificação de requisito armazenado por esse resultado.

A revogação precisa da mesma precisão. Revogar uma sessão deve interromper a conexão atual sem apagar a identidade reconhecida do programa. Revogar uma identidade deve obrigar processos futuros correspondentes a passar por aprovação novamente. Revogar uma concessão de recurso deve deixar as demais concessões intactas. Se um único booleano chamado trusted controla as três coisas, o modelo de dados não consegue expressar o que o usuário realmente decidiu.

Essas fronteiras tornam a análise de incidentes muito menos especulativa. Um auditor pode determinar que certo programa assinado foi executado, que uma pessoa aprovou aquela execução e que ela recebeu autoridade para uma operação definida. Sem os três registros, um DR perfeito ainda deixa sem resposta a pergunta mais importante: o que reconhecer o processo permitiu?

As telas de aprovação devem dizer o que foi comprovado

Uma pessoa não consegue revisar um blob bruto de requisito durante uma aprovação interruptiva. Mostre uma declaração compacta derivada de fatos validados: assinante ou equipe, identificador de assinatura, categoria da assinatura, caminho do executável e se a aprovação dura para o processo ou para uma chamada. Coloque o fato mais amplo em primeiro lugar apenas quando o desenho conceder autoridade ampla de forma consciente.

Evite nomes amigáveis de apps como identidade principal. Nomes de exibição vêm de metadados mutáveis e frequentemente coincidem. Eles são rótulos úteis depois dos fatos de assinatura validados, assim como o caminho. Uma aprovação que diz Example Agent quer acesso esconde se quem solicita é o app lançado, um auxiliar, uma recompilação local ou uma cópia sem assinatura.

A primeira chamada do Sallyport feita por um novo processo de agente mostra um cartão de aprovação liderado pela autoridade de assinatura de código do processo e vincula a aprovação àquela execução até ela terminar. A proteção do cofre e a opção de aprovação por chamada continuam sendo controles separados, de modo que reconhecer um processo nunca transforma identidade em acesso ilimitado a segredos.

O evento de auditoria deve preservar o que o verificador observou e qual regra aplicou. Registre a categoria validada, Team ID, identificador de assinatura, referência do requisito, caminho, identificadores de processo e sessão, decisão, motivo da negação e escopo da concessão. Quem revisar depois não deve precisar do arquivo atual no caminho antigo para entender a chamada.

Não chame o resultado de processo confiável. O verificador provou algo mais limitado: este processo ativo satisfez um requisito específico de código, e uma pessoa ou política concedeu a ele uma ação definida. Essa redação reduz a expansão indevida de autoridade quando surgem novos tipos de segredo e novas ferramentas de agente.

Um Team ID faz parte dessa afirmação, mas não consegue sustentá-la sozinho. Use o Team ID para nomear o assinante, o identificador de assinatura para nomear o programa dentro desse assinante, o requisito designado para preservar a identidade entre versões legítimas e o identificador do processo ativo para vincular a prova a quem solicita. Quando uma dessas partes faltar, restrinja a concessão ou peça novamente. Uma fronteira de segredos deve expor a incerteza, não convertê-la em acesso permanente.

FAQ

Dois apps diferentes do macOS podem ter o mesmo Team ID?

Sim. Todos os apps e auxiliares assinados pela mesma equipe de desenvolvedores Apple podem compartilhar esse Team ID. Use o identificador de assinatura ou um requisito designado para diferenciar programas dentro da equipe.

Um identificador de pacote é igual a um identificador de assinatura?

Frequentemente, mas o macOS não exige isso. Quem assina escolhe o identificador de assinatura, e ferramentas de linha de comando podem ter um sem pertencer a um pacote de app. Portanto, leia-o na assinatura de código validada.

Devo salvar um requisito designado ou os campos Team ID e identificador?

Salve o requisito designado que pode ser avaliado pela máquina e mantenha o Team ID e o identificador de assinatura como informações legíveis de auditoria. Avalie o requisito com o Code Signing Services, em vez de analisar e comparar o texto impresso.

Um requisito designado prova que um processo é seguro?

Não. Ele prova que o código satisfaz uma expressão de identidade. Ainda é preciso decidir separadamente quais segredos e ações essa identidade pode usar, por quanto tempo e com qual aprovação humana.

Um caminho de executável pode fazer parte da autorização de processo?

Ele pode ser uma restrição adicional de localização depois que a identidade pela assinatura for confirmada. Um caminho sozinho é inseguro porque arquivos mudam de lugar e invasores podem substituir um arquivo em um local gravável aprovado.

Como um serviço deve identificar o processo em uma conexão IPC?

Derive o par a partir de dados de conexão fornecidos pelo kernel, como um token de auditoria, e então valide o objeto de código ativo correspondente. Nunca confie em um PID, caminho ou identificador enviado dentro da solicitação do cliente.

O que acontece com a autorização quando um app assinado é atualizado?

Um requisito designado escolhido corretamente deve permitir que atualizações legítimas satisfaçam a mesma identidade. Se o assinante, o identificador ou o canal de distribuição mudar fora desse requisito, exija uma migração explícita de identidade ou nova aprovação.

Posso autorizar permanentemente uma compilação de desenvolvimento sem assinatura?

Você pode, mas uma concessão permanente baseada em caminho não tem continuidade confiável do código. Prefira uma aprovação de desenvolvimento ligada ao tempo de vida do processo e à compilação exata, restrita a segredos que não sejam de produção, e peça aprovação novamente após cada recompilação.

Um processo filho deve herdar a identidade de seu processo pai assinado?

Não automaticamente. Se o processo filho se conecta, ele é o par direto. Percorrer a árvore de processos pode emprestar autoridade a descendentes substituídos. Passe uma capacidade com escopo por um canal controlado se a herança fizer parte do projeto.

Um hash de código é uma identidade melhor do que um Team ID?

Um hash identifica os bytes exatos do código, então funciona bem para uma exceção temporária de compilação sem assinatura. Ele não sobrevive a atualizações legítimas, enquanto Team ID mais identificador de assinatura, ou um requisito designado, podem expressar continuidade entre versões.

Sallyport

O Sallyport executa chamadas de API e comandos SSH pelo seu agente de IA. As chaves ficam em um cofre local no seu Mac; você aprova cada execução e toda ação vai para um registro selado.

© 2026 Sallyport · Código aberto sob Apache-2.0 · Oleg Sotnikov