Moving from Rest PKI to Rest PKI Core
Rest PKI, the cloud service at pki.rest, is a legacy product: it still receives bug and security fixes, but new cloud integrations should use Rest PKI Core. This guide is for an application already integrated with Rest PKI that moves to Rest PKI Core, on the SaaS instance at core.pki.rest or on an instance of your own.
Rest PKI Core serves most of the Rest PKI APIs, so the move can happen in two stages:
- Point the application at Rest PKI Core. The Rest PKI APIs it serves keep the same routes and models: your code changes where it gets the endpoint and the credential, where your pages initialize Web PKI and, if you created security contexts of your own, where it names them. See Serving your code as-is.
- Adopt the newer APIs, at your own pace. Signature sessions, two-step signatures and certificate authentication replace the Rest PKI signature and authentication flows, with hosted signing pages, webhooks and newer client libraries. See Moving to the newer APIs.
A few Rest PKI APIs have no counterpart on Rest PKI Core: check What Rest PKI Core doesn't serve before you start.
Before you start
- Get access to an instance. On the SaaS instance, ask developer support for access if your organization doesn't have it yet; for an instance of your own, see Rest PKI Core on-premises.
- Create an application and an API key on the instance's dashboard, with the Worker role. Worker covers every Rest PKI API that Rest PKI Core serves: signatures, certificate authentication, timestamps, PDF marks and signature inspection. See Create an API key.
- Plan for the Web PKI license. With Rest PKI at pki.rest, Web PKI needs no license, even in production. With Rest PKI Core, it does, on the SaaS instance as on your own. See Licensing.
Serving your code as-is
What Rest PKI Core serves
Rest PKI Core answers these Rest PKI routes with the Rest PKI request and response models:
| Rest PKI feature | Routes |
|---|---|
| PAdES signature | POST Api/PadesSignatures, Api/v2/PadesSignatures, Api/PadesSignatures/{token}/SignedBytes, Api/PadesSignatures/{token}/Finalize, Api/v2/PadesSignatures/{token}/SignedBytes |
| CAdES signature, including co-signing | POST Api/CadesSignatures, Api/v2/CadesSignatures, Api/v3/CadesSignatures, Api/CadesSignatures/{token}/SignedBytes, Api/CadesSignatures/{token}/Finalize, Api/v2/CadesSignatures/{token}/SignedBytes, Api/CadesSignatures/RequiredHashes |
| XML signature of the whole document or of an element | POST Api/XmlSignatures/FullXmlSignature, Api/XmlSignatures/XmlElementSignature, Api/XmlSignatures/{token}/SignedBytes, Api/XmlSignatures/{token}/Finalize |
| Opening and validating signatures | POST Api/PadesSignatures/Open, Api/CadesSignatures/Open, Api/XmlSignatures/Open, Api/v2/XmlSignatures/Open |
| Certificate authentication | POST Api/Authentications, Api/Authentications/{token}/Finalize, Api/Authentications/{token}/SignedBytes; GET and POST Api/Authentication |
| Opening a certificate | POST Api/Certificates/Open |
| PDF marks (printer-friendly versions) | POST Api/Pdf/AddMarks |
| Visual representation presets | GET Api/PadesVisualPositioningPresets/Footnote, .../FootnoteBottomUp, .../NewPage |
| Uploading large files | POST Api/MultipartUploads, Api/MultipartUploads/{token}/{partNumber}, Api/MultipartUploads/{token} |
| Timestamps | POST tsp/{id} (TSP protocol) and POST Api/TimestampPlans/{id}/Issue |
Signing in the browser with Web PKI's signWithRestPki() | GET and POST Api/PendingSignatures/{token}, POST Api/PendingSignatures/{token}/Certificate (called by Web PKI, not by your code) |
The same standard signature policies are available, with the same IDs, such as StandardPadesSignaturePolicies.PkiBrazil.AdrBasica and
StandardCadesSignaturePolicies.PkiBrazil.AdrArquivamento, and so are the tags of the PDF visual representation, such as {{name}} and
{{br_cpf_formatted}} (see PAdES tags). The callbackArgument of a signature also comes back when it is finished.
What changes
| Rest PKI | Rest PKI Core | |
|---|---|---|
| Endpoint | https://pki.rest/, or your on-premises instance | https://core.pki.rest/ on the SaaS instance, or the address of your own instance's dashboard |
| Credential | An access token, generated on the Control Panel at pki.rest | An API key of an application with the Worker role, created on the dashboard of the instance |
| Header | Authorization: Bearer <access token> | X-Api-Key: <API key>; Authorization: Bearer <API key> is also accepted, so a client library that sends the access token as a bearer token works when you give it the API key instead |
| Web PKI | Calls https://restpki.lacunasoftware.com/ by default | Pass the endpoint of Rest PKI Core to init() as restPkiUrl (see below) |
| Web PKI license | Not needed with pki.rest | Needed |
| Dates on PDF signatures | Region and Date in your account | Settings > Region and Time on the dashboard |
If your pages sign with Web PKI's signWithRestPki(), as the Rest PKI samples do, Web PKI fetches the pending signature from the Rest PKI instance
itself. Tell it where Rest PKI Core is:
pki.init({
restPkiUrl: 'https://core.pki.rest/', // the endpoint of your Rest PKI Core instance
ready: onWebPkiReady,
});
Client libraries
The Rest PKI client libraries send the access token as Authorization: Bearer, and Rest PKI Core accepts an API key sent that way, so an
application can keep its Rest PKI client library at first and only give it the new endpoint and the API key. The Rest PKI Core libraries differ by
language:
| Language | Rest PKI | Rest PKI Core | What the Rest PKI Core library brings |
|---|---|---|---|
| .NET | Lacuna.RestPki.Client | Lacuna.RestPkiCore.Client 5.0.0 | It depends on Lacuna.RestPki.Client 5.0.0 and shares its namespace, Lacuna.RestPki.Client: adding it keeps RestPkiClient, the starters, finishers and explorers, Authentication and PdfMarker, next to IRestPkiService for the newer APIs. Both target .NET Standard 2.0 |
| Java | com.lacunasoftware.restpki:restpki-client | com.lacunasoftware.restpki:restpkicore-client 1.4.0 | A new package, com.lacunasoftware.restpkicore, without the Rest PKI classes. Its RestPkiService has methods for the Rest PKI routes, such as startPadesSignature(), completePadesSignature(), startCadesSignature(), startFullXmlSignature() and addPdfMarks(), besides the newer APIs. Both need Java 8 |
| PHP | lacuna/restpki-client | lacuna/restpkicore-client 1.2.1 | It requires lacuna/restpki-client ^2.7.0 and shares its namespace, Lacuna\RestPki, so the Rest PKI classes stay available. Its RestPkiService covers signature sessions and documents; the PHP sample calls the two-step signature routes through getRestClient()->post(), since the library has no method for them |
| Node.js | restpki-client | restpki-core-client 1.0.2 | Classes generated from the API for each group of routes, including the Rest PKI ones (PadesSignatureApi, CadesSignatureApi, XmlSignatureApi, PdfApi, TimestampApi, AuthenticationApi) and the newer ones (SignatureApi, SignatureSessionsApi, DocumentsApi, SignatureInspectionApi), behind a RestPkiCoreClient built with baseUrl and apiKey. It has no starters or finishers |
| Python | restpki-client | restpki-ng-python-client, used by the Python sample (0.9.1.1) | — |
| Ruby | rest_pki | None: the Ruby sample calls the REST API directly | — |
On .NET, the Rest PKI client 2.2.0 and later share version numbers with Lacuna.RestPkiCore.Client and target only .NET Standard 2.0; an
application on 1.24.1 (.NET Framework 3.5 to 4.6) upgrades first. See .NET on the Rest PKI
documentation. To set up the Rest PKI Core library for the newer APIs, see Get started.
TODO(docs): no page says whether the Rest PKI client libraries for Java, PHP, Node.js, Python and Ruby are supported against Rest PKI Core, and the
Python library restpki-ng-python-client is documented nowhere.
Security contexts
Rest PKI Core creates the standard security contexts on every instance, with the same IDs as on Rest PKI, so code that passes
StandardSecurityContexts.PkiBrazil or StandardSecurityContexts.LacunaTest works unchanged:
| Security context | ID |
|---|---|
PkiBrazil (ICP-Brasil) | 201856ce-273c-4058-a872-8937bd547d36 |
PkiItaly | c438b17e-4862-446b-86ad-6f85734f0bfe |
WindowsServer | 3881384c-a54d-45c5-bbe9-976b674f5ec7 |
LacunaTest (Lacuna Test PKI, for development only) | 803517ad-3bbc-4169-b085-60053a8f6dbf |
Rest PKI Core adds PkiBrazilExtended, GovBR, PkiBrazilWithENotariado and PkiBrazilWithGovBrAndENotariado.
A security context you created yourself on Rest PKI is not carried over: create it again on Rest PKI Core, where users with the Manager or Admin role manage the subscription's security contexts, and use its new ID. You can also choose a Default security context for the subscription, in Settings > General settings, which Rest PKI Core uses when a call names none.
TODO(docs): no page describes how to manage security contexts on the Rest PKI Core dashboard.
Testing with the Lacuna Test PKI
The test certificates work as they did on Rest PKI: name the LacunaTest security context in the calls, in
development only. Unlike a Rest PKI on-premises instance, where it might have to be created first, every Rest PKI Core instance creates it when it
starts. See Rest PKI Core on the test certificates page.
TODO(docs): no page describes a sandbox or test environment of the SaaS instance, nor test API keys for it.
Timestamps
On Rest PKI Core, timestamps come from tiers instead of plans. The PkiBrazil tier (ICP-Brasil) has the ID of the Rest PKI plan,
a402df41-8559-47b2-a05c-be555bf66310 (StandardTimestampPlans.PkiBrazil), so tsp/a402df41-8559-47b2-a05c-be555bf66310 and
Api/TimestampPlans/a402df41-8559-47b2-a05c-be555bf66310/Issue keep working on an instance where that tier is enabled, as on the SaaS instance.
These routes also take the tier's name instead of its ID, such as tsp/PkiBrazil, and Rest PKI Core adds api/tsp/{tier}, where the documented
header is Authorization: ApiKey <API key>. See Requesting timestamps.
What Rest PKI Core doesn't serve
- XML signatures of detached or online resources:
Api/XmlSignatures/DetachedResourceXmlSignatureandApi/XmlSignatures/OnlineResourceXmlSignature(in .NET,DetachedResourceXmlSignatureStarterandOnlineResourceXmlSignatureStarter) were not ported. The source asks users who need them to contact Lacuna: write to developer support. - Account and management APIs: generating access tokens, managing security contexts, listing signature policies, timestamp plans and
transactions through the Rest PKI routes (
Api/Account,Api/SecurityContexts,Api/SignaturePolicies,Api/TimestampPlans,Api/Transactions,Api/Usersand others). Rest PKI Core has its own dashboard and APIs for these. - System information routes other than
api/system/info, such asApi/System/Cultures,Api/System/TimeZonesandApi/System/Date.
The remarks of the XML signature API in the source also list Api/XmlSignatures/Open as not ported, but Rest PKI Core 5.0.5 serves it, with
Api/v2/XmlSignatures/Open.
Moving to the newer APIs
Once the application runs on Rest PKI Core, replace each Rest PKI flow with its newer equivalent when convenient:
| With Rest PKI | With Rest PKI Core | See |
|---|---|---|
Start a PAdES, CAdES or XML signature, sign with Web PKI's signWithRestPki() on your page, finish it | Create a signature session and redirect the user to the signing page hosted by Rest PKI Core, which uses Web PKI or cloud certificates; get the signed documents through the API or a webhook | Signature sessions |
| The same, keeping the signing page in your application | Prepare the signature, sign the hash with Web PKI's signHash() on your page, complete it | Two-step signatures |
| Sign with a key held by your server (the server key samples) | Prepare the signature, sign the hash on your server, complete it | Two-step signatures |
Authentication: StartWithWebPkiAsync(), signWithRestPki(), CompleteWithWebPkiAsync() | Prepare the authentication, sign the hash with Web PKI's signHash(), complete it; the state stays on your page, and reused nonces are rejected | Certificate authentication |
Open and validate signatures (PadesSignatureExplorer, CadesSignatureExplorer, XmlSignatureExplorer) | Signature inspection, PUT api/signature-inspection, with validate = true to validate | API reference |
Add marks to a PDF (PdfMarker) | POST api/pdf/stamp | API reference |
| Request a timestamp | POST api/tsp/{tier} | Requesting timestamps |
TODO(docs): no page describes the signature inspection API (api/signature-inspection) or the PDF stamp API (api/pdf/stamp) of Rest PKI Core, nor
how a stamp compares with Rest PKI's PDF marks.
The newer APIs also bring what Rest PKI doesn't have: webhooks, certificate requirements, PDF/A conversion, background processing and verification codes on the signed documents.
Comparing the samples
The PkiSuiteSamples projects have Rest PKI and Rest PKI Core versions of some samples side by side, which show the same feature before and after the move:
| Feature | Rest PKI sample | Rest PKI Core sample |
|---|---|---|
| PAdES signature on your page with Web PKI | PadesSignatureRestController (.NET, Java), pades-signature-rest (PHP), pades-signature-restpki.js (Node.js) | PadesSignatureRestCoreController (.NET), PadesSignatureCoreController (Java), pades-signature-rest-core (PHP), pades-signature-core.js (Node.js), pades_signature_rest_core.py (Python, Flask), pades_signature_rest_core_controller.rb (Ruby) |
| Batch of PAdES signatures | batch-pades-signature-restpki.js (Node.js) | batch-pades-signature-core.js (Node.js) |
| Certificate authentication | AuthenticationRestController (.NET, Java) | AuthenticationRestPkiCoreController (Java) |
| PAdES signature with a server key | pades-server-key-rest (PHP) | PadesServerKeyRestCoreController (.NET) |
| Hosted signing page | — | SignatureSessionRestCoreController and SignatureSessionPreDefRestCoreController (.NET, Java), signature-session-rest-core (PHP), with WebhookRestCoreController (.NET, Java) and webhook-rest-core (PHP) |
In the pages, the Rest PKI samples call Web PKI's signWithRestPki() with the token; the Rest PKI Core samples read the certificate with
readCertificate(), post it to the server, which prepares the signature, then sign the hash with signHash(). In .NET the samples keep one
security context helper, Util.GetSecurityContextId(), for both products, and the Node.js, PHP, Python and Ruby samples pass the Rest PKI
StandardSecurityContexts IDs to Rest PKI Core, since the standard IDs are the same.
No Rest PKI Core sample exists yet for CAdES signatures, XML signatures (including NF-e), opening and validating signatures, or printer-friendly versions; for those, the application can keep the Rest PKI APIs that Rest PKI Core serves as-is.