Coletar registros de auditoria do Tines

Compatível com:

Este documento explica como ingerir registros de auditoria do Tines no Google Security Operations usando o Amazon S3.

Antes de começar

Verifique se você tem os pré-requisitos a seguir:

  • Uma instância do Google SecOps.
  • Acesso privilegiado ao Tines.
  • Acesso privilegiado à AWS (S3, Identity and Access Management (IAM), Lambda, EventBridge).

Acessar o URL do Tines

  1. No navegador, abra a interface do Tines para seu locatário.
  2. Copie o domínio da barra de endereço. Você vai usá-lo como TINES_BASE_URL.
    • Formato: https://<tenant-domain> (por exemplo, https://<tenant-domain>.tines.com).

Valores a serem salvos para etapas posteriores:

  • TINES_BASE_URL — Por exemplo, https://<domain>.tines.com
  • TINES_API_KEY: o token que você vai criar nas etapas a seguir
  1. Acesse o Menu de navegação > Chaves de API.
  2. Clique em + Nova chave.
  3. Selecione Chave de API de serviço.
  4. Insira um nome descritivo (por exemplo, SecOps Audit Logs).
  5. Clique em Criar.
  6. Copie o token gerado imediatamente e salve-o com segurança. Você vai usá-lo como TINES_API_KEY.

Opção 2: chave de API pessoal (se as chaves de serviço não estiverem disponíveis)

  1. Acesse o Menu de navegação > Chaves de API.
  2. Clique em + Nova chave.
  3. Selecione Chave de API pessoal.
  4. Insira um nome descritivo.
  5. Clique em Criar.
  6. Copie e salve o token gerado com segurança.

Conceder a permissão de leitura do registro de auditoria

  1. Faça login como proprietário do locatário ou peça para alguém fazer isso.
  2. Acesse Configurações > Administrador > Administração de usuários (ou clique no nome da sua equipe no menu superior esquerdo e selecione Usuários).
  3. Encontre o usuário da conta de serviço associado à sua chave de API de serviço. Ele terá o mesmo nome da sua chave de API.
    • Se você estiver usando uma chave de API pessoal, encontre sua própria conta de usuário.
  4. Clique no usuário para abrir o perfil dele.
  5. Na seção Permissões do locatário, ative AUDIT_LOG_READ.
  6. Clique em Salvar.

(Opcional) Verificar o acesso à API

  1. Teste o endpoint usando curl ou qualquer 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"
    
  2. Você vai receber uma resposta JSON com entradas de registro de auditoria.

  3. Você também pode verificar se os registros de auditoria existem navegando até Configurações > Monitoramento > Registros de auditoria na UI (requer permissão AUDIT_LOG_READ).

Configurar o bucket da AWS S3

  1. Crie um bucket do Amazon S3 seguindo este guia do usuário: Como criar um bucket
  2. Salve o Nome e a Região do bucket para referência futura (por exemplo, tines-audit-logs).

Configurar a política e o papel do IAM para uploads do Lambda S3

  1. No console da AWS, acesse IAM > Políticas > Criar política > guia JSON.
  2. Copie e cole a política a seguir.
  3. JSON da política (substitua tines-audit-logs se você tiver inserido um nome 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"
        }
      ]
    }
    
  4. Clique em Próxima > Criar política.

  5. Nomeie a política como TinesLambdaS3Policy.

  6. Acesse IAM > Funções > Criar função > Serviço da AWS > Lambda.

  7. Anexe o TinesLambdaS3Policy que você acabou de criar.

  8. Nomeie a função como TinesAuditToS3Role e clique em Criar função.

Criar a função Lambda

  1. No console da AWS, acesse Lambda > Functions > Create function.
  2. Clique em Criar do zero.
  3. Informe os seguintes detalhes de configuração:

    Configuração Valor
    Nome tines_audit_to_s3
    Ambiente de execução Python 3.13
    Arquitetura x86_64
    Função de execução TinesAuditToS3Role
  4. Depois que a função for criada, abra a guia Código, exclua o stub e cole o código a seguir (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())
    
  5. Acesse Configuração > Variáveis de ambiente.

  6. Clique em Editar > Adicionar nova variável de ambiente.

  7. Insira as variáveis de ambiente fornecidas na tabela a seguir, substituindo os valores de exemplo pelos seus.

    Variáveis de ambiente

    Chave Valor de exemplo
    S3_BUCKET tines-audit-logs
    S3_PREFIX tines/audit/
    STATE_KEY tines/audit/state.json
    TINES_BASE_URL https://your-tenant.tines.com
    TINES_API_KEY your-tines-api-key
    LOOKBACK_SECONDS 3600
    PAGE_SIZE 500
    MAX_PAGES 20
    HTTP_TIMEOUT 60
    HTTP_RETRIES 3
  8. Depois que a função for criada, permaneça na página dela ou abra Lambda > Functions > sua-função.

  9. Selecione a guia Configuração.

  10. No painel Configuração geral, clique em Editar.

  11. Mude Tempo limite para 5 minutos (300 segundos) e clique em Salvar.

Criar uma programação do EventBridge

  1. Acesse Amazon EventBridge > Scheduler > Criar programação.
  2. Informe os seguintes detalhes de configuração:
    • Programação recorrente: Taxa (1 hour).
    • Destino: sua função Lambda tines_audit_to_s3.
    • Nome: tines-audit-1h.
  3. Clique em Criar programação.

Criar um usuário e chaves do IAM somente leitura para o Google SecOps

  1. No console da AWS, acesse IAM > Usuários.
  2. Clique em Add users.
  3. Informe os seguintes detalhes de configuração:
    • Usuário: insira secops-reader.
    • Tipo de acesso: selecione Chave de acesso — Acesso programático.
  4. Clique em Criar usuário.
  5. Anexe a política de leitura mínima (personalizada): Usuários > secops-reader > Permissões > Adicionar permissões > Anexar políticas diretamente > Criar política.
  6. 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"
        }
      ]
    }
    
  7. Name = secops-reader-policy.

  8. Clique em Criar política > pesquisar/selecionar > Próxima > Adicionar permissões.

  9. Crie uma chave de acesso para secops-reader: Credenciais de segurança > Chaves de acesso.

  10. Clique em Criar chave de acesso.

  11. Faça o download do .CSV. Cole esses valores no feed.

Configurar um feed no Google SecOps para ingerir registros de auditoria do Tines

  1. Acesse Configurações do SIEM > Feeds.
  2. Clique em + Adicionar novo feed.
  3. No campo Nome do feed, insira um nome para o feed (por exemplo, Tines Audit Logs).
  4. Selecione Amazon S3 V2 como o Tipo de origem.
  5. Selecione Tines como o Tipo de registro.
  6. Clique em Próxima.
  7. Especifique valores para os seguintes parâmetros de entrada:
    • URI do S3: s3://tines-audit-logs/tines/audit/
    • Opções de exclusão de fontes: selecione a opção de exclusão de acordo com sua preferência.
    • Idade máxima do arquivo: inclui arquivos modificados no último número de dias. O padrão é de 180 dias.
    • ID da chave de acesso: chave de acesso do usuário com acesso ao bucket do S3.
    • Chave de acesso secreta: chave secreta do usuário com acesso ao bucket do S3.
    • Namespace do recurso: o namespace do recurso.
    • Rótulos de ingestão: o rótulo aplicado aos eventos deste feed.
  8. Clique em Próxima.
  9. Revise a nova configuração do feed na tela Finalizar e clique em Enviar.

Precisa de mais ajuda? Receba respostas de membros da comunidade e profissionais do Google SecOps.