# ITMS-90034: corrigir “Missing or invalid signature”

> ITMS-90034: seu build não está assinado com um certificado de distribuição válido. Leia a assinatura com codesign e refaça um build store com o EAS.

Página original: [ITMS-90034: corrigir “Missing or invalid signature”](https://devoria.fr/pt-br/blog/itms-90034-corrigir-missing-or-invalid-signature)
Autor: [Mehdi Azizi](https://devoria.fr/pt-br/mehdi-azizi)
Publicação: 2026-11-04
Última revisão do conteúdo: 2026-11-04


ITMS-90034 aparece quando você envia seu build para o App Store Connect. Ele diz que seu app, ou um dos componentes dele, não está assinado com um certificado de envio da Apple, ou seja, um certificado de distribuição válido. **A correção: descobrir qual bundle está mal assinado e por quê, e depois refazer um build assinado para a App Store.**

Este guia fica focado no erro. Se as palavras certificado e perfil ainda estão confusas para você, leia antes [certificado de desenvolvedor iOS e provisioning profile](https://devoria.fr/pt-br/blog/certificado-ios-provisioning-profile-expo). Aqui você vai encontrar a mensagem a ler, uma árvore de decisão, os comandos que inspecionam seu IPA e a correção com as credenciais gerenciadas pelo EAS. Para a parte do EAS, eu li o código do EAS CLI 24.10.0 que escolhe o certificado.

## O que significa o erro ITMS-90034?

Esta é a forma clássica dele, com nomes de exemplo:

> ITMS-90034: Missing or invalid signature. The bundle 'com.example.myapp' at bundle path 'Payload/MyApp.app' is not signed using an Apple submission certificate.

Em 2026, no fórum da Apple, ele também aparece na forma "Validation failed (409) Missing or invalid signature", seguido do mesmo texto e de "(ID: 90034)".

O "certificado de envio" (submission certificate) é o certificado de distribuição. [A ajuda da Apple sobre certificados](https://developer.apple.com/help/account/certificates/certificates-overview) diz isso: os certificados de desenvolvimento servem para rodar seu app nos seus aparelhos, os de distribuição servem para distribuí-lo ou enviá-lo ao App Store Connect.

**Leia o caminho citado: ele aponta o bundle com problema.** `Payload/MyApp.app` se refere ao próprio app. Um caminho que termina em `.appex` se refere a uma extensão, como um widget. Um caminho em `.framework` se refere a uma biblioteca embutida.

Não é uma recusa de um reviewer. A validação acontece no envio ou durante o processamento do build, antes do TestFlight: esse build nunca vai chegar aos seus testadores.

## A árvore de decisão: da mensagem à correção

Cada linha corresponde a uma pista que você lê na mensagem, nos comandos da próxima seção ou nos logs do EAS. Siga a ordem: a primeira que bater indica o seu caminho.

| O que você observa        | Causa provável            | Correção                  |
| ------------------------- | ------------------------- | ------------------------- |
| Caminho em `.appex`       | Extensão mal assinada     | Declarar a extensão       |
| `Signature=adhoc`         | Build não assinado        | Build com perfil store    |
| `Apple Development`       | Build de desenvolvimento  | Build com perfil store    |
| `ProvisionedDevices` lido | Build interno (ad hoc)    | Build com perfil store    |
| `sealed resource`         | IPA alterado depois       | Refazer o build           |
| EAS: "no longer valid"    | Certificado revogado      | Novo certificado          |
| Tudo válido               | Problema do lado da Apple | Reenviar, depois reportar |

## Inspecionar seu IPA em quatro comandos

Baixe o IPA na página do build no expo.dev e abra um terminal no seu Mac.

**1. Quem assinou o app?**

```bash
unzip -q MyApp.ipa -d ipa
codesign -dv --verbose=4 ipa/Payload/*.app 2>&1 | grep -E "^(Identifier|Authority|Signature|TeamIdentifier)="
```

O `codesign` escreve na saída de erro, por isso o `2>&1`. Segundo [a nota técnica TN3161 da Apple](https://developer.apple.com/documentation/technotes/tn3161-inside-code-signing-certificates), cada linha `Authority` é um elo da cadeia de confiança. A primeira deve começar com `Apple Distribution:` ou `iPhone Distribution:`, seguida do nome do seu time. O segundo rótulo é o do antigo tipo iOS Distribution: pelo código dele, o EAS CLI 24.10.0 ainda cria certificados desse tipo. Se você lê `Apple Development:`, é um build de desenvolvimento. Se você lê `Signature=adhoc` sem nenhuma linha `Authority`, o binário não está assinado por nenhum certificado.

**2. O app foi alterado depois da assinatura?**

```bash
codesign --verify --deep --strict -vv ipa/Payload/*.app
```

Você quer ler `valid on disk` e depois `satisfies its Designated Requirement`. A TN3161 explica o que essa checagem garante: todos os arquivos esperados estão lá, nenhum foi adicionado, nenhum foi alterado. Num bundle de teste que eu assinei e depois mexi, o comando responde `a sealed resource is missing or invalid`, depois `file modified:` seguido do arquivo alterado. A opção `--deep` serve aqui para verificar, nunca para assinar: no fórum da Apple, um engenheiro do time de suporte desaconselha usá-la para assinar.

**3. Qual perfil está embutido?**

```bash
security cms -D -i ipa/Payload/*.app/embedded.mobileprovision -o profil.plist
plutil -extract ProvisionedDevices xml1 -o - profil.plist
plutil -extract ExpirationDate raw profil.plist
```

Esses são os comandos da [nota TN3125 sobre perfis](https://developer.apple.com/documentation/technotes/tn3125-inside-code-signing-provisioning-profiles). Um perfil App Store não contém nenhuma lista de aparelhos: a segunda linha deve responder `Could not extract value`. Se ela mostrar identificadores de aparelhos, é um perfil ad hoc, o de um build interno. A terceira mostra a data de expiração do perfil.

**4. As extensões e os frameworks estão assinados do mesmo jeito?**

```bash
find ipa/Payload/*.app \( -name "*.appex" -o -name "*.framework" \) \
  -exec sh -c 'echo "$1"; codesign -dvv "$1" 2>&1 | grep -m1 "^Authority="' _ {} \;
```

Cada componente deve mostrar a mesma linha `Authority` do app. Se algum for diferente, é ele que a mensagem cita.

Se você quiser verificar antes do envio, a TN3161 recomenda o `altool`, a mesma checagem do botão Validate App do Xcode. Ele pede uma chave de API do App Store Connect, cujo arquivo `AuthKey_<KEY_ID>.p8` fica em `~/.appstoreconnect/private_keys`:

```bash
xcrun altool --validate-app -f MyApp.ipa -t ios --api-key <KEY_ID> --api-issuer <ISSUER_ID>
```

## Corrigir com o EAS, causa por causa

### Um build interno ou de desenvolvimento enviado à Apple

Segundo a [documentação do Expo sobre o eas.json](https://docs.expo.dev/build/eas-json/), os builds com `"distribution": "internal"` não são assinados para as lojas: eles usam um perfil ad hoc. Só um perfil com distribuição `store`, o valor padrão, gera um build que pode ser enviado. **O mais seguro é enviar o build que você acabou de gerar, sem escolher na mão**:

```bash
eas build --platform ios --profile production --auto-submit
```

Se você usa `eas submit --path`, confira se o arquivo é mesmo o seu último build store. No fórum da Apple, um time descobriu que a ferramenta de envio deles mandava sempre um IPA antigo, versionado no git.

### Uma extensão esquecida

Cada extensão é um bundle separado, com seu identificador e seu próprio perfil. Num projeto Expo com geração nativa, a [página do Expo sobre extensões iOS](https://docs.expo.dev/build-reference/app-extensions/) pede para declará-las em `extra.eas.build.experimental.ios.appExtensions`. Assim o EAS CLI as conhece antes do build e cria ou valida as credenciais delas. A maioria das bibliotecas que adicionam uma extensão escreve essa declaração para você, pelo plugin delas.

O Solys, meu despertador com minijogos, tem quatro extensões: um widget e três extensões de Screen Time. As quatro estão declaradas na configuração, e o EAS tem um perfil para cada uma. **Uma extensão adicionada na mão no Xcode, sem essa declaração, é a candidata perfeita** para um caminho em `.appex` na mensagem.

### Um certificado revogado ou expirado

A [página da Apple sobre certificados](https://developer.apple.com/support/certificates/) é clara: você não pode mais enviar um build assinado com um certificado expirado ou revogado. Um build já enviado mas ainda não submetido pode até passar para Invalid Binary se o certificado dele foi revogado.

O código do EAS CLI 24.10.0 mostra quando esse caso passa despercebido:

- **Build interativo, conectado à Apple**: o EAS compara o certificado dele com os que ainda são válidos na Apple. Se ele não estiver mais lá, mostra "Current distribution certificate is no longer valid in Apple Dev Portal" e propõe escolher ou criar outro.
- **Build interativo, sem conexão**: o EAS só verifica as datas e avisa que está pulando a validação na Apple.
- **Build não interativo, em integração contínua**: o EAS mostra "Distribution Certificate is not validated for non-interactive builds" e assina mesmo assim.

**Em integração contínua, o EAS não verifica de novo o certificado em si: uma revogação pode só aparecer no envio.** A correção: rode um build interativo conectado à sua conta Apple, ou use `eas credentials --platform ios`, menu Build Credentials, depois "Distribution Certificate: Add a new one to your account". Os perfis que continham o certificado antigo ficam inválidos: o EAS os verifica no próximo build e os refaz. Os limites da Apple sobre o número de certificados estão detalhados no [guia sobre o certificado de desenvolvedor iOS](https://devoria.fr/pt-br/blog/certificado-ios-provisioning-profile-expo).

### Um binário alterado depois da assinatura

A assinatura sela o código, os recursos e os metadados com hashes, como explica [a nota TN3126 da Apple](https://developer.apple.com/documentation/technotes/tn3126-inside-code-signing-hashes). Descompactar o IPA para mudar um arquivo e compactar de novo quebra esse selo. **Faça a alteração na sua configuração e depois refaça o build.** Nunca mexa no IPA gerado pelo EAS.

A mesma lógica vale para código guardado no lugar errado, por exemplo dentro de um arquivo `.zip`: a App Store não consegue assiná-lo de novo. A Apple descreve os locais permitidos na página sobre [o conteúdo de um bundle](https://developer.apple.com/documentation/bundleresources/placing-content-in-a-bundle).

### Credenciais locais

Se o seu perfil do EAS usa `"credentialsSource": "local"`, seu arquivo `credentials.json` aponta para um certificado `.p12` e um perfil `.mobileprovision`. Verifique o perfil com os comandos da etapa 3: ele deve ser do tipo App Store e conter seu certificado de distribuição atual. E mantenha esses arquivos fora do repositório, como [as chaves de API de um app Expo](https://devoria.fr/pt-br/blog/chave-api-secreta-expo-o-que-proteger).

### Quando tudo está válido

Sobra um caso frustrante. No fórum da Apple, desenvolvedores veem o erro sumir reenviando o mesmo build, sem mudar nada. Em agosto e setembro de 2026, duas threads descrevem o contrário: certificado e perfil novos, assinatura verificada, falha persistente. Em uma delas, um engenheiro da Apple recomenda um relatório de bug com o IPA, a análise da assinatura e os logs do Transporter, e depois um contato com o App Store Connect.

Então reenvie uma vez com um novo número de build. Se o erro voltar com os seus quatro comandos limpos, reporte à Apple com esses elementos. **Não revogue seu certificado por reflexo**: isso não resolve nada a mais e invalida seus perfis.

## Enviar seu build sem surpresa ruim

Uma assinatura se verifica em dois minutos antes do envio. As outras checagens automáticas pedem o mesmo cuidado, como o [ITMS-90725](https://devoria.fr/pt-br/blog/itms-90725-sdk-version-issue-expo) para a versão do Xcode ou o [ITMS-90683](https://devoria.fr/pt-br/blog/itms-90683-missing-purpose-string-expo) para as frases de permissão. O caminho completo do build ao envio, sem Mac, está em [publicar um app iOS sem Mac](https://devoria.fr/pt-br/blog/publicar-app-ios-sem-mac-expo-eas).

As recusas de um reviewer pedem mais calma: o passo a passo está na página [app recusado pela Apple](https://devoria.fr/pt-br/expertise/app-recusado-pela-apple), e os motivos mais comuns estão em [por que a Apple recusa um app](https://devoria.fr/pt-br/blog/app-rejeitado-apple-casos-reais).

Para revisar seu app antes do envio, o [Review Kit](https://devoria.fr/pt-br/kits/app-review) reúne meu checklist e skills do Claude Code que revisam seu projeto. Se o seu envio travou e você quer um olhar humano, [agende uma hora comigo](https://devoria.fr/pt-br/coaching): a gente revisa seu projeto por vídeo, na sua tela. E se você está preparando seu primeiro lançamento, [faça seu diagnóstico gratuito](https://devoria.fr/pt-br/diagnostic): ele coloca as etapas em ordem e te envia meu checklist anti-recusa da Apple.

## Perguntas frequentes

### O ITMS-90034 é uma recusa do App Review?

Não. É uma validação automática feita no envio do build, antes do TestFlight e antes de qualquer revisão. Ninguém abriu seu app: a Apple só constatou que a assinatura dele não vem de um certificado de distribuição válido.

### Preciso revogar meu certificado de distribuição para corrigir o ITMS-90034?

Só se ele estiver comprometido ou já for inválido. Revogar um certificado que funciona invalida seus perfis sem corrigir a causa. Comece lendo a assinatura do seu IPA com `codesign` e depois corrija o que a árvore de decisão apontar.

### Dá para corrigir o ITMS-90034 com uma atualização remota?

Não. A assinatura faz parte do binário, e o build recusado nunca vai poder ser usado. É preciso gerar um novo binário assinado corretamente e enviá-lo de novo.

### Por que o erro cita meu widget e não meu app?

Porque o widget é um bundle separado, assinado com o próprio perfil. Se ele não foi declarado ao EAS ou foi assinado de outro jeito, ele derruba o envio inteiro. Declare a extensão na sua configuração e refaça o build.

### O que fazer se o codesign diz que está tudo válido?

Verifique também o perfil embutido e cada extensão. Se tudo estiver limpo, reenvie uma vez com um novo número de build. Se o erro continuar, mande um relatório para a Apple com o IPA, a saída do `codesign` e os logs de envio.


## Seu projeto

[Review Kit](https://devoria.fr/pt-br/kits/app-review): Meu checklist de revisão da App Store, as recusas da Apple que corrigi, o checklist do Google Play e três skills do Claude Code. R$ 289.

[iOS & Android Kit](https://devoria.fr/pt-br/kits/ios): Crie seu app para iPhone e Android com o Claude Code: o código inicial dos meus apps, o caminho até as lojas e todos os kits. R$ 589.

[Diagnóstico: o que te separa do seu app de iPhone](https://devoria.fr/pt-br/diagnostic): 7 perguntas, 60 segundos: descubra o que realmente te impede de publicar seu app de iPhone, seu caminho em 4 etapas e o kit certo para você.
