playwright-secure-mcp
Wrapper em torno do servidor MCP Playwright com o objetivo de manter segredos da IA
Documentação
playwright-secure-mcp
Um servidor MCP em Crystal que faz proxy de forma transparente para o
servidor MCP do Playwright
(@playwright/mcp) e adiciona manipulação segura de senhas. Seu objetivo: um valor
de segredo resolvido nunca chega acidentalmente ao LLM.
Como funciona
- O binário fala MCP JSON-RPC 2.0 via stdio com o cliente (o host do LLM)
e inicia
@playwright/mcpcomo um processo filho stdio, encaminhando quase todas as mensagens sem alteração. - Ele adiciona quatro ferramentas de segredo ao
tools/listupstream: três ferramentas de descoberta que listam ou encontram itens LOGIN do 1Password utilizáveis na página atual do navegador, ebrowser_type_secret, que digita um campo de um item escolhido na página. Fechar o navegador (browser_close) esvazia o cache local de itens. Veja Ferramentas de segredo. - Cada mensagem que flui de volta ao cliente passa por um redator que
substitui cada segredo resolvido — incluindo suas variantes codificadas em URL, Base64,
HTML e JSON — pelo token literal
«REDACTED». Os segredos são capturados onde quer que apareçam: snapshots de página, dumps de requisições de rede, mensagens de console e texto de erro.
Ferramentas de segredo
Descoberta: listar ou encontrar itens para a página atual
Três ferramentas consultam itens LOGIN do 1Password e retornam apenas aqueles utilizáveis na
página atual do navegador: o proxy lê o location.href da página por conta própria (o
chamador nunca fornece uma URL) e mantém um item apenas quando uma de suas URLs
corresponde à página por host e prefixo de caminho. Se a URL atual não puder ser
determinada, a descoberta falha com um erro. Os resultados são um array JSON de identidades
de itens mais metadados de campos não secretos — vault, item, title, urls,
tags, fields (id, rótulo, tipo, propósito, seção) e sections — nunca um
valor de campo. Todas as três aceitam um vault opcional (ID ou nome) para limitar a
busca.
| Ferramenta | Argumentos obrigatórios | Resultado |
|---|---|---|
browser_list_items | (nenhum) | Todos os itens LOGIN utilizáveis na página atual |
browser_find_items_by_name | item (título ou ID) | Itens correspondentes, filtrados para a página atual |
browser_find_items_by_tag | tag | Itens com a tag, filtrados para a página atual |
Digitação: browser_type_secret
Espelha a ferramenta browser_type upstream, mas em vez de um valor literal text,
recebe as coordenadas 1Password do segredo:
- Obrigatórios:
element,ref(como embrowser_type),vault(ID do cofre 1Password),item(ID do item 1Password),field(ex.:usernameoupassword) - Opcionais:
submit,slowly(como embrowser_type)
O proxy resolve o campo do item em cache (buscando o item do
1Password sob demanda quando não está em cache), descriptografa o valor localmente e
emite uma chamada interna browser_type ao servidor upstream com o valor
resolvido. A digitação é recusada a menos que a página atual esteja no conjunto de URLs do item (a
mesma correspondência de host + prefixo de caminho da descoberta), e recusada quando a URL
da página atual não puder ser determinada.
Vida útil do cache
Itens descobertos — com seus valores de campo criptografados — são armazenados em cache
na memória, com escrita única. Chamar a ferramenta browser_close upstream esvazia esse cache (o
fechamento ainda é encaminhado ao navegador como de costume); caso contrário, ele dura
pela vida útil do processo.
Fluxo de trabalho: encontrar, depois digitar
- Navegue até a página de login e chame uma ferramenta de descoberta — ex.:
browser_list_items— para obter os IDsvaulteitemde um item utilizável nessa página. - Chame
browser_type_secretcom esses IDs e ofieldpara digitar.
Instalação
Homebrew (macOS e Linux)
Instale a partir do tap Homebrew. A fórmula instala o binário pré-compilado da última versão do GitHub (os builds para macOS são assinados e notarizados):
brew install jochenseeber/tap/playwright-secure-mcp
Isso coloca playwright-secure-mcp no seu PATH. Ainda é necessário o CLI do 1Password
(op) e um servidor MCP do Playwright — veja Requisitos.
Para compilar a partir do código-fonte, veja Compilação.
Requisitos
- Crystal
>= 1.20 - O CLI do 1Password (
op), conectado pnpmounpmpara baixar@playwright/mcpsob demanda, ou um binário pré-instalado do servidor MCP do Playwright
Compilação
rake setup
rake build
rake build grava um binário de depuração em
bin/<profile>-<mode>/playwright-secure-mcp (ex.:
bin/darwin-arm64-system-dynamic-debug/…) e um symlink bin/playwright-secure-mcp
para a compilação mais recente. Use rake "build[release]" para um binário de versão.
Execute rake -T para listar todas as tarefas disponíveis.
Opções
| Opção | Padrão | Significado |
|---|---|---|
--package-manager | pnpm | pnpm (pnpm dlx), npm (npx -y) ou none (pré-instalado) |
--mcp-version | latest | Tag/intervalo de versão @playwright/mcp (ignorado quando none) |
--mcp-bin | mcp-server-playwright | Binário pré-instalado; implica --package-manager none |
--command | (nenhum) | Substituição explícita do comando upstream |
--op-command | op | Binário do CLI do 1Password |
--account-from-git | (nenhum) | Ler o e-mail da conta de DIR/.git/config (user.email) |
--account | (nenhum) | Conta 1Password (abreviação, e-mail de login ou ID da conta) |
--account-email | (nenhum) | E-mail da conta 1Password |
--token-tag | (nenhum) | Tag do item 1Password cujo campo credential contém um token de conta de serviço |
--require-hardware-key | (desativado) | Recusar iniciar sem proteção de chave Secure Enclave/TPM |
--version | (nenhum) | Imprimir a versão e sair |
-- <args...> | (nenhum) | Argumentos extras encaminhados ao servidor upstream |
As três opções de conta resolvem para uma única conta passada a op via
--account; quando mais de uma é fornecida, a precedência é --account-from-git >
--account-email > --account. Com --token-tag, a conta resolvida é
usada uma vez na inicialização (op interativo) para buscar o campo credential
do item marcado, e esse valor é então usado como OP_SERVICE_ACCOUNT_TOKEN para toda
resolução subsequente de segredos — nesse modo, --account não é passado para
op read. Sem --token-tag, cada op read usa a conta resolvida
diretamente.
Configuração do cliente MCP
{
"mcpServers": {
"playwright": {
"command": "/path/to/bin/playwright-secure-mcp",
"args": ["--", "--headless"]
}
}
}
Modelo de segurança
- O segredo resolvido viaja
op→ este processo → filho upstream → navegador. Ele nunca está presente em nada que o LLM enviou e nunca está presente sem redação em nada que o LLM recebe. - Itens revelados são armazenados em cache na memória pela vida útil do processo (ou até o
navegador ser fechado via
browser_close) em um cofre ofuscado: cada valor de campo é criptografado com AES-256-CBC sob uma chave de dados aleatória por processo com um IV aleatório novo por entrada. A própria chave de dados é protegida por hardware quando possível — veja Proteção da chave do cache. - Ressalva: o cofre é ofuscação / defesa em profundidade, não um limite
de segurança. Com a camada de fallback em memória, a chave de criptografia vive na
mesma memória do processo que o texto cifrado, então isso impede inspeção casual de heap,
varredura estilo
stringse registro acidental de texto simples — mas não um atacante com acesso total à memória do processo. Uma camada com suporte a hardware remove a chave de longa duração da memória do processo, mas veja as limitações abaixo.
Proteção da chave do cache
Na inicialização, o proxy escolhe a melhor camada de proteção disponível para a chave de dados AES-256 do cofre e registra a escolha:
- Secure Enclave (macOS, hardware): uma chave P-256 efêmera e não extraível é gerada dentro da Secure Enclave, e a chave de dados é encapsulada com ECIES sob ela. A chave encapsulada é desencapsulada na enclave por lote criptográfico e a chave em texto simples é zerada depois; a chave de longa duração nunca existe na memória do processo ou em disco.
- TPM 2.0 (Linux, hardware): a chave de dados é selada dentro do TPM
da plataforma via biblioteca ESYS do tpm2-tss sobre
/dev/tpmrm0e desselada transitoriamente por lote criptográfico, depois zerada. O binário vincula tpm2-tss, que é considerado presente no host. - Anel de chaves do kernel (Linux, não hardware): a chave de dados é armazenada no anel de chaves do kernel e o AES roda no kernel via um socket AF_ALG, então a chave nunca reentra na memória do processo — mas é suportada pelo kernel, não por hardware. Requer Linux ≥ 5.4.
- Em memória (fallback): uma chave simples por processo, com um aviso na inicialização de que a proteção com suporte a hardware não está disponível.
No Linux, a ordem é TPM → anel de chaves → em memória. Passe --require-hardware-key
para falhar de forma fechada: o proxy recusa iniciar a menos que uma camada com suporte a hardware
(Secure Enclave / TPM) seja inicializada. A camada do anel de chaves do kernel não
satisfaz --require-hardware-key.
Requisito de implantação (macOS): a Secure Enclave só é utilizável quando o
binário distribuído está assinado com a permissão apropriada (Secure
Enclave / acesso ao chaveiro). Um binário não assinado não pode gerar uma chave de enclave
(Security.framework falha com OSStatus -26276) e cai para a
chave no processo — ou recusa iniciar sob --require-hardware-key.
Limitações:
- A chave de dados desencapsulada está na memória do processo transitoriamente por lote criptográfico e depois é zerada com melhor esforço.
- O texto simples do segredo descriptografado ainda transita pela memória do processo durante a redação e digitação (fora do escopo; exigiria um processo auxiliar).
- Custo por mensagem no caminho crítico com a Secure Enclave é de ~2–20 ms (um desencapsulamento de chave por lote de mensagens).
Testes
rake spec
rake lint