---
title: "Security contexts and signature policies - Rest PKI Core"
description: "How the security context (whom to trust) and the signature policy (format and rules) work together in Rest PKI Core, with the PDF policies, the Adobe Reader policy and validation examples in Python, .NET and REST."
canonical: "https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/security-contexts-and-signature-policies"
locale: "en"
product: "Rest PKI Core"
last_updated: "2026-11-10"
---

# Security contexts and signature policies - Rest PKI Core

When it signs or validates, [Rest PKI Core](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core) answers two independent questions:

| | Security context | Signature policy |
| --- | --- | --- |
| **Question** | Whom to trust? | How must the signature be made, or have been made? |
| **Decides** | Which roots the signer's certificate chain must end at | The format (PAdES, CAdES, XML), the required and forbidden attributes, the accepted algorithms, the timestamp and the LTV data |
| **Examples** | `PkiBrazil`, `GovBR`, `PkiBrazilWithGovBrAndENotariado`, a security context created on the dashboard | PAdES basic, ICP-Brasil AD-RB, Adobe Reader |
| **Parameter** | `securityContextId` | `signaturePolicyId`, `defaultSignaturePolicyId` and `acceptableExplicitPolicies`, on the Rest PKI routes only |

A signature is valid only when both checks pass: the certificate must be trusted in the security context, and the signature must follow the
policy. Neither replaces the other. Changing the policy doesn't make Rest PKI Core trust more certificates, and changing the security context
doesn't make it accept a format the policy rejects.

Whether a signature is qualified doesn't depend on the policy either: it depends on the certificate. A signature made with an ICP-Brasil
certificate is qualified even if it doesn't follow the ICP-Brasil PAdES standard. The policy only decides whether that format is accepted.

See [Security contexts](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/security-contexts) for the standard security contexts and for creating your own.

## An example: a signature made in Adobe Acrobat

A PDF signed in Adobe Acrobat with an ICP-Brasil certificate, validated with the PAdES basic policy and the `PkiBrazil` security context, may
come back with this error:

```json
"errors": [
	{
		"type": "RequiredSignedAttributeMissing",
		"message": "A required signed attribute is missing",
		"detail": "signing-certificate",
		"innerValidationResults": null
	}
]
```

