Scopes e irreversibilidad
Cómo leer el scope requerido y la irreversibilidad de cada endpoint desde la especificación OpenAPI — las extensiones x-required-scope y x-irreversible — y el catálogo de operaciones irreversibles.
Cada endpoint público declara dos piezas de metadata de seguridad en la
especificación OpenAPI: el scope exacto que enforza y si la operación se puede
deshacer. Los clientes (el CLI, los agentes, tu propio tooling)
las leen para fallar pronto — bloquear una llamada cuando la key carece del
scope, confirmar antes de una acción irreversible — en lugar de descubrir el
problema por un 403 o una mutación irrecuperable.
Leerlo desde la especificación
Cada operación en la especificación OpenAPI lleva dos extensiones personalizadas:
{
"operationId": "public-api.v1.invoices.delete",
"x-required-scope": "invoices:delete",
"x-irreversible": true
}x-required-scope— el único scoperesource:actionque la API key debe tener para llamar a la operación. Presente en todas las operaciones.x-irreversible—truesolo en las operaciones que no se pueden deshacer. Ausente (tratado comofalse) en todo lo demás.
Son extensiones de proveedor x-*, así que un visor OpenAPI genérico puede no
renderizarlas — pero cualquier cliente que parsee la especificación (como el
CLI) las lee directamente. Genera un cliente desde la especificación y heredas
ambas.
Scopes
Los scopes son resource:action (p. ej. invoices:read, clients:delete) — el
mismo catálogo cerrado que usan la REST API y las API keys. Una petición cuya
key carece del scope devuelve 403 con code: insufficient_scope. Pide solo
los scopes que tu integración necesita.
El catálogo completo — cada scope, qué concede, y los sensibles — está en
Scopes y permisos. Un scope no siempre se deriva del nombre
del recurso: algunos endpoints enforzan un scope distinto del que adivinarías
(las descargas de PDF enforzan pdfs:read, los métodos de pago enforzan
invoices:read, las transiciones de estado enforzan un scope :transition, las
acciones de VeriFactu enforzan verifactu:*). Lee siempre x-required-scope en
lugar de inferirlo.
Una API key puede tener el super-scope *, que satisface cualquier
x-required-scope. Consulta Autenticación.
Operaciones irreversibles
Una operación marcada x-irreversible: true no tiene deshacer: borra datos,
emite un registro fiscal, transiciona un documento a un estado terminal, o rota
un secret. El CLI pide una confirmación
tipada antes de ejecutar una; tu propio tooling debería protegerlas igual.
Estas son las categorías que llevan x-irreversible: true:
| Categoría | Ejemplos | Scope |
|---|---|---|
| Borrados (individuales) | clients.delete, invoices.delete, products.delete, taxes.delete, webhook_endpoints.delete… | <resource>:delete |
| Borrados masivos | invoices.bulk_delete, clients.bulk_delete, products.bulk_delete, suppliers.bulk_delete… | <resource>:delete |
| Emisión / numeración fiscal | invoices.send, invoices.mark_sent, invoices.assign_real_number, invoices.corrective, invoices.substitute_simplified | invoices:send / invoices:write |
| Void / anulación | invoices.void, invoices.annul | invoices:void |
| Conversiones terminales | quotes.convert, proformas.convert, delivery_notes.convert | <resource>:transition |
| Cancelar / firmar | delivery_notes.cancel, delivery_notes.sign, recurring_invoices.cancel, recurring_invoices.generate | <resource>:transition / :write |
| VeriFactu (AEAT) | invoices.verifactu_create, verifactu.records.subsanar, verifactu.settings.update, verifactu.certificates.revoke | verifactu:write |
| Secret / certificado | webhook_endpoints.rotate_secret, verifactu.certificates.revoke | webhooks:write / verifactu:write |
| Olvido GDPR | delivery_notes.signature_audits.forget | delivery_notes:gdpr_forget |
| Envío FacturaE (B2G) | invoices.face_submissions.submit, face_submissions.cancel | facturae:write |
Esta lista es el resumen legible. La fuente de verdad legible por máquina
es x-irreversible en la especificación — un cliente que la lee se mantiene
correcto aunque el catálogo crezca.
Juntándolo todo
Un cliente seguro hace dos comprobaciones antes de una mutación:
- Scope-check — ¿tiene la key el
x-required-scope? Si no, para en local (sin gastar un round trip). El CLI sale con4; consulta scope-check. - Confirmación de irreversibilidad — ¿es
x-irreversibletrue? Si lo es, confirma antes de llamar. El CLI requiere--confirm <id>; consulta operaciones irreversibles.
Los SDKs oficiales y el CLI hacen ambas por ti. Si generas tu propio cliente desde la especificación, cablea estas dos comprobaciones tú mismo desde las extensiones.