O que significa distribuir diretamente com o Developer ID
Há basicamente dois caminhos para entregar um app macOS aos usuários. Um é pela Mac App Store (MAS), e o outro é a distribuição direta (direct distribution) — permitir que os usuários baixem um arquivo .dmg (ou .app) criado por você mesmo a partir de um site, do GitHub ou similar.
A distribuição direta tem vantagens claras. Você não precisa esperar pela revisão da App Store, não há comissões de pagamento e pode publicar atualizações quando e como quiser. Em troca, as tarefas que a App Store costumava fazer por você — assinatura de código, notarização (notarization) e atualizações automáticas — passam a ser responsabilidade sua.
Se você não configurar essas tarefas, o mecanismo de segurança do macOS, o Gatekeeper, impedirá que o app seja executado. Quando o usuário abrir o app pela primeira vez, verá um aviso como “este app não pode ser aberto porque é de um desenvolvedor não identificado”, e a maioria dos usuários desistirá da instalação nesse ponto. Para que o app abra com um simples duplo clique, como qualquer app distribuído corretamente, você precisa assinar o app com um certificado Developer ID e obter a notarização da Apple.
Esta série cobre esse processo de configuração inicial. Uma boa notícia: a maior parte da configuração descrita aqui só precisa ser feita uma vez e é reutilizada em todas as versões.
O que você vai construir nesta série
Ao longo de 3 partes, você vai configurar o seguinte.
- (Parte 1, este artigo) Certificado Developer ID Application + credenciais para notarização
- (Parte 2) Chave de assinatura EdDSA para atualizações automáticas com Sparkle
- (Parte 3) Repositório público para hospedar o feed de atualizações + ajustes finais de build
Ao final da série, você deverá ter em mãos o seguinte. Por enquanto, apenas dê uma olhada na lista; iremos completá-la item por item em cada parte.
- Certificado
Developer ID Applicationno Keychain do macOS - Perfil de credenciais para notarização armazenado no Keychain
- Par de chaves EdDSA para assinar atualizações do Sparkle (chave pública + chave privada)
- Backup da chave privada em local seguro
- Repositório público do GitHub + GitHub Pages para hospedar o feed de atualizações (appcast)
- Arquivo de configurações de build (
ExportOptions.plist) e configuração do lado do app
App de exemplo — FocusTimer
Esta série usa um app macOS fictício, FocusTimer (um app de temporizador simples para gerenciar o tempo de foco), como exemplo. Os valores que aparecem em comandos e caminhos, como FocusTimer, o identificador de bundle com.example.FocusTimer, o domínio example.com, o nome do certificado, o Team ID, e assim por diante, são todos valores de exemplo. Ao seguir o tutorial, substitua-os pelo nome do seu próprio app e pelas informações da sua conta.
Este artigo foi escrito para o Xcode 26 e o Sparkle 2.x (o framework de atualizações automáticas, que aparece na Parte 2). A Apple frequentemente altera o layout de suas telas e a localização dos menus, portanto, mesmo que o nome de um botão seja ligeiramente diferente, o fluxo geral é o mesmo.
Pré-requisitos — Ferramentas de linha de comando
Primeiro, instale duas ferramentas de linha de comando necessárias para automatizar o build e o lançamento. Isso pressupõe que você já tenha o gerenciador de pacotes do macOS, Homebrew, instalado.
brew install gh create-dmg
gh— A CLI oficial do GitHub. Você a usará mais tarde para criar GitHub Releases.create-dmg— Uma ferramenta para criar uma imagem de disco.dmgpara distribuição. Ela também gera a tela que orienta o usuário a arrastar o app para a pastaApplications.
Você não vai usá-las agora, mas scripts de automação de lançamento muitas vezes são projetados para verificar primeiro a presença dessas ferramentas e parar imediatamente se estiverem ausentes, por isso vale a pena instalá-las com antecedência.
Passo 1 — Verificar a adesão ao Apple Developer Program
Para emitir um certificado Developer ID e notarizar um app, você precisa de uma adesão ao Apple Developer Program. Para uma conta individual, é um programa pago que custa US$ 99 por ano.
Se você já está inscrito, basta confirmar que está ativo.
- Acesse developer.apple.com/account
- Na seção Membership details, confirme que o status é Active
- Na mesma tela, anote seu Team ID (nos exemplos,
ABCDE12345). Ele é usado em todas as etapas seguintes.
Se você ainda não está inscrito, a aprovação da adesão geralmente leva cerca de um dia. Certificados não podem ser emitidos antes da aprovação, portanto é melhor resolver isso primeiro.
Passo 2 — Emitir um certificado Developer ID Application
O certificado Developer ID Application é o certificado usado para assinar o .app e o .dmg que você vai distribuir. O Gatekeeper do macOS reconhece um app assinado com esse certificado como “um app feito por um desenvolvedor conhecido”.
A Apple também tem um certificado Developer ID Installer separado para assinar pacotes de instalação
.pkg. Como esta série distribui via.dmg, lidamos apenas com o certificado Application.
Procedimento de emissão
A maneira mais simples é pelo Xcode.
- Abra o Xcode → menu Xcode → Settings… (
⌘,) - Selecione a aba Accounts → clique no seu Apple ID na lista à esquerda
- Clique no botão Manage Certificates… no canto inferior direito
- Na nova janela que se abre, clique no botão
+no canto inferior esquerdo - Selecione Developer ID Application no menu
- Após um ou dois segundos, um novo certificado aparece na lista — clique em Done
Um certificado emitido dessa forma é automaticamente armazenado no Keychain do macOS. O certificado e sua chave privada correspondente são armazenados juntos como um par, e essa chave privada é o que torna a assinatura possível.
Verificando a emissão
No terminal, execute o seguinte comando para confirmar que o certificado foi instalado corretamente.
security find-identity -v -p codesigning | grep "Developer ID Application"
Se aparecer uma única linha como a seguinte, funcionou.
1) A1B2C3D4E5F6... "Developer ID Application: Gildong Hong (ABCDE12345)"
A string entre aspas é o nome oficial do certificado. Gildong Hong é o nome registrado na conta Apple, e ABCDE12345 entre parênteses é o Team ID que você anotou no Passo 1. Esse nome é usado exatamente assim quando você automatizar a assinatura de código mais tarde, então verifique-o novamente agora.
Renovando o certificado
Um certificado Developer ID é válido por 5 anos. À medida que a expiração se aproxima, ele será marcado como Expired na lista Manage Certificates do Xcode. Nesse momento, basta emitir um novo certificado usando exatamente o mesmo procedimento acima.
A boa notícia é que os apps já assinados e distribuídos com o certificado antigo não são invalidados no momento em que ele expira. Somente os novos builds criados a partir daí precisam ser assinados com o novo certificado. Portanto, não há necessidade de se preocupar demais com a expiração.
Passo 3 — Registrar uma senha específica do app para notarização
O que é notarização (notarization)?
Notarização é o processo de enviar seu app para os servidores da Apple antes da distribuição para que seja verificado em busca de malware. Se passar na verificação, a Apple emite um “ticket de notarização”, e esse ticket deve estar anexado ao app para que o Gatekeeper o abra sem avisos. Se a assinatura prova “quem o fez”, a notarização é um processo separado que prova “a Apple o verificou uma vez”.
O envio para notarização usa o comando notarytool da Apple, que solicita sua senha do Apple ID toda vez que você envia. Para evitar digitá-la a cada vez, você cria uma senha específica do app (App-Specific Password) e a armazena no Keychain antecipadamente.
3-1. Emitir uma senha específica do app
Uma senha específica do app é uma senha de 16 caracteres usada apenas para uma finalidade específica, no lugar da sua senha principal do Apple ID.
- Acesse appleid.apple.com → faça login com o Apple ID inscrito no Apple Developer Program (nos exemplos,
[email protected]) - Vá em Sign-In and Security → selecione App-Specific Passwords
- Clique no botão
+→ insira um nome para a senha (ex.:focustimer-notarize) - Clique em Create → insira sua senha do Apple ID mais uma vez
- Uma senha de 16 caracteres no formato
abcd-efgh-ijkl-mnopaparece na tela.
Depois que você fechar esta tela, não poderá visualizar a senha novamente. Antes de passar para a próxima etapa, copie-a brevemente para um gerenciador de senhas ou similar.
3-2. Armazená-la em um perfil do notarytool
Salve a senha recebida como um perfil do Keychain. No comando abaixo, substitua o valor de --password pela senha real que você acabou de receber antes de executá-lo.
xcrun notarytool store-credentials "focustimer-notarize" \
--apple-id "[email protected]" \
--team-id "ABCDE12345" \
--password "abcd-efgh-ijkl-mnop"
- Primeiro argumento
"focustimer-notarize"— o nome a ser dado a este perfil. A partir de agora, você carregará as credenciais por esse nome ao notarizar. --apple-id— o e-mail da conta do Apple Developer Program--team-id— o Team ID do Passo 1--password— a senha específica do app emitida em 3-1
Se a seguinte saída aparecer, funcionou.
Credentials saved to Keychain.
Agora que as credenciais estão armazenadas no Keychain, você não precisa mais da senha específica do app original. (Dito isso, se você planeja fazer builds em outros computadores também, é conveniente mantê-la em um gerenciador de senhas.)
3-3. Verificação
Verifique se o perfil salvo realmente funciona.
xcrun notarytool history --keychain-profile "focustimer-notarize"
Se a mensagem Successfully received submission history. aparecer, está tudo bem. O histórico de envios abaixo pode estar vazio (o que é normal, pois você ainda não notarizou nada) ou pode conter registros anteriores.
Uma armadilha importante — sua conta Apple ID e a conta GitHub são diferentes
Este é o ponto onde as pessoas que estão configurando a distribuição direta pela primeira vez mais frequentemente ficam presas.
- Conta do Apple Developer Program — usada para emitir certificados e para notarização (exemplo:
[email protected]) - Conta do GitHub — usada na Parte 3 para hospedar os arquivos de atualização (exemplo:
[email protected])
Em muitos casos, essas duas são e-mails diferentes. Em particular, o --apple-id do notarytool store-credentials deve ser o e-mail da conta Apple Developer. Se você inserir o e-mail da conta do GitHub, a autenticação falha — e a mensagem de erro não é amigável, então fica difícil rastrear a causa.
Se os e-mails das duas contas forem fáceis de confundir, recomendamos anotar qual é para a Apple e qual é para o GitHub. Essa distinção aparece repetidamente ao longo de toda a série.
Resumo da Parte 1
Se você acompanhou até aqui, agora tem o seguinte.
- ✅ Ferramentas de linha de comando para automação de lançamento (
gh,create-dmg) - ✅ Uma adesão ativa ao Apple Developer Program
- ✅ Um certificado Developer ID Application armazenado no Keychain
- ✅ Um perfil de credenciais para notarização armazenado no Keychain (
focustimer-notarize)
Com isso, você está pronto para assinar e notarizar o app. Mas quase nenhum app é entregue aos usuários apenas uma vez e pronto. Você precisa continuar lançando novas versões que corrigem bugs e adicionam funcionalidades. Na App Store, as atualizações automáticas são tratadas para você, mas na distribuição direta isso também é algo que você mesmo precisa configurar.
Na próxima parte, criaremos a chave de assinatura EdDSA para o Sparkle, o framework de atualização automática que é o padrão de fato para apps macOS. É um mecanismo de verificação dedicado a arquivos de atualização — uma camada separada do certificado.