Skip to content

PingFederate

Overview

PingFederate is an enterprise federation server from Ping Identity that provides secure single sign-on (SSO), API security, and identity bridging. It generates audit and operational logs (authentication events, token lifecycle actions, administrative changes) that can be forwarded via Syslog for centralized monitoring and detection.

In this documentation, you will learn how to collect and send PingFederate logs to Sekoia.io.

  • Vendor: Ping Identity
  • Supported environment: On Premise
  • Detection based on: Telemetry
  • Supported application or feature: Authentication, Authorization, Token lifecycle, Administrative audit logs

Warning

This format is currently in beta. We highly value your feedback to improve its performance.

High-Level Architecture Diagram

  • Type of integration: Outbound (PUSH to Sekoia.io)
  • Schema

Specification

Prerequisites

  • Resource:
    • Self-managed syslog forwarder (e.g. rsyslog, syslog-ng)
  • Network:
    • Outbound TCP allowed from the PingFederate appliance to the forwarder on your chosen port
  • Permissions:
    • Root (or equivalent) access on the PingFederate appliance
    • Root (or equivalent) access on the Linux server hosting the syslog forwarder

Transport Protocol/Method

  • Indirect Syslog (RFC5424)

Logs details

  • Supported functionalities: See section Overview
  • Supported type(s) of structure: Syslog messages (RFC5424)
  • Supported verbosity level: Informational / Audit

Note

Log levels follow the RFC5424 taxonomy. Adapt your forwarder's parsing rules accordingly.

Step-by-Step Configuration Procedure

Instructions on the 3rd Party Solution

Forward PingFederate Logs to a syslog forwarder

This setup guide will lead you into forwarding PingFederate's logs to Sekoia.io by means of a syslog transport channel.

Detailed Procedure:

  1. Prerequisites:
  2. An internal syslog concentrator is required to collect and forward events to Sekoia.io.

  3. Create the Intake in Sekoia.io:

  4. Go to the intake page and create a new intake from the format PingFederate. Copy the intake key.

  5. Configure Log4j2 for Syslog Forwarding:

