docs(ccsp): formalize ccsp v1 json schema error catalog and versioning policy

This commit is contained in:
Claudecio Martins
2026-10-20 16:28:33 -03:00
parent 92d4ea3411
commit e9f90b42cb
2 changed files with 397 additions and 11 deletions
+41 -11
View File
@@ -357,22 +357,52 @@ Quando qualquer operação falha, o servidor local CCSP/1 responde com um objeto
}
```
### Mapeamento de Status HTTP
### Lista Completa de Códigos de Erro Estruturados
| Código HTTP | Erro Típico | Descrição |
Todos os códigos de erro são estáveis, estruturados e interoperáveis entre o backend Java e o SDK JavaScript:
| Código de Erro (`error_code`) | Descrição e Causa Raiz | Mapeamento no SDK |
|---|---|---|
| `400 Bad Request` | `USER_CANCELLED`, `PIN_INCORRECT`, `SIGNATURE_FAILED` | Requisição malformada, cancelamento pelo usuário ou falha de PIN |
| `401 Unauthorized` | `APPLICATION_NOT_AUTHORIZED` | Aplicação não autorizada ou sem cabeçalho `X-CyberCore-AppId` |
| `403 Forbidden` | `INVALID_ORIGIN` | Cabeçalho `Origin` não confere com o domínio cadastrado |
| `404 Not Found` | `CERTIFICATE_NOT_FOUND`, `TOKEN_NOT_FOUND` | Certificado ou dispositivo físico ausente |
| `409 Conflict` | `REPLAY_DETECTED` | Nonce já utilizado anteriormente na janela de validação |
| `422 Unprocessable`| `REQUEST_EXPIRED`, `CERTIFICATE_EXPIRED` | Parâmetros sintaticamente válidos mas expirados temporalmente |
| `500 Server Error` | `PKCS11_ERROR`, `PROVIDER_NOT_AVAILABLE` | Falha interna no middleware do fabricante ou driver criptográfico |
| `503 Service Unavail`| `TOKEN_REMOVED`, `COMMUNICATION_ERROR` | Hardware desconectado ou serviço em recuperação |
| `CERTIFICATE_NOT_FOUND` | Certificado não encontrado pelo ID ou hint especificado | `CertificateNotFoundError` |
| `CERTIFICATE_EXPIRED` | Certificado ultrapassou a data limite de validade (`notAfter`) | `CertificateExpiredError` |
| `CERTIFICATE_INVALID` | Certificado corrompido, revogado ou com estrutura X.509 inválida | `CertificateInvalidError` |
| `PRIVATE_KEY_NOT_AVAILABLE` | Chave privada inacessível, protegida por hardware desconectado ou ausente | `PrivateKeyNotAvailableError` |
| `TOKEN_NOT_FOUND` | Nenhum token USB, smart card ou leitora física detectada | `TokenNotFoundError` |
| `TOKEN_REMOVED` | O dispositivo físico foi desconectado durante a operação | `TokenNotFoundError` |
| `PIN_REQUIRED` | O hardware criptográfico A3 exige digitação de PIN para desbloqueio | `PinRequiredError` |
| `PIN_INCORRECT` | O PIN digitado pelo usuário foi rejeitado pelo token (risco de bloqueio de PUK) | `PinIncorrectError` |
| `PKCS11_ERROR` | Falha interna no driver, middleware PKCS#11 ou DLL do fabricante | `CyberCoreError` |
| `SIGNATURE_FAILED` | Erro matemático na cifra assimétrica ou payload malformado | `SignatureFailedError` |
| `APPLICATION_NOT_AUTHORIZED` | A aplicação web solicitante não possui autorização concedida pelo usuário | `ApplicationNotAuthorizedError` |
| `REQUEST_EXPIRED` | O timestamp `expires_at` da requisição foi ultrapassado (timeout) | `RequestExpiredError` |
| `REPLAY_DETECTED` | O identificador `nonce` já foi processado anteriormente (ataque de replay) | `ReplayDetectedError` |
| `INVALID_ORIGIN` | O cabeçalho `Origin` não confere com os domínios homologados para o AppId | `InvalidOriginError` |
| `INVALID_HOST` | O cabeçalho `Host` foi adulterado (tentativa de DNS Rebinding) | `CyberCoreError` |
| `UNSUPPORTED_ALGORITHM` | Algoritmo criptográfico solicitado não é suportado pelo provider | `UnsupportedAlgorithmError` |
| `USER_CANCELLED` | O usuário clicou explicitamente em 'Cancelar' no diálogo nativo do sistema | `UserCancelledError` |
| `PROVIDER_NOT_AVAILABLE` | Provedor criptográfico nativo indisponível na plataforma atual | `ProviderNotAvailableError` |
| `COMMUNICATION_ERROR` | Falha na camada de transporte HTTP local do loopback | `CyberCoreError` |
| `AGENT_NOT_RUNNING` | O agente desktop não está rodando em 127.0.0.1:21325 (lado SDK) | `AgentNotRunningError` |
---
## 5. Diagrama de Sequência Completo
## 5. Especificação JSON Schema e Versionamento
O contrato canônico e exaustivo de todos os endpoints e payloads do protocolo CCSP/1 está formalizado no arquivo:
- [docs/ccsp-v1.schema.json](file:///var/www/cybercore/cybercore-signer/docs/ccsp-v1.schema.json)
### Política de Versionamento e Retrocompatibilidade
1. **Identificador de Versão Maior (`version: "1"`):**
- O campo `version` em todos os requests e responses identifica a versão maior do protocolo. O agente desktop garante compatibilidade retroativa com todas as revisões do CCSP/1.
2. **Evolução Aditiva (Não Quebrante):**
- Novos campos opcionais de requisição e novos metadados informativos de resposta podem ser adicionados dentro da versão CCSP/1 sem quebrar clientes existentes. Clientes e servidores devem ignorar propriedades adicionais desconhecidas (`additionalProperties` tolerantes).
3. **Mudança Quebrante (Nova Versão Maior):**
- Qualquer alteração na semântica de autenticação, remoção de campos obrigatórios ou mudança estrutural de URLs exigirá a introdução de uma nova versão de protocolo (ex: CCSP/2 com prefixo `/ccsp/v2/`). O agente manterá os endpoints `/ccsp/v1/` operacionais em paralelo para garantir transição suave.
---
## 6. Diagrama de Sequência Completo
```mermaid
sequenceDiagram
+356
View File
@@ -0,0 +1,356 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://cybercore.com.br/schemas/ccsp-v1.json",
"title": "CyberCore Signing Protocol v1 (CCSP/1) Specification",
"description": "Especificação formal do protocolo JSON para comunicação local entre aplicações web e o agente desktop CyberCore Signer.",
"type": "object",
"properties": {
"version": {
"type": "string",
"enum": ["1"],
"description": "Versão do protocolo CCSP (sempre '1' para CCSP/1)."
}
},
"definitions": {
"ErrorCode": {
"type": "string",
"enum": [
"CERTIFICATE_NOT_FOUND",
"CERTIFICATE_EXPIRED",
"CERTIFICATE_INVALID",
"PRIVATE_KEY_NOT_AVAILABLE",
"TOKEN_NOT_FOUND",
"TOKEN_REMOVED",
"PIN_REQUIRED",
"PIN_INCORRECT",
"PKCS11_ERROR",
"SIGNATURE_FAILED",
"APPLICATION_NOT_AUTHORIZED",
"REQUEST_EXPIRED",
"REPLAY_DETECTED",
"INVALID_ORIGIN",
"INVALID_HOST",
"UNSUPPORTED_ALGORITHM",
"USER_CANCELLED",
"PROVIDER_NOT_AVAILABLE",
"COMMUNICATION_ERROR",
"BAD_REQUEST",
"METHOD_NOT_ALLOWED"
],
"description": "Códigos formais de erro estruturados do protocolo CCSP/1."
},
"ErrorResponse": {
"type": "object",
"required": ["version", "status", "error_code", "message"],
"properties": {
"version": { "type": "string", "enum": ["1"] },
"status": { "type": "string", "enum": ["error"] },
"error_code": { "$ref": "#/definitions/ErrorCode" },
"message": { "type": "string" },
"request_id": { "type": ["string", "null"] }
},
"additionalProperties": true
},
"StatusResponse": {
"type": "object",
"required": ["version", "status", "agent", "agent_version", "os", "timestamp"],
"properties": {
"version": { "type": "string", "enum": ["1"] },
"status": { "type": "string", "enum": ["ready", "busy", "error"] },
"agent": { "type": "string" },
"agent_version": { "type": "string" },
"os": { "type": "string" },
"timestamp": { "type": "string" }
},
"additionalProperties": true
},
"AuthorizeRequest": {
"type": "object",
"required": ["version", "application_id"],
"properties": {
"version": { "type": "string", "enum": ["1"] },
"application_id": { "type": "string", "pattern": "^[0-9a-fA-F-]{36}$" },
"name": { "type": "string" }
},
"additionalProperties": true
},
"AuthorizeResponse": {
"type": "object",
"required": ["version", "status", "application_id"],
"properties": {
"version": { "type": "string", "enum": ["1"] },
"status": { "type": "string", "enum": ["authorized"] },
"application_id": { "type": "string" },
"message": { "type": "string" }
},
"additionalProperties": true
},
"CertificateItem": {
"type": "object",
"required": ["id", "alias", "type", "can_sign", "status"],
"properties": {
"id": { "type": "string" },
"alias": { "type": "string" },
"common_name": { "type": ["string", "null"] },
"subject_dn": { "type": ["string", "null"] },
"issuer_dn": { "type": ["string", "null"] },
"type": { "type": "string", "enum": ["A1", "A3"] },
"provider_id": { "type": ["string", "null"] },
"device_name": { "type": ["string", "null"] },
"valid_from": { "type": ["string", "null"] },
"valid_to": { "type": ["string", "null"] },
"serial_number": { "type": ["string", "null"] },
"cpf": { "type": ["string", "null"] },
"cnpj": { "type": ["string", "null"] },
"can_sign": { "type": "boolean" },
"status": { "type": "string" }
},
"additionalProperties": true
},
"CertificatesResponse": {
"type": "object",
"required": ["version", "status", "certificates"],
"properties": {
"version": { "type": "string", "enum": ["1"] },
"status": { "type": "string", "enum": ["success"] },
"certificates": {
"type": "array",
"items": { "$ref": "#/definitions/CertificateItem" }
}
},
"additionalProperties": true
},
"SealThemeItem": {
"type": "object",
"required": ["id", "name"],
"properties": {
"id": { "type": "string" },
"name": { "type": "string" },
"description": { "type": ["string", "null"] },
"width": { "type": "number" },
"height": { "type": "number" },
"primary_color": { "type": ["string", "null"] },
"secondary_color": { "type": ["string", "null"] },
"background_color": { "type": ["string", "null"] },
"border_color": { "type": ["string", "null"] },
"text_color": { "type": ["string", "null"] },
"icon_style": { "type": ["string", "null"] },
"custom": { "type": "boolean" }
},
"additionalProperties": true
},
"SealsResponse": {
"type": "object",
"required": ["version", "status", "themes"],
"properties": {
"version": { "type": "string", "enum": ["1"] },
"status": { "type": "string", "enum": ["success"] },
"default_seal_id": { "type": ["string", "null"] },
"themes": {
"type": "array",
"items": { "$ref": "#/definitions/SealThemeItem" }
}
},
"additionalProperties": true
},
"SignRequest": {
"type": "object",
"required": [
"version",
"request_id",
"application_id",
"operation",
"algorithm",
"digest",
"nonce",
"expires_at"
],
"properties": {
"version": { "type": "string", "enum": ["1"] },
"request_id": { "type": "string" },
"application_id": { "type": "string" },
"operation": { "type": "string", "enum": ["sign", "authenticate"] },
"algorithm": { "type": "string" },
"digest": { "type": "string", "description": "Digest SHA-256 em Base64" },
"certificate_hint": { "type": ["string", "null"] },
"document_name": { "type": ["string", "null"] },
"document_type": { "type": ["string", "null"] },
"purpose": { "type": ["string", "null"] },
"challenge": { "type": ["string", "null"] },
"nonce": { "type": "string" },
"expires_at": { "type": "string" }
},
"additionalProperties": true
},
"SignResponse": {
"type": "object",
"required": [
"version",
"request_id",
"status",
"signature",
"certificate",
"algorithm"
],
"properties": {
"version": { "type": "string", "enum": ["1"] },
"request_id": { "type": "string" },
"status": { "type": "string", "enum": ["signed", "authenticated"] },
"signature": { "type": "string", "description": "Assinatura digital em Base64" },
"certificate": { "type": "string", "description": "Certificado X.509 do signatário em Base64" },
"certificate_chain": {
"type": "array",
"items": { "type": "string" }
},
"algorithm": { "type": "string" },
"sha256": { "type": ["string", "null"] },
"subject_name": { "type": ["string", "null"] },
"subject_cpf_cnpj": { "type": ["string", "null"] },
"document_name": { "type": ["string", "null"] },
"document_type": { "type": ["string", "null"] },
"challenge": { "type": ["string", "null"] }
},
"additionalProperties": true
},
"SignPdfRequest": {
"type": "object",
"required": [
"version",
"request_id",
"application_id",
"operation",
"pdf",
"nonce",
"expires_at"
],
"properties": {
"version": { "type": "string", "enum": ["1"] },
"request_id": { "type": "string" },
"application_id": { "type": "string" },
"operation": { "type": "string", "enum": ["sign_pdf"] },
"pdf": { "type": "string", "description": "Documento PDF completo codificado em Base64" },
"certificate_hint": { "type": ["string", "null"] },
"document_name": { "type": ["string", "null"] },
"page": { "type": ["integer", "null"] },
"page_choice": { "type": ["string", "null"] },
"position": { "type": ["string", "null"] },
"x": { "type": ["number", "null"] },
"y": { "type": ["number", "null"] },
"scale": { "type": ["number", "null"] },
"visible_seal": { "type": ["boolean", "null"] },
"seal_theme_id": { "type": ["string", "null"] },
"seal_custom": { "type": ["object", "null"] },
"reason": { "type": ["string", "null"] },
"location": { "type": ["string", "null"] },
"cpf_display_mode": { "type": ["string", "null"] },
"include_date_time": { "type": ["boolean", "null"] },
"custom_extra_info": { "type": ["string", "null"] },
"nonce": { "type": "string" },
"expires_at": { "type": "string" }
},
"additionalProperties": true
},
"SignPdfResponse": {
"type": "object",
"required": [
"version",
"request_id",
"status",
"signed_pdf",
"signature",
"certificate",
"algorithm"
],
"properties": {
"version": { "type": "string", "enum": ["1"] },
"request_id": { "type": "string" },
"status": { "type": "string", "enum": ["signed"] },
"signed_pdf": { "type": "string", "description": "PDF assinado completo com envelope PAdES em Base64" },
"sha256": { "type": ["string", "null"] },
"signature": { "type": "string" },
"certificate": { "type": "string" },
"certificate_chain": {
"type": "array",
"items": { "type": "string" }
},
"algorithm": { "type": "string" },
"subject_name": { "type": ["string", "null"] },
"subject_cpf_cnpj": { "type": ["string", "null"] },
"document_name": { "type": ["string", "null"] }
},
"additionalProperties": true
},
"SignXmlRequest": {
"type": "object",
"required": [
"version",
"request_id",
"application_id",
"operation",
"nonce",
"expires_at"
],
"properties": {
"version": { "type": "string", "enum": ["1"] },
"request_id": { "type": "string" },
"application_id": { "type": "string" },
"operation": { "type": "string", "enum": ["sign_xml"] },
"xml": { "type": ["string", "null"], "description": "XML em texto puro UTF-8" },
"xml_base64": { "type": ["string", "null"], "description": "XML codificado em Base64" },
"certificate_hint": { "type": ["string", "null"] },
"document_name": { "type": ["string", "null"] },
"profile": { "type": ["string", "null"], "enum": ["XADES_BES", "XMLDSIG", null] },
"target_element_tag": { "type": ["string", "null"] },
"target_element_id": { "type": ["string", "null"] },
"algorithm": { "type": ["string", "null"] },
"nonce": { "type": "string" },
"expires_at": { "type": "string" }
},
"additionalProperties": true
},
"SignXmlResponse": {
"type": "object",
"required": [
"version",
"request_id",
"status",
"signed_xml",
"signature",
"certificate",
"algorithm"
],
"properties": {
"version": { "type": "string", "enum": ["1"] },
"request_id": { "type": "string" },
"status": { "type": "string", "enum": ["signed"] },
"signed_xml": { "type": "string", "description": "Documento XML assinado completo com assinatura enveloped" },
"sha256": { "type": ["string", "null"] },
"signature": { "type": "string" },
"certificate": { "type": "string" },
"certificate_chain": {
"type": "array",
"items": { "type": "string" }
},
"algorithm": { "type": "string" },
"subject_name": { "type": ["string", "null"] },
"subject_cpf_cnpj": { "type": ["string", "null"] },
"document_name": { "type": ["string", "null"] }
},
"additionalProperties": true
}
}
}