Skip to main content

Duo

Overview​

Duo collects Cisco Duo MFA authentication logs by polling the Duo Admin API (GET /admin/v2/logs/authentication). Every record in Duo's Authentication Log is collected — sign-ins, denials, fraud reports and enrollments, for every user, application and factor — and forwarded with the original Duo JSON as the log body, so the Google SecOps DUO_AUTH parser receives the complete record.

Supported types: Logs

Supported platforms

  • Linux: Logs
  • Windows: Logs
  • macOS: Logs

Typical uses:

  • MFA monitoring in a SIEM — successful and failed sign-ins, with the user, application, factor and IP address of each attempt.
  • Fraud and abuse detection — pushes users reported as fraud, lockouts, and sign-ins denied by policy.
  • Enrollment tracking — users adding Duo Mobile, passkeys or security keys.

Requires collector v0.5.59 or later. Earlier releases do not build the Duo receiver, and the node will not be offered for older agents.

Authentication logs only. Duo's administrator, telephony, activity and authorization logs are separate Admin API endpoints and are not collected. Signing in to the Duo Admin Panel itself is recorded in the administrator log, not here.

Authentication​

The node holds no secret. Attach one Duo credential:

CredentialRequiredFields
Duo (duo)Yesintegration_key, secret_key

Create it from an Admin API application in the Duo Admin Panel (requires the Owner role):

  1. Go to Applications → Protect an Application and choose Admin API.
  2. Under Permissions, select only Grant read log.
  3. Click Save Changes — the permission does not apply until saved.
  4. Copy the Integration key and Secret key into the duo credential, and the API hostname into the node's api_hostname.

The collector signs every request itself (HMAC-SHA512, as the Admin API requires). The secret key is stored encrypted, is never returned by the API, and reaches the collector as a credential reference rather than in plaintext.

Use Admin API keys, not Auth API keys. Keys from any other Duo application type fail with duo error 40102: Invalid identity in request credentials. A wrong secret key fails with 40103: Invalid signature, and a missing or unsaved Grant read log permission with 40301: Access forbidden.

Basic Configuration​

ParameterTypeDefaultRequiredDescription
api_hostnamestringnoneYesThe Admin API hostname, e.g. api-xxxxxxxx.duosecurity.com. Host only, without https://.
poll_intervalinteger (seconds)120NoHow often new logs are fetched. Minimum 60, per Duo's guidance for the log endpoints.
lookbackinteger (seconds)3600NoFirst start only: how far back to back-fill when no saved position exists. Minimum 180 and must be longer than delay; at most 15552000 (180 days, Duo's retention).
persist_offsetsbooleantrueNoSave the read position so a restart resumes from the last delivered record instead of replaying lookback.

Lookback applies only once. After the first start the source always continues from its saved position, so changing lookback on a source that has already run has no effect. Set it before first publishing the node. To redo a back-fill, stop the collector, delete <collector home>/metadata/duo_offsets/<node name>, and start it again — records already delivered are sent again.

How polling works​

Each poll asks Duo for every authentication log between the saved position and now − delay, oldest first. Duo returns up to limit records per request and a next_offset while more remain; the source follows it until the window is fully read. The first poll runs immediately when the collector starts, then one every poll_interval.

After each page is accepted downstream the read position is saved, and records already delivered are skipped by their Duo transaction ID — so a restart, crash or downstream failure neither duplicates nor skips records. With persist_offsets on, the position is written under <collector home>/metadata/duo_offsets/<node name>, one directory per node.

New sign-ins arrive 2–4 minutes after they happen. Duo intentionally returns nothing newer than two minutes, and the next poll can be up to poll_interval away.

Failures never lose records. A rate limit (429), server error or network failure is retried with backoff (1s → 60s, up to 6 attempts); if it still fails, the next poll requests the same window again. A page the pipeline temporarily refuses is re-sent on the next poll.

Output​

Each Duo authentication log becomes one log record:

Duo fieldRecord
(whole record JSON)Body
isotimestamp (or timestamp)Timestamp
resultSeverity — success → INFO; denied, failure, fraud → WARN; error → ERROR
txid, event_type, result, reason, factor, emailAttributes duo.txid, duo.event_type, duo.result, duo.reason, duo.factor, duo.email
user.name / user.keyAttributes duo.user.name / duo.user.key
application.name / application.keyAttributes duo.application.name / duo.application.key
access_device.ip / access_device.hostnameAttributes duo.access_device.ip / duo.access_device.hostname
auth_device.ip / auth_device.nameAttributes duo.auth_device.ip / duo.auth_device.name
(constant / from api_hostname)Resource attributes vendor = duo, duo.api_hostname

Fields not listed (location, browser, OS, groups, trust assessments, …) remain in the body.

Advanced Configuration​

ParameterTypeDefaultDescription
delayinteger (seconds)120How far behind now each fetch stops. Range 120–3600: Duo returns nothing newer than two minutes, so a shorter delay would skip records.
limitinteger1000Records per request (1–1000, Duo's maximum). Larger windows are read page by page, so no records are missed.
timeoutinteger (seconds)30HTTP timeout for each request. A timed-out request is retried; the read position does not move.

Leave delay at 120 unless clocks drift. If the collector's clock may run ahead of Duo's, a slightly larger value (e.g. 150) keeps the edge of each window safely inside what Duo has released.

The connection is always HTTPS with Duo's certificate verified. Behind a proxy that re-signs HTTPS traffic the source fails with duo TLS certificate not trusted; install the proxy's CA certificate in the collector host's trust store.

Example Configuration​

{
"api_hostname": "api-xxxxxxxx.duosecurity.com", // required
"poll_interval": 120, // default; minimum 60
"lookback": 3600, // default; first start only, minimum 180
"persist_offsets": true, // default

"advanced": {
"delay": 120, // default; minimum 120
"limit": 1000, // default; Duo max
"timeout": 30, // default
},
}

Attach a duo credential to the node; integration_key and secret_key are not part of the node config.

Metrics​

Metric NameDescription
prx_src_records_received_total{signal="logs"}Log records emitted, one per Duo authentication log.
prx_src_bytes_received_totalAPI response bytes read from Duo.
prx_src_pipeline_latency_secondsDownstream handoff time per page.
prx_src_errors_total{reason}Source errors by reason — io for request failures, including credential and permission errors.
prx_src_parse_errors_total{parser="json"}A page or record returned by Duo that could not be fully decoded.
prx_src_records_dropped_total{reason}backpressure — the pipeline refused a page; it is re-sent on the next poll. permanent — the pipeline permanently rejected a page; it is dropped.
prx_health_status{component="receiver"}1 after start and after each successful poll; 0 when a poll fails (credentials, permission, Duo or network down) and at shutdown.