The certificate is fine: its chain ends at the ICP-Brasil root, which the `PkiBrazil` security context trusts. The format is what fails. PAdES
requires the `signing-certificate` signed attribute, and Acrobat's default signature format (`adbe.pkcs7.detached`) doesn't include it. To
accept this PDF, keep the security context and switch the policy to [Adobe Reader](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/security-contexts-and-signature-policies#adobe-reader).

## How they work together in each API

### Rest PKI routes

On the [Rest PKI](https://docs.lacunasoftware.com/en-us/articles/rest-pki) routes that Rest PKI Core serves, you choose the policy. That applies to starting a PAdES
signature (`Api/PadesSignatures`) and to validation (`Api/PadesSignatures/Open`, which the client libraries' `PadesSignatureExplorer` calls):

* **With `securityContextId`**: the security context decides whom to trust, and the policy decides the rest. The security context replaces
  the roots the policy brings, the ICP-Brasil policies included.
* **Without `securityContextId`**: the policy's trust applies. The ICP-Brasil policies trust ICP-Brasil. The others trust no root, and the
  call fails with `SecurityContextRequired`.

### Rest PKI Core APIs

[Signature sessions](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/signature-sessions), [two-step signatures](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/two-step-signatures) and
[signature inspection](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/signature-inspection) take no policy:

* **When signing**, the instance settings choose the policy. `General:DefaultSignaturePolicy` (`Basic`, the default, or `WithTime`) says
  whether the signature gets a timestamp. With `General:UseBrazilianPdfSigningPolicies` on, PDF signatures follow ICP-Brasil (AD-RB or
  AD-RT). With it off, the default, they follow PAdES basic (or PAdES-T).
* **When validating**, inspection uses the basic policy of the format, PAdES basic for PDF. It rejects signatures in Adobe's format with the
  error in the [example above](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/security-contexts-and-signature-policies#adobe-example). To accept them, validate through the `Api/PadesSignatures/Open` route with the Adobe Reader
  policy.
* **Trust always comes from the security context**: the one given in the call or, without it, the subscription's or the instance's default.

## Policies for PDF

These are the PAdES policies. In .NET they're in `StandardPadesSignaturePolicies` (namespace `Lacuna.RestPki.Api`). In Python, the
`StandardSignaturePolicies` constants (package `restpki_client`) don't include Adobe Reader or the one without LTV: pass the ID.

| Policy | ID | What it defines | Without a security context, trusts |
| --- | --- | --- | --- |
| `Basic` | `78d20b33-014d-440e-ad07-929f05d00cdf` | PAdES basic, with LTV data | No root: requires a security context |
| `BasicWithoutLtv` | `ed93a777-ad5a-49a0-8b67-5aa5dfad1c98` | PAdES basic, without LTV data | No root: requires a security context |
| `AdobeReader` | `aaed831b-fa9d-4732-82fc-8d25f2c16c57` | PAdES basic without the attribute and algorithm requirements; accepts Adobe's format (see [below](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/security-contexts-and-signature-policies#adobe-reader)) | No root: requires a security context |
| `PkiBrazil.AdrBasica` | `531d5012-4c0d-4b6f-89e8-ebdcc605d7c2` | ICP-Brasil AD-RB (explicit policy) | ICP-Brasil |
| `PkiBrazil.AdrTempo` | `10f0d9a5-a0a9-42e9-9523-e181ce05a25b` | ICP-Brasil AD-RT, with a timestamp (explicit policy) | ICP-Brasil |
| `PkiBrazil.BasicWithPkiBrazilCerts` | `3fec800c-366c-49bf-82c5-2e72154e70f6` | PAdES basic | ICP-Brasil |
| `PkiBrazil.PadesTWithPkiBrazilCerts` | `6a39aeea-a2d0-4754-bf8c-19da15296ddb` | PAdES-T, with a timestamp | ICP-Brasil |

The policies with a timestamp use the security context's timestamp plan (see
[Settings of a security context](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/security-contexts#settings)).

`StandardPadesSignaturePolicies.PkiBrazil` also has `AdrCompleta` and `AdrArquivamento`, but the server doesn't accept them: the call fails
with `SignaturePolicyNotFound`.

### Default policy and explicit policies

On validation, the PDF may declare an explicit policy (ICP-Brasil AD-RB or AD-RT) or none. Two parameters decide how each signature is
validated:

* `acceptableExplicitPolicies` lists the explicit policies to accept. Only `PkiBrazil.AdrBasica` and `PkiBrazil.AdrTempo` can be on the list.
  The others are implicit, and the call fails with `InvalidRequest`.
* `defaultSignaturePolicyId` validates the signatures that declare no policy and those that declare a policy not on the list. Without it,
  those signatures fail validation.

With Adobe Reader as the `defaultSignaturePolicyId`, ICP-Brasil PAdES signatures pass too, because Adobe Reader requires less than AD-RB. To
require the ICP-Brasil standard, use `acceptableExplicitPolicies` without `defaultSignaturePolicyId` (see the
[example](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/security-contexts-and-signature-policies#require-pki-brazil)).

## The Adobe Reader policy

The Adobe Reader policy (`aaed831b-fa9d-4732-82fc-8d25f2c16c57`) starts from PAdES basic and relaxes the format checks:

* It doesn't require the mandatory signed attributes, such as `signing-certificate`.
* It accepts unknown attributes and attributes PAdES forbids, such as `signing-time` inside the CMS signature.
* It accepts any hash and signature algorithm.

The rest of the validation is unchanged: the document's integrity, the certificate chain, revocation and trust in the security context. That's
why the policy requires a security context, and a certificate outside it is still rejected.

It's an implicit policy: use it as `defaultSignaturePolicyId`, never in `acceptableExplicitPolicies`.

When signing, Adobe Reader produces the signature in Adobe's format (subfilter `adbe.pkcs7.detached`) and without LTV data. That works on
Rest PKI Core 4.1.2 and later, through the Rest PKI PAdES signature start route. On Rest PKI, Adobe Reader is for validation only.

> **Note: What Adobe Reader shows**
>
> The policy's name has nothing to do with what Adobe Reader shows when it opens the PDF. Adobe Reader validates with Adobe's own list of roots
> (AATL) and its settings, not with the Rest PKI Core security context. A signature valid on Rest PKI Core may show as not verified in Adobe
> Reader. See [Certificates trusted by Adobe](https://docs.lacunasoftware.com/en-us/articles/pki-guide/adobe-trust) and
> [Adobe Reader validation](https://docs.lacunasoftware.com/en-us/articles/pki-sdk/signatures/pades/adobe-validation).

## Examples

The examples validate through the `Api/PadesSignatures/Open` route. In the Rest PKI client libraries, which work with a Rest PKI Core key, the
`PadesSignatureExplorer` calls it (see [Moving from Rest PKI](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/migrating-from-rest-pki)).

### Accepting Adobe signatures from several hierarchies

A PDF has signatures from ICP-Brasil (some made in Adobe Acrobat), gov.br and e-Notariado, and you want to validate all of them. Use the
`PkiBrazilWithGovBrAndENotariado` security context, which trusts the three hierarchies, and the Adobe Reader policy as the default.

#### Python

With the [restpki-client](https://pypi.org/project/restpki-client/) package:

```python
from restpki_client import PadesSignatureExplorer, RestPkiClient

ADOBE_READER = 'aaed831b-fa9d-4732-82fc-8d25f2c16c57'
PKI_BRAZIL_WITH_GOVBR_AND_ENOTARIADO = '4bf4409f-db45-4aab-91bf-2c73930ca556'

client = RestPkiClient('https://your-instance.example.com/', 'YOUR_API_KEY')

explorer = PadesSignatureExplorer(client)
explorer.signature_file_path = 'signed-document.pdf'
explorer.validate = True
explorer.default_signature_policy_id = ADOBE_READER
explorer.security_context_id = PKI_BRAZIL_WITH_GOVBR_AND_ENOTARIADO

signature = explorer.open()
for signer in signature.signers:
    name = signer.certificate.subject_name.common_name
    results = signer.validation_results
    if results is None:
        print(name, '- not validated')
    elif results.is_valid:
        print(name, '- valid')
    else:
        print(name, '- invalid')
        for error in results.errors:
            print('   ', error.item_type, error.message, error.detail)
```

#### .NET

With the `Lacuna.RestPkiCore.Client` package, which brings `Lacuna.RestPki.Client`:

```cs
var client = new RestPkiClient("https://your-instance.example.com/", "YOUR_API_KEY");

var explorer = new PadesSignatureExplorer(client) {
	Validate = true,
	DefaultSignaturePolicyId = StandardPadesSignaturePolicies.AdobeReader,
	SecurityContextId = StandardSecurityContexts.PkiBrazilWithGovBrAndENotariado,
};
explorer.SetSignatureFile("signed-document.pdf");

var signature = await explorer.OpenAsync();
foreach (var signer in signature.Signers) {
	var name = signer.Certificate.SubjectName.CommonName;
	if (signer.ValidationResults == null) {
		Console.WriteLine($"{name} - not validated");
	} else if (signer.ValidationResults.IsValid) {
		Console.WriteLine($"{name} - valid");
	} else {
		Console.WriteLine($"{name} - invalid");
		Console.WriteLine(signer.ValidationResults);
	}
}
```

#### REST

```bash
curl -X POST "https://your-instance.example.com/Api/PadesSignatures/Open" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "file": { "content": "<PDF in Base64>", "mimeType": "application/pdf" },
    "validate": true,
    "defaultSignaturePolicyId": "aaed831b-fa9d-4732-82fc-8d25f2c16c57",
    "securityContextId": "4bf4409f-db45-4aab-91bf-2c73930ca556"
  }'
```

Each signer comes back with its own validation results. A signer whose certificate doesn't end at any of the three roots fails with
`CertificateChainRootNotTrusted`, without affecting the others.

### Validating one hierarchy only

To check only the signatures of one hierarchy, use a security context that trusts only that one, such as `GovBR`
(`5d323217-c031-4eed-9001-1cd82d86a8b5`) or `PkiBrazil` (`201856ce-273c-4058-a872-8937bd547d36`), and keep the policy. With `GovBR`, the
gov.br signatures pass, and the ICP-Brasil ones in the same PDF come back with `CertificateChainRootNotTrusted`. That's expected: the security
context doesn't trust them.

To tell the signatures apart by hierarchy in a single call, use the security context that trusts all of them and look at each signer's
certificate issuer.

### Requiring the ICP-Brasil PAdES standard

To accept only signatures that follow the ICP-Brasil AD-RB or AD-RT policies, list them in `acceptableExplicitPolicies` and leave out
`defaultSignaturePolicyId`. A signature made in Adobe, which declares no policy, fails.

```cs
var explorer = new PadesSignatureExplorer(client) {
	Validate = true,
	AcceptableExplicitPolicies = SignaturePolicyCatalog.GetPkiBrazilPades(),
	SecurityContextId = StandardSecurityContexts.PkiBrazil,
};
```

In the REST API, send `"acceptableExplicitPolicies": ["531d5012-4c0d-4b6f-89e8-ebdcc605d7c2", "10f0d9a5-a0a9-42e9-9523-e181ce05a25b"]`.

### Signing in Adobe's format

To produce a signature in Adobe's format, without LTV data, start the PAdES signature with the Adobe Reader policy and a security context:

```cs
var starter = new PadesSignatureStarter(client) {
	SignaturePolicyId = StandardPadesSignaturePolicies.AdobeReader,
	SecurityContextId = StandardSecurityContexts.PkiBrazil,
};
```

The rest of the flow is that of a Rest PKI PAdES signature (see [Using Rest PKI on .NET](https://docs.lacunasoftware.com/en-us/articles/rest-pki/dotnet)). Prefer the PAdES
basic or AD-RB policy unless a system requires Adobe's format.

## Common errors

| Error | Cause | What to do |
| --- | --- | --- |
| `SecurityContextRequired` | The policy trusts no root (`Basic`, `BasicWithoutLtv`, `AdobeReader`) and the call gave no `securityContextId` | Pass the security context |
| `InvalidRequest` (*implicit policy*) | An implicit policy, such as Adobe Reader, was passed in `acceptableExplicitPolicies` | Pass it in `defaultSignaturePolicyId` |
| `SignaturePolicyNotFound` | The ID isn't a policy the server accepts, such as AD-RC or AD-RA for PDF | Use a policy from the [table](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/security-contexts-and-signature-policies#pdf-policies) |
| `RequiredSignedAttributeMissing` (`signing-certificate`) | The signature doesn't follow PAdES, like those made in Adobe Acrobat | Validate with the Adobe Reader policy |
| `CertificateChainRootNotTrusted` | The certificate doesn't end at a root of the security context | Use a security context that trusts the certificate's hierarchy |

Validation covers only the first signers of each file (10 by default; see [Signature inspection](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/signature-inspection#validation)). The
rest come back without validation results. And a file signed on the instance itself comes back as stored when it was signed, without a new
validation: the call's security context and policy aren't used.

## On Rest PKI

On [Rest PKI](https://docs.lacunasoftware.com/en-us/articles/rest-pki/validate-signatures) the relationship is the same, with these differences:

* The Adobe Reader policy is for validation only.
* The standard security contexts are only `PkiBrazil`, `PkiItaly`, `WindowsServer` and `LacunaTest`, without the gov.br and e-Notariado ones.

## See also

* [Security contexts](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/security-contexts)
* [Signature inspection](https://docs.lacunasoftware.com/en-us/articles/rest-pki/core/integration/signature-inspection)
* [Validating signatures on Rest PKI](https://docs.lacunasoftware.com/en-us/articles/rest-pki/validate-signatures)
* [Certificates trusted by Adobe](https://docs.lacunasoftware.com/en-us/articles/pki-guide/adobe-trust)
