Allowlist domains and IP addresses
Let a job in block mode reach the destinations it needs, whether you identify them by name or by address.
Before you begin
- A job running Bullfrog with
egress-policy: block. See Switch a job to block mode.
Allowlist a domain
Add one domain per line to allowed-domains:
- uses: bullfrogsec/bullfrog@7dee337d4575320b6d8cbe9a56d48d2fb765963a # v0.11.1
with:
egress-policy: block
allowed-domains: |
registry.npmjs.org
github.com
Match subdomains with a wildcard
A leading *. matches any subdomain, at any depth:
*.example.commatchesapi.example.comandeu.api.example.com.*.example.comdoes not matchexample.com.
Allowlist both when a service uses the apex domain and its subdomains:
allowed-domains: |
example.com
*.example.com
Prefer the exact hostname over a wildcard. *.example.com gives every subdomain of example.com an egress path, so one compromised or attacker-registered subdomain is enough to reach the network from your job.
Allowlist an IP address or a range
Add addresses to allowed-ips. IPv4, IPv6, and CIDR notation all work:
- uses: bullfrogsec/bullfrog@7dee337d4575320b6d8cbe9a56d48d2fb765963a # v0.11.1
with:
egress-policy: block
allowed-ips: |
203.0.113.10
198.51.100.0/24
2001:db8::/32
Localhost is always allowed. You don't need to add 127.0.0.1 or ::1.
Reach an allowlisted IP address by hostname
Allowlisting an IP address is not enough when your job uses a hostname to get there. The default dns-policy is allowed-domains-only, so Bullfrog refuses to resolve a name that isn't in allowed-domains, and the connection never gets as far as the address.
The fix is to allowlist the domain as well:
- uses: bullfrogsec/bullfrog@7dee337d4575320b6d8cbe9a56d48d2fb765963a # v0.11.1
with:
egress-policy: block
allowed-domains: |
api.example.com
allowed-ips: |
203.0.113.10
If you can't enumerate the names in advance and want to control egress by address alone, set dns-policy: any:
- uses: bullfrogsec/bullfrog@7dee337d4575320b6d8cbe9a56d48d2fb765963a # v0.11.1
with:
egress-policy: block
dns-policy: any
allowed-ips: |
203.0.113.10
dns-policy: any lets a step resolve any name it likes. A DNS query carries data in the name itself, so a job that can reach an arbitrary resolver can exfiltrate secrets over DNS without ever opening a connection Bullfrog would block.
Use a custom DNS server
A job that resolves names through Tailscale MagicDNS, a corporate resolver, or a VPN-provided one has to reach that resolver. Add its address to allowed-ips:
- uses: bullfrogsec/bullfrog@7dee337d4575320b6d8cbe9a56d48d2fb765963a # v0.11.1
with:
egress-policy: block
allowed-ips: |
100.100.100.100 # Tailscale MagicDNS
Verify
Run the job and open the Bullfrog results in the job summary. Every destination you allowlisted shows an Authorized decision. Anything still Blocked is missing from the list.