El método estándar es una Lista de control de acceso discrecional (DACL) . Dicha estructura asigna entidades (por ejemplo, usuarios, grupos de usuarios, etc.) a recursos (por ejemplo, archivos, mutexes, sockets, etc.) con un conjunto definido de atributos de permisos ubicados en cada enlace.
Por ejemplo, lo siguiente representa una DACL de lectura / escritura simple:
Resource | Entity | R | W |
----------------+----------+---+---+
/foo/bar | Alice | 1 | 0 |
/foo/bar | Bob | 1 | 1 |
/bar/foo | Eve | 1 | 1 |
/log | Everyone | 0 | 1 |
/log | Alice | 1 | 1 |
En este caso, Alice tiene acceso de lectura a /foo/bar
y Bob tiene acceso de lectura / escritura a /foo/bar
, mientras que Eve no tiene acceso a /foo/bar
porque no tiene ninguna entrada en la tabla DACL. Solo Eve tiene acceso a /bar/foo
.
El caso interesante es cuando observamos el recurso /log
, al cual el grupo Todos tiene acceso de solo escritura. Como Alice está en el grupo Todos, podríamos imaginar que no debería necesitar una entrada, pero su entrada en realidad anula la configuración del grupo. En este punto, hemos creado una DACL jerárquica , que nos permite heredar permisos y proporcionar comportamientos de anulación específicos más bajos en la jerarquía.
Este modelo proporciona permisos extremadamente flexibles y puede implementarse en una variedad de diferentes sistemas de almacenamiento de datos, por ejemplo. sistema de archivos, RDBMS, motor de almacenamiento de valores clave, etc.
Por supuesto, el ejemplo anterior no se traduce directamente a una tabla de base de datos relacional, debido a la ambigüedad entre los grupos de usuarios y los usuarios. Esto se puede resolver utilizando un identificador de seguridad (SID) , que identifica de forma única a cualquier entidad. Probablemente lo implementaría algo como esto:
TABLE resource_dacl
resource_id INTEGER NOT_NULL
security_id INTEGER NULL
perm_read TINYINT(1) DEFAULT 0 // permission to read the resource
perm_write TINYINT(1) DEFAULT 0 // permission to write to the resource
perm_delete TINYINT(1) DEFAULT 0 // permission to delete the resource
perm_acl TINYINT(1) DEFAULT 0 // permission to change the resource's ACL
...
PRIMARY_KEY ( resource_id, security_id )
El security_id
debería ser único para cada entidad y se almacenaría dentro de las tablas de usuarios y grupos de usuarios.
Esto le permite consultar fácilmente los permisos en SQL usando un JOIN
con WHERE EXISTS
, lo que resulta en un solo valor de la base de datos, que contiene un 1 o 0 para indicar si los permisos necesarios están establecidos.