9 de julio de 2026

Notificaciones push desde cualquier script: el appliance como canal de alertas

Envíe notificaciones push informativas a los teléfonos registrados con un solo curl: alertas de servidor, guardias, precios y domótica.

El Notakey appliance suele describirse como un servidor de autenticación: se produce un inicio de sesión, llega una solicitud push al teléfono y el usuario la aprueba. Pero ese mismo canal de entrega admite un segundo tipo de mensaje —una simple notificación— y eso convierte el appliance en algo más general: un canal de mensajería push hacia cada teléfono registrado en su servicio, invocable desde cualquier script con un único curl.

any script ──HTTPS──▶ appliance API ──push──▶ enrolled phone
 (cron, monitoring,    /notify                 Notakey Authenticator
  home automation…)

A diferencia de una solicitud de autenticación, una notificación no pide aprobación: simplemente aparece en el teléfono, dirigida a un nombre de usuario, y se entrega a la vez en todos los dispositivos registrados de esa persona. Eso la convierte en un sustituto directo allí donde, de otro modo, tendría que recurrir al SMS (coste por mensaje, remitente falsificable) o al correo electrónico (ignorado hasta el lunes): supervisión de tareas, avisos de guardia, comunicados a los empleados.

Requisitos

  • Un Notakey appliance en funcionamiento (en la nube u on-premise) con un servicio y al menos un usuario con un teléfono ya registrado. Si ya utiliza VPN 2FA o SSO, dispone de todo esto: las notificaciones pasan por el mismo servicio que sus inicios de sesión, o por uno aparte si desea una marca distinta.
  • Credenciales de acceso a la API (un client ID y un client secret), creadas en el panel, en la sección Access credentials (paso 1, más abajo).
  • curl y jq en cualquier equipo que pueda alcanzar el appliance. Esa es toda la lista de dependencias.

Paso 1: cree credenciales de acceso a la API

En el panel, abra Access credentials y cree una credencial para sus scripts. Aquí importan dos cosas:

  • Scopes (permisos). Conceda urn:notakey:notify: es el scope que necesita esta guía. También existe urn:notakey:auth, para crear solicitudes de autenticación (aprobar/denegar); añádalo solo si la misma credencial va a hacer ambas cosas. Una credencial limitada a notificaciones no puede utilizarse indebidamente para provocar aprobaciones de inicio de sesión, así que mantenga la lista de scopes tan corta como permita la tarea.
  • Recibirá un client ID y un client secret. El secret autoriza a enviar mensajes a todos los usuarios del servicio: trátelo como una contraseña de root.

Paso 2: cámbielas por un token y mantenga el token al día

La propia llamada de notify no usa el client secret, sino un token de acceso de tipo bearer obtenido mediante el flujo estándar client-credentials de OAuth 2.0. Los tokens de acceso son deliberadamente efímeros: prevea renovarlos aproximadamente una vez por hora o, en algún momento, sus scripts empezarán a fallar con errores de autorización, justo después de haber funcionado a la perfección durante 59 minutos.

Por eso la renovación del token es una tarea de cron, no un paso de configuración puntual:

#!/bin/bash
# /usr/local/bin/ntk-token-renew — cron: 0 * * * *

curl -s -X POST https://ntk.example.com/api/token \
  -d 'grant_type=client_credentials&client_id=<client-id>&client_secret=<client-secret>&scope=urn:notakey:notify' \
  | jq -r .access_token > /etc/notakey/api.token

El script incrusta el client secret y escribe el token, así que proteja ambos:

chmod 700 /usr/local/bin/ntk-token-renew    # root-only, holds the secret
install -m 600 /dev/null /etc/notakey/api.token

Si también concedió urn:notakey:auth, solicítelo como un token aparte en un archivo aparte (la misma llamada, scope=urn:notakey:auth) en lugar de un único token con ambos scopes: así los scripts de notificación nunca guardan un token capaz de crear aprobaciones de inicio de sesión.

Paso 3: un único script de notify reutilizable

Todo lo demás en esta guía llama a este único script. Recibe un nombre de usuario, un título y el cuerpo del mensaje:

#!/bin/bash
# /usr/local/bin/ntk-notify <username> <title> <description>

token=$(cat /etc/notakey/api.token)

curl -X POST -H "Content-Type: application/json" \
  -H "Authorization: Bearer $token" \
  -d '{ "username": "'"$1"'", "title": "'"$2"'", "description": "'"$3"'", "type": "notification" }' \
  "https://ntk.example.com/api/v3/services/<service-id>/notify"

Sustituya ntk.example.com por la dirección de su appliance y <service-id> por el UUID del servicio que aparece en el panel. Pruébelo:

ntk-notify j.doe "Test" "If you can read this on your phone, the channel works."

El push llega a la app Notakey Authenticator, la misma que el usuario ya tiene para iniciar sesión, de modo que no hay nada nuevo que instalar, explicar ni hacer pasar por la gestión de dispositivos móviles.

