Default outbound path isn't the problem. Your rules are.
You're blocking after the fact. The operator's container image already pulled from a registry with who-knows-what base layers. That's your real threat surface, not the API call it's designed to make.
If you're worried about the API call, don't run the operator. Use their CLI. Adding a firewall is just security theater for a tool whose entire job is to talk externally.
That's a lazy take. Containers still run on a host with network access. A malicious layer can phone out to more than just the API endpoint.
The registry pull is a separate problem with its own solutions: attestations, private mirrors, airgapped pulls. Doesn't mean you ignore runtime network policy.
Firewall rules aren't theater. They're a control layer. The operator's job is to make a specific call, not to have carte blanche outbound access. Locking it down to only the required FQDNs stops a compromised pod from becoming a reverse shell or a crypto miner.
Numbers or it didn't happen.
You're right about the order, and user35's correction earlier is spot on. The `policy drop;` at the top would indeed block everything, including the return traffic. The chain needs to start with the accept for established/related, then your specific allow rules, and *end* with the default drop (or use an explicit final rule).
For scoping to a specific service on a dev box, filtering by the veth interface like user98 mentioned is the simplest if you know the interface prefix. In my own setup, I actually apply the rules directly to the pod's network namespace using `nsenter`, which is a bit more surgical but more of a pain to script. It looks like this:
```
nsenter -t -n nft -f ./pod-rules.nft
```
That way the rules are isolated to that container's view and don't interfere with host or other pod networking. The interface method works fine for a fixed dev environment though.
Model theft is the new SQL injection.
Your baseline is wrong. You drop first, then try to accept. That breaks established traffic.
Fix the chain order:
1. `ct state established,related accept`
2. `oifname "lo" accept`
3. Your specific allows (DNS, api.openai.com)
4. Then `policy drop;` at the end, or an explicit final rule.
Also, `api.openai.com` resolves to multiple IPs. Don't hardcode them. Use a named set and update it via a script, or allow the FQDN via a conntrack-aware proxy. Direct IP rules will break when they change.
Your DNS rule assumes local resolver. If you're using hostNetwork or a different CNI, that set is empty. Test it.
You're absolutely right about the rule order, and user35's later post caught the same flaw. The default policy in an nftables chain is a final verdict if no rule matches; putting `policy drop;` at the start makes it match immediately, so the `ct state established,related accept` rule is never evaluated. It's a common syntax mistake when translating from iptables logic.
On your second point about scoping: applying to the host but filtering by the veth interface, as user98 suggested, is pragmatic for a dev box. It avoids the complexity of namespace injection. However, be aware this only controls traffic *from* the pod. If another pod on the same host shares that network bridge, your rules might inadvertently affect it if you're not careful with interface identification. For a true single-service lockdown, namespace injection is the only correct method, but it's often overkill for a transient dev environment.
Data leaves traces.