@jantstack/adonis-authz 2.5.0-alpha.3 → 2.5.0-alpha.4
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 +414 -35
- package/build/commands/authz_catalog_diff.d.ts +0 -1
- package/build/commands/authz_catalog_diff.js +0 -1
- package/build/commands/authz_catalog_prune_orphans.d.ts +0 -1
- package/build/commands/authz_catalog_prune_orphans.js +0 -1
- package/build/commands/authz_catalog_sync.d.ts +0 -1
- package/build/commands/authz_catalog_sync.js +0 -1
- package/build/commands/authz_freeze.d.ts +0 -1
- package/build/commands/authz_freeze.js +0 -1
- package/build/commands/authz_reconcile.d.ts +0 -1
- package/build/commands/authz_reconcile.js +0 -1
- package/build/commands/authz_relations_reconcile.d.ts +0 -1
- package/build/commands/authz_relations_reconcile.js +56 -8
- package/build/commands/authz_scopes_relay.d.ts +0 -1
- package/build/commands/authz_scopes_relay.js +49 -5
- package/build/commands/authz_scopes_requeue.d.ts +0 -1
- package/build/commands/authz_scopes_requeue.js +14 -2
- package/build/commands/authz_unfreeze.d.ts +0 -1
- package/build/commands/authz_unfreeze.js +0 -1
- package/build/commands/main.d.ts +0 -1
- package/build/commands/main.js +0 -1
- package/build/commands/openfga_provision.d.ts +10 -1
- package/build/commands/openfga_provision.js +43 -3
- package/build/configure.d.ts +0 -1
- package/build/configure.js +0 -1
- package/build/index.d.ts +7 -5
- package/build/index.js +10 -3
- package/build/providers/authz_provider.d.ts +0 -1
- package/build/providers/authz_provider.js +0 -1
- package/build/services/main.d.ts +0 -1
- package/build/services/main.js +0 -1
- package/build/services/relations.d.ts +0 -1
- package/build/services/relations.js +0 -1
- package/build/src/catalog/catalog.d.ts +0 -1
- package/build/src/catalog/catalog.js +0 -1
- package/build/src/catalog/catalog_cache.d.ts +13 -1
- package/build/src/catalog/catalog_cache.js +25 -1
- package/build/src/clock.d.ts +0 -1
- package/build/src/clock.js +0 -1
- package/build/src/define_config.d.ts +0 -1
- package/build/src/define_config.js +24 -1
- package/build/src/drivers/database_driver.d.ts +6 -1
- package/build/src/drivers/database_driver.js +22 -2
- package/build/src/drivers/database_relations_driver.d.ts +11 -5
- package/build/src/drivers/database_relations_driver.js +90 -18
- package/build/src/drivers/openfga_driver.d.ts +159 -26
- package/build/src/drivers/openfga_driver.js +882 -199
- package/build/src/drivers/openfga_facts.d.ts +91 -1
- package/build/src/drivers/openfga_facts.js +277 -3
- package/build/src/drivers/openfga_relations_driver.d.ts +41 -13
- package/build/src/drivers/openfga_relations_driver.js +422 -228
- package/build/src/errors.d.ts +121 -1
- package/build/src/errors.js +153 -1
- package/build/src/expiry.d.ts +51 -2
- package/build/src/expiry.js +96 -2
- package/build/src/freeze.d.ts +0 -1
- package/build/src/freeze.js +0 -1
- package/build/src/hierarchical_resolver.d.ts +0 -1
- package/build/src/hierarchical_resolver.js +0 -1
- package/build/src/http/app_access_middleware.d.ts +0 -1
- package/build/src/http/app_access_middleware.js +0 -1
- package/build/src/http/resource_access_middleware.d.ts +0 -1
- package/build/src/http/resource_access_middleware.js +0 -1
- package/build/src/identity.d.ts +2 -1
- package/build/src/identity.js +4 -1
- package/build/src/manager.d.ts +0 -1
- package/build/src/manager.js +156 -28
- package/build/src/memoize_ancestors.d.ts +0 -1
- package/build/src/memoize_ancestors.js +0 -1
- package/build/src/models/authz_assignment.d.ts +5 -6
- package/build/src/models/authz_assignment.js +0 -1
- package/build/src/models/authz_deny.d.ts +5 -6
- package/build/src/models/authz_deny.js +0 -1
- package/build/src/models/authz_permission.d.ts +5 -6
- package/build/src/models/authz_permission.js +0 -1
- package/build/src/models/authz_role.d.ts +5 -6
- package/build/src/models/authz_role.js +0 -1
- package/build/src/models/authz_role_permission.d.ts +5 -6
- package/build/src/models/authz_role_permission.js +0 -1
- package/build/src/openfga.d.ts +2 -3
- package/build/src/openfga.js +4 -2
- package/build/src/reconcile.d.ts +0 -1
- package/build/src/reconcile.js +0 -1
- package/build/src/relation_partition_trigger.d.ts +0 -1
- package/build/src/relation_partition_trigger.js +0 -1
- package/build/src/relations/check_many.d.ts +0 -1
- package/build/src/relations/check_many.js +0 -1
- package/build/src/relations/define_relations_config.d.ts +25 -3
- package/build/src/relations/define_relations_config.js +8 -3
- package/build/src/relations/deny_reach.d.ts +102 -0
- package/build/src/relations/deny_reach.js +230 -0
- package/build/src/relations/group_depth.d.ts +215 -0
- package/build/src/relations/group_depth.js +453 -0
- package/build/src/relations/manager.d.ts +14 -7
- package/build/src/relations/manager.js +60 -15
- package/build/src/relations/page.d.ts +19 -0
- package/build/src/relations/page.js +74 -0
- package/build/src/relations/reconcile.d.ts +58 -4
- package/build/src/relations/reconcile.js +266 -12
- package/build/src/relations/tuple_key.d.ts +0 -1
- package/build/src/relations/tuple_key.js +0 -1
- package/build/src/relations/tuple_order.d.ts +5 -4
- package/build/src/relations/tuple_order.js +5 -4
- package/build/src/relations_config_store.d.ts +57 -2
- package/build/src/relations_config_store.js +155 -5
- package/build/src/relations_reconcile.d.ts +0 -1
- package/build/src/relations_reconcile.js +0 -1
- package/build/src/scope_outbox.d.ts +0 -1
- package/build/src/scope_outbox.js +0 -1
- package/build/src/shared/backend_guard.d.ts +52 -1
- package/build/src/shared/backend_guard.js +164 -2
- package/build/src/shared/sql_expiry.d.ts +0 -1
- package/build/src/shared/sql_expiry.js +0 -1
- package/build/src/shared/transaction_guard.d.ts +0 -1
- package/build/src/shared/transaction_guard.js +0 -1
- package/build/src/sql_descendants.d.ts +0 -1
- package/build/src/sql_descendants.js +0 -1
- package/build/src/testing/contract.d.ts +7 -1
- package/build/src/testing/contract.js +77 -1
- package/build/src/testing/main.d.ts +0 -1
- package/build/src/testing/main.js +0 -1
- package/build/src/testing/migration_contract.d.ts +0 -1
- package/build/src/testing/migration_contract.js +0 -1
- package/build/src/testing/relations_contract.d.ts +7 -1
- package/build/src/testing/relations_contract.js +174 -7
- package/build/src/testing/relations_reconcile_contract.d.ts +0 -1
- package/build/src/testing/relations_reconcile_contract.js +0 -1
- package/build/src/testing/scope_outbox_contract.d.ts +0 -1
- package/build/src/testing/scope_outbox_contract.js +0 -1
- package/build/src/testing/scope_tree.d.ts +0 -1
- package/build/src/testing/scope_tree.js +0 -1
- package/build/src/testing/test_clock.d.ts +0 -1
- package/build/src/testing/test_clock.js +0 -1
- package/build/src/traits/authz_scopes.d.ts +0 -1
- package/build/src/traits/authz_scopes.js +0 -1
- package/build/src/traits/has_uuid.d.ts +5 -6
- package/build/src/traits/has_uuid.js +0 -1
- package/build/src/types.d.ts +89 -14
- package/build/src/types.js +4 -1
- package/build/stubs/config/authorization.stub +22 -6
- package/build/stubs/main.d.ts +0 -1
- package/build/stubs/main.js +0 -1
- package/package.json +4 -3
- package/build/commands/authz_catalog_diff.d.ts.map +0 -1
- package/build/commands/authz_catalog_diff.js.map +0 -1
- package/build/commands/authz_catalog_prune_orphans.d.ts.map +0 -1
- package/build/commands/authz_catalog_prune_orphans.js.map +0 -1
- package/build/commands/authz_catalog_sync.d.ts.map +0 -1
- package/build/commands/authz_catalog_sync.js.map +0 -1
- package/build/commands/authz_freeze.d.ts.map +0 -1
- package/build/commands/authz_freeze.js.map +0 -1
- package/build/commands/authz_reconcile.d.ts.map +0 -1
- package/build/commands/authz_reconcile.js.map +0 -1
- package/build/commands/authz_relations_reconcile.d.ts.map +0 -1
- package/build/commands/authz_relations_reconcile.js.map +0 -1
- package/build/commands/authz_scopes_relay.d.ts.map +0 -1
- package/build/commands/authz_scopes_relay.js.map +0 -1
- package/build/commands/authz_scopes_requeue.d.ts.map +0 -1
- package/build/commands/authz_scopes_requeue.js.map +0 -1
- package/build/commands/authz_unfreeze.d.ts.map +0 -1
- package/build/commands/authz_unfreeze.js.map +0 -1
- package/build/commands/main.d.ts.map +0 -1
- package/build/commands/main.js.map +0 -1
- package/build/commands/openfga_provision.d.ts.map +0 -1
- package/build/commands/openfga_provision.js.map +0 -1
- package/build/configure.d.ts.map +0 -1
- package/build/configure.js.map +0 -1
- package/build/index.d.ts.map +0 -1
- package/build/index.js.map +0 -1
- package/build/providers/authz_provider.d.ts.map +0 -1
- package/build/providers/authz_provider.js.map +0 -1
- package/build/services/main.d.ts.map +0 -1
- package/build/services/main.js.map +0 -1
- package/build/services/relations.d.ts.map +0 -1
- package/build/services/relations.js.map +0 -1
- package/build/src/catalog/catalog.d.ts.map +0 -1
- package/build/src/catalog/catalog.js.map +0 -1
- package/build/src/catalog/catalog_cache.d.ts.map +0 -1
- package/build/src/catalog/catalog_cache.js.map +0 -1
- package/build/src/clock.d.ts.map +0 -1
- package/build/src/clock.js.map +0 -1
- package/build/src/define_config.d.ts.map +0 -1
- package/build/src/define_config.js.map +0 -1
- package/build/src/drivers/database_driver.d.ts.map +0 -1
- package/build/src/drivers/database_driver.js.map +0 -1
- package/build/src/drivers/database_relations_driver.d.ts.map +0 -1
- package/build/src/drivers/database_relations_driver.js.map +0 -1
- package/build/src/drivers/openfga_driver.d.ts.map +0 -1
- package/build/src/drivers/openfga_driver.js.map +0 -1
- package/build/src/drivers/openfga_facts.d.ts.map +0 -1
- package/build/src/drivers/openfga_facts.js.map +0 -1
- package/build/src/drivers/openfga_relations_driver.d.ts.map +0 -1
- package/build/src/drivers/openfga_relations_driver.js.map +0 -1
- package/build/src/errors.d.ts.map +0 -1
- package/build/src/errors.js.map +0 -1
- package/build/src/expiry.d.ts.map +0 -1
- package/build/src/expiry.js.map +0 -1
- package/build/src/freeze.d.ts.map +0 -1
- package/build/src/freeze.js.map +0 -1
- package/build/src/hierarchical_resolver.d.ts.map +0 -1
- package/build/src/hierarchical_resolver.js.map +0 -1
- package/build/src/http/app_access_middleware.d.ts.map +0 -1
- package/build/src/http/app_access_middleware.js.map +0 -1
- package/build/src/http/resource_access_middleware.d.ts.map +0 -1
- package/build/src/http/resource_access_middleware.js.map +0 -1
- package/build/src/identity.d.ts.map +0 -1
- package/build/src/identity.js.map +0 -1
- package/build/src/manager.d.ts.map +0 -1
- package/build/src/manager.js.map +0 -1
- package/build/src/memoize_ancestors.d.ts.map +0 -1
- package/build/src/memoize_ancestors.js.map +0 -1
- package/build/src/models/authz_assignment.d.ts.map +0 -1
- package/build/src/models/authz_assignment.js.map +0 -1
- package/build/src/models/authz_deny.d.ts.map +0 -1
- package/build/src/models/authz_deny.js.map +0 -1
- package/build/src/models/authz_permission.d.ts.map +0 -1
- package/build/src/models/authz_permission.js.map +0 -1
- package/build/src/models/authz_role.d.ts.map +0 -1
- package/build/src/models/authz_role.js.map +0 -1
- package/build/src/models/authz_role_permission.d.ts.map +0 -1
- package/build/src/models/authz_role_permission.js.map +0 -1
- package/build/src/openfga.d.ts.map +0 -1
- package/build/src/openfga.js.map +0 -1
- package/build/src/reconcile.d.ts.map +0 -1
- package/build/src/reconcile.js.map +0 -1
- package/build/src/relation_partition_trigger.d.ts.map +0 -1
- package/build/src/relation_partition_trigger.js.map +0 -1
- package/build/src/relations/check_many.d.ts.map +0 -1
- package/build/src/relations/check_many.js.map +0 -1
- package/build/src/relations/define_relations_config.d.ts.map +0 -1
- package/build/src/relations/define_relations_config.js.map +0 -1
- package/build/src/relations/manager.d.ts.map +0 -1
- package/build/src/relations/manager.js.map +0 -1
- package/build/src/relations/reconcile.d.ts.map +0 -1
- package/build/src/relations/reconcile.js.map +0 -1
- package/build/src/relations/tuple_key.d.ts.map +0 -1
- package/build/src/relations/tuple_key.js.map +0 -1
- package/build/src/relations/tuple_order.d.ts.map +0 -1
- package/build/src/relations/tuple_order.js.map +0 -1
- package/build/src/relations_config_store.d.ts.map +0 -1
- package/build/src/relations_config_store.js.map +0 -1
- package/build/src/relations_reconcile.d.ts.map +0 -1
- package/build/src/relations_reconcile.js.map +0 -1
- package/build/src/scope_outbox.d.ts.map +0 -1
- package/build/src/scope_outbox.js.map +0 -1
- package/build/src/shared/backend_guard.d.ts.map +0 -1
- package/build/src/shared/backend_guard.js.map +0 -1
- package/build/src/shared/sql_expiry.d.ts.map +0 -1
- package/build/src/shared/sql_expiry.js.map +0 -1
- package/build/src/shared/transaction_guard.d.ts.map +0 -1
- package/build/src/shared/transaction_guard.js.map +0 -1
- package/build/src/sql_descendants.d.ts.map +0 -1
- package/build/src/sql_descendants.js.map +0 -1
- package/build/src/testing/contract.d.ts.map +0 -1
- package/build/src/testing/contract.js.map +0 -1
- package/build/src/testing/main.d.ts.map +0 -1
- package/build/src/testing/main.js.map +0 -1
- package/build/src/testing/migration_contract.d.ts.map +0 -1
- package/build/src/testing/migration_contract.js.map +0 -1
- package/build/src/testing/relations_contract.d.ts.map +0 -1
- package/build/src/testing/relations_contract.js.map +0 -1
- package/build/src/testing/relations_reconcile_contract.d.ts.map +0 -1
- package/build/src/testing/relations_reconcile_contract.js.map +0 -1
- package/build/src/testing/scope_outbox_contract.d.ts.map +0 -1
- package/build/src/testing/scope_outbox_contract.js.map +0 -1
- package/build/src/testing/scope_tree.d.ts.map +0 -1
- package/build/src/testing/scope_tree.js.map +0 -1
- package/build/src/testing/test_clock.d.ts.map +0 -1
- package/build/src/testing/test_clock.js.map +0 -1
- package/build/src/traits/authz_scopes.d.ts.map +0 -1
- package/build/src/traits/authz_scopes.js.map +0 -1
- package/build/src/traits/has_uuid.d.ts.map +0 -1
- package/build/src/traits/has_uuid.js.map +0 -1
- package/build/src/types.d.ts.map +0 -1
- package/build/src/types.js.map +0 -1
- package/build/stubs/main.d.ts.map +0 -1
- package/build/stubs/main.js.map +0 -1
|
@@ -142,8 +142,12 @@ export declare function isDuplicateWrite(error: unknown): boolean;
|
|
|
142
142
|
export interface OpenFgaDriverOptions {
|
|
143
143
|
apiUrl: string;
|
|
144
144
|
storeId: string;
|
|
145
|
-
/**
|
|
146
|
-
|
|
145
|
+
/**
|
|
146
|
+
* **Pin del model — OBLIGATORIO** (lote «antes de RC» · L11, decisión del dueño 2026-10-17 (2)): el driver comprueba
|
|
147
|
+
* UNA vez por proceso que ese modelo es el que genera su config (la puerta L11) y el servidor evalúa con ÉL. Sin él,
|
|
148
|
+
* 500 `E_AUTHZ_CONFIG` al construir con la receta (`openfga:provision` imprime `OPENFGA_MODEL_ID`).
|
|
149
|
+
*/
|
|
150
|
+
modelId: string;
|
|
147
151
|
/** Jerarquía del consumidor (ver ScopeChainResolver). */
|
|
148
152
|
resolveChain?: ScopeChainResolver;
|
|
149
153
|
/**
|
|
@@ -225,6 +229,14 @@ export interface OpenFgaDriverOptions {
|
|
|
225
229
|
* valor «truthy» no es una aceptación.
|
|
226
230
|
*/
|
|
227
231
|
acceptScopeDriftRisk?: boolean;
|
|
232
|
+
/**
|
|
233
|
+
* **`openfga` es EXPERIMENTAL en 2.5.x** (estrategia 2.5.0, firma 4 del dueño 2026-10-21): no apto para producción,
|
|
234
|
+
* con límites declarados en README «Limits» que se cierran en 2.6. Construirlo exige este LITERAL, versionado; sin él
|
|
235
|
+
* (o con `true`, `'acknowledged'`, otra versión…) el constructor lanza 500 `E_AUTHZ_CONFIG` como primera línea, sin
|
|
236
|
+
* crear el cliente. Opcional en el TIPO —como `acceptScopeDriftRisk`— para que un config que solo REGISTRA la factory
|
|
237
|
+
* `openfga` (el stub publicado) siga compilando; obligatorio al construir.
|
|
238
|
+
*/
|
|
239
|
+
experimental?: 'openfga@2.5';
|
|
228
240
|
}
|
|
229
241
|
/**
|
|
230
242
|
* **El gate de construcción de `facts`** (3b-2d, panel 2 cruce 4 · S5).
|
|
@@ -247,6 +259,13 @@ export declare function assertScopeDriftGuarded(options: {
|
|
|
247
259
|
acceptScopeDriftRisk?: boolean;
|
|
248
260
|
}): void;
|
|
249
261
|
export declare const DEFAULT_TIMEOUT_MS = 5000;
|
|
262
|
+
/**
|
|
263
|
+
* **Vueltas del settle** (lote C · carreras, resolución 7 del juez; linaje L13): aplicaciones que
|
|
264
|
+
* `settleRoleVisibility` intenta antes de rendirse. Al agotarlas BORRA las aristas `scope#binding` de los pares (fail-CLOSED,
|
|
265
|
+
* intra-tenant: el churn exige `within` en los dos padres) y lanza 409 `E_AUTHZ_WRITE_CONFLICT` marcado PARCIAL
|
|
266
|
+
* (invariante 13: `indeterminate: true` en `onWrite`).
|
|
267
|
+
*/
|
|
268
|
+
export declare const SETTLE_MAX_ROUNDS = 5;
|
|
250
269
|
/**
|
|
251
270
|
* Cota de páginas de una enumeración (1.000.000 de tuplas a 100 por página).
|
|
252
271
|
* Un `continuation_token` que no avanza —un servidor roto, un proxy o una
|
|
@@ -284,6 +303,7 @@ export declare class OpenFgaAuthorizationDriver implements AuthorizationDriver {
|
|
|
284
303
|
canonicalScopeReads: false;
|
|
285
304
|
enumerateFacts: true;
|
|
286
305
|
transactionalWrites: false;
|
|
306
|
+
experimental: true;
|
|
287
307
|
}>;
|
|
288
308
|
private client;
|
|
289
309
|
private chainResolver;
|
|
@@ -306,6 +326,12 @@ export declare class OpenFgaAuthorizationDriver implements AuthorizationDriver {
|
|
|
306
326
|
* con el que este driver escribe y responde, no el último del store.
|
|
307
327
|
*/
|
|
308
328
|
private readonly modelId;
|
|
329
|
+
/**
|
|
330
|
+
* **La comparación modelo ↔ config de L11, UNA por proceso** (`modelGate`). Es un OBJETO que se MUTA y nunca se
|
|
331
|
+
* reasigna (H11 b): las vistas `withChainResolver`/`withClock` son `Object.create(this)` y lo heredan por prototipo,
|
|
332
|
+
* así que `forRequest()` no relee el modelo por petición.
|
|
333
|
+
*/
|
|
334
|
+
private readonly modelMemo;
|
|
309
335
|
private consistency;
|
|
310
336
|
/** Reloj de pared del driver (J1): el ÚNICO `now` de checks, filtros y re-grant. */
|
|
311
337
|
private now;
|
|
@@ -355,6 +381,22 @@ export declare class OpenFgaAuthorizationDriver implements AuthorizationDriver {
|
|
|
355
381
|
* `authorize` evaluaba el deny en un instante y el rol en otro.
|
|
356
382
|
*/
|
|
357
383
|
private checkContext;
|
|
384
|
+
/**
|
|
385
|
+
* **La lectura del modelo, UNA por proceso** (L11): `readAuthorizationModel` del `modelId` FIJADO y
|
|
386
|
+
* `factsModelDifferences` con `slice: 'roles'` (los holders, `role`, `role_binding`, `scope` y las condiciones; la
|
|
387
|
+
* igualdad es «módulo el catálogo»: `P_M` sale del propio modelo). Se memoriza el ÉXITO —también con diferencias— y un
|
|
388
|
+
* generador que no puede generar (500); **un fallo al LEER el modelo NO se memoriza, sea 503 o 500** (cierre de L11).
|
|
389
|
+
*/
|
|
390
|
+
private modelGate;
|
|
391
|
+
/**
|
|
392
|
+
* **La puerta L11 del driver de ROLES** (lote «antes de RC», decisión del dueño 2026-10-17 (1); hasta L11 este driver
|
|
393
|
+
* no comparaba NINGUNA regla —P7: solo el conjunto de `permits_*`, «no es una barrera de seguridad»—: un `can_<P>` sin
|
|
394
|
+
* `but not denied_<P>`, un `rooted` cambiado o un `assignee` sin `not_expired` concedían o negaban sin error). Toda
|
|
395
|
+
* operación que llega al store la pasa ENTERA, justo después de validar su entrada y antes de la primera llamada
|
|
396
|
+
* (catálogo, resolutor y cliente incluidos); `enumerateFacts` —el ORIGEN de una migración— solo la parte
|
|
397
|
+
* `conditions`. Distinta ⇒ 500 `E_AUTHZ_CONFIG` con las rutas y CERO llamadas que evalúen o escriban.
|
|
398
|
+
*/
|
|
399
|
+
private assertModel;
|
|
358
400
|
/**
|
|
359
401
|
* Consulta al catálogo local clasificando su fallo. Con este driver el
|
|
360
402
|
* catálogo SQL sigue siendo una dependencia dura de cada pregunta: su caída
|
|
@@ -368,6 +410,58 @@ export declare class OpenFgaAuthorizationDriver implements AuthorizationDriver {
|
|
|
368
410
|
* alineada por ese id: un resultado por check, ni uno más ni uno menos.
|
|
369
411
|
*/
|
|
370
412
|
private batchCheckAll;
|
|
413
|
+
/**
|
|
414
|
+
* **El catálogo de una ESCRITURA** (K4, resolución 2 del juez): con la versión contrastada en fresco SIEMPRE
|
|
415
|
+
* (`CatalogCache.freshView`), ignore o no la ventana `{ everyMs }`. Un `catalog` inyectado que no lo traiga cae en
|
|
416
|
+
* `view()` (el contrato del memo es suyo).
|
|
417
|
+
*/
|
|
418
|
+
private writeCatalog;
|
|
419
|
+
/**
|
|
420
|
+
* K4 (segunda mitad): un uuid de rol que el STORE tiene y el catálogo de la escritura no conoce fuerza UNA recarga del
|
|
421
|
+
* memo (`invalidate` + foto en fresco). Si tras ella sigue ausente, el rol se borró: quien llama BORRA su arista.
|
|
422
|
+
*/
|
|
423
|
+
private writeCatalogKnowing;
|
|
424
|
+
/**
|
|
425
|
+
* Un `batchCheck` con `HIGHER_CONSISTENCY` para el settle, SIN colapsar los errores por ítem: el llamante decide qué
|
|
426
|
+
* hacer con un `E_AUTHZ_RESOLUTION_LIMIT` de `ancestor` (caer a `storeChain`, condición 2 de la resolución 9) y propaga
|
|
427
|
+
* el resto (clasificados por el MISMO `fgaFailureError` que `alignBatchResults`).
|
|
428
|
+
*/
|
|
429
|
+
private checkForWrite;
|
|
430
|
+
/**
|
|
431
|
+
* **La decisión del settle**, con el STORE (todas las lecturas con HIGHER, en UN `batchCheck`): para cada par, si la
|
|
432
|
+
* arista TIENE que estar (`want`) y si ESTÁ (`has`). `want` exige, por este orden:
|
|
433
|
+
* - el rol en el catálogo de la escritura (K4: en fresco y, si falta, tras una recarga; si sigue faltando, `known: false`
|
|
434
|
+
* y la arista se borra — «rol ausente ⇒ borra»);
|
|
435
|
+
* - declarado para el NIVEL del scope (3b-2g · R1);
|
|
436
|
+
* - `role_binding#role` VIVO (auditor ⚪ 8: tras un `revoke`/`purgeScope`/`purgeRole` concurrente el settle no resucita
|
|
437
|
+
* la arista; `liveness: false` solo en la decisión PREVIA del `grant`, que escribe esa arista en el mismo `Write`);
|
|
438
|
+
* - y, si el rol es LOCAL, su owner ancestro-o-igual del scope EN EL STORE: atajo `scope == owner` (`ancestor` no es
|
|
439
|
+
* reflexivo, K6), `Check(scope:<owner> ancestor scope:<S>)` y, si ese `Check` excede la cota del servidor (medido en M2:
|
|
440
|
+
* solo cuando el owner SÍ es ancestro a > 26 saltos), la cadena del store salto a salto (`storeChain`) — nunca «borrar
|
|
441
|
+
* por si acaso» (fail-closed aleatorio cerca de la cota). La laxitud de `ancestor` ante DOS padres es deriva que ya
|
|
442
|
+
* denuncian `moved` y reconcile (riesgo declarado del juez).
|
|
443
|
+
*/
|
|
444
|
+
private decideRoleVisibility;
|
|
445
|
+
/**
|
|
446
|
+
* **El ÚNICO sitio que da de ALTA una arista `scope#binding` de rol local** (y borra las que se le pidan), en lotes ≤ 100
|
|
447
|
+
* (`Write` con `Ignore` en las dos direcciones: dice el estado que DEBE quedar, no el delta — invariante 6).
|
|
448
|
+
*/
|
|
449
|
+
private writeBindingEdges;
|
|
450
|
+
/**
|
|
451
|
+
* **`settleRoleVisibility`** — el punto de paso de L13. Decide con el store (`decideRoleVisibility`), y si alguna
|
|
452
|
+
* arista no está como tiene que estar, aplica la diferencia y VUELVE A LEER; termina cuando una lectura POSTERIOR a su
|
|
453
|
+
* última escritura ve el store coherente (punto fijo: «borro una vez» deja CLOSED persistente al entrar, R1-entrar).
|
|
454
|
+
*
|
|
455
|
+
* **Cota** (resolución 7): tras `SETTLE_MAX_ROUNDS` aplicaciones sin converger (un churn que mueve el árbol en cada
|
|
456
|
+
* relectura) se RINDE: borra las aristas de los pares que NO convergieron —y, en el mismo `Write`, `giveUpDeletes` (el `assignee` de un
|
|
457
|
+
* `grant` que CREÓ la asignación: vuelta a «no ocurrió»)— y lanza 409 `E_AUTHZ_WRITE_CONFLICT` marcado PARCIAL
|
|
458
|
+
* (`indeterminate: true`). Fail-CLOSED declarado e intra-tenant; en un re-grant el 409 NO significa «no asignado».
|
|
459
|
+
*
|
|
460
|
+
* Devuelve los pares cuyo rol el catálogo ya no conoce (`known: false`): el `grant` que los CREÓ deshace su asignación.
|
|
461
|
+
*/
|
|
462
|
+
private settleRoleVisibility;
|
|
463
|
+
/** Las vueltas del settle (lo que hasta el cierre 1 era el cuerpo de `settleRoleVisibility`). */
|
|
464
|
+
private settleRounds;
|
|
371
465
|
private findPermission;
|
|
372
466
|
/**
|
|
373
467
|
* Filtro por catálogo de las lecturas de membresía (`listRoles`,
|
|
@@ -438,6 +532,13 @@ export declare class OpenFgaAuthorizationDriver implements AuthorizationDriver {
|
|
|
438
532
|
*/
|
|
439
533
|
private rejectTransaction;
|
|
440
534
|
grant(subject: SubjectRef, role: RoleQuery, scope: ScopeRef, options?: GrantOptions): Promise<GrantOutcome>;
|
|
535
|
+
/**
|
|
536
|
+
* El cuerpo de ESCRITURA del `grant` (sin la decisión de visibilidad): lee la asignación, decide entre no-op, write o
|
|
537
|
+
* delete+write, y re-aplica ante una carrera. `structure` son las aristas que van con el `assignee` en el MISMO `Write`
|
|
538
|
+
* (las tres para un rol global; sin la `scope#binding` si el store dice que el rol local no es visible ahí). `progress`
|
|
539
|
+
* cuenta los `Write` INTENTADOS (el settle del `grant` local corre si hubo alguno, también si falló: invariante 13).
|
|
540
|
+
*/
|
|
541
|
+
private writeGrant;
|
|
441
542
|
/**
|
|
442
543
|
* Write directo de la asignación CON su estructura (3b-2f · R3); si algo ya
|
|
443
544
|
* estaba, camino largo. Devuelve si existía la ASIGNACIÓN —lo dice la
|
|
@@ -550,8 +651,12 @@ export declare class OpenFgaAuthorizationDriver implements AuthorizationDriver {
|
|
|
550
651
|
* borrar una tupla inexistente—, la cadena del padre NUEVO en el store
|
|
551
652
|
* (3b-8 · A5: el anti-ciclos del consumidor no ve un store
|
|
552
653
|
* desincronizado) y **UN solo `Write`** con el delete del padre viejo y el
|
|
553
|
-
* write del nuevo, que es atómico
|
|
554
|
-
*
|
|
654
|
+
* write del nuevo, que es atómico PARA EL ESCRITOR (el store nunca guarda
|
|
655
|
+
* los dos padres ni ninguno) pero NO para un lector concurrente: un `Check`
|
|
656
|
+
* que dura lo que el `Write` puede leer la arista vieja por una rama del
|
|
657
|
+
* modelo y la nueva por otra (lector rasgado, fila «torn read» de Limits del
|
|
658
|
+
* README; medido 1,2–7,1 %, decisión del dueño 6b). O(profundidad) requests;
|
|
659
|
+
* con roles locales, además el barrido F4 (ver `reparent`).
|
|
555
660
|
*/
|
|
556
661
|
onScopeMoved(child: ScopeRef, newParent: ScopeRef): Promise<void>;
|
|
557
662
|
/**
|
|
@@ -623,8 +728,8 @@ export declare class OpenFgaAuthorizationDriver implements AuthorizationDriver {
|
|
|
623
728
|
*/
|
|
624
729
|
private reparent;
|
|
625
730
|
/**
|
|
626
|
-
* **El barrido del rol local** (3b-2e · E1; decisión del dueño del
|
|
627
|
-
* 2026-08-30, opción 1).
|
|
731
|
+
* **El barrido PREVIO del rol local** (3b-2e · E1; decisión del dueño del
|
|
732
|
+
* 2026-08-30, opción 1; F4: solo borra).
|
|
628
733
|
*
|
|
629
734
|
* En (c2) el modelo no tiene `owner`, así que `authorize` NO vuelve a
|
|
630
735
|
* decidir con el árbol de hoy si un rol LOCAL sigue siendo visible: un
|
|
@@ -634,11 +739,12 @@ export declare class OpenFgaAuthorizationDriver implements AuthorizationDriver {
|
|
|
634
739
|
* un **fail-open** — y encima uno que solo se ve comparando drivers.
|
|
635
740
|
*
|
|
636
741
|
* Lo que se toca es la arista `scope#binding`, que es lo que hace
|
|
637
|
-
* ALCANZABLE la asignación:
|
|
638
|
-
*
|
|
639
|
-
*
|
|
640
|
-
*
|
|
641
|
-
* ni nada de un rol GLOBAL, cuya
|
|
742
|
+
* ALCANZABLE la asignación: el barrido previo la BORRA donde el owner del
|
|
743
|
+
* rol no estará en la cadena NUEVA; las ALTAS (volver a su sitio restaura)
|
|
744
|
+
* son del settle de después (`settleSubtree`), el punto de paso único de
|
|
745
|
+
* L13. No se toca el `assignee` —el hecho de la asignación no cambia porque
|
|
746
|
+
* el árbol se mueva, igual que en `database`— ni nada de un rol GLOBAL, cuya
|
|
747
|
+
* visibilidad no depende del árbol.
|
|
642
748
|
*
|
|
643
749
|
* **Por subárbol, no por nodo** (consecuencia 2): los descendientes del
|
|
644
750
|
* nodo movido también cambian de cadena.
|
|
@@ -647,9 +753,22 @@ export declare class OpenFgaAuthorizationDriver implements AuthorizationDriver {
|
|
|
647
753
|
* que no usa delegación— son **cero** requests y `moved` sigue siendo el
|
|
648
754
|
* `Read` + `Write` del cruce 8. Con roles locales: una lectura por rol local
|
|
649
755
|
* (sus bindings, por `role_binding#role`), la bajada del subárbol y un
|
|
650
|
-
* `Write` por lote.
|
|
756
|
+
* `Write` por lote (el coste O(roles locales) por `moved` es el 🟡 6, declarado hasta 2.6).
|
|
651
757
|
*/
|
|
652
758
|
private sweepLocalRoleBindings;
|
|
759
|
+
/**
|
|
760
|
+
* Los bindings de roles LOCALES que cuelgan del subárbol de `movedKey` en el STORE (HIGHER), con la cadena de cada
|
|
761
|
+
* scope del subárbol. El catálogo es el de una ESCRITURA (K4: en fresco), y un uuid que el store tiene y el catálogo no
|
|
762
|
+
* conoce fuerza una recarga (`writeCatalogKnowing`); los roles se enumeran por el catálogo (el amarillo 6 —enumerar
|
|
763
|
+
* desde el store— es de 2.6). `chain` es la cadena que el nodo TENDRÁ (barrido previo) o, sin ella, la del store.
|
|
764
|
+
*/
|
|
765
|
+
private localBindingsBelow;
|
|
766
|
+
/**
|
|
767
|
+
* **El settle del subárbol de un cambio de árbol** (lote C · L13): los bindings de roles locales del subárbol de
|
|
768
|
+
* `movedKey` (en el store, HIGHER, catálogo en fresco) pasan por `settleRoleVisibility`. Lo llaman `reparent` tras la
|
|
769
|
+
* arista, su atajo idempotente y su `finally`.
|
|
770
|
+
*/
|
|
771
|
+
private settleSubtree;
|
|
653
772
|
/**
|
|
654
773
|
* **El barrido por NIVEL** (3b-2g · R1; decisión del dueño del 2026-08-30
|
|
655
774
|
* (2), mismo mecanismo que E1).
|
|
@@ -660,18 +779,22 @@ export declare class OpenFgaAuthorizationDriver implements AuthorizationDriver {
|
|
|
660
779
|
* —donde `declaredRoleAt` se evalúa en cada pregunta— y **sigue
|
|
661
780
|
* concediendo** en `facts`, que es la divergencia R1 del lote 2e.
|
|
662
781
|
*
|
|
663
|
-
* Se cierra igual que el owner:
|
|
664
|
-
* bindings de ESE rol
|
|
782
|
+
* Se cierra igual que el owner: dejando la arista `scope#binding` de los
|
|
783
|
+
* bindings de ESE rol como dice la regla única de visibilidad. Lo llama
|
|
665
784
|
* `projectCatalogRole`, que es el hook de «una escritura de catálogo cambió
|
|
666
785
|
* este rol»: el manager lo dispara tras `defineScopedRole`/`updateScopedRole`
|
|
667
786
|
* y un escritor «a mano» de `authz_*` tiene el mismo deber que ya tenía con
|
|
668
787
|
* el espejo de permisos (sin él, en `facts` un rol recién definido no
|
|
669
788
|
* concedería nada y quitarle un permiso seguiría concediéndolo).
|
|
670
789
|
*
|
|
671
|
-
*
|
|
672
|
-
*
|
|
673
|
-
*
|
|
674
|
-
*
|
|
790
|
+
* **Desde el lote C pasa ENTERO por el settle** (L13; 🟠 1 de F4-carreras: este barrido leía `storeChain` y escribía
|
|
791
|
+
* DESPUÉS, y un `moved` que barriera entre medias quedaba pisado — fail-OPEN persistente entre tenants). El catálogo es
|
|
792
|
+
* el de una escritura (K4, hallazgo 4 del panel TREE): con un memo rancio un rol recién definido en otro proceso se
|
|
793
|
+
* ignoraba. Un rol que el catálogo ya no declara —tras la recarga— no tiene visibilidad que decidir: sus aristas se BORRAN
|
|
794
|
+
* («rol ausente ⇒ borra», K4); el resto de sus hechos son de `purgeRole`/`authz:reconcile`.
|
|
795
|
+
*
|
|
796
|
+
* Coste: una lectura (los bindings del rol) y un `batchCheck` (HIGHER) por vuelta del settle; un `Write` por lote solo
|
|
797
|
+
* si hay algo que corregir. Un rol sin bindings —todo `defineScopedRole`— son 0 escrituras.
|
|
675
798
|
*/
|
|
676
799
|
private sweepRoleVisibility;
|
|
677
800
|
/**
|
|
@@ -681,15 +804,12 @@ export declare class OpenFgaAuthorizationDriver implements AuthorizationDriver {
|
|
|
681
804
|
* NIVEL de ese scope (3b-2g · R1) y ser global o tener a su owner en la
|
|
682
805
|
* cadena (3b-2e · E1). Visible ⇒ la arista se (re)escribe; no visible ⇒ se
|
|
683
806
|
* borra. El `assignee` no se toca: la asignación existe igual, lo que
|
|
684
|
-
* cambia es dónde se la ve.
|
|
807
|
+
* cambia es dónde se la ve. (Desde el lote C solo lo usa el barrido PREVIO, que solo borra.)
|
|
685
808
|
*/
|
|
686
809
|
private classifyBindingEdge;
|
|
687
810
|
/**
|
|
688
|
-
* Aplica
|
|
689
|
-
*
|
|
690
|
-
* `Ignore` en las dos direcciones: el barrido dice el estado que DEBE
|
|
691
|
-
* quedar, no el delta — borrar lo que ya no está y reescribir lo que ya
|
|
692
|
-
* estaba son no-ops, no errores (invariante 6).
|
|
811
|
+
* Aplica los BORRADOS de un barrido (lote C · L13: `applyBindingSweep` ya no da ALTAS; las altas de `scope#binding` de
|
|
812
|
+
* rol local solo salen del settle). Borrar nunca concede, así que va directo, en lotes ≤ 100 con `Ignore`.
|
|
693
813
|
*/
|
|
694
814
|
private applyBindingSweep;
|
|
695
815
|
/**
|
|
@@ -698,7 +818,8 @@ export declare class OpenFgaAuthorizationDriver implements AuthorizationDriver {
|
|
|
698
818
|
* tiene que gobernar el barrido; el resolutor del consumidor no participa.
|
|
699
819
|
* Un nodo con más de un padre es deriva y se dice (`assertOneParent`), y el
|
|
700
820
|
* recorrido está acotado por el mismo tope de páginas que las
|
|
701
|
-
* enumeraciones: un ciclo escrito a mano no cuelga el proceso.
|
|
821
|
+
* enumeraciones: un ciclo escrito a mano no cuelga el proceso. Alimenta
|
|
822
|
+
* escrituras (anti-ciclos de `reparent`, barrido, caída del settle) ⇒ HIGHER (hallazgo 3 TREE).
|
|
702
823
|
*/
|
|
703
824
|
private storeChain;
|
|
704
825
|
/**
|
|
@@ -826,6 +947,13 @@ export declare class OpenFgaAuthorizationDriver implements AuthorizationDriver {
|
|
|
826
947
|
* divergencia R1 del lote 2e.
|
|
827
948
|
*/
|
|
828
949
|
projectCatalogRole(roleUuid: string): Promise<void>;
|
|
950
|
+
/**
|
|
951
|
+
* La proyección `permits_<P>` de UN rol (la otra mitad de `projectCatalogRole`). **Hallazgo 4 del panel TREE (K4)**: el
|
|
952
|
+
* catálogo es el de una ESCRITURA (`writeCatalog`, versión en fresco) — con un memo `{ everyMs }` que todavía no conoce
|
|
953
|
+
* un rol recién definido en otro proceso, `rolePermissionsOf` devolvía `[]` y esto BORRABA sus `permits_*` (fail-closed
|
|
954
|
+
* medido: `dave@C`). Mutante `project.memo-catalog`.
|
|
955
|
+
*/
|
|
956
|
+
private projectRolePermits;
|
|
829
957
|
/**
|
|
830
958
|
* **Reconstruye el store desde `authz_*` + el árbol del consumidor.**
|
|
831
959
|
*
|
|
@@ -1085,6 +1213,12 @@ export declare class OpenFgaAuthorizationDriver implements AuthorizationDriver {
|
|
|
1085
1213
|
* default `?? []` sobre `tuples` vuelva a este fichero.
|
|
1086
1214
|
*/
|
|
1087
1215
|
private tuplesOrThrow;
|
|
1216
|
+
/**
|
|
1217
|
+
* **`readAllTuples` para una lectura que ALIMENTA UNA ESCRITURA** (lote C · carreras, resolución 8; hallazgo 3 TREE):
|
|
1218
|
+
* con `HIGHER_CONSISTENCY` siempre (`WRITE_CONSISTENCY`). Es el helper ÚNICO: la guardia de fuente de
|
|
1219
|
+
* `tests/visibility_settle.spec.ts` exige que los métodos que escriben lean por aquí (o por `checkForWrite`).
|
|
1220
|
+
*/
|
|
1221
|
+
private readForWrite;
|
|
1088
1222
|
private readAllTuples;
|
|
1089
1223
|
}
|
|
1090
1224
|
/**
|
|
@@ -1120,4 +1254,3 @@ export declare class OpenFgaAuthorizationDriver implements AuthorizationDriver {
|
|
|
1120
1254
|
* en silencio los datos de quien ya usaba ese nombre).
|
|
1121
1255
|
*/
|
|
1122
1256
|
export declare const OWN_FACTS_OBJECT_TYPES: ReadonlySet<string>;
|
|
1123
|
-
//# sourceMappingURL=openfga_driver.d.ts.map
|