Audience: Implementation engineers, operators. Use: Reference for JetStream-specific naming when deploying BSFG with NATS. For abstract naming rules (subjects, predicates, schemas, artifacts, zones), see Naming Conventions.
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