Recopila registros de auditoría de Tines
En este documento, se explica cómo transferir registros de auditoría de Tines a Google Security Operations con Amazon S3.
Antes de comenzar
Asegúrate de cumplir con los siguientes requisitos previos:
- Es una instancia de Google SecOps.
- Acceso privilegiado a Tines
- Acceso con privilegios a AWS (S3, Identity and Access Management [IAM], Lambda, EventBridge).
Obtén la URL de Tines
- En tu navegador, abre la IU de Tines para tu arrendatario.
- Copia el dominio de la barra de direcciones. Lo usarás como
TINES_BASE_URL.- Formato:
https://<tenant-domain>(por ejemplo,https://<tenant-domain>.tines.com)
- Formato:
Crea una clave de API de servicio de Tines (recomendado) o una clave de API personal
Valores que se deben guardar para los pasos posteriores:
TINES_BASE_URL: Por ejemplo,https://<domain>.tines.comTINES_API_KEY: Es el token que crearás en los siguientes pasos.
Opción 1: Clave de API de servicio (recomendada)
- Ve al menú de navegación > Claves de API.
- Haz clic en + Nueva clave.
- Selecciona Clave de API de servicio.
- Ingresa un nombre descriptivo (por ejemplo,
SecOps Audit Logs). - Haz clic en Crear.
- Copia el token generado de inmediato y guárdalo de forma segura. Lo usarás como
TINES_API_KEY.
Opción 2: Clave de API personal (si las claves de servicio no están disponibles)
- Ve al menú de navegación > Claves de API.
- Haz clic en + Nueva clave.
- Selecciona Clave de API personal.
- Ingresa un nombre descriptivo.
- Haz clic en Crear.
Copia el token generado y guárdalo de forma segura.
Otorga el permiso de lectura del registro de auditoría
- Accede como propietario del arrendatario (o pídele a uno que lo haga).
- Ve a Configuración > Administrador > Administración de usuarios (o haz clic en el nombre de tu equipo en el menú superior izquierdo y selecciona Usuarios).
- Busca el usuario de la cuenta de servicio asociado con tu clave de la API de Service (tendrá el mismo nombre que tu clave de API).
- Si usas una clave de API personal, busca tu propia cuenta de usuario.
- Haz clic en el usuario para abrir su perfil.
- En la sección Tenant permissions, habilita AUDIT_LOG_READ.
- Haz clic en Guardar.
(Opcional) Verifica el acceso a la API
Prueba el extremo con curl o cualquier cliente HTTP:
curl -X GET "https://<tenant-domain>/api/v1/audit_logs?per_page=1" \ -H "Authorization: Bearer <TINES_API_KEY>" \ -H "Content-Type: application/json"Deberías recibir una respuesta JSON con las entradas del registro de auditoría.
También puedes verificar que existan registros de auditoría. Para ello, navega a Configuración > Supervisión > Registros de auditoría en la IU (se requiere el permiso AUDIT_LOG_READ).
Configura el bucket de AWS S3
- Crea un bucket de Amazon S3 siguiendo esta guía del usuario: Crea un bucket
- Guarda el Nombre y la Región del bucket para futuras referencias (por ejemplo,
tines-audit-logs).
Configura la política y el rol de IAM para las cargas de Lambda en S3
- En la consola de AWS, ve a IAM > Políticas > Crear política > pestaña JSON.
- Copia y pega la siguiente política.
JSON de la política (reemplaza
tines-audit-logssi ingresaste un nombre de bucket diferente):{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowPutObjects", "Effect": "Allow", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::tines-audit-logs/*" }, { "Sid": "AllowGetStateObject", "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::tines-audit-logs/tines/audit/state.json" } ] }Haz clic en Siguiente > Crear política.
Asigna a la política el nombre
TinesLambdaS3Policy.Ve a IAM > Roles > Crear rol > Servicio de AWS > Lambda.
Adjunta el
TinesLambdaS3Policyque acabas de crear.Asigna el nombre
TinesAuditToS3Roleal rol y haz clic en Crear rol.
Crea la función Lambda
- En la consola de AWS, ve a Lambda > Functions > Create function.
- Haz clic en Author from scratch.
Proporciona los siguientes detalles de configuración:
Configuración Valor Nombre tines_audit_to_s3Tiempo de ejecución Python 3.13 Arquitectura x86_64 Rol de ejecución TinesAuditToS3RoleDespués de crear la función, abre la pestaña Code, borra el código auxiliar y pega el siguiente código (
tines_audit_to_s3.py).#!/usr/bin/env python3 # Lambda: Pull Tines Audit Logs to S3 (no transform) import os, json, time, urllib.parse from urllib.request import Request, urlopen from urllib.error import HTTPError, URLError import boto3 S3_BUCKET = os.environ["S3_BUCKET"] S3_PREFIX = os.environ.get("S3_PREFIX", "tines/audit/") STATE_KEY = os.environ.get("STATE_KEY", "tines/audit/state.json") LOOKBACK_SEC = int(os.environ.get("LOOKBACK_SECONDS", "3600")) # default 1h PAGE_SIZE = int(os.environ.get("PAGE_SIZE", "500")) # Max is 500 for Tines MAX_PAGES = int(os.environ.get("MAX_PAGES", "20")) TIMEOUT = int(os.environ.get("HTTP_TIMEOUT", "60")) HTTP_RETRIES = int(os.environ.get("HTTP_RETRIES", "3")) TINES_BASE_URL = os.environ["TINES_BASE_URL"] TINES_API_KEY = os.environ["TINES_API_KEY"] s3 = boto3.client("s3") def _iso(ts: float) -> str: return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(ts)) def _load_state() -> dict: try: obj = s3.get_object(Bucket=S3_BUCKET, Key=STATE_KEY) b = obj["Body"].read() return json.loads(b) if b else {} except Exception: return {} def _save_state(st: dict) -> None: s3.put_object( Bucket=S3_BUCKET, Key=STATE_KEY, Body=json.dumps(st, separators=(",", ":")).encode("utf-8"), ContentType="application/json", ) def _req(url: str) -> dict: attempt = 0 while True: try: req = Request(url, method="GET") req.add_header("Authorization", f"Bearer {TINES_API_KEY}") req.add_header("Accept", "application/json") req.add_header("Content-Type", "application/json") with urlopen(req, timeout=TIMEOUT) as r: data = r.read() return json.loads(data.decode("utf-8")) except HTTPError as e: if e.code in (429, 500, 502, 503, 504) and attempt < HTTP_RETRIES: retry_after = 1 + attempt try: retry_after = int(e.headers.get("Retry-After", retry_after)) except Exception: pass time.sleep(max(1, retry_after)) attempt += 1 continue raise except URLError: if attempt < HTTP_RETRIES: time.sleep(1 + attempt) attempt += 1 continue raise def _write(payload, page: int) -> str: ts = time.gmtime() key = f"{S3_PREFIX}{time.strftime('%Y/%m/%d/%H%M%S', ts)}-tines-audit-{page:05d}.json" s3.put_object( Bucket=S3_BUCKET, Key=key, Body=json.dumps(payload, separators=(",", ":")).encode("utf-8"), ContentType="application/json", ) return key def _extract_items(payload) -> list: if isinstance(payload, list): return payload if isinstance(payload, dict): audit_logs = payload.get("audit_logs") if isinstance(audit_logs, list): return audit_logs return [] def _extract_newest_ts(items: list, current: str | None) -> str | None: newest = current for it in items: # Use created_at as the timestamp field t = it.get("created_at") if isinstance(t, str) and (newest is None or t > newest): newest = t return newest def lambda_handler(event=None, context=None): st = _load_state() since = st.get("since") or _iso(time.time() - LOOKBACK_SEC) page = 1 pages = 0 total = 0 newest_ts = since while pages < MAX_PAGES: # Build URL with query parameters # Note: Tines audit logs API uses 'after' parameter for filtering base_url = f"{TINES_BASE_URL.rstrip('/')}/api/v1/audit_logs" params = { "after": since, # Filter for logs created after this timestamp "page": page, "per_page": PAGE_SIZE } url = f"{base_url}?{urllib.parse.urlencode(params)}" payload = _req(url) _write(payload, page) items = _extract_items(payload) total += len(items) newest_ts = _extract_newest_ts(items, newest_ts) pages += 1 # Check if there's a next page using meta.next_page_number meta = payload.get("meta") or {} next_page = meta.get("next_page_number") if not next_page: break page = next_page if newest_ts and newest_ts != since: st["since"] = newest_ts _save_state(st) return {"ok": True, "pages": pages, "items": total, "since": st.get("since")} if __name__ == "__main__": print(lambda_handler())Ve a Configuration > Environment variables.
Haz clic en Editar > Agregar nueva variable de entorno.
Ingresa las variables de entorno que se proporcionan en la siguiente tabla y reemplaza los valores de ejemplo por tus valores.
Variables de entorno
Clave Valor de ejemplo S3_BUCKETtines-audit-logsS3_PREFIXtines/audit/STATE_KEYtines/audit/state.jsonTINES_BASE_URLhttps://your-tenant.tines.comTINES_API_KEYyour-tines-api-keyLOOKBACK_SECONDS3600PAGE_SIZE500MAX_PAGES20HTTP_TIMEOUT60HTTP_RETRIES3Después de crear la función, permanece en su página (o abre Lambda > Funciones > tu-función).
Selecciona la pestaña Configuración.
En el panel Configuración general, haz clic en Editar.
Cambia Tiempo de espera a 5 minutos (300 segundos) y haz clic en Guardar.
Crea una programación de EventBridge
- Ve a Amazon EventBridge > Scheduler > Create schedule.
- Proporciona los siguientes detalles de configuración:
- Programación recurrente: Frecuencia (
1 hour) - Destino: Tu función Lambda
tines_audit_to_s3. - Nombre:
tines-audit-1h.
- Programación recurrente: Frecuencia (
- Haz clic en Crear programación.
Crea un usuario y claves de IAM de solo lectura para Google SecOps
- En la consola de AWS, ve a IAM > Usuarios.
- Haz clic en Agregar usuarios.
- Proporciona los siguientes detalles de configuración:
- Usuario: Ingresa
secops-reader. - Tipo de acceso: Selecciona Clave de acceso: Acceso programático.
- Usuario: Ingresa
- Haz clic en Crear usuario.
- Adjunta una política de lectura mínima (personalizada): Usuarios > secops-reader > Permisos > Agregar permisos > Adjuntar políticas directamente > Crear política.
JSON:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["s3:GetObject"], "Resource": "arn:aws:s3:::tines-audit-logs/*" }, { "Effect": "Allow", "Action": ["s3:ListBucket"], "Resource": "arn:aws:s3:::tines-audit-logs" } ] }Nombre =
secops-reader-policy.Haz clic en Crear política > busca o selecciona > Siguiente > Agregar permisos.
Crea una clave de acceso para
secops-reader: Credenciales de seguridad > Claves de acceso.Haz clic en Crear clave de acceso.
Descarga el
.CSV. (Pegarás estos valores en el feed).
Configura un feed en Google SecOps para transferir registros de auditoría de Tines
- Ve a Configuración de SIEM > Feeds.
- Haz clic en + Agregar feed nuevo.
- En el campo Nombre del feed, ingresa un nombre para el feed (por ejemplo,
Tines Audit Logs). - Selecciona Amazon S3 V2 como el Tipo de fuente.
- Selecciona Tines como el Tipo de registro.
- Haz clic en Siguiente.
- Especifica valores para los siguientes parámetros de entrada:
- URI de S3:
s3://tines-audit-logs/tines/audit/ - Opciones de borrado de la fuente: Selecciona la opción de borrado según tu preferencia.
- Antigüedad máxima del archivo: Incluye los archivos modificados en la cantidad de días especificada. El valor predeterminado es de 180 días.
- ID de clave de acceso: Clave de acceso del usuario con acceso al bucket de S3.
- Clave de acceso secreta: Clave secreta del usuario con acceso al bucket de S3.
- Espacio de nombres del recurso: Es el espacio de nombres del recurso.
- Etiquetas de transmisión: Es la etiqueta que se aplica a los eventos de este feed.
- URI de S3:
- Haz clic en Siguiente.
- Revisa la nueva configuración del feed en la pantalla Finalizar y, luego, haz clic en Enviar.
¿Necesitas más ayuda? Obtén respuestas de miembros de la comunidad y profesionales de Google SecOps.