# Task: Assinar em lote (Certificado em nuvem, com CloudHub)

I want my application to do what Lacuna's "Assinar em lote (Certificado em nuvem, com CloudHub)" demo does: Assine vários PDFs com uma só autorização do certificado em nuvem que seu PSC guarda, alcançado pelo CloudHub, com o PKI SDK no servidor.

- Docs: https://docs.lacunasoftware.com/articles/cloudhub/pades-signature
- Live demo: https://try.lacunasoftware.com/pt/pki-suite/sign-a-batch-with-cloud-certificate
- This demo for AI agents: https://try.lacunasoftware.com/pt/pki-suite/sign-a-batch-with-cloud-certificate.md

## Samples

- .NET (aspnet-mvc): [Assinar um PDF com um certificado em nuvem usando o CloudHub](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/dotnet/mvc/PkiSuiteAspNetMvcSample/Controllers/PadesCloudHubSdkController.cs)
- .NET (aspnet-mvc): [Assinar um PDF com um certificado em nuvem (fluxo OAuth) usando o PKI SDK](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/dotnet/mvc/PkiSuiteAspNetMvcSample/Controllers/PadesCloudOauthSdkController.cs)
- .NET (aspnet-mvc): [Assinar um PDF com um certificado em nuvem (fluxo com senha) usando o PKI SDK](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/dotnet/mvc/PkiSuiteAspNetMvcSample/Controllers/PadesCloudPwdSdkController.cs)
- Java (spring-boot): [Assinar um PDF com um certificado em nuvem usando o CloudHub](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/java/springmvc/src/main/java/com/lacunasoftware/pkisuite/controller/PadesSignatureCloudhubRestController.java)
- Node.js (express): [Assinar um PDF com um certificado em nuvem usando o CloudHub](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/nodejs/expressmvc/routes/pades-signature-cloudhub-restpki.js)
- PHP (php): [Assinar um PDF com um certificado em nuvem usando o CloudHub](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/php/plain/public/pades-signature-cloudhub-rest/index.php)

## Call sequence

No call sequence is recorded for this demo, so none is shown here: this page doesn't guess calls. There is no CloudHub sandbox to record against, and authorizing the signatures at the PSC needs the certificate's holder. The docs and samples below show the calls; the live demo makes them.

## Patterns to copy

- Sign a batch in one Signature session: look the CPF up once, send the user to their PSC once, and sign every PDF in the session CloudHub hands back. CloudHub has no batch call, so each PDF goes through the same Start, CloudHub sign-hash and Complete as a single file, one PDF at a time, and only each PDF's hash leaves your server.
- Read the certificate once, in the session, before the first Start, and prepare every PDF with it; Start validates it, so a certificate that can't sign is refused before the PSC is asked to sign anything.
- The PSC decides when the session ends, 15 minutes by default: if it ends mid-batch (`SessionExpired` or `SessionInvalidOrAlreadyUsed` on the exception's `CodeStr`), fail the PDFs not signed yet with that code, keep the signed ones, and look the CPF up again for the rest. A PDF that fails for any other reason fails alone.
- Treat `session` as a bearer secret: keep it on the server, never log it, and strip it from the return page's address bar. Several pages can share one return page by naming themselves in the redirect URI, checked against an allow-list, so the return page's Start over leads back to the right one.
- Count the Batch against your per-IP limit for all its PDFs before the first Start, so it is never refused halfway.

## What to do

Implement this in my project with its existing stack, language, framework and conventions, following the call sequence and the patterns above, and adapting the samples rather than copying them whole. Ask me before adding any dependency or package. Keep API keys and private keys out of the browser and out of the repository.
