Autorización de la bóveda
Este documento describe el servicio de autorización del daemon local y la interfaz HTTP de autorización del Center SaaS. Las operaciones RPC locales siguientes están disponibles en el núcleo compartido, la CLI y las herramientas de autorización MCP. Los comandos existentes memories mcp grant, memories mcp revoke, la importación de tickets del Center y los comandos de auditoría de bóvedas utilizan las comprobaciones actualizadas del núcleo.
Roles y límites máximos de alcance
| Rol en la bóveda | Alcance máximo de la concesión | ¿Puede emitir o delegar? |
|---|---|---|
| Lector | read |
No |
| Editor | read_write |
No |
| Administrador | read_write_delete |
Sí |
| Propietario | allow_all |
Sí |
Omitir el alcance significa lectura, no allow_all. Esto se aplica a las concesiones locales, la emisión de tickets del Center, las concesiones estáticas alojadas y la creación de miembros. La opción heredada explícita write: true sigue seleccionando read_write; write: false selecciona read. write sigue siendo un alcance de solo escritura. allow_all requiere una selección explícita y un emisor Propietario, aunque actualmente cubra las mismas operaciones de contenido de activos ordinarios que read_write_delete.
La emisión comprueba tanto el rol actual del emisor en la bóveda como, para un llamador con token de portador, el alcance de la concesión emisora. Una concesión no puede autorizar otra bóveda, superar ninguno de los dos límites ni durar más que su concesión padre. Las duraciones son de 1–60 minutos. Las solicitudes de una autoridad más amplia o prolongada fallan en lugar de reducir silenciosamente el alcance solicitado. Los destinatarios ya deben ser miembros de la bóveda seleccionada. Una concesión de contenido puede proporcionar acceso adicional al contenido a un miembro, pero no cambia su rol: un Editor o Lector con una concesión amplia sigue sin poder delegar ni aprobar solicitudes.
Los registros de concesiones exponen id, vault, scope, issued_by (ID del miembro), grantee, parent (ID de la concesión emisora, o null), depth y expiry en segundos Unix. El ID de una concesión es un identificador opaco aleatorio independiente de su token de portador. La emisión devuelve el token una sola vez; las listas de acceso y concesiones nunca lo incluyen. Los ID de concesiones y solicitudes, y los ID de principales, son identificadores opacos y canónicos; los ID de bóveda visibles para el cliente conservan la proyección normal de ID corto.
La emisión local de concesiones por un Administrador/Propietario requiere una bóveda desbloqueada, no elevación de privilegios del terminal. La revocación tampoco necesita elevación, pero solo se permite al emisor de la concesión o a un Administrador/Propietario actual de su bóveda. La revocación es transitiva. Eliminar un emisor o destinatario, o reducir el rol de un emisor por debajo del alcance que emitió, invalida las concesiones afectadas y sus descendientes cuando se confirma la política, incluidos los cambios de política importados por sincronización y los realizados después de un reinicio. Las concesiones persisten en el Store cifrado local del dispositivo utilizando únicamente el hash SHA-256 del token de portador y los metadatos de autorización; la autenticación compara los hashes en tiempo constante. La revocación y la eliminación de descendientes se confirman junto con el estado cifrado. El bloqueo elimina las concesiones en memoria y las claves del Store, por lo que todas las concesiones quedan inutilizables hasta el desbloqueo; las concesiones no vencidas se reactivan después del desbloqueo o de reiniciar el daemon. Se persiste el vencimiento absoluto y las concesiones vencidas y sus descendientes se purgan al cargar y en los ciclos del daemon. Las concesiones no se exportan mediante la sincronización de bóvedas ni las copias de seguridad de recuperación.
Los cambios de miembros y las aprobaciones de dispositivos conservan sus comprobaciones de elevación existentes, además del nuevo requisito de Administrador/Propietario. Crear una invitación ahora requiere pertenecer como Administrador/Propietario a al menos una bóveda local. Los llamadores sin bóvedas y aquellos que solo tienen pertenencias como Editor/Lector se rechazan de forma segura. Los Administradores pueden gestionar la pertenencia de Administradores, pero no pueden añadir, eliminar ni modificar un Propietario. Los cambios de propiedad utilizan la operación firmada de transferencia de propiedad y conservan exactamente un Propietario.
Solicitudes de permisos
Destinatarios designados y profundidad de delegación
Tanto el daemon como el Center alojado rechazan la emisión a un destinatario cuyo rol sea superior al rol efectivo del emisor, incluso cuando el alcance de contenido solicitado sea solo read. El Center también rechaza el destinatario reservado center-admin, incluidas las concesiones previamente persistidas con ese sujeto.
Un llamador mediante concesión utiliza la autoridad de una concesión con un sujeto diferente de su emisor real (subject != issued_by). Estos llamadores pueden crear solicitudes, pero no pueden aprobar, rechazar, cancelar ni reclamar ninguna solicitud de permisos, incluidas las suyas. El daemon devuelve Unauthorized; el Center devuelve HTTP 403. Estos llamadores no son aprobadores elegibles. Las concesiones autoemitidas conservan sus reglas existentes para solicitudes; las reclamaciones en el Center siguen requiriendo la credencial duradera de miembro del solicitante. Los tokens de portador duraderos de miembros del Center representan autoridad de miembro, no autoridad delegada por una concesión.
El daemon mantiene la vinculación exacta con la credencial del solicitante: una solicitud creada con un token de portador de destinatario designado no puede reclamarse posteriormente con una credencial de miembro diferente. Vuelva a crear esa solicitud utilizando la credencial de miembro o autoemitida que la reclamará. En cambio, el Center vincula las reclamaciones al token de portador duradero de miembro del solicitante.
Ambas implementaciones definen pub const MAX_DELEGATION_DEPTH: u32 = 2. Las concesiones emitidas directamente por un miembro tienen profundidad 1. La emisión mediante autoridad de concesión, incluido el padre de una aprobación diferida en el momento de reclamarla, tiene profundidad parent.depth + 1; la profundidad 3 se rechaza. depth se persiste y se incluye en los resúmenes de concesiones, las respuestas de emisión, las vistas de acceso y las listas de concesiones emitidas. Los registros heredados sin depth se reconstruyen a partir de su cadena de padres (una concesión sin padre tiene profundidad 1). Una ascendencia de concesiones ausente, cíclica o que supere el límite se rechaza de forma segura y se purga al cargar. Las credenciales internas duraderas de miembros del Center tienen profundidad 0, no son concesiones delegadas.
La emisión delegada conserva el emisor real a través de la cadena de padres, en lugar de convertir a un destinatario designado en un principal autoemitido. Las cadenas heredadas existentes también se comprueban al determinar el emisor real del llamador.
Las aprobaciones heredadas diferidas registradas mediante una concesión de destinatario designado también se rechazan de forma segura al reclamarlas; obtenga una nueva aprobación de una autoridad de miembro elegible.
Cambios incompatibles: los destinatarios de rol superior y los destinatarios center-admin ya no pueden recibir concesiones; los tokens de portador de destinatarios designados ya no pueden participar en decisiones, cancelaciones o reclamaciones de permisos; las cadenas de más de dos concesiones ya no son utilizables. Utilice una credencial de miembro para las decisiones y reclamaciones de permisos, y emita una nueva concesión raíz cuando una delegación adicional supere el límite.
Cualquier miembro actual puede presentar una solicitud para su propio acceso en una bóveda:
{
"op": "request_create",
"vault": "VAULT",
"target": {"type": "scope", "scope": "read_write"},
"reason": "Update the shared project notes",
"duration_minutes": 15,
"approvers": []
}
target puede ser {"type":"scope","scope":"..."} (el alcance predeterminado es read) o {"type":"role","role":"editor"}. El motivo, la duración y los aprobadores son opcionales. La aprobación de alcance tiene una duración predeterminada de 30 minutos si se omite. Los cambios de rol son permanentes: se rechaza una duración en una solicitud de rol, y los llamadores mediante concesiones con límite temporal no pueden aprobar un cambio de rol permanente. Aprobar una solicitud de rol requiere la misma elevación vinculada al llamador que los cambios directos de rol de miembro. Un Propietario que aprueba una solicitud del rol Propietario realiza una transferencia de propiedad firmada.
Una lista vacía de aprobadores difunde la solicitud a todos los miembros actuales Administradores/Propietarios de esa bóveda. De lo contrario, solo los ID de miembros indicados pueden decidirla; cada ID indicado debe corresponder a un miembro Administrador/Propietario en el momento de la creación, y la elegibilidad se vuelve a comprobar al decidir. Los Lectores y Editores no pueden figurar como aprobadores. El solicitante no puede aprobar ni rechazar su propia solicitud, incluso como Administrador/Propietario o aprobador designado; sí puede cancelarla. La aprobación de alcance/rol debe ajustarse al rol y al alcance del token de portador del aprobador, y el vencimiento del alcance debe ajustarse al padre. Una aprobación que supere los límites deja la solicitud pendiente.
Las solicitudes tienen exactamente una transición de pending a approved, rejected o cancelled. Solo el solicitante puede cancelar una solicitud pendiente. La aprobación de alcance registra los parámetros de la concesión, sin generar un token de portador. El solicitante utiliza request_claim una sola vez para generar y recibir el token; request_list devuelve únicamente metadatos. La creación/generación y la duración de la concesión comienzan al reclamarla, limitadas por el vencimiento registrado del padre. El estado de aprobación y reclamación sobrevive al bloqueo/reinicio, pero una autoridad aprobadora revocada o vencida no puede autorizar una reclamación. No se conserva ningún token en texto plano en el estado de la solicitud ni en el estado persistido del Store. Las concesiones reclamadas sobreviven al bloqueo/reinicio como hashes y metadatos. Las solicitudes y los tokens no se exportan en la sincronización de bóvedas.
request_list devuelve las solicitudes del llamador (incluidas las ya decididas) y las solicitudes pendientes que puede decidir. Otros miembros no pueden inspeccionar una solicitud dirigida. Una bóveda admite como máximo 1,000 solicitudes almacenadas; los motivos están limitados a 4,096 bytes. Puede haber como máximo 10,000 concesiones activas simultáneamente, tanto en el daemon local como en un Center alojado.
Límites de solicitudes pendientes: un solicitante puede tener como máximo 20 solicitudes pendientes por bóveda y una bóveda como máximo 200 solicitudes pendientes; la creación por encima del límite falla con un error de límite (HTTP 429 en un Center alojado). Las solicitudes pendientes y las aprobadas pero no reclamadas vencen después de 7 días (auditadas como request.expire, actor system); las solicitudes decididas se eliminan 30 días después de su última transición.
Operaciones RPC e interfaces
Los nombres JSON op del daemon son:
| Operación | Campos | Autoridad |
|---|---|---|
access_list |
vault |
Administrador/Propietario |
grant_list |
vault |
Los Administradores/Propietarios ven todas; los demás miembros actuales solo ven las concesiones que emitieron |
grant_issue |
vault, minutes, scope opcional, grantee |
Administrador/Propietario |
grant_revoke |
vault, id |
Emisor o Administrador/Propietario |
request_create |
vault, target, reason opcional, duration_minutes, approvers |
Cualquier miembro |
request_list |
vault |
Solicitudes propias o pendientes para cuya decisión sea elegible |
request_approve |
vault, id |
Administrador/Propietario elegible |
request_claim |
vault, id |
Credencial original del solicitante de la solicitud de alcance aprobada; una sola vez |
request_reject |
vault, id, reason opcional |
Administrador/Propietario elegible |
request_cancel |
vault, id |
Solicitante de la solicitud pendiente |
audit |
vault, verify_only |
Administrador/Propietario |
Los heredados mcp_grant y mcp_revoke siguen siendo compatibles. Los llamadores con token de portador solo pueden utilizar estas RPC de autorización para la bóveda de su concesión; esto no permite que MCP herede la elevación del terminal ni acceda a credenciales almacenadas. La FFI móvil sigue rechazando la gestión de concesiones y las nuevas operaciones de solicitudes de permisos; no se necesitan cambios en la ABI nativa.
access_list devuelve principals agrupados en owner, admin, editor y reader, además de grants activas, devices (dispositivos autorizados y no revocados de la política de la bóveda: device, member propietario, name; la política no registra la hora de creación), pending_requests y approved_unclaimed_requests (cada una con id, requester, target de alcance/rol, lista approvers o "broadcast", y created y expires en segundos Unix). La visibilidad sigue siendo para Administrador/Propietario. grant_list devuelve {"vault":"VAULT","grants":[...]} sin grupos de principales. Cada concesión emitida contiene id, parent (null para una concesión raíz), issued_by, grantee, scope, vault, expiry en segundos Unix, generation, depth y created en segundos Unix cuando está disponible. La generación local es la generación del estado confirmado en el momento de la emisión, no la generación actual al listar. Se excluyen las concesiones vencidas/revocadas. Los Administradores/Propietarios pueden listar todas las concesiones de la bóveda; los demás miembros actuales solo pueden listar las concesiones que ellos mismos emitieron, no las que simplemente recibieron. Los llamadores con token de portador siguen vinculados a la bóveda de su concesión. Ninguna respuesta contiene tokens, hashes de tokens de portador ni cuerpos de activos. La RPC del daemon, grant_list de MCP y memories grant list
VAULT comparten esta respuesta del servicio.
Los envoltorios de la CLI se implementan con estos comandos exactos (los ID son opacos):
memories access list VAULT
memories grant issue VAULT --minutes N [--scope S] [--grantee ID]
memories grant list VAULT
memories grant revoke VAULT ID
memories request create VAULT [--scope S | --role R] [--reason T] [--duration M] [--approver ID]...
memories request list VAULT
memories request approve VAULT ID
memories request claim VAULT ID
memories request reject VAULT ID [--reason T]
memories request cancel VAULT ID
memories audit list VAULT [--verify-only]
La sintaxis heredada memories audit VAULT [--verify] sigue siendo compatible. El alcance predeterminado es read; las solicitudes locales de alcance sin duración conservan el valor predeterminado de aprobación de 30 minutos del daemon. Las solicitudes de rol no pueden incluir una duración. La salida es JSON en el envoltorio normal de la CLI.
Los equivalentes del Center alojado utilizan las rutas HTTP de autorización:
memories center access VAULT
memories center grant issue VAULT --minutes N [--scope S] [--grantee ID]
memories center grant list [VAULT]
memories center grant revoke ID
memories center request create VAULT [--scope S] [--reason T] [--duration M] [--approver ID]...
memories center request list [VAULT]
memories center request approve ID
memories center request claim ID
memories center request reject ID [--reason T]
memories center request cancel ID
memories center audit [--vault V] [--format json|jsonl]
Estos comandos aceptan --center-url; en caso contrario utilizan MEMORIES_CENTER_URL o el Center SaaS configurado. Utilizan MEMORIES_CENTER_TOKEN cuando está definido; de lo contrario, MEMORIES_CENTER_ADMIN_TOKEN; los fallos de permisos no se reintentan con otro token de portador. Las solicitudes alojadas admiten alcance, no cambios de rol locales. El alcance predeterminado es read y la duración de solicitud predeterminada es de 30 minutos. La exportación de auditoría JSONL imprime una entrada JSON por línea sin el envoltorio de la CLI; el resto de la salida utiliza el envoltorio JSON.
Las herramientas MCP del daemon son access_list, grant_issue, grant_list, grant_revoke, request_create, request_list, request_approve, request_claim, request_reject, request_cancel y audit_list. Sus argumentos siguen los campos RPC anteriores (minutes para emitir concesiones, target y duration_minutes para crear solicitudes, y verify_only para auditoría). El alcance de concesión o el destino de solicitud omitidos tienen read como valor predeterminado. Cada llamada utiliza la capacidad MCP existente, nunca la elevación del terminal ni un token de portador del Center alojado.
El Center SaaS implementa GET /v1/access/{vault}, POST/GET /v1/grants, DELETE /v1/grants/{id}, POST/GET /v1/requests, POST /v1/requests/{id}/approve|claim|reject|cancel y GET /v1/audit, exclusivo para Administrador/Propietario. Estas rutas requieren el modo alojado (--data). Consulte center.md para conocer los cuerpos HTTP, parámetros de consulta, respuestas y archivos persistidos exactos.
Autorización del Center SaaS
Los miembros alojados tienen un role explícito opcional (reader, editor, admin, owner) independiente de su scope de contenido. Cuando se omite role, los niveles de alcance existentes se corresponden con Lector (read), Editor (write/read_write), Administrador (read_write_delete) o Propietario (allow_all). El token de portador del operador actúa como el Propietario center-admin en todas las bóvedas alojadas. Los principales con tokens de portador estáticos utilizan ID static:OPAQUE_ID y la misma correspondencia entre alcance y rol. Los ID de miembros no pueden utilizar el nombre reservado center-admin. El alcance de contenido no eleva a un destinatario Lector/Editor a un rol administrativo.
POST /v1/grants establece scope en read y duration_minutes en 30 de forma predeterminada; minutes es un alias de duración. La emisión requiere el rol Administrador/Propietario, con los mismos límites de rol, alcance, bóveda y vencimiento que la emisión local. Las respuestas utilizan subject para el destinatario e incluyen parent, issued_by, expiry, generation y depth. Los tokens de concesión solo aparecen en las respuestas de emisión/reclamación, nunca en las aprobaciones, listas ni auditorías. Para los llamadores miembros, el destinatario predeterminado es el emisor; un grantee explícito debe identificar un principal existente en la bóveda seleccionada. La emisión por el operador sin grantee crea un principal de concesión anónimo identificado por el ID de su concesión, nunca un sujeto center-admin. Esto también se aplica a la emisión de tickets alojada.
Cada miembro alojado tiene un contador de generación persistido. Las concesiones generadas fijan las generaciones del emisor y del destinatario en el momento de la emisión; la autenticación nunca las actualiza. Cambiar el alcance, el rol o la bóveda de un miembro, o eliminarlo, incrementa únicamente la generación de ese miembro. Los contadores de miembros eliminados persisten para que recrear un ID no reinicie su generación. La eliminación o actualización revoca las concesiones emitidas por ese miembro o para él y todos sus descendientes, con registros de auditoría, mientras las concesiones no relacionadas siguen funcionando. El campo público generation es la generación del destinatario en el momento de la emisión. Los principales estáticos y del operador tienen una generación fija. Las credenciales duraderas de miembros se restablecen únicamente en la transición explícita de política, no mediante autenticación.
Las concesiones generadas alojadas sobreviven al reinicio en DIR/grants.json, accesible solo para el propietario y que contiene únicamente hashes SHA-256 de tokens de portador, generaciones fijadas, metadatos de vencimiento/padre y revocaciones. La comparación de hashes es en tiempo constante. Las concesiones vencidas y sus descendientes se purgan al cargar, periódicamente y durante la autenticación/emisión. El bloqueo elimina las claves del Store y suspende las concesiones sin revocarlas; las concesiones no vencidas y las credenciales estáticas/duraderas se reactivan después del desbloqueo. Los fallos de persistencia bloquean el servicio y requieren reparación/reinicio por el operador en lugar de arriesgarse a una reactivación indebida.
POST /v1/requests acepta vault, scope opcional, reason, duration_minutes (alias duration) y approvers. approvers vacío u omitido difunde la solicitud mediante las listas de solicitudes pendientes de Administradores/Propietarios elegibles; los ID proporcionados dirigen la solicitud. GET /v1/requests devuelve las solicitudes pendientes que pertenecen al llamador o están dentro de su autoridad de aprobación, además de las solicitudes aprobadas y no reclamadas del solicitante, opcionalmente filtradas por vault. Tanto la aprobación como el rechazo requieren la autoridad de rol, alcance, bóveda y vencimiento del aprobador seleccionado. El solicitante no puede aprobar ni rechazar su propia solicitud, incluso como Administrador/Propietario o aprobador designado; solo el solicitante puede cancelarla. Se serializa y persiste una sola decisión; las repeticiones devuelven 409. La aprobación devuelve únicamente metadatos de request con status: approved, claimed: false y límites validados de alcance, duración y emisor; no genera una concesión ni devuelve un token. A continuación, el solicitante llama a POST /v1/requests/{id}/claim con su token de portador duradero de miembro y recibe request junto con una respuesta grant de una sola vez. Los aprobadores, los demás miembros y otras concesiones para el mismo sujeto no pueden reclamarla utilizando esas credenciales. Una segunda reclamación devuelve 409. La generación, la hora de creación y la duración comienzan al reclamar, con un vencimiento limitado por el vencimiento registrado de la autoridad aprobadora. Las credenciales aprobadoras revocadas/vencidas o las generaciones de miembros modificadas no pueden utilizarse para reclamar.
El daemon utiliza el mismo flujo de generación diferida para las solicitudes de alcance: request_approve almacena los límites de aprobación y request_claim devuelve metadatos de concesión junto con token una sola vez. Los llamadores locales autenticados por el sistema operativo deben seguir siendo el miembro solicitante; MCP debe presentar la capacidad exacta que creó la solicitud, no una concesión diferente para el mismo sujeto. Las listas nunca devuelven tokens. Las aprobaciones de rol siguen siendo cambios inmediatos de política y no tienen ninguna concesión reclamable. El estado cifrado del Store y DIR/requests.json contienen únicamente metadatos de solicitudes; las concesiones persisten solo hashes de tokens de portador. El inicio concilia las decisiones y reclamaciones del Center con la auditoría verificada para que los guardados interrumpidos de metadatos no puedan reabrir una decisión o solicitud reclamada. Si se pierde una respuesta de reclamación exitosa, el token no puede recuperarse de nuevo; solicite una nueva aprobación.
Formato y verificación de auditoría
Las entradas de auditoría locales conservan vault, previous, sequence, timestamp, action, object, result, el certificado de firma y la firma. Los nuevos campos opcionales de nivel superior son actor, subject (destinatario), scope, expiry, parent, reason, issued_by, via_grant y request_id. El actor identifica al miembro que actúa; el firmante identifica al dispositivo del daemon que registra el evento. Por tanto, una acción delegada puede tener un actor y un usuario firmante diferentes. Las entradas de auditoría no incluyen contraseñas, credenciales almacenadas ni tokens de portador.
Las entradas realizadas mediante autoridad de concesión incluyen issued_by (el emisor real) y via_grant (el ID de concesión del llamador); actor sigue siendo el sujeto de la concesión. La excepción del evento de emisión (mcp.grant / grant.issue del Center) registra al emisor real como actor y al destinatario como subject, incluida la emisión delegada. Ambos campos opcionales utilizan valores predeterminados de serde y se omiten cuando están ausentes, conservando la serialización y verificación de auditorías firmadas antiguas y registros JSONL del Center. Las auditorías de contenido alojado llevan la misma atribución en el Store compartido.
Las auditorías son cadenas de hashes firmadas por dispositivo. previous apunta al hash SHA-256 de la entrada firmada serializada anterior, y el mapa de auditoría utiliza esos hashes como claves. Vault::verify valida las firmas, los hashes, la continuidad de la secuencia y las invariantes existentes del historial de la bóveda. Los registros antiguos omiten todos los campos nuevos y conservan exactamente sus bytes de firma y hashes heredados. Los campos nuevos utilizan valores predeterminados de serde y se omiten cuando están ausentes; los detalles presentes están cubiertos por la firma.
Los eventos incluyen device.authorize, mcp.grant, mcp.grant.center, mcp.revoke, session.lock, session.unlock y request.create|request.approve|request.claim|request.reject|request.cancel, junto con los eventos existentes de pertenencia y dispositivos. Los bloqueos explícitos propagan los errores de persistencia de auditoría, pero aun así borran el estado desbloqueado. Los bloqueos de ciclo de vida/inactividad intentan registrar una auditoría y siempre borran el estado aunque falle la persistencia; no deben dejar secretos desbloqueados para conservar un registro de auditoría. Los fallos en estado bloqueado no pueden firmar una auditoría.
El Center SaaS tiene una cadena SHA-256 independiente en DIR/audit.jsonl, de solo anexado y con modo 0600, que no es el formato local de auditoría firmada. GET /v1/audit requiere Administrador/Propietario, acepta vault y format=json|jsonl, y verifica la cadena completa antes de filtrar/exportar. Los administradores vinculados a una bóveda no pueden leer los eventos de otra bóveda; el operador también puede ver los eventos globales de bloqueo/desbloqueo/inscripción. Las entradas contienen sequence, timestamp, prev_hash, hash, action, actor, subject, scope, vault, expiry, parent, reason, request_id y object; los detalles opcionales son null. El hash cubre la tupla serializada (sequence, timestamp, prev_hash, event_fields); prev_hash es null para la primera entrada y después es el hash de la entrada anterior.
verify_audit_chain(path) en crates/center/src/saas/audit.rs comprueba los hashes, la continuidad de la secuencia, los hashes anteriores y las líneas JSONL completas. El inicio verifica el archivo existente; el anexado/lectura también compara su cabecera con la cabecera conocida del proceso en ejecución. Los eventos incluyen device.authorize, grant.issue, grant.revoke, member.add|member.set|member.remove, session.lock|session.unlock y request.create|request.approve|request.claim|request.reject|request.cancel. Los eventos de reclamación registran al solicitante como actor y el ID de la concesión generada como objeto, nunca el token. Los fallos al anexar auditoría o persistir solicitudes/miembros bloquean el servicio alojado, establecen restart_required y bloquean el desbloqueo remoto hasta que un operador lo repare y reinicie. Las modificaciones de autorización y las decisiones de permisos también se detienen mientras esté establecido restart_required; la inspección de solo lectura por el operador sigue disponible. Estas cadenas sin clave no protegen frente a un operador que reescriba todo el registro o revierta todos los archivos; las garantías más fuertes necesitan anclajes externos de la cabecera.
Modelo de amenazas y cambios de comportamiento
- Los llamadores locales autenticados por el sistema operativo actúan como el miembro del dispositivo desbloqueado. Los procesos maliciosos del mismo usuario permanecen dentro del límite de confianza existente del punto final.
- Los tokens de portador de capacidades son secretos; cualquiera que posea uno puede utilizar su autoridad limitada hasta la revocación, el bloqueo o el vencimiento. Un token de portador no puede ampliar su propio alcance, escapar de su bóveda, prolongar el vencimiento ni eludir el rol de delegación de su sujeto.
- La revocación no borra el texto plano o las claves previamente copiados y no puede llegar instantáneamente a los pares sin conexión. La invalidación de políticas y concesiones es efectiva en el daemon que ha confirmado la política actualizada.
- Las cadenas de hashes detectan alteraciones respecto al estado conocido, no la reversión completa de la base de datos ni los eventos omitidos por un dispositivo comprometido. Los anclajes externos y una auditoría de seguridad independiente siguen siendo necesarios para obtener garantías más fuertes.
- Cambios incompatibles: la emisión sin alcance es de solo lectura; los Editores/Lectores no pueden generar concesiones ni invitaciones; el acceso a auditoría requiere Administrador/Propietario en lugar de elevación; los cambios de miembros invalidan las concesiones delegadas. La nueva emisión de concesiones por Administrador/Propietario y la revocación por emisor/Administrador ya no requieren elevación. La creación de invitaciones sin bóvedas se rechaza en lugar de tratar silenciosamente a un llamador como administrador.
- Cambio incompatible: la aprobación ya no genera ni entrega un token de portador, y las listas de solicitudes ya no entregan un token de portador aprobado. Los solicitantes deben reclamar explícitamente una sola vez. Las solicitudes previamente aprobadas sin límites de aprobación diferida registrados no pueden reclamarse; cree una nueva solicitud. Las concesiones existentes emitidas por separado siguen sus reglas normales de vencimiento/revocación.
Consulte SECURITY.md para conocer los límites y center.md para los límites de confianza independientes del Center alojado de solo tickets y con claves del operador.
Límites, vencimiento y retención de solicitudes de permisos
Se aplica tanto al daemon (solicitudes en el Store cifrado) como al Center (requests.json):
MAX_PENDING_PER_REQUESTER_PER_VAULT = 20yMAX_PENDING_PER_VAULT = 200cuentan únicamente las solicitudes pendientes. Las solicitudes decididas, canceladas, vencidas y aprobadas pero no reclamadas no cuentan para estos límites. (Esto sustituye al antiguo límite global de 1000 solicitudes, que contaba todas las solicitudes realizadas.) Si supera un límite, el daemon devuelve un error de límite y el Center devuelve HTTP 429.PENDING_REQUEST_TTL = 7 days: una solicitud pendiente más antigua que este plazo pasa al estadoexpired. Se audita comorequest.expirecon actorsystemy ya no puede aprobarse. Una solicitud de alcance aprobada que no se haya reclamado en los 7 días posteriores a su aprobación también vence del mismo modo y no puede reclamarse después.REQUEST_RETENTION = 30 days: las solicitudes rechazadas, canceladas, vencidas o reclamadas se eliminan transcurrido este plazo desde su última transición (la marca temporaldecided, ocreatedpara los registros antiguos que no la tengan).- El vencimiento y la eliminación se ejecutan de forma diferida: el daemon los realiza al inicio de cualquier solicitud de autorización y el Center al crear, listar, decidir y reclamar solicitudes. No se ejecutan durante el inicio.
- La conciliación al iniciar el Center ignora las entradas de auditoría de solicitudes eliminadas y acepta las entradas
request.expire. Una solicitudexpireddebe tener un vencimiento auditado. Los ID de solicitudes son valores aleatorios de 128 bits que nunca se reutilizan, por lo que una solicitud eliminada (incluida una reclamada) ya no existe y no puede reclamarse. Por eso, el Center no conserva un conjunto separado de registros de eliminación.