Share configuration across firewalls
Let firewalls inherit rules, exceptions, and upstreams from a baseline firewall, so one policy change applies across the organization.
A firewall can inherit configuration from another firewall in the same namespace by naming it as its parent. The parent's rules, exceptions, and upstreams then apply to the child's traffic, live: change the parent and every inheriting firewall picks it up within a few seconds, no copying or re-import.
This is how one baseline policy serves a whole organization. Keep the organization's non-negotiables (malware blocking, vulnerability thresholds, approved upstreams) in one baseline firewall per ecosystem, and let each team's firewall inherit it and add its own rules on top.
org rules, exceptions, upstreams
Set a parent
In the dashboard, the firewall form (create or edit) has an Inherit configuration from selector. It offers firewalls of the same ecosystem and hides any choice that would create a loop. The parent can be any firewall; nothing special marks it as a baseline, and it can keep serving its own traffic.
In config as code, the parent is the parentId field:
{
"id": "3e7f5cb806f26e3beae2",
"ecosystem": "npm",
"parentId": "43b5799c6cb335570cad",
"rules": [],
"exceptions": [],
"upstreams": []
}Setting or changing the parent is a configuration change (fw:update:config). The server rejects a parent that does not exist, has a different ecosystem, or would close a cycle, including inheriting from itself.
What the child serves
At request time the firewall resolves the parent chain into one effective configuration:
| Part | Merge behavior |
|---|---|
| Rules | Union, parents first, the firewall's own last. That is the merge order, not the evaluation order |
| Exceptions | Union, same order |
| Upstreams | Union; a child upstream with the same id replaces the parent's |
| Publish target | The child's own if set, otherwise the nearest ancestor's |
| Permissions | Not inherited; access is granted per firewall |
Three consequences:
- Inheritance is additive. A child can add rules. It cannot delete, edit, or override an inherited one, and an inherited rule that blocks still blocks.
- Parents can inherit too. Chains work (baseline → division → team) up to a depth of 32.
- Editing and export stay local. The firewall's own configuration contains only its own entries plus
parentId;bsfw firewall exportdoes not embed inherited rules. The merge happens at serving time only.
Inherited rules and the child's own end up in one set, evaluated cheapest selector first rather than parents before children; see rule evaluation.
What a child can and cannot change
| Inherited part | Can the child change it? |
|---|---|
| Rules | No. It cannot delete, edit, or disable an inherited rule. It can only add an exception to one, described below |
| Exceptions | No. A parent's exception reaches the child as it stands |
| Upstreams | Yes. An upstream with the same id as an inherited one replaces it, for example to point the child at a different mirror |
| Publish target | Yes. Setting the child's own publishTarget sends its publishes elsewhere |
The child cannot remove, edit, or disable a baseline rule. It can add a narrow exception, but only with permission from the firewall that owns the rule.
Exceptions on an inherited rule
An exception tells one rule not to block requests that match the exception's selector. Other rules still apply. An exception stored on a child applies on that child and on descendants that inherit from it. It does not apply upward to its parent or sideways to sibling firewalls. Manage exceptions covers how to add one.
An example. The org baseline blocks packages with a critical vulnerability. One team depends on a package that has one, and no fixed version exists yet. On the team's firewall, they open Rules, find the baseline rule under Inherited rules, and select Add exception. They choose the package and version, then add a reason and expiry date. The exception is stored on the team's firewall. It stops that inherited rule from blocking the selected version there and on any descendants, but it does not edit or disable the baseline rule. Other rules can still block the package. The parent and sibling firewalls are unchanged. When the exception expires, it stops matching.
Inheritance guarantees the rule is present throughout the descendant chain. It does not guarantee that no descendant has an exception to it. That is why exceptions need permission from both sides, show up in the audit log, and can be given an expiry date.
Both firewalls have to allow it
Adding or changing an exception on an inherited rule needs fw:update:exception on two firewalls:
- The child, because that is where the exception is stored.
- The source firewall that owns the rule, which may be any ancestor in the chain.
If you have permission on only one, the save is refused. This requires approval from both the firewall storing the exception and the firewall responsible for the rule. If the source permission is missing, ask that firewall's owners.
Removing an exception needs permission on the child only because deletion strengthens enforcement. Other matching exceptions, if any, can still apply.
Two details worth knowing:
- The same two-firewall check runs when you import a whole config or roll one back, not only when you save a single exception. Exceptions that were already stored and are unchanged are left alone, so an unrelated edit never trips over an old one.
- An exception names its rule by ID. If that ID matches no rule, or matches two different rules in the chain, the save is refused rather than guessed at.
See what a firewall inherits
Open the firewall in the dashboard. The line under its name lists readable ancestors, closest parent first, each one a link: inherits team-npm → org-baseline.
Read access is granted per firewall. If the immediate parent is unreadable, the line shows its ID without a link. If the visible chain continues past an unreadable ancestor, it ends with →…. Rules from hidden firewalls still apply to your traffic; you just cannot open those firewalls from here.
The Rules, Exceptions, and Upstreams tabs show the firewall's own count first and an inherited count in parentheses. When every ancestor is readable, Rules showing 2 (+7) means two rules of its own and seven from ancestors. If part of the chain is unreadable, Rules and Exceptions count only visible ancestors even though their inherited sections can still show entries from the whole chain. Upstreams counts inherited entries that remain in effect.
Inherited entries never mix into the firewall's own list. They get their own section below it:
| Tab | Section | What is in it |
|---|---|---|
| Rules | Inherited rules | Rules from parent firewalls. You can add an exception here, if you have permission |
| Exceptions | Inherited exceptions | Exceptions the parents set on their own rules |
| Upstreams | Inherited upstreams | Upstreams from parent firewalls. A struck-through row is replaced by a nearer firewall in the chain with the same id |
Every inherited row carries a Source badge naming the firewall it comes from. Nothing inherited can be edited or deleted here. The badge links to the firewall where it can be, and a change made there reaches every firewall that inherits it.
If Add exception is greyed out on an inherited rule, hover it. The tooltip names the reason; see the troubleshooting entry below for what to do about each.
Inheritance or cloning
These are different features. Clone (fw:clone, "use as template" when creating a firewall) copies a configuration once; the copy diverges freely afterwards. Inheritance (parentId) is a live link; the child follows every parent change. Use clone for a starting point, inheritance for an enforced baseline.
Verify
- The firewall list shows the parent in Inherits.
- Open the child. If its ancestors are readable, its Rules tab badge reads
0 (+1)when the child has no rules of its own and inherits one. Exceptions follows the same visible-ancestor rule. Upstreams leaves out every overridden inherited entry because it is no longer in effect. - On the child's Rules tab, the Inherited rules section lists the parent's rules, each with a Source badge naming the parent.
- Trigger an inherited rule through the child firewall (install a package the baseline blocks). Select its log entry to open the complete detail. It records the child firewall ID in
firewalland the baseline firewall ID insourceFirewall, which is how you tell baseline policy from team policy.
Troubleshoot
A firewall that others inherit from cannot be deleted; the API answers 409 and names the inheriting firewalls. Clear or repoint parentId on each of them first.
The selector only offers firewalls of the same ecosystem, and excludes the firewall itself and its descendants, because those would create a loop. The API enforces the same on save: self-parent, ecosystem mismatch, and circular inheritance are rejected.
Do not change the baseline for one team. Add an exception on that team's firewall referencing the inherited rule's ID. It applies there and on descendants that inherit from it, but not on the parent or sibling firewalls. See Manage exceptions.
Hover the button. The tooltip names one of three reasons:
- You do not have
fw:update:exceptionon this firewall. Ask an admin for it. - You do not have it on the firewall that owns the rule. Adding an exception to that rule needs permission there too, so ask that firewall's owners.
- The rule's ID appears more than once in the chain, so the firewall cannot tell which one you mean. On one source firewall, create a replacement rule with a unique ID, then delete the duplicate rule.
Parent and child must share an ecosystem, so a firewall's ecosystem cannot change while others inherit from it. Create a new firewall for the other ecosystem. Do not detach children merely to change an exported config: imports do not translate ecosystem-specific upstreams or rules. See the firewall-config warning.
Related
- Concept: Rule evaluation, Upstreams and caching
- How-to: Manage exceptions, Manage config as code
- Reference: Firewall config, Logs, Permissions