Stream Naming
BSFG facts are organized into JetStream streams by category and subject prefix.
Format
stream_name := facts.<category>[.<prefix>]
Standard Categories
| Category | Purpose | Subjects | Retention | Example Stream |
|---|---|---|---|---|
| operational | Production data (orders, batches, steps) | facts.operational.* |
7–10 years | facts.operational.batch.* |
| audit | System access and change logs | facts.audit.* |
3–7 years | facts.audit.user.* |
| documents | Document and file references | facts.documents.* |
5–10 years | facts.documents.compliance.* |
| telemetry | Sensor readings and metrics | facts.telemetry.* |
1–3 years | facts.telemetry.temperature.* |
Subject-Based Partitioning
Streams can use subject prefixes to partition by subject kind:
facts.operational.batch.* (all batch facts)
facts.operational.order.* (all order facts)
facts.operational.device.* (all device facts)
facts.audit.system.* (system-level audit)
facts.audit.user.* (user-level audit)
Partitioning enables:
- Different retention policies per subject kind
- Better consumer performance (smaller subscription scope)
- Clearer semantic organization
JetStream Stream Configuration
streams:
- name: facts_operational
subjects:
- facts.operational.>
max_age: 10y # 10-year retention for operational data
storage: file # persistent storage
replicas: 3 # HA: replicate to 3 nodes
discard: old # evict oldest when full (for non-safety-critical)
- name: facts_audit
subjects:
- facts.audit.>
max_age: 7y
storage: file
replicas: 3
discard: old
- name: facts_telemetry
subjects:
- facts.telemetry.>
max_age: 3y
storage: file
replicas: 1 # lower HA requirement for ephemeral telemetry
discard: old
Account Naming
Each BSFG zone has zone-scoped NATS accounts for access control.
Format
account_name := <zone>_account
Examples
enterprise_account (Enterprise IT zone)
plant_a_account (Plant A OT zone)
plant_b_account (Plant B OT zone)
idmz_account (Industrial DMZ, optional)
Account Model
Each zone has at least two accounts:
zone: enterprise-bsfg
accounts:
enterprise_account: # Application-facing account
purpose: emit/consume facts
permissions:
- publish: facts.operational.>
- subscribe: facts.operational.>
- publish: facts.audit.>
- subscribe: facts.audit.>
system_account: # BSFG node system account
purpose: internal JetStream operations
permissions:
- publish: $JS.>
- subscribe: $JS.>
The enterprise_account is used by producers and consumers (applications). The system_account is used by the BSFG node itself for internal stream/consumer management.
Subject-Level Authorization
NATS enforces authorization at the subject level using ACLs (Access Control Lists).
Subject Hierarchies
Topics use dot-separated hierarchies:
facts.operational.batch.PlantA.B1042
facts.operational.order.ENT-12345
facts.audit.user.john_doe
facts.telemetry.temperature.sensor_7
Authorization Rules
# Enterprise zone permissions
enterprise_account:
permissions:
publish:
allow:
- 'facts.operational.>' # produce facts
- 'facts.audit.>'
- 'facts.documents.>'
subscribe:
allow:
- 'facts.operational.>' # consume facts
- 'facts.audit.>'
- 'facts.documents.>'
# Plant zone permissions (restricted)
plant_a_account:
permissions:
publish:
allow:
- 'facts.operational.batch.PlantA.>' # only PlantA batches
- 'facts.audit.plant_a.>'
subscribe:
allow:
- 'facts.operational.batch.PlantA.>'
- 'facts.audit.plant_a.>'
JetStream System Subject Rules
JetStream uses reserved subjects for cluster and consumer operations:
$JS.API.* # API calls (create stream, consumer, etc.)
$JS.EVENT.* # Events (stream created, message acknowledged)
$JS.DEBUG.* # Debug information
$KV.* # Key-value store (if used)
$OBJ.* # Object store (if used)
The system_account must have permission to $JS.>:
system_account:
permissions:
subscribe:
allow: ['$JS.>']
publish:
allow: ['$JS.>']
Message ID (Deduplication) Naming
Within each stream, producers provide a message ID for idempotent deduplication:
// High-entropy stable ID derived from business key
const message_id = sha256(order_id + event_type + timestamp);
// Publish with message ID header
await stream.publish(subject, payload, {
msgID: message_id
});
JetStream stores message IDs in a deduplication window (default: stream's MaxAge). Any message with the same ID within the window is deduplicated.
Zone Identity and Certificates
Zone identities appear in mTLS certificate Common Names:
Zone Identity: enterprise-bsfg
└─ Certificate CN: enterprise-bsfg
└─ Private Key: /etc/bsfg/certs/enterprise-bsfg.key
└─ Certificate: /etc/bsfg/certs/enterprise-bsfg.crt
└─ CA Bundle: /etc/bsfg/certs/ca.crt
Zone Identity: plant-a-bsfg
└─ Certificate CN: plant-a-bsfg
└─ ...
Zone Identity Rules
- Zone names are stable: Once deployed, a zone name is never changed
- Zone names are DNS-friendly: Lowercase, dash-separated (not underscore or dot)
- Zone names appear in NATS accounts: Account naming derives from zone names (
<zone>_account) - Zone names appear in certificate CN: Authentication relies on CN matching zone identity
- Renaming zones requires infrastructure updates: Re-issue certificates, re-provision NATS accounts, update firewall rules
Environment Variables and Secrets
Store NATS credentials and keys in environment variables or secrets manager:
# Zone identity for this BSFG node
export BSFG_ZONE="enterprise-bsfg"
# NATS server connection
export NATS_SERVERS="nats://enterprise-nats:4222"
# mTLS certificate paths
export BSFG_CERT="/etc/bsfg/certs/enterprise-bsfg.crt"
export BSFG_KEY="/etc/bsfg/certs/enterprise-bsfg.key"
export BSFG_CA="/etc/bsfg/certs/ca.crt"
# NATS account credentials (if using user accounts instead of mTLS)
export NATS_USER="$BSFG_ZONE-user"
export NATS_PASSWORD="<secure-password>"
Relationship to Abstract Naming
For the abstract naming rules that apply to all BSFG deployments, see Naming Conventions.
Abstract grammar (substrate-neutral):
- Subjects:
<entity_type>:<identifier>(e.g.,batch:PlantA/B1042) - Predicates:
<verb>_<object>(e.g.,batch_started) - Schema IDs:
<predicate>_v<#>(e.g.,batch_started_v1) - Artifact paths:
<bucket>/<entity>/<identifier>(e.g.,batch-files/PlantA/B1042/recipe.pdf) - Zone names:
<zone>-bsfg(e.g.,enterprise-bsfg)
NATS/JetStream specifics (this document):
- JetStream streams:
facts.<category>[.<prefix>] - Subject hierarchies:
facts.<category>.<subject_kind>.<entity>.* - NATS accounts:
<zone>_account - Certificate CN:
<zone>-bsfg
Cross-Links
- Naming Conventions — Abstract naming grammar (architecture-neutral)
- NATS/JetStream Reference — Implementation details
- Identity Model — Zone identity and mTLS