On the system hosting PingFederate:

  1. SSH into your PingFederate server and open the Log4j2 configuration file:

    vi /opt/pingfederate/server/default/conf/log4j2.xml
    
  2. Enable tracking ID correlation (recommended for event correlation):

    Tracking IDs (tid) allow you to correlate events across multiple log entries for the same transaction. Ensure the TrackingIdSupport is enabled in your PingFederate configuration.

  3. Add or modify the Syslog appender to forward logs with the proper format. The pattern must match the format expected by Sekoia.io's parser:

    <Configuration>
      <Appenders>
        <!-- Existing appenders ... -->
    
        <!-- Syslog appender for Sekoia.io -->
        <Syslog name="SekoiaSyslog"
                format="RFC5424"
                host="<concentrator-ip-address>"
                port="<concentrator-port>"
                protocol="TCP"
                facility="LOCAL0"
                appName="pingfederate">
          <!-- CRITICAL: Use this exact pattern for proper parsing -->
          <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} tid:%X{trackingid} %-5level [%c] %msg%n"/>
        </Syslog>
    
        <!-- Optional: HTTP access logs appender (if using embedded Jetty logging) -->
        <Syslog name="SekoiaHttpAccess"
                format="RFC5424"
                host="<concentrator-ip-address>"
                port="<concentrator-port>"
                protocol="TCP"
                facility="LOCAL1"
                appName="pingfederate-http">
          <PatternLayout pattern="%msg%n"/>
        </Syslog>
      </Appenders>
    
      <Loggers>
        <!-- Application logs: audit, authentication, token lifecycle -->
        <Root level="info">
          <AppenderRef ref="SekoiaSyslog"/>
        </Root>
    
        <!-- Capture detailed authentication events -->
        <Logger name="org.sourceid.saml20.domain.mgmt.impl" level="info" additivity="false">
          <AppenderRef ref="SekoiaSyslog"/>
        </Logger>
    
        <!-- Capture OAuth/OIDC token events -->
        <Logger name="org.sourceid.oauth20" level="info" additivity="false">
          <AppenderRef ref="SekoiaSyslog"/>
        </Logger>
    
        <!-- Capture session and SSO events -->
        <Logger name="org.sourceid.websso" level="info" additivity="false">
          <AppenderRef ref="SekoiaSyslog"/>
        </Logger>
    
        <!-- Capture administrative audit events -->
        <Logger name="com.pingidentity.console.audit" level="info" additivity="false">
          <AppenderRef ref="SekoiaSyslog"/>
        </Logger>
    
        <!-- Optional: Capture DEBUG level for troubleshooting (generates more logs) -->
        <!-- Uncomment if needed for detailed debugging -->
        <!--
        <Logger name="org.sourceid" level="debug" additivity="false">
          <AppenderRef ref="SekoiaSyslog"/>
        </Logger>
        -->
      </Loggers>
    </Configuration>
    

    Key Configuration Notes:

    • Pattern Layout: The pattern %d{yyyy-MM-dd HH:mm:ss,SSS} tid:%X{trackingid} %-5level [%c] %msg%n ensures compatibility with Sekoia.io's parser
    • Tracking ID: %X{trackingid} includes the correlation ID in every log entry (appears as tid: in logs)
    • Timestamp format: yyyy-MM-dd HH:mm:ss,SSS matches the expected ISO8601-like format with milliseconds
    • Logger name: [%c] includes the full Java class name for better event categorization
  4. Configure HTTP access logs (optional but recommended):

    If you want to capture HTTP access logs separately, edit the Jetty configuration:

    vi /opt/pingfederate/server/default/conf/jetty-runtime.xml
    

    Enable request logging with the Common Log Format (CLF):

    <Set name="RequestLog">
      <New class="org.eclipse.jetty.server.NCSARequestLog">
        <Arg>
          <SystemProperty name="pf.log.dir" default="<pf_install>/pingfederate/log"/>
          /pf-http-access.log
        </Arg>
        <Set name="extended">false</Set>
        <Set name="append">true</Set>
        <Set name="LogTimeZone">GMT</Set>
      </New>
    </Set>
    

    Then configure rsyslog on the PingFederate host to forward these logs to your concentrator (see step 5).

  5. Forward HTTP access logs via rsyslog (if using file-based HTTP logs):

    On the PingFederate host, configure rsyslog to monitor the HTTP access log file:

    vi /etc/rsyslog.d/10-pingfederate-http.conf
    

    Add:

    # Monitor PingFederate HTTP access logs
    module(load="imfile" PollingInterval="10")
    
    input(type="imfile"
          File="/opt/pingfederate/log/pf-http-access.log"
          Tag="pingfederate-http:"
          Severity="info"
          Facility="local1")
    
    # Forward to concentrator
    local1.* @@<concentrator-ip-address>:<concentrator-port>
    

    Restart rsyslog:

    systemctl restart rsyslog
    
  6. Save log4j2.xml and restart PingFederate:

    systemctl restart pingfederate
    
  7. Verify log format by checking the syslog output:

    tail -f /var/log/messages | grep pingfederate
    

    You should see logs in this format:

    2025-09-02 11:02:32,869 tid:Z8I1vdotGu084PB7b2HrQ0A1kKU INFO [org.sourceid.saml20.service.impl.AuthnRequestProcessorImpl] Processing authentication request
    

Note

Important Pattern Requirements:

  • The timestamp must use the format yyyy-MM-dd HH:mm:ss,SSS (comma before milliseconds)
  • The tracking ID must appear as tid:XXXXX (with the colon)
  • The log level must be 5 characters wide with left padding (%-5level)
  • The logger name must be enclosed in brackets [%c]

Any deviation from this pattern will cause parsing failures in Sekoia.io.

Instruction on Sekoia

Configure Your Intake

This section will guide you through creating the intake object in Sekoia, which provides a unique identifier called the "Intake key." The Intake key is essential for later configuration, as it references the Community, Entity, and Parser (Intake Format) used when receiving raw events on Sekoia.

  1. Go to the Sekoia Intake page.
  2. Click on the + New Intake button at the top right of the page.
  3. Search for your Intake by the product name in the search bar.
  4. Give it a Name and associate it with an Entity (and a Community if using multi-tenant mode).
  5. Click on Create.

Note

For more details on how to use the Intake page and to find the Intake key you just created, refer to this documentation.

Configure a forwarder

To forward events using syslog to Sekoia.io, you need to update the syslog header with the intake key you previously created. Here is an example of your message before the forwarder

