MÓDULO RELAY.Art¶
Bridge OOBI ↔ customer MGMT — telemetry ingress + control egress.
The only path between OOBI overlay (trusted) and customer-side MGMT interfaces (untrusted). Customer DUTs + switches NEVER join the OOBI overlay — RELAY bridges via dedicated MGMT NICs.
See primer for the operator- facing intro.
Identity¶
| Element | Value |
|---|---|
| Plane | MGMT (cloud-portable; needs L2 reach to customer for ingress) |
| Internal code | relay-bridge |
| K8s namespace | oobi-fabric |
| OOBI slot | .240 (primary) / .241 (HA standby) |
| Customer-side iface | per-customer dedicated macvlan NIC (eth2/eth3) |
| ADR | ADR-0092 |
| Sister module | HyperBridge.Art (DATA-plane bridge) |
Hard rules¶
- MGMT-only — never data plane. Memo §"Hard rule (no exceptions)". Routers (BGP/OSPF/SDWAN) NEVER peer with NGFW MGMT interfaces; peering is always over routed data-plane interfaces (
/30or/126transits) - Read-only Mode default. Memo §"DOM mode interactions". Production DOM forces read-only; only explicit UnlockWindow accepts writes
- PII strip on ingress (k-anonymity ≥ 10 threshold, Phase B). Per memo §"PII strip enforcement"
- Per-target cred isolation in vault. RELAY-3
CredentialSourceper pod; breach of one doesn't expose GATEWAY operator creds - DOM-aware — production mode = read-only enforced; PIE Auto-Abort engine watches egress writes
Architecture¶
OOBI Fabric (VXLAN VNI 254254 — IMMUTABLE)
.50 .60..84 .100 .240 (RELAY primary) .241 (standby)
▲ ▲
vxlan0│ vxlan0│
┌────────┴─────┐ ┌────────┴────┐
│ RELAY.Art │ │ RELAY.Art │
│ primary │ │ standby │
│ slot .240 │ │ slot .241 │
└─┬────┬───┬───┘ └─────────────┘
eth1 ←┘ │ │
underlay │ │
│ │
eth2 (customer MGMT VLAN N)
▼ ▼
┌──────────────────────────────────────┐
│ Customer's existing MGMT network │
│ NGFW MGMT 172.16.10.10 │
│ Switch MGMT 172.16.10.5 │
└──────────────────────────────────────┘
K8s Service load-balances across both pods; readiness probe drops the failing pod from endpoints automatically. Phase B-late adds Multus whereabouts floating-IP for true VRRP-style semantics.
Functions — Ingress (Customer MGMT → OOBI)¶
pkg/relay-art/internal/ingress/ per RELAY-2.
| Protocol | Port | Forwards to (OOBI MÓDULO) |
|---|---|---|
| NetFlow v5/v9 | UDP 2055 | FLOW.Art |
| IPFIX | UDP 4739 | FLOW.Art |
| sFlow | UDP 6343 | FLOW.Art |
| Syslog (RFC 5424) | UDP 514 / TCP 514 | SYSLOG.Art |
| Syslog over TLS | TCP 6514 | SYSLOG.Art |
| SNMP traps v2c/v3 | UDP 162 | SNMP.Art |
| gNMI/gRPC streaming | TCP 9339 | TELEMETRY.Art (Phase B) |
| REST webhook | TCP 443 | API INFRA.Art |
Forwarding semantics: RELAY rewrites source IP to OOBI canonical addressing (Phase B); device IP preserved in metadata (NetFlow exporter ID, syslog hostname, SNMP agent address).
Token-bucket rate limit: per-protocol RatePerSecond cap, drop-oldest (FIFO) on backpressure per memo §"Backpressure" — operator alerted via SYSLOG.Art alert pipeline.
Functions — Egress (OOBI → Customer MGMT)¶
pkg/relay-art/internal/egress/ per RELAY-3.
| Protocol | Use case | Source MÓDULO |
|---|---|---|
| SSH (v2 only) | Send CLI commands to NGFW/switch | CLI.Art |
| SNMP polls v2c/v3 | Pull counters, table dumps | SNMP.Art |
| HTTPS REST | FMC/Panorama/FortiManager/SCC API | API INFRA.Art |
| NETCONF over SSH | Modern routers/switches (RFC 6241) | API INFRA.Art |
| RESTCONF | Modern devices (RFC 8040) | API INFRA.Art |
Source IP: RELAY's customer-MGMT-side IP (operator-assigned). Customer's firewall sees a single source identity for all outbound, simplifies their ACLs.
Per-target rate limit: RateLimited wrapper with map[Target.Name]→bucket; independent per-target so one chatty target doesn't starve others.
ReadOnly Mode default: IsWrite=true rejected with ErrReadOnly unless explicit UnlockWindow {Active, Until} window open. Memo §"write_mode_unlock" defaults: 15 min duration, requires approval (PIE workflow in production DOM), per-command audit.
CPOS schema¶
relay:
enabled: true
legs:
- name: customer-mgmt-primary
iface: eth2
vlan: 100
ipv4: 172.16.10.50/24
ipv4_gw: 172.16.10.1
targets:
- name: dut-1
ipv4: 172.16.10.10
role: ngfw
vendor: cisco-ftd
mgmt_via: fmc
credential_ref: "file:///etc/relay-art/credentials/dut-1.yaml"
mode: read-only # read-only | write | unlock-window
per_target_rate_per_sec: 10
strip_source_ip: false # set true for PURE Discovery Hub use case
Security model¶
- Network namespace isolation — RELAY pod in dedicated K8s netns with strict NetworkPolicy
- eBPF egress filter — only declared protocols/ports leave (Phase B)
- Per-leg credentials — Vault scoping enforced via
Target.CredentialRef - Read-only default —
IsWrite=truerejected without UnlockWindow - Audit log every action — operator IP, identity, target, command, timestamp → SYSLOG.Art
- Rate limits hard-enforced — per-target token buckets
- TLS verify enforced for HTTPS/RESTCONF egress
- No outbound to internet — only declared
targets
Vault separation from GATEWAY¶
| Vault scope | Stores | Used by |
|---|---|---|
| GATEWAY.Art vault | Operator creds (LDAP, SAML, passkeys, op-side TLS keys) | GATEWAY only |
| RELAY.Art vault | Customer-device creds (SSH keys, SNMP communities, API tokens) | RELAY only |
Breach of one vault does NOT compromise the other.
DOM mode interactions¶
| DOM mode | RELAY behavior |
|---|---|
greenfield |
Read+write enabled; full SSH/REST permissions |
staging |
Read+write enabled; rate limits stricter; per-action audit |
lab |
Read+write enabled; standard rate limits |
production |
Read-only enforced (PIE); write-mode requires unlock + approval; ultra-strict rate limits |
prod-partition |
Read+write on partition only; out-of-partition writes blocked |
PIE Auto-Abort Engine watches egress: write to out-of-partition resource → immediate connection terminate + audit + alert.
Operator controls¶
/admin/relay-art (planned UI):
| Section | Action |
|---|---|
| Live status header | Primary/standby health; ingress + egress throughput |
| Targets table | Per-target |
| Audit log tail | JSONL stream of every dispatch / forward |
| UnlockWindow control | 15-min write-mode override (requires PIE approval in production) |
Telemetry (Prometheus)¶
| Metric | Description |
|---|---|
relay_ingress_received_total{protocol} |
UDP datagrams received |
relay_ingress_forwarded_total{protocol} |
Datagrams successfully forwarded to OOBI |
relay_ingress_dropped_total{protocol} |
Dropped (rate limit / backpressure) |
relay_ingress_errors_total{protocol} |
Forward errors |
relay_egress_dispatched_total{target,protocol} |
Egress commands sent |
relay_egress_rate_limited_total{target} |
Per-target rate-limit hits |
relay_egress_read_only_rejected_total{target} |
Write commands rejected (ReadOnly mode) |
relay_ha_active_role |
1 when primary, 0 when standby |
Hardware footprint¶
| Component | Image size | RAM baseline | CPU baseline |
|---|---|---|---|
| relay-art (Go) | ~25 MB | 128 MiB | 100m CPU |
| relay-art-standby (Go) | ~25 MB | 128 MiB | 100m CPU |
Deferred (post-Phase-A)¶
- Phase B: real protocol parsing (NetFlow v9 templates, IPFIX IEs, sFlow XDR) + HC Vault / cert-manager
CredentialSourceadapters + Multus whereabouts floating-IP - Phase B-late: per-vendor session multiplexer (FMC, Panorama long-lived sessions); credential auto-rotation via vendor APIs
- PII strip k-anonymity ≥ 10 threshold — depends on URL extraction pipeline
- Telemetry forwarding to customer SIEM (Splunk / QRadar) — opt-in CPOS knob, v5.x
Related¶
- Strategic memo:
discuss_module_relay_art_2026_05_10 - ADR: ADR-0092
- Sister bridges: HyperBridge.Art (ADR-0036) — DATA-plane peer; GATEWAY.Art (slot .250/.251) — operator-facing peer
- Pattern reference: ADR-0086/0089 adapter pattern (Disabled/Fake/real) used here
- Patent reservation: claim #12 in DOM/OOBI/GATEWAY/RELAY family