Recopila registros del CRM de Zendesk
En este documento, se explica cómo transferir registros de la administración de relaciones con clientes (CRM) de Zendesk 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 Zendesk
- Acceso con privilegios a AWS (S3, Identity and Access Management [IAM], Lambda, EventBridge).
Obtén los requisitos previos de Zendesk
- Confirmar plan y rol
- Debes ser administrador de Zendesk para crear tokens de API o clientes de OAuth. La API de Audit Logs solo está disponible en el plan Enterprise. (Si tu cuenta no es de Enterprise, omite
audit_logs
enRESOURCES
).
- Debes ser administrador de Zendesk para crear tokens de API o clientes de OAuth. La API de Audit Logs solo está disponible en el plan Enterprise. (Si tu cuenta no es de Enterprise, omite
- Activa el acceso al token de API (único)
- En el Centro de administración, ve a Apps y integraciones > APIs > Configuración de la API.
- Habilita Permitir acceso al token de API.
- Genera un token de API (para la autenticación básica)
- Ve a Apps and integrations > APIs > API tokens.
- Haz clic en Agregar token de API > (opcionalmente) agrega una descripción > Guardar.
- Copia y guarda el token de API ahora (no podrás volver a verlo).
- Guarda el correo electrónico del administrador que se autenticará con este token.
- Formato de autenticación básica que usa Lambda:
email_address/token:api_token
- Formato de autenticación básica que usa Lambda:
- (Opcional) Crea un cliente de OAuth (para la autenticación de portador en lugar del token de API)
- Ve a Apps and integrations > APIs > OAuth clients > Add OAuth client.
- Completa los campos Nombre, Identificador único (automático), URLs de redireccionamiento (puede ser un marcador de posición si solo generas tokens con la API) y Guardar.
- Crea un token de acceso para la integración y otorga los permisos mínimos que requiere esta guía:
tickets:read
(para entradas incrementales)auditlogs:read
(para Registros de auditoría; solo para empresas)- Si no sabes qué elegir,
read
también funciona para el acceso de solo lectura.
- Copia el token de acceso (pégalo en
ZENDESK_BEARER_TOKEN
) y registra el ID y el secreto del cliente de forma segura (para futuros flujos de actualización de tokens).
Registra tu URL base de Zendesk
- Usa
https://<your_subdomain>.zendesk.com
(pégalo en la variable de entornoZENDESK_BASE_URL
).
Qué copiar y guardar para más tarde
- URL base (por ejemplo,
https://acme.zendesk.com
) - Dirección de correo electrónico del usuario administrador (para la autenticación con token de API)
- Token de API (si usas
AUTH_MODE=token
) - o token de acceso de OAuth (si se usa
AUTH_MODE=bearer
) - (Opcional) ID y secreto del cliente de OAuth para la administración del ciclo de vida
- Usa
Configura el bucket de AWS S3 y el IAM para Google SecOps
- 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,
zendesk-crm-logs
). - Crea un usuario siguiendo esta guía del usuario: Cómo crear un usuario de IAM.
- Selecciona el usuario creado.
- Selecciona la pestaña Credenciales de seguridad.
- Haz clic en Crear clave de acceso en la sección Claves de acceso.
- Selecciona Servicio de terceros como Caso de uso.
- Haz clic en Siguiente.
- Opcional: Agrega una etiqueta de descripción.
- Haz clic en Crear clave de acceso.
- Haz clic en Descargar archivo .CSV para guardar la clave de acceso y la clave de acceso secreta para consultarlas en el futuro.
- Haz clic en Listo.
- Selecciona la pestaña Permisos.
- Haz clic en Agregar permisos en la sección Políticas de permisos.
- Selecciona Agregar permisos.
- Selecciona Adjuntar políticas directamente.
- Busca la política AmazonS3FullAccess.
- Selecciona la política.
- Haz clic en Siguiente.
- Haz clic en Agregar permisos.
Configura la política y el rol de IAM para las cargas de S3
- En la consola de AWS, ve a IAM > Políticas.
- Haz clic en Crear política > pestaña JSON.
- Copia y pega la siguiente política.
JSON de la política (reemplaza
zendesk-crm-logs
si ingresaste un nombre de bucket diferente):{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowPutObjects", "Effect": "Allow", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::zendesk-crm-logs/*" }, { "Sid": "AllowGetStateObject", "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::zendesk-crm-logs/zendesk/crm/state.json" } ] }
Haz clic en Siguiente > Crear política.
Ve a IAM > Roles > Crear rol > Servicio de AWS > Lambda.
Adjunta la política recién creada.
Asigna el nombre
ZendeskCRMToS3Role
al 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 zendesk_crm_to_s3
Tiempo de ejecución Python 3.13 Arquitectura x86_64 Rol de ejecución ZendeskCRMToS3Role
Después de crear la función, abre la pestaña Code, borra el código auxiliar y pega el siguiente código (
zendesk_crm_to_s3.py
).#!/usr/bin/env python3 import os, json, time, base64 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", "zendesk/crm/") STATE_KEY = os.environ.get("STATE_KEY", "zendesk/crm/state.json") BASE_URL = os.environ["ZENDESK_BASE_URL"].rstrip("/") # e.g. https://your_subdomain.zendesk.com AUTH_MODE = os.environ.get("AUTH_MODE", "token").lower() # token|bearer EMAIL = os.environ.get("ZENDESK_EMAIL", "") API_TOKEN = os.environ.get("ZENDESK_API_TOKEN", "") BEARER = os.environ.get("ZENDESK_BEARER_TOKEN", "") RESOURCES = [r.strip() for r in os.environ.get("RESOURCES", "audit_logs,incremental_tickets").split(",") if r.strip()] MAX_PAGES = int(os.environ.get("MAX_PAGES", "20")) LOOKBACK = int(os.environ.get("LOOKBACK_SECONDS", "3600")) # 1h default HTTP_TIMEOUT = int(os.environ.get("HTTP_TIMEOUT", "60")) HTTP_RETRIES = int(os.environ.get("HTTP_RETRIES", "3")) s3 = boto3.client("s3") def _headers() -> dict: if AUTH_MODE == "bearer" and BEARER: return {"Authorization": f"Bearer {BEARER}", "Accept": "application/json"} if AUTH_MODE == "token" and EMAIL and API_TOKEN: token = base64.b64encode(f"{EMAIL}/token:{API_TOKEN}".encode()).decode() return {"Authorization": f"Basic {token}", "Accept": "application/json"} raise RuntimeError("Invalid auth settings: provide token (EMAIL + API_TOKEN) or BEARER") def _get_state() -> dict: try: obj = s3.get_object(Bucket=S3_BUCKET, Key=STATE_KEY) b = obj["Body"].read() return json.loads(b) if b else {"audit_logs": {}, "incremental_tickets": {}} except Exception: return {"audit_logs": {}, "incremental_tickets": {}} def _put_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 _http_get_json(url: str) -> dict: attempt = 0 while True: try: req = Request(url, method="GET") for k, v in _headers().items(): req.add_header(k, v) with urlopen(req, timeout=HTTP_TIMEOUT) as r: return json.loads(r.read().decode("utf-8")) except HTTPError as e: if e.code in (429, 500, 502, 503, 504) and attempt < HTTP_RETRIES: ra = 1 + attempt try: ra = int(e.headers.get("Retry-After", ra)) except Exception: pass time.sleep(max(1, ra)) attempt += 1 continue raise except URLError: if attempt < HTTP_RETRIES: time.sleep(1 + attempt) attempt += 1 continue raise def _put_page(payload: dict, resource: str) -> str: ts = time.gmtime() key = f"{S3_PREFIX}/{time.strftime('%Y/%m/%d/%H%M%S', ts)}-zendesk-{resource}.json" s3.put_object( Bucket=S3_BUCKET, Key=key, Body=json.dumps(payload, separators=(",", ":")).encode("utf-8"), ContentType="application/json", ) return key def fetch_audit_logs(state: dict): """GET /api/v2/audit_logs.json with pagination via `next_page` (Zendesk).""" next_url = state.get("next_url") or f"{BASE_URL}/api/v2/audit_logs.json?page=1" pages = 0 written = 0 last_next = None while pages < MAX_PAGES and next_url: data = _http_get_json(next_url) _put_page(data, "audit_logs") written += len(data.get("audit_logs", [])) last_next = data.get("next_page") next_url = last_next pages += 1 return {"resource": "audit_logs", "pages": pages, "written": written, "next_url": last_next} def fetch_incremental_tickets(state: dict): """Cursor-based incremental export: /api/v2/incremental/tickets/cursor.json (pagination via `links.next`).""" next_link = state.get("next") if not next_link: start = int(time.time()) - LOOKBACK next_link = f"{BASE_URL}/api/v2/incremental/tickets/cursor.json?start_time={start}" pages = 0 written = 0 last_next = None while pages < MAX_PAGES and next_link: data = _http_get_json(next_link) _put_page(data, "incremental_tickets") written += len(data.get("tickets", [])) links = data.get("links") or {} next_link = links.get("next") last_next = next_link pages += 1 return {"resource": "incremental_tickets", "pages": pages, "written": written, "next": last_next} def lambda_handler(event=None, context=None): state = _get_state() summary = [] if "audit_logs" in RESOURCES: res = fetch_audit_logs(state.get("audit_logs", {})) state["audit_logs"] = {"next_url": res.get("next_url")} summary.append(res) if "incremental_tickets" in RESOURCES: res = fetch_incremental_tickets(state.get("incremental_tickets", {})) state["incremental_tickets"] = {"next": res.get("next")} summary.append(res) _put_state(state) return {"ok": True, "summary": summary} 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_BUCKET
zendesk-crm-logs
S3_PREFIX
zendesk/crm/
STATE_KEY
zendesk/crm/state.json
ZENDESK_BASE_URL
https://your_subdomain.zendesk.com
AUTH_MODE
token
ZENDESK_EMAIL
analyst@example.com
ZENDESK_API_TOKEN
<api_token>
ZENDESK_BEARER_TOKEN
<leave empty unless using OAuth bearer>
RESOURCES
audit_logs,incremental_tickets
MAX_PAGES
20
LOOKBACK_SECONDS
3600
HTTP_TIMEOUT
60
Despué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
zendesk_crm_to_s3
. - Nombre:
zendesk_crm_to_s3-1h
.
- Programación recurrente: Frecuencia (
- Haz clic en Crear programación.
(Opcional) Crea un usuario y claves de IAM de solo lectura para Google SecOps
- Ve a Consola de AWS > IAM > Usuarios > Agregar 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:::zendesk-crm-logs/*" }, { "Effect": "Allow", "Action": ["s3:ListBucket"], "Resource": "arn:aws:s3:::zendesk-crm-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 los registros del CRM de Zendesk
- 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,
Zendesk CRM logs
). - Selecciona Amazon S3 V2 como el Tipo de fuente.
- Selecciona Zendesk CRM como el Tipo de registro.
- Haz clic en Siguiente.
- Especifica valores para los siguientes parámetros de entrada:
- URI de S3:
s3://zendesk-crm-logs/zendesk/crm/
- 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.