netrc no Python: credenciais por host

Publicado em: 08/08/2026
Tempo de leitura: 7 minutos
Cadeado digital representando credenciais por host com netrc no Python

Ferramentas de linha de comando, clientes FTP, scripts de automação e bibliotecas HTTP frequentemente precisam localizar credenciais sem exigir que o usuário digite login e senha a cada execução. O formato .netrc surgiu no ecossistema Unix para armazenar autenticação por host. O módulo netrc no Python lê esse arquivo, valida sua sintaxe e oferece uma API simples para consultar login, conta e senha.

Apesar da conveniência, um arquivo de credenciais exige cuidados rigorosos. Permissões abertas, logs acidentais, backups inseguros e uso do host errado podem expor segredos. Este guia mostra como analisar o arquivo, lidar com a entrada default, interpretar erros, proteger permissões e decidir quando usar um cofre de segredos em vez de um arquivo local.

O conteúdo complementa nossos guias sobre shlex, tempfile, atexit, zoneinfo e mimetypes.

Estrutura básica do arquivo

Uma entrada comum possui a palavra machine, o nome do host e os campos de autenticação.

machine api.exemplo.com
    login usuario
    password senha-secreta

O campo account também pode existir, embora muitos serviços modernos não o utilizem.

Localização padrão

Quando nenhum caminho é informado, netrc.netrc() procura .netrc no diretório pessoal determinado por os.path.expanduser().

from netrc import netrc

credenciais = netrc()

Se o arquivo padrão não existir, a inicialização gera FileNotFoundError. Isso permite distinguir claramente a ausência da configuração de um erro de sintaxe.

Ler um arquivo específico

from netrc import netrc

credenciais = netrc("/etc/minha-app/credenciais.netrc")

Ao fornecer um caminho explícito, você controla onde a configuração fica armazenada. Em serviços, prefira um diretório com permissões restritas e proprietário definido durante o deploy.

Consultar um host

authenticators() retorna uma tupla com login, account e password.

auth = credenciais.authenticators("api.exemplo.com")
if auth is None:
    raise RuntimeError("host sem credenciais")

login, account, password = auth

O retorno pode conter strings vazias quando campos foram omitidos. Valide os valores exigidos pelo seu cliente antes de iniciar a conexão.

A entrada default

O formato permite uma entrada especial usada quando o host solicitado não possui configuração própria.

default
    login convidado
    password senha-padrao

authenticators() consulta primeiro o host exato e depois default. Esse fallback é conveniente, mas pode enviar uma credencial genérica ao destino errado. Em sistemas sensíveis, evite default ou imponha uma lista explícita de hosts autorizados.

Permissões em sistemas POSIX

Quando o arquivo padrão contém senhas, o Python verifica proprietário e permissões em plataformas com os.getuid(). Se outro usuário puder ler ou escrever o arquivo, uma NetrcParseError será gerada.

chmod 600 ~/.netrc

O arquivo deve pertencer ao usuário que executa o processo. Em containers, confirme o UID efetivo e o proprietário do volume montado.

Limitações em outras plataformas

Sistemas sem suporte a os.getuid() não aplicam a mesma verificação automática. Isso não significa que permissões sejam irrelevantes. Use ACLs, proteção do perfil, criptografia de disco e políticas de acesso adequadas ao sistema operacional.

Tratar erros de sintaxe

Erros de parsing geram NetrcParseError, que contém mensagem, arquivo e número da linha.

from netrc import netrc, NetrcParseError

try:
    config = netrc()
except NetrcParseError as erro:
    print(erro.msg)
    print(erro.filename)
    print(erro.lineno)

Mostre informações suficientes para o operador corrigir o arquivo, mas nunca registre o conteúdo da linha se ela puder conter senha.

UTF-8 e caracteres especiais

Desde Python 3.10, o parser tenta UTF-8 antes do encoding específico da localidade. Campos podem conter caracteres não ASCII e whitespace. Mesmo assim, interoperabilidade com ferramentas antigas pode variar.

Quando o arquivo será compartilhado com clientes externos, teste acentos, espaços e caracteres especiais no ambiente real.

