@jantstack/adonis-authz 2.0.0-alpha.1 → 2.4.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +462 -35
- package/build/commands/authz_catalog_diff.js +1 -1
- package/build/commands/authz_catalog_diff.js.map +1 -1
- package/build/commands/authz_catalog_prune_orphans.d.ts +78 -0
- package/build/commands/authz_catalog_prune_orphans.d.ts.map +1 -0
- package/build/commands/authz_catalog_prune_orphans.js +136 -0
- package/build/commands/authz_catalog_prune_orphans.js.map +1 -0
- package/build/commands/authz_catalog_sync.d.ts +17 -0
- package/build/commands/authz_catalog_sync.d.ts.map +1 -1
- package/build/commands/authz_catalog_sync.js +27 -4
- package/build/commands/authz_catalog_sync.js.map +1 -1
- package/build/commands/authz_freeze.d.ts +44 -0
- package/build/commands/authz_freeze.d.ts.map +1 -0
- package/build/commands/authz_freeze.js +95 -0
- package/build/commands/authz_freeze.js.map +1 -0
- package/build/commands/authz_reconcile.d.ts +102 -0
- package/build/commands/authz_reconcile.d.ts.map +1 -0
- package/build/commands/authz_reconcile.js +294 -0
- package/build/commands/authz_reconcile.js.map +1 -0
- package/build/commands/authz_relations_reconcile.d.ts +73 -0
- package/build/commands/authz_relations_reconcile.d.ts.map +1 -0
- package/build/commands/authz_relations_reconcile.js +225 -0
- package/build/commands/authz_relations_reconcile.js.map +1 -0
- package/build/commands/authz_scopes_relay.d.ts +47 -0
- package/build/commands/authz_scopes_relay.d.ts.map +1 -0
- package/build/commands/authz_scopes_relay.js +141 -0
- package/build/commands/authz_scopes_relay.js.map +1 -0
- package/build/commands/authz_unfreeze.d.ts +37 -0
- package/build/commands/authz_unfreeze.d.ts.map +1 -0
- package/build/commands/authz_unfreeze.js +92 -0
- package/build/commands/authz_unfreeze.js.map +1 -0
- package/build/commands/main.d.ts +6 -1
- package/build/commands/main.d.ts.map +1 -1
- package/build/commands/main.js +6 -1
- package/build/commands/main.js.map +1 -1
- package/build/commands/openfga_provision.d.ts +46 -4
- package/build/commands/openfga_provision.d.ts.map +1 -1
- package/build/commands/openfga_provision.js +90 -7
- package/build/commands/openfga_provision.js.map +1 -1
- package/build/configure.d.ts +11 -0
- package/build/configure.d.ts.map +1 -1
- package/build/configure.js +37 -1
- package/build/configure.js.map +1 -1
- package/build/index.d.ts +39 -10
- package/build/index.d.ts.map +1 -1
- package/build/index.js +35 -6
- package/build/index.js.map +1 -1
- package/build/providers/authz_provider.d.ts +26 -2
- package/build/providers/authz_provider.d.ts.map +1 -1
- package/build/providers/authz_provider.js +48 -2
- package/build/providers/authz_provider.js.map +1 -1
- package/build/services/relations.d.ts +14 -0
- package/build/services/relations.d.ts.map +1 -0
- package/build/services/relations.js +17 -0
- package/build/services/relations.js.map +1 -0
- package/build/src/{catalog.d.ts → catalog/catalog.d.ts} +41 -2
- package/build/src/catalog/catalog.d.ts.map +1 -0
- package/build/src/{catalog.js → catalog/catalog.js} +120 -14
- package/build/src/catalog/catalog.js.map +1 -0
- package/build/src/{catalog_cache.d.ts → catalog/catalog_cache.d.ts} +46 -22
- package/build/src/catalog/catalog_cache.d.ts.map +1 -0
- package/build/src/{catalog_cache.js → catalog/catalog_cache.js} +53 -43
- package/build/src/catalog/catalog_cache.js.map +1 -0
- package/build/src/define_config.d.ts +101 -3
- package/build/src/define_config.d.ts.map +1 -1
- package/build/src/define_config.js.map +1 -1
- package/build/src/drivers/database_driver.d.ts +86 -4
- package/build/src/drivers/database_driver.d.ts.map +1 -1
- package/build/src/drivers/database_driver.js +425 -11
- package/build/src/drivers/database_driver.js.map +1 -1
- package/build/src/drivers/database_relations_driver.d.ts +75 -0
- package/build/src/drivers/database_relations_driver.d.ts.map +1 -0
- package/build/src/drivers/database_relations_driver.js +450 -0
- package/build/src/drivers/database_relations_driver.js.map +1 -0
- package/build/src/drivers/openfga_driver.d.ts +713 -119
- package/build/src/drivers/openfga_driver.d.ts.map +1 -1
- package/build/src/drivers/openfga_driver.js +2048 -476
- package/build/src/drivers/openfga_driver.js.map +1 -1
- package/build/src/drivers/openfga_facts.d.ts +369 -0
- package/build/src/drivers/openfga_facts.d.ts.map +1 -0
- package/build/src/drivers/openfga_facts.js +813 -0
- package/build/src/drivers/openfga_facts.js.map +1 -0
- package/build/src/drivers/openfga_relations_driver.d.ts +120 -0
- package/build/src/drivers/openfga_relations_driver.d.ts.map +1 -0
- package/build/src/drivers/openfga_relations_driver.js +466 -0
- package/build/src/drivers/openfga_relations_driver.js.map +1 -0
- package/build/src/errors.d.ts +258 -5
- package/build/src/errors.d.ts.map +1 -1
- package/build/src/errors.js +238 -7
- package/build/src/errors.js.map +1 -1
- package/build/src/freeze.d.ts +120 -0
- package/build/src/freeze.d.ts.map +1 -0
- package/build/src/freeze.js +172 -0
- package/build/src/freeze.js.map +1 -0
- package/build/src/http/app_access_middleware.d.ts.map +1 -0
- package/build/src/http/app_access_middleware.js.map +1 -0
- package/build/src/http/resource_access_middleware.d.ts +105 -0
- package/build/src/http/resource_access_middleware.d.ts.map +1 -0
- package/build/src/http/resource_access_middleware.js +81 -0
- package/build/src/http/resource_access_middleware.js.map +1 -0
- package/build/src/identity.d.ts +74 -1
- package/build/src/identity.d.ts.map +1 -1
- package/build/src/identity.js +100 -2
- package/build/src/identity.js.map +1 -1
- package/build/src/manager.d.ts +315 -4
- package/build/src/manager.d.ts.map +1 -1
- package/build/src/manager.js +1187 -181
- package/build/src/manager.js.map +1 -1
- package/build/src/models/authz_assignment.d.ts +6 -6
- package/build/src/models/authz_assignment.d.ts.map +1 -1
- package/build/src/models/authz_deny.d.ts +6 -6
- package/build/src/models/authz_deny.d.ts.map +1 -1
- package/build/src/models/authz_permission.d.ts +6 -6
- package/build/src/models/authz_permission.d.ts.map +1 -1
- package/build/src/models/authz_role.d.ts +6 -6
- package/build/src/models/authz_role.d.ts.map +1 -1
- package/build/src/models/authz_role_permission.d.ts +6 -6
- package/build/src/models/authz_role_permission.d.ts.map +1 -1
- package/build/src/openfga.d.ts +18 -2
- package/build/src/openfga.d.ts.map +1 -1
- package/build/src/openfga.js +15 -1
- package/build/src/openfga.js.map +1 -1
- package/build/src/reconcile.d.ts +37 -0
- package/build/src/reconcile.d.ts.map +1 -0
- package/build/src/reconcile.js +69 -0
- package/build/src/reconcile.js.map +1 -0
- package/build/src/relation_partition_trigger.d.ts +8 -0
- package/build/src/relation_partition_trigger.d.ts.map +1 -0
- package/build/src/relation_partition_trigger.js +85 -0
- package/build/src/relation_partition_trigger.js.map +1 -0
- package/build/src/relations/define_relations_config.d.ts +58 -0
- package/build/src/relations/define_relations_config.d.ts.map +1 -0
- package/build/src/relations/define_relations_config.js +144 -0
- package/build/src/relations/define_relations_config.js.map +1 -0
- package/build/src/relations/manager.d.ts +38 -0
- package/build/src/relations/manager.d.ts.map +1 -0
- package/build/src/relations/manager.js +156 -0
- package/build/src/relations/manager.js.map +1 -0
- package/build/src/relations/reconcile.d.ts +62 -0
- package/build/src/relations/reconcile.d.ts.map +1 -0
- package/build/src/relations/reconcile.js +138 -0
- package/build/src/relations/reconcile.js.map +1 -0
- package/build/src/relations_config_store.d.ts +22 -0
- package/build/src/relations_config_store.d.ts.map +1 -0
- package/build/src/relations_config_store.js +74 -0
- package/build/src/relations_config_store.js.map +1 -0
- package/build/src/scope_outbox.d.ts +69 -0
- package/build/src/scope_outbox.d.ts.map +1 -0
- package/build/src/scope_outbox.js +291 -0
- package/build/src/scope_outbox.js.map +1 -0
- package/build/src/{drivers → shared}/backend_guard.d.ts +14 -0
- package/build/src/shared/backend_guard.d.ts.map +1 -0
- package/build/src/{drivers → shared}/backend_guard.js +26 -1
- package/build/src/shared/backend_guard.js.map +1 -0
- package/build/src/shared/sql_expiry.d.ts.map +1 -0
- package/build/src/shared/sql_expiry.js.map +1 -0
- package/build/src/sql_descendants.d.ts +47 -1
- package/build/src/sql_descendants.d.ts.map +1 -1
- package/build/src/sql_descendants.js +75 -1
- package/build/src/sql_descendants.js.map +1 -1
- package/build/src/testing/contract.d.ts +74 -0
- package/build/src/testing/contract.d.ts.map +1 -1
- package/build/src/testing/contract.js +672 -169
- package/build/src/testing/contract.js.map +1 -1
- package/build/src/testing/main.d.ts +6 -0
- package/build/src/testing/main.d.ts.map +1 -1
- package/build/src/testing/main.js +3 -0
- package/build/src/testing/main.js.map +1 -1
- package/build/src/testing/migration_contract.d.ts +284 -0
- package/build/src/testing/migration_contract.d.ts.map +1 -0
- package/build/src/testing/migration_contract.js +586 -0
- package/build/src/testing/migration_contract.js.map +1 -0
- package/build/src/testing/relations_contract.d.ts +51 -0
- package/build/src/testing/relations_contract.d.ts.map +1 -0
- package/build/src/testing/relations_contract.js +654 -0
- package/build/src/testing/relations_contract.js.map +1 -0
- package/build/src/testing/relations_reconcile_contract.d.ts +24 -0
- package/build/src/testing/relations_reconcile_contract.d.ts.map +1 -0
- package/build/src/testing/relations_reconcile_contract.js +172 -0
- package/build/src/testing/relations_reconcile_contract.js.map +1 -0
- package/build/src/traits/authz_scopes.js +1 -1
- package/build/src/traits/authz_scopes.js.map +1 -1
- package/build/src/traits/has_uuid.d.ts +7 -7
- package/build/src/traits/has_uuid.d.ts.map +1 -1
- package/build/src/types.d.ts +865 -82
- package/build/src/types.d.ts.map +1 -1
- package/build/src/types.js +10 -0
- package/build/src/types.js.map +1 -1
- package/build/stubs/config/authorization.stub +104 -4
- package/build/stubs/migration.stub +126 -0
- package/build/stubs/scopes_outbox_migration.stub +57 -0
- package/package.json +4 -2
- package/build/commands/openfga_import.d.ts +0 -34
- package/build/commands/openfga_import.d.ts.map +0 -1
- package/build/commands/openfga_import.js +0 -97
- package/build/commands/openfga_import.js.map +0 -1
- package/build/src/catalog.d.ts.map +0 -1
- package/build/src/catalog.js.map +0 -1
- package/build/src/catalog_cache.d.ts.map +0 -1
- package/build/src/catalog_cache.js.map +0 -1
- package/build/src/drivers/backend_guard.d.ts.map +0 -1
- package/build/src/drivers/backend_guard.js.map +0 -1
- package/build/src/drivers/sql_expiry.d.ts.map +0 -1
- package/build/src/drivers/sql_expiry.js.map +0 -1
- package/build/src/middleware/app_access_middleware.d.ts.map +0 -1
- package/build/src/middleware/app_access_middleware.js.map +0 -1
- /package/build/src/{middleware → http}/app_access_middleware.d.ts +0 -0
- /package/build/src/{middleware → http}/app_access_middleware.js +0 -0
- /package/build/src/{drivers → shared}/sql_expiry.d.ts +0 -0
- /package/build/src/{drivers → shared}/sql_expiry.js +0 -0
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
import type { CatalogProjectionRole, HolderTypeMap } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* `holderTypes` tiene que ser INYECTIVO. Si dos morph names caen en el mismo
|
|
4
|
+
* tipo FGA, para el store son un solo holder: un grant a `users:U` autoriza a
|
|
5
|
+
* `integrations:U`, `listSubjects` devuelve el morph equivocado y un revoke
|
|
6
|
+
* borra al otro (invariante 4, L0.2). El generador del modelo lo "sabía"
|
|
7
|
+
* (deduplicaba con un Set) y publicaba sin quejarse: ahora lanza aquí, al
|
|
8
|
+
* construir el driver y al generar cualquiera de los dos modelos, antes de
|
|
9
|
+
* tocar nada.
|
|
10
|
+
*/
|
|
11
|
+
export declare function assertHolderTypes(holderTypes: HolderTypeMap): void;
|
|
12
|
+
/**
|
|
13
|
+
* Longitud máxima de un nombre de relación en FGA. `MAX_SLUG_LENGTH` (42) es
|
|
14
|
+
* justo esto menos el prefijo derivado más largo (`permits_`), así que un
|
|
15
|
+
* slug legal siempre cabe: la comprobación de aquí es la red del generador,
|
|
16
|
+
* que también lo llaman herramientas con listas de permisos que no pasaron
|
|
17
|
+
* por `assertValidSlug` (una base sincronizada por otra versión, un driver
|
|
18
|
+
* de terceros).
|
|
19
|
+
*/
|
|
20
|
+
export declare const FGA_MAX_RELATION_NAME = 50;
|
|
21
|
+
/**
|
|
22
|
+
* Longitud máxima del id de un objeto FGA. Con la gramática publicada nada
|
|
23
|
+
* se acerca (`role_binding:<tipo>|<uuid>|<roleUuid>` son 107 como mucho),
|
|
24
|
+
* pero el id se compone de partes que vienen de la BASE: un catálogo
|
|
25
|
+
* corrupto no puede fabricar un objeto que el store no pueda leer de vuelta.
|
|
26
|
+
*/
|
|
27
|
+
export declare const FGA_MAX_OBJECT_ID = 256;
|
|
28
|
+
/**
|
|
29
|
+
* Techo del authorization model (default de
|
|
30
|
+
* `OPENFGA_MAX_AUTHORIZATION_MODEL_SIZE_IN_BYTES`). **El techo son BYTES; el
|
|
31
|
+
* número de permisos que caben NO es una propiedad del modelo** (3b-4 · C3):
|
|
32
|
+
* depende de cuántos holder types declaras, de cuánto miden sus NOMBRES en el
|
|
33
|
+
* modelo y de cuánto miden los slugs de tus permisos. Medido con
|
|
34
|
+
* `factsModelBytes` —que cuenta los mismos bytes que el servidor, contrastado
|
|
35
|
+
* contra un `:8101` real— y fijado por un caso (`3b-4 · C3`):
|
|
36
|
+
*
|
|
37
|
+
* | catálogo | permisos que caben |
|
|
38
|
+
* |---|---|
|
|
39
|
+
* | 1 holder type, slugs `p0`…`pN` | **800** |
|
|
40
|
+
* | 3 holder types (`user`/`admin`/`integration`), slugs `p0`…`pN` | **691** |
|
|
41
|
+
* | 1 holder type, slugs `docs:readN` | **576** |
|
|
42
|
+
* | 3 holder types, slugs `recursoN:accion` (REALISTAS) | **447** |
|
|
43
|
+
* | 3 holder types, slugs de 40 caracteres | **272** |
|
|
44
|
+
*
|
|
45
|
+
* O sea: el «≈691» que se publicó es la cifra de un catálogo cuyos permisos se
|
|
46
|
+
* llaman `p0`, `p1`, `p2`…; **con nombres de permiso normales el techo está en
|
|
47
|
+
* ~450**. Y los mismos tres holder types con nombres más cortos (`bot` en vez
|
|
48
|
+
* de `integration`) dan 721: no basta con decir «tres holder types».
|
|
49
|
+
*
|
|
50
|
+
* Se valida en `syncAuthzCatalog` ANTES de escribir el catálogo: un catálogo
|
|
51
|
+
* que no se puede publicar no se escribe a medias en un entorno y entero en
|
|
52
|
+
* otro. El gate por bytes es exacto y salta antes de escribir, así que
|
|
53
|
+
* equivocarse con la cifra derivada no concede nada: solo sorprende.
|
|
54
|
+
*/
|
|
55
|
+
export declare const FACTS_MODEL_MAX_BYTES = 262144;
|
|
56
|
+
/**
|
|
57
|
+
* **Profundidad máxima de cadena que el modelo (c2) resuelve** (3b-2e · E5),
|
|
58
|
+
* MEDIDA contra OpenFGA v1.19 con el `--resolve-node-limit` por defecto (25).
|
|
59
|
+
* Con el grant en la RAÍZ y el `Check` a profundidad creciente, 25
|
|
60
|
+
* repeticiones por punto:
|
|
61
|
+
*
|
|
62
|
+
* | saltos `parent` | `can_<P>` |
|
|
63
|
+
* |---|---|
|
|
64
|
+
* | 21 | 25/25 resuelve |
|
|
65
|
+
* | **22** | **25/25 resuelve** ← la cota que se declara |
|
|
66
|
+
* | 23 | resuelve casi siempre y **falla entre un 4 % y un 26 %** de las veces según la carga — el borde NO es nítido |
|
|
67
|
+
* | 24 | 0/25: siempre falla |
|
|
68
|
+
*
|
|
69
|
+
* (Remedido en 3b-4 · C4 sobre 50 hojas a la misma profundidad: a 22, 200 de
|
|
70
|
+
* 200 resuelven en cuatro lotes; a 23, entre 6 y 13 errores por lote de 50, y
|
|
71
|
+
* 15 de 100 en checks sueltos; a 24, 100 de 100 fallan.)
|
|
72
|
+
*
|
|
73
|
+
* Las otras dos ramas del modelo llegan más lejos (`denied_<P>` hasta 25,
|
|
74
|
+
* `ancestor` hasta 26): manda la más baja, y es `can_<P>` porque es una resta
|
|
75
|
+
* (`difference`) sobre una unión con DOS TTU (`binding` y `parent`), o sea dos
|
|
76
|
+
* reescrituras más que las otras.
|
|
77
|
+
*
|
|
78
|
+
* **Lo importante del hallazgo no es el número, es que el borde es
|
|
79
|
+
* PROBABILÍSTICO**: a 23 saltos la misma pregunta responde casi siempre y
|
|
80
|
+
* falla de vez en cuando (el presupuesto de nodos se consume de forma no
|
|
81
|
+
* determinista al resolver la unión). Por eso se declara **22**, que es la
|
|
82
|
+
* profundidad que resuelve SIEMPRE, y no el primer valor que falló. Un caso
|
|
83
|
+
* de la suite apoyado en 23 habría sido flaky en el artefacto publicado —la
|
|
84
|
+
* misma lección que 3G · Y1—, y de hecho lo fue una vez antes de medirlo.
|
|
85
|
+
*
|
|
86
|
+
* **Y por eso la constante se clava con REPETICIONES, no con una tirada**
|
|
87
|
+
* (3b-4 · C4): el par de casos original —positivo en la cota, negativo en la
|
|
88
|
+
* cota + 2— sujetaba el intervalo [22, 23] y no el 22 (con la constante a 23
|
|
89
|
+
* la suite seguía verde 3 corridas de 3, tester Fase 3b · M12b). El caso que
|
|
90
|
+
* lo cierra hace **500 resoluciones por lado** (10 lotes de 50 con
|
|
91
|
+
* `authorizeMany`): en la cota tienen que resolver las 500, y un salto más
|
|
92
|
+
* tiene que fallar al menos una vez. Con la tasa de fallo más baja jamás
|
|
93
|
+
* medida (4 %) un verde falso es 0,96^500 ≈ 1e-9.
|
|
94
|
+
*
|
|
95
|
+
* Los «~23» que citaba el panel (riesgo S9) eran de un modelo MÁS SIMPLE y
|
|
96
|
+
* estaban sin medir sobre (c2).
|
|
97
|
+
*
|
|
98
|
+
* Pasado el techo el servidor responde 400 («resolution required too many
|
|
99
|
+
* rewrite rules») y el paquete lo propaga como 503, **nunca como un `false`**
|
|
100
|
+
* (invariante 5): es fail-closed, pero es un DoS al alcance de quien pueda
|
|
101
|
+
* crear sub-scopes anidados, y `database` no tiene ese techo — el mismo árbol
|
|
102
|
+
* es legal en un driver y una caída en el otro. Sube
|
|
103
|
+
* `OPENFGA_RESOLVE_NODE_LIMIT` en el servidor si tu árbol es más profundo.
|
|
104
|
+
*/
|
|
105
|
+
export declare const FACTS_MAX_RESOLVE_DEPTH = 22;
|
|
106
|
+
/** Tope de checks por `batchCheck` en OpenFGA (el driver trocea en lotes de este tamaño). */
|
|
107
|
+
export declare const FGA_MAX_BATCH_CHECK = 50;
|
|
108
|
+
/** Fracción del techo a partir de la cual se avisa (cruce 9: "aviso al 80 %"). */
|
|
109
|
+
export declare const FACTS_MODEL_WARN_RATIO = 0.8;
|
|
110
|
+
/** El tipo FGA cuyo id es el uuid del rol del catálogo. */
|
|
111
|
+
export declare const FACTS_ROLE_TYPE = "role";
|
|
112
|
+
/** Prefijo de la familia que materializa el catálogo (`role:<uuid>#permits_<P>`). */
|
|
113
|
+
export declare const FACTS_PERMITS_PREFIX = "permits_";
|
|
114
|
+
/**
|
|
115
|
+
* **La relación de (c2r)**: «desde este scope se llega a la raíz `app`»
|
|
116
|
+
* (3b-2i). Es una relación PROPIA del modelo, como `parent` o `ancestor`, y
|
|
117
|
+
* la única que se escribe una vez por STORE en vez de por hecho: el marcador
|
|
118
|
+
* de raíz (`factsRootTuples`).
|
|
119
|
+
*/
|
|
120
|
+
export declare const FACTS_ROOTED_RELATION = "rooted";
|
|
121
|
+
/** Las CUATRO familias de (c2) para un permiso: `<P>`, `can_<P>`, `denied_<P>`, `permits_<P>`. */
|
|
122
|
+
export interface FactsRelations {
|
|
123
|
+
permission: string;
|
|
124
|
+
/** `<P>` en `role_binding` y en `scope`. */
|
|
125
|
+
base: string;
|
|
126
|
+
/** `can_<P>`: lo que responde `authorize`. */
|
|
127
|
+
can: string;
|
|
128
|
+
/** `denied_<P>`: el deny explícito, heredado hacia abajo. */
|
|
129
|
+
denied: string;
|
|
130
|
+
/** `permits_<P>`: la proyección del catálogo (qué permisos vincula un rol). */
|
|
131
|
+
permits: string;
|
|
132
|
+
}
|
|
133
|
+
/** Las cuatro relaciones que un permiso genera, sin validar nada. */
|
|
134
|
+
export declare function factsRelationsOf(permission: string): FactsRelations;
|
|
135
|
+
/**
|
|
136
|
+
* **S4, bloqueante del juez.** Con CUATRO familias, dos permisos distintos
|
|
137
|
+
* pueden generar el mismo nombre de relación: `can_x` sale del permiso
|
|
138
|
+
* `can_x` y también del permiso `x`. El generador de antes las colapsaba en
|
|
139
|
+
* silencio y el modelo publicado anulaba un deny (el auditor lo reprodujo de
|
|
140
|
+
* punta a punta con `allowed: true`). Se detecta con un `Map` nombre→origen
|
|
141
|
+
* y se LANZA: nunca se escribe un modelo ambiguo.
|
|
142
|
+
*
|
|
143
|
+
* Es un espacio de nombres plano a propósito (aunque las relaciones vivan en
|
|
144
|
+
* tipos distintos): las familias tienen prefijos disjuntos, así que dos
|
|
145
|
+
* permisos legales jamás chocan aquí, y lo que sí choca es exactamente lo que
|
|
146
|
+
* `RESERVED_SLUGS`/`RESERVED_SLUG_PREFIXES` prohíben en el núcleo.
|
|
147
|
+
*/
|
|
148
|
+
export declare function factsRelationMap(permissions: readonly string[]): FactsRelations[];
|
|
149
|
+
/**
|
|
150
|
+
* El authorization model del modo `facts` en el JSON del API de FGA. El mismo
|
|
151
|
+
* `holderTypes` y el mismo conjunto de permisos deben usarse al construir el
|
|
152
|
+
* driver: si difieren, los checks no encuentran las tuplas y `permits_<P>` de
|
|
153
|
+
* un permiso que el modelo no declara es un 400 del servidor.
|
|
154
|
+
*
|
|
155
|
+
* `permissions` son los slugs del CATÁLOGO (`authz_permissions`), que sigue
|
|
156
|
+
* siendo propiedad local: esto es una proyección derivada y reconstruible, no
|
|
157
|
+
* una fuente de verdad (regla del catálogo reescrita, cruce 7 del panel).
|
|
158
|
+
*/
|
|
159
|
+
export declare function openFgaFactsModel(holderTypeMap: HolderTypeMap, permissions: readonly string[], relationsConfig?: FactsRelationsConfig): any;
|
|
160
|
+
/**
|
|
161
|
+
* Los bytes que el servidor contará para este modelo. Incluye el id (un ULID
|
|
162
|
+
* de 26 caracteres) porque el servidor lo asigna ANTES de medir: sin él la
|
|
163
|
+
* cuenta se queda 28 bytes corta.
|
|
164
|
+
*/
|
|
165
|
+
export declare function factsModelBytes(model: any): number;
|
|
166
|
+
/**
|
|
167
|
+
* ¿Este catálogo se puede PUBLICAR como modelo `facts`? Se responde ANTES de
|
|
168
|
+
* escribir nada (`syncAuthzCatalog`), no en runtime: un catálogo que rebasa
|
|
169
|
+
* el techo del servidor entra en la base y deja el store sin poder
|
|
170
|
+
* regenerarse, que es la avería silenciosa.
|
|
171
|
+
*
|
|
172
|
+
* Pasado el 80 % del techo se AVISA por el canal de log del driver: quien
|
|
173
|
+
* declara permisos a ese ritmo tiene que enterarse antes de chocar, no el día
|
|
174
|
+
* del deploy que no arranca.
|
|
175
|
+
*/
|
|
176
|
+
export declare function assertFactsModelPublishable(holderTypeMap: HolderTypeMap, permissions: readonly string[], warn?: (message: string) => void, relationsConfig?: FactsRelationsConfig): {
|
|
177
|
+
bytes: number;
|
|
178
|
+
permissions: number;
|
|
179
|
+
};
|
|
180
|
+
/** Cota de id de objeto (A4): lo que el store no podría leer de vuelta no se escribe. */
|
|
181
|
+
export declare function assertFgaObjectId(kind: string, id: string): void;
|
|
182
|
+
/** Una tupla de la proyección: `role:<uuid>#permits_<P>@<holder>:*`. */
|
|
183
|
+
export interface FactsCatalogTuple {
|
|
184
|
+
user: string;
|
|
185
|
+
relation: string;
|
|
186
|
+
object: string;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Las tuplas que materializan los vínculos rol→permiso del catálogo. Una por
|
|
190
|
+
* (rol, permiso, holder): el comodín de USUARIO es lo que hace (c2) barato
|
|
191
|
+
* —quitar un permiso de un rol son `holders` deletes en un solo `Write`, no
|
|
192
|
+
* una escritura por scope—.
|
|
193
|
+
*
|
|
194
|
+
* NO es catálogo: es una proyección derivada, reconstruible desde `authz_*`,
|
|
195
|
+
* que ningún camino de lectura del driver consulta para responder qué
|
|
196
|
+
* permisos tiene un rol (cruce 7 del panel; A6).
|
|
197
|
+
*/
|
|
198
|
+
export declare function factsCatalogTuples(roles: readonly CatalogProjectionRole[], holderTypeMap: HolderTypeMap): FactsCatalogTuple[];
|
|
199
|
+
/** Clave textual de una tupla de la proyección, para comparar conjuntos. */
|
|
200
|
+
export declare function factsTupleId(tuple: FactsCatalogTuple): string;
|
|
201
|
+
/** El tipo FGA cuyo id es la `scopeKey` del paquete (`app` o `<tipo>|<uuid>`). */
|
|
202
|
+
export declare const FACTS_SCOPE_TYPE = "scope";
|
|
203
|
+
/** La arista del árbol: `scope:<hijo>#parent@scope:<padre>` (una por nodo). */
|
|
204
|
+
export declare const FACTS_PARENT_RELATION = "parent";
|
|
205
|
+
/** Una tupla del modo `facts` (misma forma que la del SDK, sin depender de él). */
|
|
206
|
+
export interface FactsTuple {
|
|
207
|
+
user: string;
|
|
208
|
+
relation: string;
|
|
209
|
+
object: string;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* El objeto FGA de un scope. La `scopeKey` es la MISMA codificación que ya
|
|
213
|
+
* usan los ids de binding (`identity.ts`), así que el árbol y los hechos
|
|
214
|
+
* hablan del mismo nodo con la misma cadena; el scope tiene que venir ya
|
|
215
|
+
* CANÓNICO (invariante 17: `chain[0]`), o se abriría una segunda rama para
|
|
216
|
+
* el alias del uuid.
|
|
217
|
+
*/
|
|
218
|
+
export declare function factsScopeObject(key: string): string;
|
|
219
|
+
/**
|
|
220
|
+
* La arista `hijo → padre` del árbol. Una sola tupla por nodo (c2): mover un
|
|
221
|
+
* subárbol es reescribir ESA tupla, no recorrer nada — por eso el `moved`
|
|
222
|
+
* del cruce 8 cabe en un `Write` atómico.
|
|
223
|
+
*/
|
|
224
|
+
export declare function factsParentTuple(childKey: string, parentKey: string): FactsTuple;
|
|
225
|
+
/**
|
|
226
|
+
* **El marcador de raíz** (3b-2i): `scope:app#rooted@<holder>:*`, una tupla
|
|
227
|
+
* por holder type en TODO el store — cero por scope.
|
|
228
|
+
*
|
|
229
|
+
* Es lo que hace verdadera la premisa de `rooted`: solo la raíz la tiene
|
|
230
|
+
* directa. `attached`/`moved`/`detached` no escriben ni una tupla más por su
|
|
231
|
+
* culpa (la outbox y el relay no llevan entradas nuevas), y a cambio lo
|
|
232
|
+
* escribe quien toca el CATÁLOGO —`projectCatalog`, en cada
|
|
233
|
+
* `syncAuthzCatalog` con proyección, de forma idempotente— porque ése es el
|
|
234
|
+
* momento en el que un holderType nuevo del config aparece.
|
|
235
|
+
*
|
|
236
|
+
* ⚠️ **Modo de fallo que hay que conocer: sin marcador, todo el store
|
|
237
|
+
* DENIEGA** (medido: `can_<P>` es `false` en `app`, en la org y en la unit).
|
|
238
|
+
* Es fail-closed —no es una fuga— y ruidoso a la primera pregunta, pero es
|
|
239
|
+
* una caída total silenciosa desde el punto de vista del log. Por eso el
|
|
240
|
+
* marcador se repone en cada sync y `authz:reconcile` (3b-3) tiene que
|
|
241
|
+
* reportarlo como deriva cuando falte.
|
|
242
|
+
*/
|
|
243
|
+
export declare function factsRootTuples(holderTypeMap: HolderTypeMap): FactsTuple[];
|
|
244
|
+
/** El tipo FGA de una asignación: `role_binding:<scopeKey>|<roleUuid>`. */
|
|
245
|
+
export declare const FACTS_BINDING_TYPE = "role_binding";
|
|
246
|
+
/** `scope:<key>#binding@role_binding:…` — qué asignaciones cuelgan del scope. */
|
|
247
|
+
export declare const FACTS_BINDING_RELATION = "binding";
|
|
248
|
+
/** `role_binding:…#role@role:<roleUuid>` — qué rol vincula la asignación. */
|
|
249
|
+
export declare const FACTS_ROLE_RELATION = "role";
|
|
250
|
+
/** `role_binding:…#assignee@<holder>` — quién está asignado (con la caducidad). */
|
|
251
|
+
export declare const FACTS_ASSIGNEE_RELATION = "assignee";
|
|
252
|
+
/**
|
|
253
|
+
* El objeto de una asignación. Mismo id que en el modo `resolver`
|
|
254
|
+
* (`<scopeKey>|<roleUuid>`, 3A · A1: uuid del catálogo, nunca el slug), y por
|
|
255
|
+
* eso el cambio de modelo no renombra un solo binding: lo que (c2) añade son
|
|
256
|
+
* las DOS aristas de abajo, no una identidad nueva.
|
|
257
|
+
*/
|
|
258
|
+
export declare function factsBindingObject(scopeKeyValue: string, roleUuid: string): string;
|
|
259
|
+
/**
|
|
260
|
+
* Las dos aristas que hacen ALCANZABLE una asignación en (c2): el binding
|
|
261
|
+
* cuelga del scope (`scope#binding`) y apunta a su rol (`role_binding#role`).
|
|
262
|
+
* Sin ellas el `assignee` es un hecho huérfano que `can_<P>` no ve — es la
|
|
263
|
+
* diferencia entre el modo `resolver` (donde la cadena la expande el paquete
|
|
264
|
+
* y basta con el `assignee`) y el modo `facts`.
|
|
265
|
+
*
|
|
266
|
+
* Son ESTRUCTURA, no concesión: no llevan caducidad y no dicen quién está
|
|
267
|
+
* asignado. Por eso `revoke` no las borra (otro holder puede seguir usando el
|
|
268
|
+
* mismo binding) y re-escribirlas es idempotente.
|
|
269
|
+
*/
|
|
270
|
+
export declare function factsBindingTuples(scopeKeyValue: string, roleUuid: string): FactsTuple[];
|
|
271
|
+
/**
|
|
272
|
+
* La arista `scope:<key>#binding@role_binding:<key>|<rol>` sola, que es la
|
|
273
|
+
* que hace ALCANZABLE la asignación desde el scope.
|
|
274
|
+
*
|
|
275
|
+
* **Qué significa** (3b-2g · R1, decisión del dueño del 2026-08-30 (2)): desde
|
|
276
|
+
* el barrido, «**el rol es visible aquí**» — no «esta asignación existe». El
|
|
277
|
+
* hecho de la asignación es el `assignee`, que el barrido no toca; esta arista
|
|
278
|
+
* la escribe y la borra el paquete cada vez que la REGLA DE VISIBILIDAD cambia
|
|
279
|
+
* de respuesta para ese `(rol, scope)`: el árbol se mueve y el owner deja de
|
|
280
|
+
* estar en la cadena (`scopes.moved`, 3b-2e · E1) o el catálogo cambia el
|
|
281
|
+
* NIVEL declarado del rol (`projectCatalogRole`, 3b-2g · R1). Es lo que en
|
|
282
|
+
* `database` se evalúa en cada pregunta con `declaredRoleAt`, y aquí hay que
|
|
283
|
+
* materializar porque el modelo (c2) no lleva ni el owner ni el nivel.
|
|
284
|
+
*/
|
|
285
|
+
export declare function factsScopeBindingTuple(scopeKeyValue: string, roleUuid: string): FactsTuple;
|
|
286
|
+
/**
|
|
287
|
+
* El deny explícito de (c2): `scope:<key>#denied_<P>@<holder>`. Ya no existe
|
|
288
|
+
* el tipo `deny_binding` — el deny es una relación DEL SCOPE, que es lo que
|
|
289
|
+
* permite que `denied_<P>` se herede hacia abajo por `parent` dentro del
|
|
290
|
+
* propio modelo y que `can_<P>` sea la resta (invariante 2) en un solo Check.
|
|
291
|
+
*/
|
|
292
|
+
export declare function factsDenyTuple(scopeKeyValue: string, permission: string, user: string): FactsTuple;
|
|
293
|
+
/** Prefijo de la familia del deny (`denied_<P>`), para leer denies por relación. */
|
|
294
|
+
export declare const FACTS_DENIED_PREFIX = "denied_";
|
|
295
|
+
/**
|
|
296
|
+
* El tipo `group` de las relaciones ReBAC: el portador de los usersets
|
|
297
|
+
* (`group:eng#member`) que hace que un `viewer` valga para todos los miembros
|
|
298
|
+
* de un grupo. Lo emite SIEMPRE el generador de relaciones (no lo declara el
|
|
299
|
+
* consumidor), y por eso es un tipo RESERVADO igual que los de `facts`.
|
|
300
|
+
*/
|
|
301
|
+
export declare const FACTS_GROUP_TYPE = "group";
|
|
302
|
+
/** La relación de pertenencia del grupo: `group:<id>#member@<holder>` y `@group:<otro>#member`. */
|
|
303
|
+
export declare const FACTS_GROUP_MEMBER_RELATION = "member";
|
|
304
|
+
/**
|
|
305
|
+
* Los tipos reservados del modelo compartido (⚪4). La fuente única está en
|
|
306
|
+
* `src/identity.ts` (la gramática compartida), porque también la consume
|
|
307
|
+
* `defineRelationsConfig` en `src/relations/`, que la frontera de pureza
|
|
308
|
+
* mantiene disjunto de `drivers/`. Se re-exporta aquí para no romper el
|
|
309
|
+
* subpath `/openfga` (`src/openfga.ts` la publica desde este módulo).
|
|
310
|
+
*/
|
|
311
|
+
export { RESERVED_FACTS_TYPES } from '../identity.js';
|
|
312
|
+
/** Una relación de un tipo de objeto de relaciones (`document#viewer`). */
|
|
313
|
+
export interface RelationObjectRelation {
|
|
314
|
+
/** El nombre de la relación (`owner`, `editor`, `viewer`). */
|
|
315
|
+
name: string;
|
|
316
|
+
/**
|
|
317
|
+
* Otras relaciones del MISMO tipo que ésta INCLUYE (`viewer or editor`): un
|
|
318
|
+
* `relate(u, editor, doc)` concede también `viewer`. Un nivel, SIN `from` en
|
|
319
|
+
* v1 (la herencia cross-objeto `viewer from parent` metería un TTU entre
|
|
320
|
+
* tipos y habría que re-medir profundidad — diferido a 2.6+).
|
|
321
|
+
*/
|
|
322
|
+
includes?: readonly string[];
|
|
323
|
+
}
|
|
324
|
+
/** Un tipo de objeto de relaciones (`document`, `folder`, `space`…). */
|
|
325
|
+
export interface RelationObjectType {
|
|
326
|
+
/** El tipo FGA del objeto. */
|
|
327
|
+
type: string;
|
|
328
|
+
/** Sus relaciones, en orden de declaración. */
|
|
329
|
+
relations: readonly RelationObjectRelation[];
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* La config de relaciones que el generador FUSIONA en el modelo `facts`
|
|
333
|
+
* (Fase 4-1). Es la forma MÍNIMA que consume el generador; el puerto
|
|
334
|
+
* `RelationsDriver` y `defineRelationsConfig` completos son 4-2.
|
|
335
|
+
*/
|
|
336
|
+
export interface FactsRelationsConfig {
|
|
337
|
+
/** Los tipos de objeto declarados por el consumidor. */
|
|
338
|
+
objectTypes: readonly RelationObjectType[];
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* **⚪4 + F-04, a nivel de MODELO.** Antes de emitir un solo `type_definition`
|
|
342
|
+
* de relaciones, el generador comprueba que la config es FUSIONABLE en el
|
|
343
|
+
* modelo compartido:
|
|
344
|
+
*
|
|
345
|
+
* - ningún `objectType` duplica un tipo reservado de `facts`/`group` ni un
|
|
346
|
+
* holder type (⚪4 · tipo), ni se repite;
|
|
347
|
+
* - ningún NOMBRE de relación (deduplicado entre tipos: `document#viewer` y
|
|
348
|
+
* `folder#viewer` son la misma relación lógica y se permiten) empieza por
|
|
349
|
+
* una familia derivada (`can_`/`denied_`/`permits_`) ni coincide con una
|
|
350
|
+
* relación PROPIA del modelo (`parent`/`rooted`/`assignee`… — ⚪4 · familia)
|
|
351
|
+
* ni con un permiso del catálogo (F-04);
|
|
352
|
+
* - los `includes` refieren relaciones del MISMO tipo (un nivel).
|
|
353
|
+
*
|
|
354
|
+
* Lanza 422 `E_AUTHZ_RELATION_CONFIG` del PAQUETE (no el 400 opaco del
|
|
355
|
+
* servidor), nombrando qué choca con qué.
|
|
356
|
+
*/
|
|
357
|
+
export declare function assertRelationsConfigPublishable(permissionRelations: readonly FactsRelations[], config: FactsRelationsConfig, holderTypes: readonly string[]): void;
|
|
358
|
+
/**
|
|
359
|
+
* Los `type_definitions` de relaciones que el generador AÑADE al modelo
|
|
360
|
+
* `facts`: el tipo `group` (usersets) + un tipo por objeto declarado. El
|
|
361
|
+
* literal medido contra el `:8101` está en la §1 del plan de la Fase 4.
|
|
362
|
+
*
|
|
363
|
+
* `group.member` admite holders directos y `group#member` (grupos anidan un
|
|
364
|
+
* nivel); cada relación de objeto admite `[holders, group#member]` directos y,
|
|
365
|
+
* si declara `includes`, se une a las relaciones incluidas del mismo tipo
|
|
366
|
+
* (`viewer or editor`), sin una sola tupla extra.
|
|
367
|
+
*/
|
|
368
|
+
export declare function factsRelationTypeDefinitions(permissionRelations: readonly FactsRelations[], config: FactsRelationsConfig, holderTypes: readonly string[]): any[];
|
|
369
|
+
//# sourceMappingURL=openfga_facts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openfga_facts.d.ts","sourceRoot":"","sources":["../../../src/drivers/openfga_facts.ts"],"names":[],"mappings":"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"}
|