A aprovação da sessão para substituição de processos sobrevive ao exec?
A aprovação da sessão para substituição de processos precisa de um limite claro: preserve a confiança apenas para a mesma imagem verificada e peça novamente para um novo executável.

Uma aprovação de sessão deve acompanhar uma identidade de execução verificada, não um identificador de processo do sistema operacional. Quando um processo chama exec, o kernel pode manter o PID enquanto substitui o código, os argumentos, o ambiente e, muitas vezes, a finalidade prática desse processo. Permitir que a aprovação anterior sobreviva a essa substituição dá a um código não analisado a autoridade que uma pessoa concedeu a outra coisa.
A regra que eu adotaria é simples: quando a substituição tiver uma identidade de executável diferente, será preciso pedir aprovação novamente antes que ela possa realizar ações com credenciais. Preserve a continuidade apenas em um reexec restritamente verificado da mesma imagem executável. Essa política cria uma solicitação extra ocasional em um fluxo legítimo. Ela fecha uma brecha muito mais perigosa em qualquer fluxo no qual um agente, iniciador, atualizador ou dependência comprometida possa escolher o que será executado em seguida.
A aprovação vincula um ator, não um PID
Um PID identifica uma posição de controle do kernel, enquanto uma aprovação precisa identificar o programa capaz de usar uma decisão humana. São funções diferentes, e tratá-las como o mesmo objeto causa problemas assim que um código começa outro código.
O Sallyport descreve a autorização por sessão como uma aprovação para um novo processo de agente que dura até o encerramento daquela execução. Essa é uma regra útil para quem usa o produto, mas a implementação precisa de uma definição interna mais precisa: a execução aprovada deve continuar sendo o executável aprovado, em vez de apenas manter o mesmo PID.
Essa diferença importa porque os segredos permanecem no gateway e o agente recebe resultados, não o material das credenciais. Esse modelo elimina o desastre conhecido em que um processo filho lê um token de uma variável de ambiente. Mas ele não impede que um processo substituído peça ao gateway para chamar uma API ou executar SSH com uma credencial armazenada. Se esse processo herdar a aprovação, poderá causar o mesmo dano externo sem jamais ver o segredo.
Deixe explícito quem é o sujeito da aprovação. Ele deve incluir uma identidade estável do executável, o evento de criação do processo ou um nonce de sessão, a autoridade de assinatura do código mostrada à pessoa e contexto suficiente de inicialização para explicar por que o processo existe. Use o PID como atributo de auditoria e como um identificador útil para solucionar problemas. Não o use como credencial de acesso.
Essa distinção também mantém a revogação honesta. Se uma pessoa revogar uma execução, o gateway deve negar chamadas posteriores dessa execução, mesmo que ela faça um reexec. Se uma substituição receber uma nova aprovação, deve receber um novo registro de sessão que possa ser revogado de forma independente.
O exec altera o executável mesmo quando o PID permanece
O exec deve redefinir a autorização quando carrega um programa diferente, porque substitui a imagem do programa mesmo que o sistema operacional preserve o PID. O POSIX diz que uma função exec «substitui a imagem do processo atual». A frase é curta, mas acerta o ponto principal: a continuidade é administrativa, não uma prova de que o mesmo ator continua em execução.
Um shell facilita não perceber isso. Um desenvolvedor inicia um agente aprovado, o agente chama um auxiliar e o auxiliar usa exec para não deixar um processo pai extra. As listagens de processos podem mostrar o mesmo PID antes e depois da substituição. Se a consulta da sessão disser pid 4127 is approved, o novo auxiliar terá a autoridade do agente anterior.
A mudança do executável também pode alterar o risco de formas que um PID não consegue descrever. A substituição pode se comunicar com outro host, interpretar um arquivo de repositório não confiável, carregar extensões, aceitar dados pela entrada padrão ou existir apenas para encaminhar solicitações de ação. Nenhum desses fatos aparece em um número de processo.
Não baseie a decisão em uma aparência familiar da nova linha de comando. Os argumentos são um contexto útil, mas um programa pode reescrevê-los, e um iniciador pode fazer um comando aparentemente inofensivo executar um destino sem relação. Estabeleça a identidade do executável a partir da imagem que o sistema operacional realmente iniciou. Depois, mantenha o caminho e os argumentos observados como evidências para a pessoa que analisa a solicitação.
posix_spawn pertence à mesma discussão de design, mas tem um resultado diferente. Ele cria um processo filho em vez de substituir a imagem do processo chamador. Por padrão, o filho não deve ter aprovação de sessão. Um fork seguido de exec deve chegar ao mesmo resultado: o novo processo solicita aprovação para a imagem que finalmente será executada.
Um novo executável precisa de uma nova aprovação
Um gateway deve exigir uma nova aprovação antes que um executável diferente possa realizar qualquer ação por meio de uma sessão já autorizada. Defina «diferente» usando uma identidade de imagem verificada, não um nome de arquivo nem um nome de exibição.
Um registro prático de identidade pode conter o identificador imutável do executável fornecido pela plataforma, um resumo do código assinado quando disponível, a autoridade de assinatura e o caminho concreto do executável observado na inicialização. Os dois primeiros campos respondem se a imagem mudou. O assinante informa à pessoa que analisará a solicitação quem assumiu a responsabilidade pelo código. O caminho mostra de onde veio a inicialização. Cada campo responde a uma pergunta diferente, portanto não os reduza a uma única string.
Este é o problema que faz a herança permissiva parecer atraente até ser tarde demais. Um agente de programação aprovado chama um auxiliar do repositório. O auxiliar vê uma configuração de ambiente e se substitui por um utilitário compilado localmente no mesmo caminho esperado. O utilitário não precisa extrair uma credencial de API. Ele pede uma ação HTTP que exclui uma implantação, altera uma configuração de cobrança ou publica uma versão. O gateway vê o PID antigo e aceita a chamada. A pessoa aprovou o agente de programação, não o utilitário que se escolheu depois da aprovação.
O argumento habitual a favor da aprovação herdada é o cansaço causado por solicitações repetidas. Essa preocupação é real, mas permitir qualquer substituição não resolve o problema. Isso apenas esconde uma decisão da única pessoa capaz de julgar se a substituição faz sentido. Mantenha os cartões de aprovação raros tornando a execução normal do agente estável. Depois, peça novamente quando o ator mudar.
A verificação precisa acontecer antes da injeção de credenciais, da execução de SSH ou de qualquer outra ação de saída. Também deve acontecer antes que o gateway devolva metadados capazes de ajudar uma substituição a planejar uma ação. Uma aprovação pendente não é um estado parcialmente autorizado.
O reexec da mesma imagem é a exceção restrita
Um reexec verificado da mesma imagem executável exata pode manter a aprovação da sessão, porque não introduz um novo ator. Os programas usam o próprio reexec para reinicializações limpas, descritores de arquivo alterados ou uma transferência deliberada depois de atualizar o próprio ambiente. Exigir um novo cartão nesse caso acrescenta ruído sem acrescentar uma decisão relevante.
Mantenha a exceção restrita. O gateway deve comparar a imagem observada atual com a imagem que recebeu aprovação. Se a identidade for idêntica, ele pode manter o nonce da sessão e registrar um evento de continuidade no log de auditoria. Se não conseguir estabelecer essa identidade, deve pedir novamente. Ambiguidade não é prova de que a substituição é segura.
Não transforme isso em uma exceção para toda a autoridade de assinatura. Um assinante pode publicar um agente, um instalador, uma ferramenta de diagnóstico e um utilitário de rede. Esses programas podem ter autoridades de ação muito diferentes. A autoridade de assinatura exibida ajuda a pessoa a julgar a solicitação, mas não deve estender silenciosamente a aprovação a todo binário que carregue a mesma autoridade.
Também não transforme isso em uma exceção para todo o caminho. Uma atualização automática pode substituir os bytes em um caminho fixo. Um link simbólico pode apontar para outro lugar depois da aprovação. Um script pode manter o nome do arquivo enquanto seu conteúdo muda. A comparação de identidade precisa resistir aos três casos.
Quando uma atualização legítima instalar uma nova versão do agente, deixe que ela peça novamente. Essa solicitação comunica um fato real: o executável que atuará mudou. Quem considera a atualização rotineira poderá aprová-la com um clique. Quem não esperava a mudança terá a chance de interrompê-la.
A autoridade de assinatura ajuda as pessoas a julgar, mas não concede escopo
Mostre a autoridade de assinatura do código com destaque, porque ela responde a uma pergunta que as pessoas realmente têm: quem distribuiu este executável? Não confunda essa resposta com uma regra completa de autorização.
O modelo de assinatura de código da Apple dá ao macOS uma forma de identificar código assinado e verificar sua integridade de acordo com as regras de confiança aplicáveis. Isso é uma evidência forte para o cartão de aprovação. Mas não significa que todo código de uma autoridade tenha a mesma finalidade operacional, nem informa ao gateway se um processo pai selecionou o executável por meio de uma configuração não confiável do repositório.
Um bom cartão de aprovação coloca primeiro o nome e o caminho do executável, depois a autoridade de assinatura, a identidade do processo pai e o motivo da nova solicitação. Em uma substituição por exec, ele deve apresentar os dois lados da mudança em uma frase: o agente aprovado substituiu a si mesmo por este executável. A pessoa não deve precisar deduzir a transição comparando dois avisos desconectados.
Casos assinados e não assinados devem respeitar o mesmo limite. Uma compilação local não assinada pode ser esperada em um fluxo de desenvolvimento, e um utilitário assinado ainda pode ser o processo errado para herdar autoridade. O cartão deve descrever as evidências sem fingir que uma assinatura transforma um novo executável no anterior.
Evite rótulos vagos como «processo confiável». Eles incentivam as pessoas a aprovar uma categoria em vez de uma solicitação concreta. Dê nome ao executável e mostre sua relação com o processo já aprovado. Assim, a pessoa que analisa terá algo que poderá reconhecer ou rejeitar.
Scripts e iniciadores expõem o limite frágil
Uma execução iniciada por script tem duas identidades: o interpretador que executa e o script cujo conteúdo controla a execução. Se você verificar apenas o interpretador, todo script de shell parecerá ser o mesmo shell. Se verificar apenas o script, poderá não perceber um interpretador selecionado por uma linha shebang ou por um wrapper.
Para um script de shell, registre a identidade do executável do interpretador, o caminho resolvido do script e um resumo do conteúdo do script. Se o script for executado por um shell aprovado e esse shell usar exec para iniciar outro binário, a substituição do binário ainda exigirá uma nova aprovação. Um script não deve se tornar um túnel através do limite da sessão.
Os iniciadores criam um problema relacionado. Um iniciador aprovado pode analisar um arquivo de configuração, encontrar uma ferramenta em PATH, baixar um auxiliar ou escolher um diretório de versão. É comum aprovar o iniciador e tratar o destino escolhido como parte da mesma execução. Essa regra está errada quando o iniciador faz a escolha relevante para a segurança depois de receber a aprovação da pessoa.
Use uma destas abordagens. Se o iniciador souber qual é o destino antes da primeira chamada ao gateway, deixe o cartão mostrar o destino final e aprove essa identidade de execução. Se ele escolher mais tarde, deixe-o funcionar sem autoridade de ação e exija aprovação quando o destino selecionado pedir para agir pela primeira vez. A segunda opção produz um registro de auditoria mais honesto.
A mesma regra vale para plug-ins de runtime e interpretadores incorporados. Um host nativo pode permanecer inalterado enquanto carrega código de um diretório do projeto. Se esse código puder formular solicitações ao gateway, a identidade da imagem do host, sozinha, não descreverá o ator prático. O gateway não consegue inspecionar todos os runtimes com segurança. Por isso, o padrão mais seguro é limitar a aprovação da sessão a um executável de agente definido e exigir uma nova decisão quando ele transferir o controle das ações a um programa externo.
Filhos e exec são casos diferentes de delegação
Um processo filho não deve herdar a aprovação da sessão apenas porque seu processo pai a possui. A criação de um processo introduz um novo ator, enquanto o exec substitui o ator atual. Nos dois casos, é preciso obter uma nova aprovação quando um executável diferente fizer chamadas ao gateway, mas as relações de auditoria são diferentes.
Para um filho, crie um novo candidato a sessão com uma referência à sessão pai. Mostre o processo pai no cartão de aprovação porque ele fornece contexto útil, não porque concede permissão. Se a pessoa aprovar o filho, dê a ele seu próprio nonce de sessão e seu próprio controle de revogação.
Para exec, encerre ou substitua a identidade do executável anterior e crie um candidato substituto vinculado à sessão anterior. Se a nova imagem corresponder exatamente à imagem aprovada, mantenha a continuidade e registre esse resultado. Se for diferente, pare no ponto de controle e aguarde uma decisão. Assim, você evita um único registro de sessão grande que contenha vários programas sem relação entre si.
Não crie um token de delegação geral para que um processo pai o entregue a filhos ou substitutos. Um token que diga «qualquer coisa que eu iniciar pode agir» vira um prêmio fácil para um agente comprometido ou um wrapper confuso. Uma referência ao processo pai no diário é suficiente para contar a história sem transformar a ancestralidade em autoridade.
Essa separação também melhora a análise de incidentes. Você consegue responder se o processo pai iniciou um filho, se substituiu a si mesmo e se uma pessoa aprovou o executável resultante. Um registro plano de solicitações permitidas não consegue responder a essas perguntas depois de uma ação indevida.
Registre a substituição como um evento próprio
Um log de auditoria deve mostrar uma substituição por exec como um evento distinto, independentemente de o gateway ter preservado a aprovação ou pedido novamente. Sem esse evento, a pessoa que analisa vê ações de uma sessão e pode presumir que um único executável estável realizou todas elas.
Um contrato de design pode ter esta aparência. Este é um exemplo das informações a persistir, não um formato de comunicação obrigatório:
{
"event": "execution_replaced",
"session_id": "sess_8f2c",
"previous_image": {
"identity": "image:4f19...",
"path": "/work/agent/bin/agent"
},
"current_image": {
"identity": "image:b66a...",
"path": "/work/agent/bin/release-helper",
"signing_authority": "Example Development Team"
},
"decision": "approval_required",
"parent_relation": "exec"
}
O evento precisa das identidades anterior e atual, não apenas de uma declaração de que ocorreu um exec. Também precisa do resultado da decisão. Um registro de ação posterior deve fazer referência à identidade da sessão atual para que uma investigação consiga associar a ação à aprovação que a permitiu.
Mantenha esse registro somente para acréscimos, junto com o restante do histórico de ações. O log de auditoria criptografado e encadeado por hash do Sallyport e a verificação offline sp audit verify são especialmente úteis aqui, porque o evento de substituição e as ações posteriores podem compartilhar uma sequência verificável. O resultado da verificação confirma que a sequência armazenada não mudou. Ele não torna aceitável uma política de aprovação ampla demais.
Quando uma pessoa revogar uma sessão, registre a revogação contra a identidade do executável que mantinha a sessão. Se uma substituição tiver recebido uma nova aprovação, ela deve continuar visível separadamente. Esse detalhe impede que um controle de revogação sugira uma cobertura mais ampla do que realmente oferece.
Um cartão de aprovação precisa mostrar os fatos anteriores e posteriores
Um cartão de nova aprovação depois de um exec deve explicar a substituição de imediato e facilitar a escolha segura. Avisos genéricos treinam as pessoas a passar por eles sem ler. Um cartão que nomeia o executável alterado dá um motivo para parar apenas quando algo realmente mudou.
Comece pela identidade do novo executável e pelo canal de ação que ele quer usar. Depois, mostre que um processo já aprovado o iniciou, o nome e o caminho do executável anterior, o novo caminho e a autoridade de assinatura do código. Se a substituição vier de um script ou iniciador, inclua essa relação em linguagem simples.
Use um modelo de decisão que mostre exatamente o que a pessoa está aprovando. Aprovar a substituição deve autorizar a execução desse executável até que ela termine, sujeita ao bloqueio do cofre e a qualquer credencial marcada para aprovação a cada chamada. Isso não deve autorizar retroativamente processos irmãos, substituições futuras ou um arquivo atualizado no mesmo caminho.
Há um teste útil para o texto: um desenvolvedor cansado conseguiria distinguir um auxiliar esperado de um baixador inesperado? Se não, o cartão não mostra os fatos importantes. Mais linguagem decorativa sobre segurança não resolverá isso.
Mantenha o número de solicitações baixo por meio de uma execução estável, não de uma herança ampla. Um agente normal que mantenha uma única imagem deve mostrar um cartão de sessão. Um processo que mude de ator deve mostrar um cartão, porque atravessou exatamente o limite que o conceito de sessão existe para impor.
Crie testes em torno das evasões que as pessoas realmente usam
Teste o limite de autorização com substituições que preservem identificadores superficiais. Testes de caminho feliz com um binário estável não encontrarão os erros que entregam autoridade ao executável errado.
Comece com estes casos:
- Um binário aprovado faz um reexec de uma cópia exata de si mesmo. O gateway preserva a sessão e registra um evento de continuidade.
- O binário faz um reexec de um executável assinado diferente da mesma autoridade. O gateway nega as ações até que a pessoa aprove a nova execução.
- Um link simbólico mantém a mesma string de caminho, mas aponta para um executável diferente. O gateway pede uma nova aprovação.
- Um script de shell muda de conteúdo depois do início da sessão. A próxima solicitação controlada pelo script não reutiliza a decisão anterior.
- Um iniciador inicia um processo filho e o filho tenta realizar uma ação HTTP ou SSH. O filho precisa de sua própria decisão de sessão.
Depois, teste a ordem dos eventos. Faça a substituição emitir uma solicitação de ação imediatamente depois do exec. Confirme que o gateway a nega ou a mantém pendente, e confirme que nem a injeção de credenciais nem a execução de SSH começam antes da chegada do resultado da aprovação. Isso detecta implementações que atualizam o diário depois de já terem enviado o trabalho para execução.
Teste a revogação no mesmo conjunto. Revogue uma execução aprovada, tente um reexec da mesma imagem e confirme que o estado revogado prevalece. Aprove uma nova substituição, revogue apenas a sessão original e confirme que os dois registros se comportam de acordo com os controles declarados do produto. Um modelo de sessão conquista confiança quando seus casos extremos se comportam como sua linguagem visível.
Por fim, examine o resultado da auditoria como uma pessoa faria. Deve ser possível rastrear uma ação até um evento de substituição e, depois, até o cartão de aprovação que cobriu o executável. Se a resposta exigir correlacionar PIDs, deduzir informações a partir de horários ou confiar em um caminho que pode ter mudado, ainda há uma brecha no modelo.
A substituição de um processo é o momento de ser rigoroso. O código anterior tinha uma decisão. O código novo precisa da sua própria.
FAQ
O exec mantém a mesma identidade do processo para fins de aprovação?
Não. O exec normalmente mantém o identificador do processo no sistema operacional, mas substitui a imagem do programa que esse identificador representa. Tratar o PID como identidade de aprovação permite que um programa diferente herde uma autoridade que nunca foi apresentada a uma pessoa.
Uma chamada exec deve exigir uma nova aprovação?
Exija uma nova aprovação sempre que a identidade do executável mudar. Um reexec restritamente definido da mesma imagem verificada pode manter a sessão, mas a correspondência do caminho ou apenas do assinante é ampla demais.
O caminho do executável é suficiente para manter uma sessão?
Não. Um caminho indica uma localização, não prova o que será executado. Um atualizador, uma troca de link simbólico, um arquivo substituído ou um interpretador alterado podem manter o caminho igual enquanto mudam o código que recebe autoridade para realizar ações com credenciais.
A autoridade de assinatura do código é suficiente para confiar em um executável substituto?
Isso ajuda a pessoa a reconhecer quem publicou o programa e deve aparecer no cartão de aprovação. Mas não prova que todo executável desse publicador merece a mesma permissão, nem mostra qual script, quais argumentos ou qual processo pai o iniciou.
Como a aprovação da sessão deve lidar com scripts de shell?
Aprove o interpretador como a imagem que executa o código e mostre a identidade e o resumo do script como contexto. Se o script mudar, trate isso como uma solicitação alterada, mesmo que o binário do interpretador continue igual.
Qual é a diferença entre um processo filho e uma substituição por exec?
São decisões separadas. Um processo filho começa como um novo processo e deve solicitar autorização com sua própria identidade. Uma substituição por exec altera a imagem dentro de um processo existente e deve reiniciar a autorização quando essa imagem mudar.
O que um registro de auditoria deve guardar quando um processo executa outro programa com exec?
Registre a imagem anterior, a imagem substituta, a relação com o processo pai, o horário, a decisão de aprovação e qualquer identificador de sessão herdado. O registro de auditoria deve deixar claro se o gateway permitiu a continuidade ou pediu uma nova decisão à pessoa.
Um iniciador aprovado pode passar sua sessão para outro programa?
Não torne a aprovação transferível apenas porque um iniciador é assinado ou aprovado. Aprove o executável final que realizará as ações ou faça o iniciador pedir uma nova aprovação depois de descobrir e iniciar esse executável.
Quais casos de exec devo testar antes de lançar?
Teste substituições por meio de um link simbólico, um script modificado, um interpretador alterado, uma atualização no próprio arquivo e um iniciador que escolhe um auxiliar durante a execução. Teste também se substituições negadas não conseguem usar nenhum canal com credenciais antes que a nova aprovação seja concluída.
O que um aviso de nova aprovação deve mostrar depois de um exec?
Mostre os nomes, caminhos e autoridades de assinatura do executável anterior e do novo, além do motivo pelo qual o gateway considera a solicitação nova. Uma pessoa consegue decidir rapidamente quando o cartão explica a mudança com clareza, em vez de exibir um aviso genérico de confiança.