Campos opcionais

Versões modernas não exigem todos os tokens. Campos ausentes recebem string vazia.

machine somente-token.exemplo
    password abc123

Uma biblioteca pode aceitar esse resultado, mas sua aplicação deve declarar quais campos são obrigatórios. Falhar cedo produz diagnósticos melhores do que um erro remoto de autenticação.

Inspecionar o dicionário hosts

A instância expõe hosts, um dicionário de host para tupla de autenticação.

for host in credenciais.hosts:
    print(host)

Não imprima os valores completos. Ferramentas de diagnóstico devem mostrar apenas nomes de hosts e a presença dos campos, nunca as senhas.

Macros

O formato histórico permite macros, disponíveis no atributo macros. Elas foram criadas para clientes FTP e são raras em aplicações modernas.

Se você apenas precisa de credenciais, ignore macros e não execute seu conteúdo como comandos. O parser devolve texto; interpretá-lo como shell ampliaria muito a superfície de ataque.

Representação com repr

repr(config) gera uma representação no formato netrc, descartando comentários e podendo reordenar entradas.

Como essa saída contém segredos, não a envie a logs, mensagens de erro ou ferramentas de monitoramento. Também não a use para editar o arquivo preservando comentários.

Integração com um cliente HTTP

def credencial_para(host: str):
    auth = config.authenticators(host)
    if auth is None:
        raise LookupError(f"credencial ausente para {host}")
    login, _, password = auth
    if not login or not password:
        raise ValueError("login ou senha vazio")
    return login, password

Valide o host antes da consulta. Não permita que uma URL fornecida por usuário selecione arbitrariamente credenciais internas.

Risco de redirecionamento

Clientes HTTP podem seguir redirecionamentos para outro domínio. Garanta que o cabeçalho de autorização não seja reenviado a um host diferente. A política deve comparar nomes normalizados e, quando necessário, portas e esquemas.

Host e porta

Uma entrada netrc normalmente usa nome de máquina, não uma URL completa. Defina uma convenção para serviços em portas diferentes e confirme como a biblioteca consumidora procura a entrada.

Não concatene dados sem normalização. Hosts são case-insensitive, podem possuir ponto final e nomes internacionais exigem tratamento adequado.

Variáveis de ambiente versus netrc

Variáveis de ambiente são simples em containers e CI, mas podem aparecer em dumps, interfaces administrativas e processos filhos. .netrc centraliza credenciais por host, porém depende de proteção do arquivo.

Nenhuma opção é universalmente segura. Avalie modelo de ameaça, rotação, auditoria e experiência operacional.

Quando usar um cofre de segredos

Prefira um secret manager quando:

  • há vários servidores ou equipes;
  • segredos precisam de rotação automática;
  • é necessária auditoria de acesso;
  • credenciais têm vida curta;
  • o serviço roda em infraestrutura compartilhada;
  • políticas exigem criptografia centralizada.

O netrc funciona bem para ferramentas locais e integração com clientes compatíveis, mas não substitui governança corporativa.

Não versionar o arquivo

Adicione .netrc e variações privadas ao .gitignore. Verifique também históricos, artifacts de CI, imagens de container e backups. Remover o arquivo do commit atual não elimina versões antigas.

Rotação de credenciais

Ao trocar uma senha, atualize o arquivo de forma atômica. Crie um temporário com permissões restritas, grave, faça fsync quando necessário e substitua o destino.

Evite janelas em que um processo leia conteúdo parcialmente escrito.

Testes sem segredos reais

from pathlib import Path
from netrc import netrc

conteudo = """machine teste.local
login usuario
password exemplo
"""

arquivo = Path("credenciais-teste.netrc")
arquivo.write_text(conteudo, encoding="utf-8")
config = netrc(str(arquivo))

Use diretórios temporários e valores fictícios. Em POSIX, ajuste permissões para reproduzir o comportamento do arquivo padrão.

Validação de permissões em testes

Teste um arquivo com modo seguro e outro acessível por grupo ou outros usuários. A verificação automática depende de o caminho padrão ser usado e da plataforma oferecer UID; portanto, escreva testes condicionais e documente diferenças.

