Feeding Your SIEM: Integrating Cisco AMP for Endpoints via Event Streams
Modern IT infrastructure generates a massive amount of log data, and today, we’re going to talk about piping even more of it into your SIEM.
While it’s relatively easy to log into individual servers to hunt for specific logs, achieving a true 360-degree view of your environment is a completely different challenge. Your SIEM is the ideal engine for correlating this multi-source data and investigating incidents—but are your endpoints fully part of that equation? Cisco AMP for Endpoints offers incredible flexibility, allowing you to integrate its telemetry with virtually any SIEM or third-party software stack.

Before We Start
Disclaimer: This article is an independent weekend project. It is not sponsored, endorsed, or administered by my employer, and the opinions expressed here are entirely my own.
While the activities outlined below are generally safe, tinkering with infrastructure always carries some inherent risk. Keep in mind that certain security best practices (like peer hostname verification) have been bypassed for the sake of simplicity in this tutorial. If you aren’t completely comfortable with these steps, please seek professional support. This guide is provided “as is,” without warranties, support, or liability for any data loss, security breaches, or other IT calamities.

What is AMP for Endpoints?
If you’ve found your way to this article, you probably already know. But for the sake of completeness: Cisco AMP for Endpoints (AMP4EP) is a next-generation endpoint security solution designed to prevent, detect, and respond to advanced threats.
Beyond its core protective features, AMP4EP acts as a massive telemetry-gathering tool. It collects a wealth of security data about the endpoints themselves, alongside their interactions with other devices, servers, files, and network connections. It is exactly this rich, relational data that we want to extract and share with our SIEM.

How Do We Set It Up?
There are a few ways to achieve this integration. Some methods work out-of-the-box, while others rely on the AMP4EP APIs. Today, we will be focusing on the API route.
- Step 1: Head over to the API documentation page and select the region that corresponds to your cloud instance (US, APJC, or EU).
- Step 2: On the following page, select the v1 APIs.
Most of the API resources listed here require on-demand polling—meaning your custom script or software has to continuously ask the server if there is new data. However, Event Streams are the perfect exception.
Instead of forcing you to write a scheduled script to constantly check for updates, Event Streams provide a continuous, real-time flow of information from AMP4EP directly to your client. By initiating a single connection to the stream, your setup can simply sit back and listen for new messages as they roll in, making the integration far more efficient and elegant.

