DOCS configure network policies
Support# Configuring Network Policies
Bauxite includes a flexible policy engine that allows you to define firewall
rules and geofencing constraints to secure your mesh traffic.
## Firewall Rules
Firewall rules allow you to control traffic between nodes based on the target
node ID, protocol, and port.
### Rule Structure
A firewall rule consists of:
- **Rule ID**: A unique identifier for the rule.
- **Destination Target**: The Node ID of the target peer, or `*` for all peers.
- **Allowed Ports**: A list of ports that are allowed. If empty, all ports are allowed.
- **Protocol**: `TCP`, `UDP`, `ICMP`, or `ANY`.
- **Action**: `Allow` or `Deny`.
### Example Rules
Rules are typically pushed to the agent from the Control Plane via gRPC, but
they can be observed in the agent's debug logs.
**1. Allow only ROS 2 traffic to a specific robot:**
- Target: `robot-2`
- Protocol: `UDP`
- Ports: `[11811]`
- Action: `Allow`
**2. Block all traffic to a legacy gateway:**
- Target: `legacy-gateway`
- Protocol: `ANY`
- Action: `Deny`
## Sandbox Degradation (Sandboxed Nodes)
When the Hub marks a node as sandboxed (e.g. legacy or unattested devices), the policy engine
enforces tier restrictions regardless of firewall rules:
- **Allowed**: Ports 8500 and 8080 (telemetry and bulk only).
- **Denied**: All other ports (Critical and Telemetry traffic).
This is enforced before rule evaluation in `PolicyEngine::check_fast()`.
## Geofencing & Sovereign Compliance
For highly regulated industries, Bauxite provides a Geofencing Engine that
enforces data residency and sovereign jurisdiction rules.
### Features
- **Jurisdiction Enforcement**: Ensure that data from a specific region
(e.g., `EU`) never travels through blocked subnets (e.g., known US-based relay addresses).
- **GDPR Compliance**: Automatically block connection attempts that violate
jurisdictional boundaries.
### Configuration
To use geofencing, you must:
1. Compile the Bauxite Agent with the `sovereign-compliance` feature flag.
2. Configure your home region and policy rules in your `config.toml` (under the `[node]` table):
```toml
[node]
# Set your home region (preferred over legacy 'jurisdiction' field)
jurisdictional_policy.home_region = "EU"
# Optional: define allowed/blocked transit regions
jurisdictional_policy.allowed_transit_regions = ["EU", "US"]
jurisdictional_policy.block_list_regions = ["CN"]
```
## Policy Evaluation Logic
1. **Default Allow**: If no rules are defined, Bauxite defaults to allowing all
traffic within the mesh.
2. **Lexicographic Rule ID**: Bauxite merges rules from three scopes
(`specific` target, `*` wildcard, and `ANY` wildcard) and evaluates them
in ascending lexicographic order of `rule_id`. The first matching rule
determines the action. Name your rule IDs with a sortable prefix (e.g.
`01-deny-all`, `02-allow-ros`) to control evaluation priority.
3. **Implicit Deny**: If rules are present but none match the packet,
the packet is denied.
---
## Managing Policies via CLI
The `bauxite policy` command provides a straightforward way to manage firewall rules by sending HTTP REST requests directly to the Hub.
### Upserting a Rule
Use `policy upsert` to create or update a firewall rule. The command maps user-friendly protocol and action strings to the Hub's internal integer values:
```bash
bauxite policy upsert \
--rule-id "10-allow-web" \
--target "web-server-node" \
--protocol tcp \
--action allow \
--port 80,443
```
- `--rule-id`: Unique identifier (used to determine priority lexicographically).
- `--target`: Destination Node ID, or `*` for all peers.
- `--protocol`: Protocol (`tcp`, `udp`, `icmp`, `any`).
- `--action`: Action to take (`allow`, `deny`).
- `--port`: (Optional) Comma-separated list of allowed ports. If omitted, all ports are allowed.
- `--config` / `-c`: Path to `config.toml` to read the Hub's URL (default: `config.toml`).
### Deleting a Rule
Use `policy delete` to delete a firewall rule by ID:
```bash
bauxite policy delete --rule-id "10-allow-web"
```
---
## Managing Policies via REST API
If you prefer programmatic integration directly with the Hub Control Plane, you can invoke the Hub's Admin API endpoints directly. By default, the admin endpoints are exposed on port `8080`.
### 1. Upsert Policy
- **Endpoint**: `POST /api/admin/policies/upsert`
- **Headers**: `Content-Type: application/json`
- **Payload Schema**:
```json
{
"rule": {
"ruleId": "string",
"destinationTarget": "string",
"protocol": number,
"action": number,
"allowedPorts": [number]
}
}
```
- **Example curl request**:
```bash
curl -X POST http://control-plane:8080/api/admin/policies/upsert \
-H "Content-Type: application/json" \
-d '{
"rule": {
"ruleId": "10-allow-web",
"destinationTarget": "web-server-node",
"protocol": 1,
"action": 1,
"allowedPorts": [80, 443]
}
}'
```
### 2. Delete Policy
- **Endpoint**: `POST /api/admin/policies/delete`
- **Headers**: `Content-Type: application/json`
- **Payload Schema**:
```json
{
"ruleId": "string"
}
```
- **Example curl request**:
```bash
curl -X POST http://control-plane:8080/api/admin/policies/delete \
-H "Content-Type: application/json" \
-d '{"ruleId": "10-allow-web"}'
```
---
## Integer Mappings & Protobuf Specs
Internally, protocols and actions are defined as Protobuf enums and stored on the Hub as integers.
### Protocol Mappings (`protocol`)
| Integer | Proto Identifier | Description |
|---|---|---|
| `0` | `PROTOCOL_UNSPECIFIED` | Default/fallback |
| `1` | `PROTOCOL_TCP` | TCP traffic |
| `2` | `PROTOCOL_UDP` | UDP traffic |
| `3` | `PROTOCOL_ICMP` | ICMP traffic |
| `4` | `PROTOCOL_ANY` | Matches any protocol |
### Action Mappings (`action`)
| Integer | Proto Identifier | Description |
|---|---|---|
| `0` | `ACTION_UNSPECIFIED` | Default/fallback |
| `1` | `ACTION_ALLOW` | Allow traffic matching the rule |
| `2` | `ACTION_DENY` | Deny/Drop traffic matching the rule |
---
## Real-Time Synchronization (WatchPolicies)
Whenever a policy is upserted or deleted via the Admin API or the CLI:
1. The Hub saves the updated policy state to the SQL database.
2. The Hub broadcasts a real-time event to all connected agent nodes.
3. Bauxite agents maintain a persistent, bidirectional gRPC stream connection (`WatchPolicies`) to the Hub and dynamically apply the policy updates to their local `PolicyEngine` (or kernel XDP/eBPF firewall maps) without requiring an agent restart.