Mensagens de erro seguras

Uma boa mensagem informa o host, o caminho de configuração e o tipo do problema. Ela não inclui senha, conteúdo integral nem objeto netrc.

raise RuntimeError(
    f"credencial para {host!r} não encontrada no arquivo configurado"
)

Erros frequentes

  • Usar permissões abertas no arquivo.
  • Registrar repr(config).
  • Confiar indiscriminadamente na entrada default.
  • Enviar credenciais após redirecionamento de domínio.
  • Permitir que entrada externa escolha o host.
  • Versionar segredos por engano.
  • Ignorar campos vazios.
  • Presumir que a verificação POSIX existe em todas as plataformas.

Boas práticas

  • Use modo 600 e proprietário correto em POSIX.
  • Valide host, login e senha antes da conexão.
  • Não registre conteúdo de credenciais.
  • Evite fallback default em sistemas sensíveis.
  • Atualize arquivos de forma atômica.
  • Use segredos fictícios em testes.
  • Impeça reenvio de autorização em redirecionamentos.
  • Migre para um cofre quando precisar de rotação e auditoria.

Conclusão

O módulo netrc no Python fornece uma forma compatível e simples de ler credenciais por host. Sua API pequena facilita integrações com clientes de rede e ferramentas de linha de comando.

A segurança depende do entorno: permissões, escolha de host, logs, redirecionamentos e governança de segredos. Use o formato para configurações locais controladas e adote um secret manager quando o ambiente exigir rotação, auditoria ou distribuição. Consulte a documentação oficial de netrc e a documentação do formato netrc para detalhes de interoperabilidade.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Mensagem digital representando codificação quoted-printable com quopri no Python
    Bibliotecas e Módulos
    Foto de perfil de Leandro Hirt da Academify

    quopri no Python: quoted-printable

    Aprenda quopri no Python para codificar e decodificar quoted-printable em e-mails, arquivos e integrações MIME com segurança.

    Ler mais

    Tempo de leitura: 7 minutos
    08/08/2026
    Ícone de arquivo digital representando tipos MIME com mimetypes no Python
    Bibliotecas e Módulos
    Foto de perfil de Leandro Hirt da Academify

    mimetypes no Python: tipos MIME

    Aprenda mimetypes no Python para identificar tipos MIME, extensões e encodings com segurança em uploads, downloads e APIs web.

    Ler mais

    Tempo de leitura: 7 minutos
    08/08/2026
    Busca binária e listas ordenadas com bisect no Python
    Bibliotecas e Módulos
    Foto de perfil de Leandro Hirt da Academify

    bisect no Python: buscas em listas ordenadas

    Aprenda bisect no Python para buscar posições, inserir valores e trabalhar com duplicatas e faixas em listas ordenadas.

    Ler mais

    Tempo de leitura: 5 minutos
    08/08/2026
    Código e arquivos empacotados com importlib.resources no Python
    Bibliotecas e Módulos
    Foto de perfil de Leandro Hirt da Academify

    importlib.resources no Python: guia prático

    Aprenda importlib.resources no Python para acessar arquivos empacotados com segurança em pacotes, wheels e aplicações instaladas.

    Ler mais

    Tempo de leitura: 6 minutos
    07/08/2026
    Teclado e fluxo de dados representando leitura de vários arquivos com fileinput no Python
    Bibliotecas e Módulos
    Foto de perfil de Leandro Hirt da Academify

    fileinput no Python: leia vários arquivos

    Aprenda fileinput no Python para ler vários arquivos ou stdin, rastrear linhas, abrir gzip e reescrever conteúdo com backup e

    Ler mais

    Tempo de leitura: 8 minutos
    07/08/2026
    Editor de código com linhas numeradas representando o módulo linecache no Python
    Bibliotecas e Módulos
    Foto de perfil de Leandro Hirt da Academify

    linecache no Python: leia linhas por número

    Aprenda linecache no Python para ler linhas por número, usar cache, atualizar arquivos modificados e integrar fontes com traceback e

    Ler mais

    Tempo de leitura: 7 minutos
    07/08/2026