Activating the APIs
Before we can start pulling data, we need to generate a dedicated username and password to access the API resources. It’s important to note that these are separate from the credentials you normally use to log into the AMP4EP web portal.
Here is how to set them up:
- Log into your AMP4EP console using your standard credentials.
- Navigate to Accounts > API Credentials (you can reference the official documentation if you get stuck).
- Create a new set of credentials with Read & Write access.
- Optional but recommended: Tick the Enable Command Line option.
Note: You may be prompted to activate Two-Step Verification if you haven’t already done so.
Before moving on, a quick heads-up: I will be using Microsoft Windows for this tutorial to quickly test the Event Stream API. However, if you are using Linux or macOS, don’t worry—the fundamental concepts and API calls are essentially identical across operating systems.
Creating the AMQP Messaging Resource
The AMP4EP Event Streamer relies on the AMQP (Advanced Message Queuing Protocol) standard. In this step, we are going to create the resource that allows us to receive data streams from AMP4EP.
As always, make sure you are referencing the API documentation specific to your cloud instance (US, APJC, or EU).
To interact with the API, we need an API client. For this guide, we will use Postman, a popular and free API development environment available for multiple operating systems.
- Download and install Postman. (You can skip creating an account by clicking “Take me straight to the app” at the bottom of the window).
- Close any introductory pop-ups to get to the main workspace.
We are almost ready to connect to the Event Streamer, but we have one crucial step left: we need to tell AMP4EP which events we actually care about.
Finding Your Event IDs
AMP4EP tracks a massive variety of events, such as Threat Quarantined, Threat Detected, and Cloud Recall Restore from Quarantine. To filter our stream, we need to locate the specific ID numbers associated with the events we want to receive.
For this test, I recommend tracking Threat Quarantined and Threat Detected.
To find their corresponding IDs, we will use the GET /v1/event_types API call:
- Open Postman and set the request type to GET.
- Enter the Request URL for your region’s API (e.g.,
https://api.amp.cisco.com/v1/event_types). - Under the Authorization tab, set the type to Basic Auth.
- Enter the API Username and Password you generated in the first step.
- Click Send.
Once the request completes, you will see a JSON response populated in the text area at the bottom of your Postman window. Scroll through this data to find the IDs for your target events.
In my environment, the ID for Threat Quarantined is 553648143, and Threat Detected is 1090519054. Take a look at your JSON output—what are yours? (They will likely be the exact same).

Creating the AMQP Resource
Now that we have our Event IDs, our next step is to create the actual queue—the streaming resource itself.
While the technical specifics are outlined in the AMP4EP documentation, the goal of this step is straightforward: we need to generate a new, distinct set of credentials (a separate username and password) that will be used exclusively to connect to this AMQP stream.
To get this set up, let’s fire up Postman once more.

The setup here is very similar to our previous API call, but with a few critical changes.
Most importantly, you need to change the request type in Postman from a GET to a POST. This is because we are actively creating the queue on the server. Keep in mind that this is a one-time operation—once the queue is created, we can connect to it as many times as we need to without having to recreate it.
Here is how to configure your Postman request:
- Change the request method from GET to POST.
- Ensure your API Basic Auth credentials are still applied under the Authorization tab.
- Pass your parameters to the API. You can do this by clicking the Params button in Postman and adding them line by line, or you can skip that and simply paste a fully constructed URL directly into the address bar.
You will need to include the Event IDs we found in the previous step, as well as a custom name for your queue. I named my queue DQrbpudi2, but you can name yours whatever makes the most sense for your environment.
For your convenience, here is the complete URL I used to build my request: https://api.amp.cisco.com/v1/event_streams?event_type[]=553648143&event_type[]=1090519054&name=DQrbpudi2

If you look under the Body section of your successful Postman request, you will see the returned JSON response. This payload is exactly what we were looking for—it contains all the essential connection details for your new AMQP resource, including the queue name, username, password, host, port, and protocol.
Now it’s time to actually retrieve events from this newly minted queue.
In a real-world production environment, this is the stage where you would implement a script or middleware to capture these events and route them to your SIEM, dump them into a database, or write them to a secure log file. The possibilities are virtually endless. You can build this integration using your favorite programming language and a variety of third-party libraries. If you are looking to build a highly scalable pipeline, integrating a robust message broker like RabbitMQ is an excellent architectural choice to explore.
For the scope of this tutorial, however, we are going to keep things simple. Instead of building a complex middleware pipeline, we will just focus on successfully pulling these incoming messages and displaying them directly in a command-line console.
Installing Ruby

Cisco’s official documentation uses Ruby to demonstrate how to capture incoming messages from the queue, so we will follow suit for this tutorial.
- Head over to Ruby Installer and download the appropriate installer for your operating system (x86 or x64). I used the “Ruby+Devkit” package.
- Run the installer. You can safely accept all the default settings, with two minor exceptions: uncheck the “MSYS2 development toolchain” and the “ridk install” options. We won’t need those components for this project.
Writing and Running the Ruby Client
To interact with our AMQP stream, we will be relying on the popular Bunny library for Ruby.
Our next step is to create the actual Ruby script that will connect to the queue and print the incoming messages. Open your favorite text editor, paste the code snippet below, and save the file into your Ruby directory (e.g., C:\Ruby25-x64 or wherever you installed it) as test.rb.
Ruby
require 'bunny'
# Replace with your unique connection string
connection_url = "amqps://531-c3f9f207XXXXXXXXXXXX:7522e7c03f4217155dXXXXXXXXXXXXXXXXXXXXXX@export-streaming.amp.cisco.com:443"
conn = Bunny.new(connection_url)
conn.start
ch = conn.create_channel
# Replace 'event_stream_531' with your specific queue name
q = ch.queue('event_stream_531', :passive => true, :durable => true)
x = ch.default_exchange
q.subscribe(:block => true) do |delivery_info, metadata, payload|
puts "Received #{payload}"
end
Customizing Your Variables
Before running the script, you must update the placeholder values with the JSON data you received from your Postman POST request in the previous step:
The Queue Name: In the Ruby line that defines the queue, replace event_stream_531 with the queue_name value returned in the JSON response under amqp_credentials. Do not use the custom name you passed in the POST request, such as DQrbpudi2, unless that exact value is returned as queue_name in your own JSON response.
The Ruby line should look like this, using the queue_name from your JSON response:
q = ch.queue('event_stream_531', :passive => true, :durable => true)The Connection URL: Notice how the connection_url string is formatted. It follows the structure: amqps://[username]:[password]@[host]:[port].
In the example above, 531-c3f9f207XXXXXXXXXXXX is the generated username, and the string immediately following the colon, 7522e7c…, is the password. Plug your specific username, password, host, and port into this format.

With your script customized and saved, it is finally time to see it in action.
Open up your command line interface, navigate to the directory where you saved your file (for example, C:\Ruby25-x64), and execute the script by typing the following command:
ruby test.rb
If everything is configured correctly, your console will establish a connection to your AMP4EP AMQP resource and begin actively listening. As soon as a relevant event (like a threat being detected or quarantined) occurs in your environment, you will see the JSON payload populate live right there in your command shell!

At this point, your Ruby client is officially connected and actively listening to your AMP4EP events. (If you don’t believe me, move on to the next section and we will prove it! 🙂)
Testing the Queue
I can’t speak to how much organic activity is currently happening in your specific AMP4EP instance. Because I am using a controlled demo environment for this tutorial, there isn’t a massive amount of background data automatically flowing through.
To generate some live activity, I am going to do two things:
- Refresh the demo data: Log into your AMP4EP console and navigate to Accounts > Demo Data > Refresh Demo Data.
- Download a test file: I am going to download the EICAR test file. If you aren’t familiar with it, EICAR is a harmless, industry-standard “fake” virus designed specifically to safely trigger antivirus alerts. Downloading this will force AMP4EP to generate a live event.
If you are following along, head over to the EICAR website to grab the test file. I recommend using the specific download link highlighted in the image below:

Depending on your endpoint’s configuration, AMP4EP (or your local built-in antivirus) might not automatically snatch up the file the second it downloads. If it slipped through the initial net, we just need to force a manual scan to generate our alert.
Since I am using Windows for this tutorial, I can simply trigger the scan directly from Windows File Explorer, as shown in the example below.

As expected, the system will immediately recognize the test file as a threat, flag it as malicious, and swiftly remove it.
While it is always satisfying to see your endpoint protection doing its job locally, the real magic is happening behind the scenes. If you switch back over to your command-line interface where your Ruby script is running, you should immediately see the fruit of our labor.

Verifying in the Console
To confirm everything is working as expected, head back over to your AMP4EP web console and verify that the EICAR threat event registered correctly.
For reference, here is a look at how that alert populates in my own environment:

The Moment of Truth
Now, let’s check back in on our Ruby script. If everything is wired up correctly, we should expect to see the exact same EICAR event that just triggered in the AMP4EP web console reflected live in our command-line interface…

…and there it is!
Because the test file was immediately removed by the system rather than quarantined, our script captured the exact Threat Detected event we were expecting to see.
Conclusion
I hope you enjoyed this hands-on example!
Keep in mind that while this Ruby script is a great proof of concept, you will want to build something significantly more robust for a production environment. The ultimate goal is to take this continuous stream of messages and systematically route them to your SIEM, where you can correlate the data, trigger alerts, and take meaningful action.
As mentioned earlier, integrating a message broker like RabbitMQ alongside your preferred programming language is an excellent way to process these payloads reliably at scale.
Consider this tutorial the starting line for your AMP4EP API journey. Best of luck building out your integrations, and happy coding!
Additional Resources
Looking to dive deeper? Here are a few helpful resources to keep you going:
- Cisco AMP for Endpoints API Documentation: Official API reference documentation.
- Cisco AMP for Endpoints API Tutorial: A broader overview of working with the AMP for Endpoints API.
- Python Event Stream Examples: Python-based Event Stream examples are available in the walbit and QuiLoxx repositories.
Originally published on LinkedIn on May 6, 2018.