Paso 4: invóquelo desde cualquier sitio

Una vez que el canal se reduce a una sola línea, los casos de uso se acumulan solos. Algunos que hoy funcionan en producción:

Una tarea de copia de seguridad que informa del resultado. El clásico fallo silencioso: copias que dejaron de funcionar hace meses y nadie se dio cuenta. Dos líneas al final de la tarea lo resuelven:

if ! /usr/local/bin/backup-run; then
  ntk-notify admin "Backup FAILED" "Nightly backup on $(hostname) exited with an error — check /var/log/backup.log"
fi

Espacio en disco, caducidad de certificados, cualquier cosa que cron pueda comprobar:

#!/bin/bash
# cron: 0 8 * * *
used=$(df --output=pcent / | tail -1 | tr -dc '0-9')
if [ "$used" -gt 90 ]; then
  ntk-notify admin "Disk warning" "Root filesystem on $(hostname) is at ${used}% — time to clean up."
fi

Un comunicado a toda la plantilla. La API se dirige a un solo nombre de usuario por llamada, así que un mensaje para toda la empresa es un bucle sobre su lista de usuarios: ventanas de mantenimiento, cierres de oficina, avisos de incidencias:

while read -r user; do
  ntk-notify "$user" "IT maintenance" "VPN unavailable Saturday 06:00–08:00 — planned appliance upgrade."
done < users.txt

Precios spot de la electricidad, dos veces cada dos horas. No todo lo que merece un push es una avería. Este se ejecuta desde cron y le indica al usuario cuánto costará la electricidad en la próxima hora, útil para decidir cuándo poner el lavavajillas:

#!/bin/bash
# cron: 5 * * * * — sends on even hours, 06–23 only
hour=$(( $(date +%H) + 1 ))
next=$(( hour + 1 ))

if [ "$hour" -gt 5 ] && [ "$hour" -lt 24 ] && (( $(date +%H) % 2 == 0 )); then
  ntk-notify "$1" "Electricity" \
    "Next hour: $(spot_price "$hour")€/kWh. After that: $(spot_price "$next")€/kWh."
fi

(spot_price es lo que sea que obtenga sus datos de mercado: una API de mercado, un CSV en caché. Lo importante es la entrega, no la fuente.)

Para mensajes recurrentes como este, conviene conocer dos extras documentados: añadir un campo fingerprint al payload hace que un envío repetido con la misma fingerprint actualice el mensaje existente en lugar de apilar uno nuevo, de modo que un ticker de precios sigue siendo una sola notificación y no cuarenta al día. Y "type": "sms" envía el mismo mensaje como SMS, si el usuario tiene definido un número de móvil: un canal de reserva para alguien cuyo teléfono perdió la app.

La lavadora ha terminado. Un enchufe inteligente que vigila el consumo, una automatización de Home Assistant, un script que consulta un contador: sea lo que sea que detecte el fin del ciclo, la notificación es la misma línea de siempre. Ejemplo trivial, hábito real: cuando enviar un push no cuesta nada, se acaba avisando de todo.

Para qué sirve este canal, y para qué no

Frente al SMS, el lado del destinatario es mucho más sólido: un SMS llega al terminal que en ese momento tenga la SIM, desde un nombre de remitente que cualquiera puede falsificar, mientras que una notificación de Notakey aterriza únicamente en la app Authenticator, en dispositivos que completaron el registro criptográfico en su servicio. Nadie puede darse de alta por su cuenta en sus alertas ni suplantar al remitente.

Una limitación honesta, directamente de la documentación de la API: el propio cuerpo de la notificación no está cifrado de extremo a extremo; como cualquier push móvil, se retransmite a través de los servicios push de Apple y Google y resulta legible para las apps con acceso a las notificaciones del dispositivo. Trate, por tanto, el cuerpo del mensaje como un aviso de buscapersonas y no como un sobre lacrado: «La copia de seguridad falló en el host X» es aceptable; una contraseña o una clave de API, no. Cuando necesite entregar algo verdaderamente secreto, utilice en su lugar una solicitud de autenticación (urn:notakey:auth): allí el push es solo una llamada a la puerta, y la app recupera el contenido por su canal autenticado con certificado después de que el usuario responda.

Dónde encaja

Si el appliance ya protege su VPN o sus aplicaciones, las notificaciones son una capacidad gratuita que no está aprovechando: el mismo servicio, la misma app, las mismas credenciales de API, un único endpoint adicional. Y si hasta ahora ha estado pagando una pasarela de SMS para las alertas internas, este canal la sustituye para todo destinatario que lleve consigo un teléfono registrado.

Guías relacionadas

← Todos los artículos

Su primer inicio de sesión sin contraseña, esta misma semana

30 minutos con un ingeniero, no una presentación comercial. Juntos planificaremos cómo poner en marcha un piloto funcional en su entorno de VPN, SSO o Windows.