Cuentas, usuarios y acceso
Tu organización es un tenant en CORE-M — tu propia porción aislada de la plataforma. Cada petición que tú y tu equipo hacen lleva una identidad que pertenece a tu tenant, y CORE-M responde dos preguntas en cada llamada: quién eres (autenticación) y tienes permiso para hacer esto (autorización). Los datos de tu tenant se acotan automáticamente a ti y nunca son visibles para ningún otro tenant.
Esta página explica todo lo que gestionas para tu propio tenant: usuarios y el modelo de roles, permisos de página basados en grupos, el ciclo de vida del JWT, el rate limiting de inicio de sesión, las claves de API, la configuración de SSO, y cómo el aislamiento mantiene tus datos separados.
Tu tenant
Sección titulada «Tu tenant»Tu tenant es tu límite de aislamiento de nivel superior. Cuando se crea tu tenant obtienes:
- Un
tenant_idúnico que acota cada parte de tus datos. - Un usuario administrador inicial (rol
tenant_admin), con la contraseña almacenada con hash bcrypt. - Una clave de API para acceso programático, devuelta una sola vez.
- Un grupo por defecto llamado “All Users” con todos los permisos de página
(
dashboard,devices,telemetry,rules,anchors). Tu administrador inicial no se añade a él — los administradores omiten las comprobaciones de grupo a través de su rol.
Los nombres de tenant son únicos; un nombre duplicado se rechaza con ALREADY_EXISTS.
Cada usuario de tu tenant tiene exactamente un rol. Los roles definen el alcance administrativo y son de grano grueso; el acceso de grano fino para los usuarios estándar proviene de los grupos.
| Rol | Alcance | Qué otorga |
|---|---|---|
platform_admin | Todo el sistema | Reservado para el equipo de plataforma de Kronox Data que opera CORE-M. No asignable por tu tenant. |
tenant_admin | Tu tenant | Acceso completo dentro de tu tenant: usuarios, grupos, dispositivos, reglas, claves de API y configuración. Omite los permisos de grupo dentro de tu tenant. |
member | Tu tenant | Usuario estándar. El acceso se controla por completo mediante las membresías de grupo. Sin acceso a /manage/* ni /admin/*. |
Grupos y permisos de página
Sección titulada «Grupos y permisos de página»Los grupos son colecciones de usuarios acotadas al tenant con un conjunto definido de permisos de página. Un usuario puede pertenecer a varios grupos, y sus permisos efectivos son la unión deduplicada de los permisos de todos sus grupos.
Permisos de página disponibles:
| Permiso | Da acceso a |
|---|---|
dashboard | Resumen del dashboard |
devices | Ver y gestionar dispositivos |
telemetry | Dashboards y gráficos de telemetry |
rules | Ver y gestionar reglas |
anchors | Datos de prueba en blockchain en las páginas de detalle de dispositivo |
Reglas de permisos en la práctica:
- Un
membersin grupos no tiene ningún acceso y ve: “Tu cuenta no tiene permisos asignados. Contacta a tu administrador.” - Un
memberque intenta una acción fuera de sus permisos se rechaza conPERMISSION_DENIEDy “missing permission: rules” (o la página correspondiente). - Cambiar los permisos de un grupo no reescribe los tokens en vivo. Los JWT existentes quedan obsoletos y adoptan los nuevos permisos en el siguiente refresco de token.
- Eliminar un grupo quita a todos sus miembros y recalcula sus permisos efectivos, lo que puede retirarles el acceso a algunas páginas.
Autenticación de usuarios
Sección titulada «Autenticación de usuarios»Los usuarios se autentican con email y contraseña. Las contraseñas se almacenan con hash bcrypt en reposo. Las respuestas de inicio de sesión son seguras frente a ataques de temporización (timing-safe) y nunca revelan si el email o la contraseña fueron incorrectos — un usuario inexistente es indistinguible de una contraseña errónea.
Un inicio de sesión exitoso emite dos tokens, ambos firmados con Ed25519:
- Un access token, con expiración de 15 minutos, presentado en cada llamada a la API.
- Un refresh token, con expiración de 7 días, usado únicamente para acuñar nuevos access tokens.
El ciclo de vida del JWT
Sección titulada «El ciclo de vida del JWT»flowchart TD
login([Login: email + password]) -->|valid| issue["Issue access (15 min)<br/>+ refresh (7 day)"]
login -->|invalid| fail["UNAUTHENTICATED<br/>(timing-safe, no field hint)"]
issue --> use["Call API with access token"]
use -->|access valid| ok([Request authorized])
use -->|access expired| refresh{Refresh token<br/>still valid?}
refresh -->|yes| rotate["Issue new access token<br/>+ rotate refresh token<br/>(old refresh invalidated)"]
rotate --> use
refresh -->|no| relogin([Redirect to login])
El refresh es rotatorio: cada llamada RefreshToken invalida el refresh token
anterior y emite uno nuevo junto con el nuevo access token. Un refresh token expirado se
rechaza con UNAUTHENTICATED, lo que obliga a un nuevo inicio de sesión.
El access token se firma con Ed25519 usando la clave de la variable de entorno
AUTH_SIGNING_KEY. Los servicios downstream verifican la firma y leen los claims — no
vuelven a llamar al servicio de autenticación por cada petición.
Ejemplo de conjunto de claims del JWT
Sección titulada «Ejemplo de conjunto de claims del JWT»Un member del tenant T1, en los grupos “Engineering” (devices, telemetry) y
“Monitoring” (dashboard, rules), recibe un access token cuyo payload se ve así:
{ "sub": "9f2c1e44-1b3a-4c8e-9d77-6a0b2f5e1c90", "tid": "1a2b3c4d-0000-4e5f-8a9b-112233445566", "role": "member", "groups": [ "grp-engineering-001", "grp-monitoring-002" ], "permissions": [ "dashboard", "devices", "rules", "telemetry" ], "iat": 1747396800, "exp": 1747397700}| Claim | Significado |
|---|---|
sub | ID de usuario |
tid | Tenant ID — la clave de aislamiento para todas las consultas downstream |
role | Uno de platform_admin, tenant_admin, member |
groups | IDs de los grupos a los que pertenece el usuario |
permissions | Unión deduplicada de todos los permisos de página de los grupos |
iat / exp | Emitido-en y expiración (ventana de 15 minutos para los access tokens) |
Rate limiting de inicio de sesión
Sección titulada «Rate limiting de inicio de sesión»Para mitigar el credential-stuffing y la fuerza bruta, los inicios de sesión fallidos se limitan por tasa en dos dimensiones independientes, ambas con un TTL de 900 segundos (15 minutos):
| Dimensión | Umbral | Clave de Aerospike | TTL |
|---|---|---|---|
| Por email | 5 intentos fallidos en 15 min → bloquea el 6.º | loginrl:{email_hash} | 900s |
| Por IP de origen | 20 intentos fallidos en 15 min → bloquea el 21.º | loginrl:ip:{ip} | 900s |
Una petición limitada por tasa se rechaza con RESOURCE_EXHAUSTED y “too many login
attempts, try again later”. La respuesta no revela si la cuenta existe, y
corem_auth_login_rate_limited_total se incrementa. Como el estado de bloqueo vive en
una clave de Aerospike con un TTL, el límite se libera por sí solo una vez que la ventana
expira — no hay ningún paso de desbloqueo manual.
Claves de API
Sección titulada «Claves de API»Las claves de API autentican las llamadas de dispositivo a plataforma y las llamadas programáticas hacia tu tenant.
- Formato: prefijo
sk_live_seguido de 32 bytes criptográficamente aleatorios, codificados en formato URL-safe. - Almacenamiento: solo se almacena el hash — nunca la clave en bruto.
- Visualización: la clave en bruto se devuelve exactamente una vez en la creación. No hay forma de recuperarla más tarde; si la pierdes, la rotas.
Presentar una clave como Authorization: Bearer sk_live_… permite a CORE-M resolver tu
tenant_id (y, para las claves de dispositivo, el device_id) y acotar la petición a tu
tenant. Una clave revocada se rechaza con UNAUTHENTICATED.
Configuración de SSO (solo configuración en v1)
Sección titulada «Configuración de SSO (solo configuración en v1)»CORE-M almacena y valida la configuración del proveedor de SSO para tu tenant para SAML 2.0 y OIDC.
| Campo | SAML 2.0 | OIDC |
|---|---|---|
| Protocolo | saml | oidc |
| Metadatos / discovery del IdP | URL del XML de metadatos o XML subido | Discovery URL (.well-known/openid-configuration) |
| Entity ID / Client ID | SP Entity ID | Client ID |
| Client Secret | N/D | Client Secret (cifrado en reposo) |
| Habilitado | Si la configuración almacenada está habilitada para una integración futura | Igual |
Una prueba de configuración comprueba que el endpoint de metadatos del IdP o de discovery de OIDC es alcanzable y válido, e informa los atributos descubiertos. La prueba nunca crea ni actualiza usuarios de CORE-M.
Cómo se mantienen aislados tus datos
Sección titulada «Cómo se mantienen aislados tus datos»El aislamiento se aplica en cada petición, no como característica de una pantalla concreta:
-
Llega una petición con un JWT o una clave de API.
-
CORE-M extrae tu
tenant_id(del claimtido de la clave de API) y lo adjunta a la petición. -
Cada lectura y escritura se acota a ese
tenant_id, de modo que una petición hecha bajo tu tenant nunca puede direccionar los datos de otro tenant. -
Cualquier acceso entre tenants se rechaza con
PERMISSION_DENIEDy se registra para auditoría.
Por eso el claim tid importa tanto: es el único valor que fija una petición entera a la
porción de la plataforma de tu tenant.