omp packages

@igor-guari/pi-sudo-prompt0.1.3

Prompt seguro de senha do sudo para o Pi Coding Agent — modal mascarado via SUDO_ASKPASS; a senha nunca passa pelo modelo

igor-guari Published 1 hour ago MIT ~358 downloads/mo

Untested on omp

This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

Readme

pi-sudo-prompt

Prompt seguro de senha do sudo para o Pi Coding Agent, no estilo do Sudo password prompting do Cursor.

Quando o agente (ou você, via !/!!) roda um comando com sudo, o pi abre um modal Sudo Authentication Required com campo mascarado. A senha vai direto para o sudo e nunca passa pelo modelo: não aparece no output do tool, na sessão nem no histórico.

pi-sudo-prompt

Versão texto
╭────────────────────────────────────────────────────────────────────╮
│ 🔐 Sudo Authentication Required                                    │
│                                                                    │
│ Command: sudo apt update                                           │
│                                                                    │
│ [sudo] senha para movida:                                          │
│                                                                    │
│ Password: ••••••••                                                 │
│                                                                    │
│ Press Enter to submit, Escape to cancel · auto-cancel in 1:54      │
│                                                                    │
│ Your password is secure and will not be visible to the AI model.   │
╰────────────────────────────────────────────────────────────────────╯

Instalação

pi install npm:@igor-guari/pi-sudo-prompt
# ou
pi install git:github.com/IgorGuariroba/pi-sudo-prompt@v0.1.3

Requer Linux e o pi no modo interativo (TUI).

Como funciona

agente: sudo whoami
        │
        ▼
   sudo -A  ──exec──►  pi-askpass  (SUDO_ASKPASS)
        ▲                   │  valida: pai é sudo/doas com euid 0 e stdout é o pipe do sudo
        │ stdout (senha)    │  Unix socket privado + HMAC
        │                   ▼
        │            extensão (sessão do pi)
        │                   │  revalida o processo solicitante
        │                   ▼
        │            modal "Sudo Authentication Required"
  1. Na sessão, a extensão cria um diretório privado ($XDG_RUNTIME_DIR/pi-sudo-prompt-*, modo 0700) com o socket e o launcher pi-askpass.
  2. Cada comando do bash tool e dos comandos !/!! recebe SUDO_ASKPASS, PI_ASKPASS_SOCKET, PI_ASKPASS_SECRET e uma função sudo() que acrescenta -A. A função não acrescenta -A quando o comando já usa -S/--stdin ou -A.
  3. O sudo executa o launcher, que limpa o ambiente (env -i) e inicia o auxiliar com o prompt ([sudo] senha para movida:). O auxiliar confere se o processo pai é sudo/doas rodando como root e se o stdout é o pipe privado do sudo (FIFO com dono root, modo 600). Depois envia um password_request assinado.
  4. A extensão revalida tudo no /proc antes de abrir o modal: pai é sudo privilegiado; argv exato node askpass.mjs <prompt>; interpretador esperado; ambiente exatamente o do launcher (sem NODE_OPTIONS, LD_PRELOAD etc.); stdout é o pipe do sudo.
  5. Enter responde com password_response; Escape, o timeout de 120 s ou o fim do sudo (por abort do tool, por exemplo) respondem com password_denied.
  6. O auxiliar imprime a senha no pipe do sudo e termina. Se a senha estiver errada, o sudo pede de novo, e o modal mostra Incorrect password, try again (2/3).

Cancelar conta como tentativa falha: para o PAM, um askpass cancelado (Escape ou timeout) é uma falha de autenticação, exatamente como no sudo sem a extensão. Com o pam_faillock padrão, 3 falhas em 15 minutos bloqueiam o sudo por 10 minutos. Para liberar antes: faillock --user "$USER" --reset.

Cache de credenciais: sem TTY, o sudo (com o padrão timestamp_type=tty) guarda o cache por processo pai, e cada comando do agente roda num shell novo. Por isso cada comando com sudo abre o modal de novo. Agrupe as etapas num único comando (sudo apt update && sudo apt upgrade -y) para autenticar uma vez só. Dentro do mesmo comando, o cache vale normalmente.

Limites

  • Só Linux. A validação usa /proc. O suporte a macOS fica para depois.
  • Só no modo interativo. Em pi -p, --mode json e RPC nada é injetado, e o sudo se comporta como sem a extensão.
  • Substitui o tool bash. A extensão registra seu próprio bash (mesma implementação e renderização do built-in, com shellCommandPrefix/shellPath das settings). Outra extensão que também substitua o bash vai conflitar.
  • A função sudo() só existe no shell do comando. Scripts filhos e xargs sudo ainda usam o modal (sem TTY, o SUDO_ASKPASS basta), mas não recebem o -A forçado.

Modelo de ameaça

A senha nunca entra no contexto do modelo nem nos registros da sessão. Além disso, a extensão resiste a um agente que tente desviar a senha usando o próprio mecanismo de askpass. Todos estes casos são recusados antes de o modal abrir e estão cobertos por test/exfiltration.test.mjs com o sudo real:

  • SUDO_ASKPASS apontando para um wrapper que roda o auxiliar com stdout redirecionado (arquivo, fifo com leitor em background, pipe próprio). O pipe legítimo é criado pelo sudo como root, e um processo do seu usuário não consegue criar nem reabrir um pipe assim.
  • Injeção de código no auxiliar via NODE_OPTIONS, --import no argv ou wrapper que contorna o launcher.

O que não é coberto: um agente que altere arquivos que pertencem a você (askpass.mjs, protocol.mjs, a extensão em ~/.pi/agent/..., o binário node do nvm). Qualquer código que rode como o seu usuário pode ser trocado por outro processo do seu usuário. Isso só se resolve com um auxiliar de dono root, previsto como modo blindado opcional numa versão futura. Até lá: o modal mostra o comando que será autorizado, confira antes de digitar, e desconfie de transcripts em que o agente edita arquivos da extensão ou do node.

Desenvolvimento

npm test                      # protocolo, auxiliar, função sudo() e ataques de exfiltração (sudo real, sem autenticar)
pi install ./                 # carrega a cópia local

Decisões de arquitetura em docs/adr/.

Licença

MIT