<%pri%>1 %timestamp:::date-rfc3339% %hostname% %app-name% %procid% LOG RAW_MESSAGE
and after
<%pri%>1 %timestamp:::date-rfc3339% %hostname% %app-name% %procid% LOG [SEKOIA@53288 intake_key=\"YOUR_INTAKE_KEY\"] RAW_MESSAGE

To achieve this you can:

  • Use the Sekoia.io forwarder which is the official supported way to collect data using the syslog protocol in Sekoia.io. In charge of centralizing data coming from many equipments/sources and forwarding them to Sekoia.io with the apporpriated format, it is a prepackaged option. You only have to provide your intake key as parameter.
  • Use your own Syslog service instance. Maybe you already have an intance of one of these components on your side and want to reuse it in order to centralize data before forwarding them to Sekoia.io. When using this mode, you have to configure and maintain your component in order to respect the expected Sekoia.io format.

Warning

Only the Sekoia.io forwarder is officially supported. Other options are documented for reference purposes but do not have official support.

Raw Events Samples

In this section, you will find examples of raw logs as generated natively by the source. These examples are provided to help integrators understand the data format before ingestion into Sekoia.io. It is crucial for setting up the correct parsing stages and ensuring that all relevant information is captured.

2025-09-02 11:02:32,869 tid:Z8I1vdotGu084PB7b2HrQ0A1kKU DEBUG [org.sourceid.servlet.HttpServletRespProxy] flush cookies: adding Cookie{OXS-U2A=hashedValue:Z8I1vdotGu084PB7b2HrQ0A1kKU; path=/; maxAge=-1; domain=.auth-int.xxxxgroup.com}
2025-09-02 11:02:34,353 tid:Q08PzbPCjfSJL8sbIj88OLO5YWg DEBUG [org.sourceid.websso.servlet.IntegrationControllerServlet] GET: https://hub-mtls.auth-int.hza.infra.xxxx/pf/heartbeat.ping
192.168.1.100 - john.doe [02/Sep/2025:13:02:34 +0000] "GET /pf/heartbeat.ping HTTP/1.1" 200 156
2025-09-02 11:02:34,353 tid:Q08PzbPCjfSJL8sbIj88OLO5YWg DEBUG [com.pingidentity.locale.LocaleUtil] Locale Override: none
2025-09-02 11:02:34,352  DEBUG [org.sourceid.util.log.internal.TrackingIdSupport] The incoming request does not contain a unique identifier. Assigning auto-generated request ID: C1CjegPq3VckLYpvYlzZEGTBe

Detection section

The following section provides information for those who wish to learn more about the detection capabilities enabled by collecting this intake. It includes details about the built-in rule catalog, event categories, and ECS fields extracted from raw events. This is essential for users aiming to create custom detection rules, perform hunting activities, or pivot in the events page.

No related built-in rules was found. This message is automatically generated.

Event Categories

The following table lists the data source offered by this integration.

Data Source Description
Authentication logs authentication and SSO events including login attempts, session management, and federation transactions
Application logs administrative actions, configuration changes, and security-related events
Network device logs SAML, OAuth, OpenID Connect, and other federation protocol interactions
Web logs Access logs

In details, the following table denotes the type of events produced by this integration.

Name Values
Kind event
Category configuration, web
Type access, info

Transformed Events Samples after Ingestion

This section demonstrates how the raw logs will be transformed by our parsers. It shows the extracted fields that will be available for use in the built-in detection rules and hunting activities in the events page. Understanding these transformations is essential for analysts to create effective detection mechanisms with custom detection rules and to leverage the full potential of the collected data.

{
    "message": "2025-09-02 11:02:32,869 tid:Z8I1vdotGu084PB7b2HrQ0A1kKU DEBUG [org.sourceid.servlet.HttpServletRespProxy] flush cookies: adding Cookie{OXS-U2A=hashedValue:Z8I1vdotGu084PB7b2HrQ0A1kKU; path=/; maxAge=-1; domain=.auth-int.xxxxgroup.com}",
    "event": {
        "category": [
            "web"
        ],
        "dataset": "pingfederate",
        "kind": "event",
        "module": "pingfederate",
        "type": [
            "info"
        ]
    },
    "@timestamp": "2025-09-02T11:02:32.869000Z",
    "log": {
        "level": "DEBUG",
        "logger": "org.sourceid.servlet.HttpServletRespProxy"
    },
    "pingfederate": {
        "labels": "flush cookies: adding Cookie{OXS-U2A=hashedValue:Z8I1vdotGu084PB7b2HrQ0A1kKU; path=/; maxAge=-1; domain=.auth-int.xxxxgroup.com}",
        "transaction_id": "Z8I1vdotGu084PB7b2HrQ0A1kKU"
    }
}
{
    "message": "2025-09-02 11:02:34,353 tid:Q08PzbPCjfSJL8sbIj88OLO5YWg DEBUG [org.sourceid.websso.servlet.IntegrationControllerServlet] GET: https://hub-mtls.auth-int.hza.infra.xxxx/pf/heartbeat.ping",
    "event": {
        "category": [
            "web"
        ],
        "dataset": "pingfederate",
        "kind": "event",
        "module": "pingfederate",
        "type": [
            "access"
        ]
    },
    "@timestamp": "2025-09-02T11:02:34.353000Z",
    "host": {
        "name": "hub-mtls.auth-int.hza.infra.xxxx"
    },
    "http": {
        "request": {
            "method": "GET"
        }
    },
    "log": {
        "level": "DEBUG",
        "logger": "org.sourceid.websso.servlet.IntegrationControllerServlet"
    },
    "pingfederate": {
        "labels": "GET: https://hub-mtls.auth-int.hza.infra.xxxx/pf/heartbeat.ping",
        "transaction_id": "Q08PzbPCjfSJL8sbIj88OLO5YWg"
    },
    "url": {
        "domain": "hub-mtls.auth-int.hza.infra.xxxx",
        "original": "https://hub-mtls.auth-int.hza.infra.xxxx/pf/heartbeat.ping",
        "path": "/pf/heartbeat.ping",
        "port": 443,
        "scheme": "https",
        "subdomain": "hub-mtls.auth-int.hza.infra"
    }
}
{
    "message": "192.168.1.100 - john.doe [02/Sep/2025:13:02:34 +0000] \"GET /pf/heartbeat.ping HTTP/1.1\" 200 156",
    "event": {
        "category": [
            "web"
        ],
        "dataset": "pingfederate",
        "kind": "event",
        "module": "pingfederate",
        "type": [
            "access"
        ]
    },
    "host": {
        "name": "192.168.1.100"
    },
    "http": {
        "request": {
            "method": "GET"
        },
        "response": {
            "body": {
                "bytes": 156
            },
            "status_code": 200
        },
        "version": "1.1"
    },
    "related": {
        "ip": [
            "192.168.1.100"
        ],
        "user": [
            "john.doe"
        ]
    },
    "source": {
        "address": "192.168.1.100",
        "ip": "192.168.1.100"
    },
    "url": {
        "original": "/pf/heartbeat.ping",
        "path": "/pf/heartbeat.ping"
    },
    "user": {
        "name": "john.doe"
    }
}
{
    "message": "2025-09-02 11:02:34,353 tid:Q08PzbPCjfSJL8sbIj88OLO5YWg DEBUG [com.pingidentity.locale.LocaleUtil] Locale Override: none",
    "event": {
        "category": [
            "configuration"
        ],
        "dataset": "pingfederate",
        "kind": "event",
        "module": "pingfederate",
        "type": [
            "info"
        ]
    },
    "@timestamp": "2025-09-02T11:02:34.353000Z",
    "log": {
        "level": "DEBUG",
        "logger": "com.pingidentity.locale.LocaleUtil"
    },
    "pingfederate": {
        "labels": "Locale Override: none",
        "transaction_id": "Q08PzbPCjfSJL8sbIj88OLO5YWg"
    }
}
{
    "message": "2025-09-02 11:02:34,352  DEBUG [org.sourceid.util.log.internal.TrackingIdSupport] The incoming request does not contain a unique identifier. Assigning auto-generated request ID: C1CjegPq3VckLYpvYlzZEGTBe",
    "event": {
        "category": [
            "web"
        ],
        "dataset": "pingfederate",
        "kind": "event",
        "module": "pingfederate",
        "type": [
            "info"
        ]
    },
    "@timestamp": "2025-09-02T11:02:34.352000Z",
    "log": {
        "level": "DEBUG",
        "logger": "org.sourceid.util.log.internal.TrackingIdSupport"
    },
    "pingfederate": {
        "labels": "The incoming request does not contain a unique identifier. Assigning auto-generated request ID: C1CjegPq3VckLYpvYlzZEGTBe"
    }
}

Extracted Fields

The following table lists the fields that are extracted, normalized under the ECS format, analyzed and indexed by the parser. It should be noted that infered fields are not listed.

Name Type Description
@timestamp date Date/time when the event originated.
event.category keyword Event category. The second categorization field in the hierarchy.
event.dataset keyword Name of the dataset.
event.kind keyword The kind of the event. The highest categorization field in the hierarchy.
event.module keyword Name of the module this data is coming from.
event.type keyword Event type. The third categorization field in the hierarchy.
host.name keyword Name of the host.
http.request.method keyword HTTP request method.
http.response.body.bytes long Size in bytes of the response body.
http.response.status_code long HTTP response status code.
http.version keyword HTTP version.
log.level keyword Log level of the log event.
log.logger keyword Name of the logger.
pingfederate.labels keyword Key-value pairs extracted from original message for additional context
pingfederate.transaction_id keyword Transaction ID (tid) for tracking requests across PingFederate components
source.domain keyword The domain name of the source.
source.ip ip IP address of the source.
url.original wildcard Unmodified original url as seen in the event source.
user.name keyword Short name or login of the user.

For more information on the Intake Format, please find the code of the Parser, Smart Descriptions, and Supported Events here.

Further Readings