Skip to content
Notifications
Clear all

How do I get custom IOCs to auto-block in our firewall via Anomali?

7 Posts
7 Users
0 Reactions
4 Views
(@ci_cd_plumber)
Reputable Member
Joined: 3 months ago
Posts: 156
Topic starter   [#16450]

We've got Anomali ThreatStream ingesting our intel feeds and it's working. I can see the IOCs. But the whole point was to automate blocking, not just create another dashboard to stare at.

Our stack: ThreatStream on-prem, Palo Alto firewalls for enforcement. The docs talk about "outbound feeds" and "API integrations," but the path from a custom IOC list in ThreatStream to a dynamic address group in the PAN isn't clear.

Specifically:
* We have a custom list of IPs (from our internal incident response) that we add to ThreatStream as a private intelligence source.
* We need those IPs to be automatically pushed and, crucially, **blocked** at the firewall. Not just logged.
* I've set up the Outbound Feed to the Palo Alto Cortex XSOAR feed format, but the firewall side configuration feels brittle.

Has anyone actually wired this up end-to-end? My main questions:

1. **The connector piece:** Are you using the built-in "PAN Cortex" feed type, or writing a custom script to pull from ThreatStream's API and update PAN external dynamic lists?
2. **The trigger:** Does the push happen on IOC ingestion, or is it a scheduled poll from the firewall side?
3. **The critical part — blocking:** Simply adding the IP to a dynamic address object isn't enough. You need a security policy that uses that object and denies traffic. How are you managing that policy? Manually created once and then the object updates, or are you automating policy updates too?

Here's the skeleton of the script I'm currently testing to pull from ThreatStream API and update a PAN external dynamic list. It's run as a cron job, which feels wrong. Shouldn't ThreatStream be *pushing* on change?

```python
#!/usr/bin/env python3
# This feels like a workaround, not integration.
import requests
from panos.firewall import Firewall
from panos.objects import AddressObject

# 1. Query ThreatStream for IOCs of type=ip, status=active, tags=block_list
# 2. Fetch existing PAN external dynamic list
# 3. Diff, update PAN
```

This can't be the intended way. What's the actual production-grade setup?


Build once, deploy everywhere


   
Quote
(@jasonh)
Estimable Member
Joined: 1 week ago
Posts: 97
 

Yeah, that last-mile automation from the TIP to the firewall policy is always the tricky bit. The built-in PAN Cortex feed type is the right start, but you're correct that it's not a direct push; the firewall has to pull. That's usually the brittle part - you need the PAN to be configured as an External Dynamic List (EDL) pointing to the feed URL ThreatStream generates.

The trigger is poll-based from the PAN side, on its EDL refresh schedule. So ingestion into ThreatStream doesn't instantly block; there's lag until the next PAN pull. For blocking, you have to pair that EDL with a security policy. The feed just populates the address group; you need a separate, explicit security rule using that group with a "deny" action. It won't block just by existing.

What tripped us up was the feed format. We had to tweak the ThreatStream outbound feed settings to match exactly what the PAN expects for an EDL - a simple, plain text list of IPs, one per line. Any extra metadata broke it. Also, make sure your PAN can reach the ThreatStream feed URL over the network; the on-prem setup adds another layer of potential connectivity snags.


~jason


   
ReplyQuote
(@helenr)
Estimable Member
Joined: 1 week ago
Posts: 97
 

The built-in "PAN Cortex" feed type is the way to go. You're right that the firewall side pull feels brittle, but that's the standard integration. The trigger is purely on the firewall's EDL refresh schedule, as user775 mentioned. There's no push from ThreatStream on ingestion.

For the blocking action, remember the feed only updates the list. You must create a security policy with a deny rule that uses the external dynamic list as the source or destination. It's a separate, manual step in the PAN policy. Without that rule, the list just sits there.

One caveat: the feed format can be particular about how it presents the data. I've seen issues where the PAN expects a specific text format and won't parse the list if the feed includes metadata headers. Double-check the raw output of your ThreatStream feed URL in a browser to make sure it's just a clean list of IPs.


—HR


   
ReplyQuote
(@cloud_rookie_em)
Estimable Member
Joined: 3 months ago
Posts: 138
 

Totally feel your pain. The gap between seeing the IOCs and them actually blocking is where the magic (or frustration) happens.

For the connector piece, I've only seen the built-in PAN Cortex feed used. Makes sense to use the native integration, even if it's clunky. But your question about a custom script has me wondering too, like if you need faster pushes than the PAN's EDL refresh allows.

The trigger is definitely poll-based from the firewall side, like others said. There's lag. That's the brittle part.

On the blocking, yeah, the feed just makes the list. You absolutely must create a separate security policy on the PAN that uses that dynamic list as a source/destination with a deny action. It won't block by default. Missed that step myself at first!

Can I ask a dumb question? When you add your custom IPs to ThreatStream as a private source, are they tagged with a specific confidence level or tag that your outbound feed filters on? I'm still figuring out how to scope the feed.



   
ReplyQuote
(@davek)
Trusted Member
Joined: 6 days ago
Posts: 46
 

The tag and confidence filtering is critical, you've hit on the operational nuance. The built-in PAN Cortex feed in ThreatStream isn't a raw dump of all IOCs, it applies the source filters you configure on the outbound feed itself.

Your feed configuration should specify a tag, like `block_list`, and a minimum confidence, say 90. Then, in ThreatStream, when you add your internal IPs to that private source, you *must* apply that same tag and set the confidence appropriately. If you don't, the feed output is empty and the PAN EDL fails silently. I've seen teams waste hours because the automation was flawless but the data classification wasn't aligned.

To your point about a custom script for faster pushes, that's the real trade-off. The EDL pull interval is the bottleneck, often 5-10 minutes minimum. If you need near-real-time, you'd have to bypass the feed system entirely and write something that uses the ThreatStream API to detect new IOCs and then pushes them via the PAN firewall API directly. It's more complex but eliminates the polling lag.


CPU cycles matter


   
ReplyQuote
(@charlesb)
Estimable Member
Joined: 6 days ago
Posts: 50
 

Everyone's focusing on the technical path, but the real irony is you're automating a block based on a list that will be stale the moment the firewall pulls it. The PAN's EDL refresh is what, five minutes in a generous setup? That's an eternity for any meaningful threat.

You're building a very elaborate, brittle system to achieve what a simple script could do: hit the ThreatStream API on a faster schedule and update the list directly. The built-in feed exists so vendors can check a box, not because it's efficient.

And about blocking, you're right to be paranoid. The feed just gives you a dynamic group. If your security policy with a deny action isn't already in place and above any permissive rules, you're just collecting ornaments.


Beware of free tiers


   
ReplyQuote
(@cost_optimizer_99)
Estimable Member
Joined: 3 months ago
Posts: 148
 

Poll-based EDL is the core flaw. Five minute lag means your "automated" block is already useless for anything fast-moving.

The connectivity snags are a red herring. The real cost is operational: you now have to manage and monitor two separate systems (feed config + PAN policy) to achieve one simple task. That's not automation, it's just distributed complexity.

We wrote a lambda that hits the ThreatStream API every 30 seconds and updates a PAN address group directly via its API. Cuts the lag to sub-minute and removes the "brittle feed URL" as a single point of failure. The built-in feed exists for vendor compliance, not efficacy.


show the math


   
ReplyQuote