Implementación de Autorización y Control de Acceso en APIs con Prisma 1

Prisma 1, en su arquitectura original integrada con GraphQL, proporciona mecanismos nativos para gestionar la seguridad de los datos a nivel de base de datos y de API. A continuación, se detalla el proceso técnico para establecer un sistema de autorización robusto, abarcando desde el modelado del esquema hasta la validación en los resolvers.

  1. Esquema de Datos y Tipificación de Roles

El primer paso para establecer el control de acceso es estructurar el modelo de datos para incluir la tipificación de usuarios y sus niveles de privilegio. Esto se logra mediante la definición de enumeraciones y la vinculación de estas al modelo principal de usuarios.

En el archivo de definición del modelo de datos, se establece la siguiente estructura:

enum AccountPrivilege {
  SUPER_USER
  CLIENT
}

type Member {
  memberId: ID! @id
  fullName: String!
  contactEmail: String! @unique
  secretKey: String!
  privilegeLevel: AccountPrivilege! @default(value: "CLIENT")
  authoredArticles: [Article!]!
}

En este esquema, se define la enumeración AccountPrivilege para categorizar a los usuarios, y se inyecta el campo privilegeLevel en el tipo Member, asignando por defecto el rol de cliente.

  1. Directivas de Seguridad en el Manifiesto del Servicio

Prisma 1 permite centralizar las reglas de acceso a nivel de modelo dentro del archivo de configuración del servicio. Estas directivas actúa como una capa de seguridad que intercepta las consultas antes de que lleguen a la base de datos.

La configuración en el manifiesto del servicio se define de la siguiente manera:

# Directivas de permisos a nivel de modelo y relación
permissions:
  - operation: "Article.create"
    roles: ["SUPER_USER"]
  - operation: "Article.update"
    roles: ["SUPER_USER", "AUTHOR"]
  - operation: "Article.delete"
    roles: ["SUPER_USER"]
  - operation: "Article.read"
    roles: ["SUPER_USER", "CLIENT"]

Esta configuración restringe las operaciones de mutación crítica (creación y eliminación) exclusivamente a los administradores. Las actualizaciones requieren ser administrador o el autor del contenido, mientras que la lectura está habilitada para cualquier usuario autenticado.

  1. Lógica de Autorización en los Resolvers

Además de las reglas a nivel de base de datos, es necesario implementar validaciones de contexto en los resolvers de GraphQL para manejar lógicas de negocio específicas, como la verificación de autoría en tiempo de ejecución.

El siguiente fragmento muestra cómo integrar esta lógica en el servidor GraphQL:

const retrieveArticle = async (_, args, context, info) => {
  const { articleId } = args;
  
  const targetArticle = await context.db.query.article(
    { where: { id: articleId } },
    info
  );

  const requesterId = extractUserId(context);
  const isSuperUser = context.currentUser.privilegeLevel === 'SUPER_USER';
  const isContentAuthor = targetArticle.writer.memberId === requesterId;

  if (!isSuperUser && !isContentAuthor) {
    throw new GraphQLError(
      'Acceso denegado: se requieren privilegios de administrador o autoría del contenido.'
    );
  }

  return targetArticle;
};

El resolver extrae el identificador del solicitante y evalúa las banderas de privilegios. Si ninguna de las condiciones de autorización se cumple, se interrumpe la ejecución lanzando un error de GraphQL, evitando así la exposición de datos sensibles.

Validación del Flujo de Seguridad

Para garantizar la integridad de las reglas implementadas, se debe someter el sistema a pruebas exhaustivas utilizando herramientas como GraphQL Playground. El protocolo de validación incluye:

  • Generar cuentas de prueba con distintos niveles de AccountPrivilege.
  • Ejecutar mutaciones y consultas utilizando tokens de autenticación correspondientes a cada perfil.
  • Confirmar que las operaciones no autorizadas devuelvan los errores de GraphQL esperados y que las operaciones permitidas retornen los datos correctamente.

Etiquetas: Prisma GraphQL ORM authorization rbac

Publicado el 6-26 05:39