Como Integrar Assinatura Digital em Go (Golang)
Se você está construindo um backend em Go e precisa coletar assinaturas com validade jurídica no Brasil, este guia é um quickstart prático de ponta a ponta. Vamos do go get do SDK oficial até o download do PDF assinado, passando por autenticação OAuth2, criação de sessão de assinatura, adição de signatários e verificação de webhooks com HMAC — sempre com código Go idiomático, tratamento de erros explícito e context.Context.
O Go é uma escolha excelente para integrações de assinatura: tipagem estática, concorrência barata e uma biblioteca padrão robusta para HTTP, JSON e criptografia. A API de assinatura digital da SignDocs Brasil foi desenhada para ser previsível e amigável a esse perfil de aplicação, com um SDK Go que empacota a parte chata (auth, retry, tipos) e deixa você focar na lógica de negócio.
Você não precisa ser um especialista em criptografia ICP-Brasil para começar. Em poucos minutos terá uma sessão de assinatura criada e um link pronto para enviar ao signatário. Se preferir ver o panorama maior primeiro, vale a leitura de o que é uma API de assinatura digital, que cobre os conceitos independentes de linguagem.
Por que Go para integrar assinatura digital
Antes do código, vale entender por que o Go cai tão bem nesse tipo de integração. Boa parte do trabalho de uma integração de assinatura é I/O de rede com APIs externas, somada a um receptor de webhooks que precisa ser rápido e seguro. Esse é exatamente o ponto forte da linguagem.
- Concorrência nativa: goroutines e channels tornam trivial enviar dezenas de documentos em paralelo sem travar threads.
- Biblioteca padrão completa:
net/http,encoding/json,crypto/hmacecontextcobrem quase tudo sem dependências externas. - Tipagem estática: os payloads da API viram
structs, e o compilador pega erros de campo antes de chegar à produção. - Binário único: seu receptor de webhooks compila para um binário sem dependências, ideal para containers enxutos e funções serverless.
- Cancelamento limpo:
context.Contextpropaga deadlines e cancelamentos, evitando goroutines vazadas em chamadas lentas.
A SignDocs Brasil oferece SDKs oficiais para Go, TypeScript/Node, Python, Java, PHP e C#/.NET. Se você trabalha com mais de uma stack, vale comparar com os guias de integração em Node.js e integração em Python — a API é a mesma, muda apenas o idioma do cliente.
Passo 1: Instalar o SDK Go
Comece criando um módulo Go para a sua integração e instalando o SDK oficial. O SDK usa apenas a biblioteca padrão — zero dependências externas em runtime.
Em seguida, configure suas credenciais. Nunca coloque client_id e client_secret direto no código — use variáveis de ambiente ou um gerenciador de segredos:
client_id e o client_secret são gerados no painel da SignDocs Brasil. Crie um par de chaves dedicado para cada ambiente (homologação e produção) e nunca reutilize as mesmas credenciais entre eles. O passo a passo de geração está em como obter suas credenciais da API; o protocolo em si, no guia de autenticação OAuth2.
Passo 2: Autenticar com OAuth2 client-credentials
A API usa o fluxo OAuth2 client-credentials: você troca suas credenciais por um token bearer de curta duração — um JWT assinado com ECDSA ES256, com as chaves protegidas em KMS, que expira em 15 minutos — e o envia no header Authorization de cada chamada. O SDK Go faz essa troca e renova o token automaticamente quando ele expira.
Usando o SDK oficial
Inicializar o client é direto. Forneça as credenciais e, opcionalmente, o BaseURL do ambiente:
Sem o SDK: net/http puro
Como a API REST é agnóstica de linguagem, você pode usar a biblioteca padrão. O pacote golang.org/x/oauth2/clientcredentials cuida da obtenção e renovação do token, devolvendo um *http.Client já autenticado:
Repare no uso de fmt.Errorf com o verbo %w para encapsular o erro original: esse é o padrão idiomático em Go para preservar a cadeia de erros e permitir inspeção posterior com errors.Is e errors.As. Trataremos os erros da API de forma estruturada mais adiante.
Passo 3: Criar uma sessão de assinatura
A forma mais rápida de coletar uma assinatura é a Assinatura Expressa (signing sessions): uma única chamada a POST /v1/signing-sessions cria a sessão e devolve a URL de checkout hospedado e o clientSecret para o embed em popup (via SDK front-end @signdocs-brasil/js). É o caminho ideal para fluxos de um signatário. Para múltiplos signatários, existe a API de envelopes (Passo 4); o ciclo de vida completo está no guia do fluxo transacional.
Vamos criar uma sessão usando o SDK. Note o uso de context.WithTimeout para limitar o tempo da chamada de rede:
DIGITAL_CERTIFICATE é o que ativa a exigência de certificado ICP-Brasil — na API, o A1 (para tokens A3, o aplicativo SignDocs oferece o assinador desktop). Um erro comum é tentar usar DIGITAL_SIGN_A1 como profile — isso é rejeitado com HTTP 400. DIGITAL_SIGN_A1 existe apenas como tipo de etapa (step type) dentro da resposta. Os demais perfis (CLICK_ONLY, CLICK_PLUS_OTP, BIOMETRIC, BIOMETRIC_PLUS_OTP) cobrem os níveis eletrônicos; veja a lista completa em o que é uma API de assinatura digital.
Passo 4: Múltiplos signatários com envelopes
Na Assinatura Expressa, o signatário já vai na própria criação da sessão — não há passo separado de "adicionar e enviar". Quando o documento precisa de mais de uma assinatura, o modelo é o envelope: você cria o envelope (com modo sequencial ou paralelo) e adiciona uma sessão por signatário, com a posição na fila dada pelo SignerIndex:
No modo SEQUENTIAL, a plataforma impõe a fila: o signatário 2 só consegue concluir depois que o 1 termina. Um envelope aceita até 100 signatários, cada um com sua própria política de autenticação. O detalhamento dos modos está em ordem de assinatura com múltiplos signatários.
Tratamento de erros estruturado
Erros da API chegam tipados pelo SDK, o que permite reagir de forma específica usando errors.As. Trate rate limiting e erros de validação separadamente de falhas genéricas:
Passo 5: Receber e verificar webhooks
Em vez de ficar consultando o status em loop (polling), o correto é deixar a API avisar você via webhook sempre que um evento acontece: SIGNING_SESSION.COMPLETED, TRANSACTION.COMPLETED, STEP.FAILED, e assim por diante. Os fundamentos da arquitetura de eventos estão no guia de webhooks e eventos da API; aqui focamos na implementação do receptor em Go.
Cada webhook chega como um POST HTTPS com o corpo em JSON e um header contendo a assinatura HMAC-SHA256 do corpo. Sua obrigação é recalcular esse HMAC com o segredo compartilhado e comparar de forma timing-safe. Veja um handler net/http completo e idiomático:
hmac.Equal para comparar assinaturas — ou delegue ao helper do SDK, signdocs.VerifyWebhookSignature(body, sig, ts, secret), que faz exatamente essa validação. Comparar com == ou bytes.Equal ingênuo abre brecha para timing attacks, onde um atacante infere a assinatura correta medindo o tempo de resposta. Leia o corpo bruto com io.ReadAll antes de qualquer parsing: re-serializar o JSON altera bytes e quebra o HMAC.
Idempotência: o mesmo evento pode chegar duas vezes
Webhooks operam com semântica de entrega ao menos uma vez. Um timeout de rede após o processamento, ou um retry da API, pode reentregar o mesmo evento. Por isso o handler acima usa markProcessed, que registra o id do evento de forma atômica e retorna false se já foi visto. Com Redis, fica assim:
Passo 6: Baixar o PDF assinado
Quando o evento TRANSACTION.COMPLETED chega, o documento final assinado está disponível para download. O SDK devolve URLs temporárias; a integração fecha o ciclo buscando o PDF e armazenando-o no seu repositório:
O PDF baixado é um documento PAdES com a assinatura embutida, o carimbo de hora do servidor (timestamp ISO-8601 registrado pelo SignDocs) e a cadeia de certificados ICP-Brasil. Além do PDF, você pode obter o evidence pack em formato .p7m, que reúne toda a trilha de auditoria como prova jurídica — assunto do guia sobre evidence pack e prova jurídica. Qualquer pessoa pode validar o documento depois no verificador público.
Assinatura Expressa vs. Transaction API em Go
A SignDocs expõe duas superfícies de API, e a escolha entre elas define a estrutura do seu código Go. A tabela abaixo resume quando usar cada uma:
| Critério | Assinatura Expressa (Signing Sessions) | Transaction API (Envelopes) |
|---|---|---|
| Chamadas para iniciar | Uma (POST /v1/signing-sessions) |
Duas por signatário (criar envelope + uma sessão por signatário) |
| Signatários | Foco em um signatário | Até 100, com ordem via SignerIndex |
| Entrega | Checkout hospedado ou embed em popup via SDK @signdocs-brasil/js |
Convites por e-mail/link, fluxo orquestrado |
| Tempo até o primeiro envio | Minutos | Algumas horas de integração |
| Ideal para | Onboarding, aceite de termos, contratos B2C | Contratos B2B, fluxos multipartes, RH, jurídico |
A boa notícia é que ambas usam o mesmo client autenticado e os mesmos webhooks. Você pode começar pela Expressa para validar o produto e migrar trechos do fluxo para a Transaction API conforme a complexidade cresce, sem reescrever a camada de autenticação ou o receptor de webhooks.
Checklist para ir à produção
Antes de apontar sua integração Go para produção, valide tudo no ambiente de homologação. O host base do sandbox é api-hml.signdocs.com.br (com hífen, não api.hml) e as entidades criadas lá têm TTL de 7 dias, expirando automaticamente.
- Credenciais separadas por ambiente: use pares distintos de
client_id/client_secretpara HML e produção, sem reaproveitar. - Segredos fora do código: mantenha
client_secretewebhook_secretem variáveis de ambiente ou em um cofre (Vault, KMS, Secrets Manager). - Timeouts e contextos: todas as chamadas de rede com
context.WithTimeout; nunca usecontext.Background()diretamente em chamadas longas. - Webhook idempotente e timing-safe:
hmac.Equalpara assinatura, dedup peloiddo evento e resposta 200 imediata. - Retry com backoff: respeite o header
Retry-Afterem respostas 429 e aplique backoff exponencial em falhas transitórias. - Observabilidade: registre o
iddo evento e otransactionIdem logs estruturados para reconciliação. - Endpoint HTTPS público: o receptor de webhooks precisa de TLS 1.2+ e ser acessível pela internet (use API Gateway ou um proxy reverso em produção).
tls.Config com o certificado do cliente no http.Transport. Os detalhes estão no guia de segurança mTLS para enterprise.
Perguntas Frequentes
Existe um SDK oficial de assinatura digital para Go?
Sim. A SignDocs Brasil mantém SDKs oficiais para Go, TypeScript/Node, Python, Java, PHP e C#/.NET. O SDK Go é instalado com go get e empacota a autenticação OAuth2, a renovação automática do token bearer, os tipos das requisições e respostas e os helpers de verificação de webhook. Como a API REST é agnóstica de linguagem, você também pode chamar os endpoints diretamente com net/http caso prefira não depender de um pacote externo.
Como autenticar na API de assinatura a partir de uma aplicação Go?
A autenticação usa o fluxo OAuth2 client-credentials. Você troca o client_id e o client_secret por um token bearer de curta duração (15 minutos), assinado com ECDSA (ES256), e o envia no header Authorization de cada requisição. Em Go, o pacote golang.org/x/oauth2/clientcredentials cuida da obtenção e da renovação automática do token, retornando um *http.Client já autenticado. O SDK oficial faz isso internamente, então você só precisa fornecer as credenciais.
Como verificar a assinatura HMAC de um webhook em Go?
Cada webhook chega com um header contendo a assinatura HMAC-SHA256 do corpo, calculada com um segredo compartilhado. No seu handler net/http, leia o corpo bruto com io.ReadAll, recalcule o HMAC usando crypto/hmac e crypto/sha256 com o mesmo segredo, e compare os valores com hmac.Equal, que é uma comparação timing-safe. Valide também o timestamp para mitigar ataques de replay. Nunca use == para comparar as assinaturas, pois isso é vulnerável a timing attacks.
Devo usar context.Context nas chamadas à API em Go?
Sim, é a prática idiomática em Go. Propagar um context.Context permite definir timeouts e deadlines por requisição e cancelar chamadas em andamento quando o request HTTP que as originou é abortado. Construa as requisições com http.NewRequestWithContext e passe um contexto derivado de context.WithTimeout. O SDK oficial aceita um context.Context em todos os métodos que fazem chamadas de rede, garantindo cancelamento limpo e ausência de goroutines vazadas.
Qual a diferença entre a Transaction API e a Assinatura Expressa para um app Go?
A Assinatura Expressa (signing sessions) é a forma mais rápida de começar: uma única chamada a POST /v1/signing-sessions retorna a URL de checkout hospedado e o clientSecret para o embed em popup, ideal para fluxos de um signatário. A API de envelopes suporta múltiplos signatários no mesmo documento (até 100), ordem de assinatura sequencial ou paralela e o ciclo de vida transacional completo. Em Go, ambas usam o mesmo client autenticado; escolha a Expressa para integrar em minutos e a Transaction API quando precisar de orquestração avançada.
A API Go suporta certificados ICP-Brasil (A1 e A3)?
Sim. Ao definir o profile da política de assinatura como DIGITAL_CERTIFICATE, a sessão exige um certificado ICP-Brasil A1 — o formato usado em integrações via API (para tokens A3, o aplicativo SignDocs oferece o assinador desktop). O passo correspondente na resposta é o DIGITAL_SIGN_A1, com a classe do certificado registrada no resultado. Perfis com OTP e biometria facial cobrem os níveis eletrônicos, com plena validade jurídica sob a MP 2.200-2/2001.
Como testar a integração Go antes de ir para produção?
Use o ambiente de homologação (sandbox), cujo host base é api-hml.signdocs.com.br. Aponte o BaseURL do client Go para esse host e use credenciais de HML. As transações criadas em homologação têm TTL de 7 dias e são automaticamente expiradas, então não há risco de poluir dados de produção. Quando os testes passarem, basta trocar o BaseURL e as credenciais para o ambiente de produção, sem alterar o restante do código.
Comece a integrar assinatura digital em Go hoje
SDK Go oficial (zero dependências), autenticação OAuth2, webhooks com HMAC-SHA256 e certificado ICP-Brasil com validade jurídica sob a MP 2.200-2/2001. O acesso à API é um plano sob medida, com sandbox de homologação gratuito para ter sua primeira sessão de assinatura rodando antes de qualquer contrato.
Fale com o time comercial Conheça a plataforma grátis