An XMPP client and server built for national security, defense and highly regulated environments — open standards end to end, so nothing about your messaging is locked in a proprietary walled garden.
Behind it: five years delivering XMPP in the federal space.
Interoperability, accessibility, and whether your operators will actually use it.
01 · Standards-based
Built on XMPP, not on a vendor
Shortfin implements NATO Federated Mission Networking Basic and Advanced Instant Messaging Collaboration Services, plus the Text-based Communication Services in NATO's Core Services Specification — so coalition partners federate instead of installing your client.
The XMPP ecosystem has mature client libraries across languages and runtimes. Your integrations stay yours.
02 · Accessible by design
WCAG and Section 508, not a remediation plan
Keyboard-first navigation lets expert operators move without touching a mouse, and the same work makes the client usable for everyone else. Accessibility conformance is built in rather than promised in a VPAT to be written later.
03 · Familiar to operators
Markdown styling, no training deck
Bold, underline and monospaced text use the Markdown notation people already type. Message retraction and the rest of the interaction model follow the conventions operators bring with them.
Shortfin datasheet
What Shortfin is, what it implements, and how to put it on contract.
Components
Web-based chat client and a scalable XMPP server
Standards
XMPP core plus XEPs; NATO FMN Basic and Advanced IM Collaboration Services; NATO Core Services Specification, Text-based Communication Services
Cryptography
FIPS 140-3 compliant
Accessibility
W3C WCAG and Section 508; VPAT on request
Experience
Five years delivering XMPP in the federal space
Licensing
Commercial software, acquired under FAR Part 12
Crab Wave
SigMF in Rust, built for the mission.
Crab Wave reads, creates, validates and annotates SigMF recordings — and modernizes legacy Midas BLUE collections — with the speed and type safety Rust gives you.
For the teams who own the collection pipeline: bad metadata fails at the parse boundary, not mid-mission.
fntyped_extensions() -> Result<(), Box<dyn Error>> {use crab_wave::api::{load_extensions_from_valid_meta, load_metadata, standard_decoders};use crab_wave::extensions::WifiExtension;let meta =load_metadata(Path::new("captures/mission-0412.sigmf-meta"))?;let exts =load_extensions_from_valid_meta(&meta, &standard_decoders())?;// No stringly-typed JSON digging: extensions come back as Rust types.if letSome(wifi) = exts.get::<WifiExtension>() {println!("wifi channel{:?}, ssid{:?}", wifi.channel, wifi.ssid);}Ok(())}
fntyped_extensions() -> Result<(), Box<dyn Error>> {use crab_wave::api::{load_extensions_from_valid_meta, load_metadata, standard_decoders};use crab_wave::extensions::WifiExtension;let meta =load_metadata(Path::new("captures/mission-0412.sigmf-meta"))?;let exts =load_extensions_from_valid_meta(&meta, &standard_decoders())?;// No stringly-typed JSON digging: extensions come back as Rust types.if letSome(wifi) = exts.get::<WifiExtension>() {println!("wifi channel{:?}, ssid{:?}", wifi.channel, wifi.ssid);}Ok(())}
Full SigMF lifecycle
Parse, create, edit and write metadata, collections and archives — schema-validated and SHA-512 verified.
Typed dataset reads
IQ samples in their native type: all 28 SigMF datatypes, real or complex, either endianness. Lossless.
Type-safe extensions
Extension namespaces modeled as plain Rust types, with a dynamic registry covering standard SigMF extensions like antenna and signal — and room to write your own.
Annotations as training data
Mark where a signal decoded and to what values — annotations become labels, and recordings become training sets.
Midas BLUE, in place
Convert BLUE to SigMF — binary keywords, detached dataset configurations, sample rates and coordinates carried across — or annotate legacy collections in place as non-conforming datasets. No copies.
Rust underneath
Memory-safe, no GC, no runtime dependencies. Predictable throughput and a clean audit story for accreditation.
Annotating a Midas BLUE collection, in place
The capture marks BLUE's fixed 512-byte header control block, so SigMF readers skip straight to the complex int16 samples — nothing is copied, and a sidecar metadata file is all that gets written.
fnannotate_blue_in_place() -> Result<(), Box<dyn Error>> {use crab_wave::sigmf::metadata::{
AnnotationBuilder, CaptureBuilder, DataType, GlobalBuilder, SigMfMetaBuilder,};// Point SigMF at the untouched BLUE file as a non-conforming dataset:// the 512-byte BLUE header is skipped, the samples are never copied.let meta = SigMfMetaBuilder::new().global(
GlobalBuilder::new(DataType::Ci16Le,"1.0.0".into()).sample_rate(2.5e6).dataset_non_conforming("intercept-1998.tmp".into(),0),).add_capture(CaptureBuilder::new(0).header_bytes(512)).add_annotation(
AnnotationBuilder::new(48_000).sample_count(12_288).label("qam16".into()).comment("decoded: 0x2E41A6".into()),).build("intercept-1998.sigmf-meta".into())?;// A sidecar file is all that's written.let file = std::fs::File::create("legacy/intercept-1998.sigmf-meta")?;
serde_json::to_writer_pretty(file, &meta)?;Ok(())}
fnannotate_blue_in_place() -> Result<(), Box<dyn Error>> {use crab_wave::sigmf::metadata::{
AnnotationBuilder, CaptureBuilder, DataType, GlobalBuilder, SigMfMetaBuilder,};// Point SigMF at the untouched BLUE file as a non-conforming dataset:// the 512-byte BLUE header is skipped, the samples are never copied.let meta = SigMfMetaBuilder::new().global(
GlobalBuilder::new(DataType::Ci16Le,"1.0.0".into()).sample_rate(2.5e6).dataset_non_conforming("intercept-1998.tmp".into(),0),).add_capture(CaptureBuilder::new(0).header_bytes(512)).add_annotation(
AnnotationBuilder::new(48_000).sample_count(12_288).label("qam16".into()).comment("decoded: 0x2E41A6".into()),).build("intercept-1998.sigmf-meta".into())?;// A sidecar file is all that's written.let file = std::fs::File::create("legacy/intercept-1998.sigmf-meta")?;
serde_json::to_writer_pretty(file, &meta)?;Ok(())}
Crab Wave datasheet
What it is
A Rust library — embedded in your own tooling, not run as a service
Formats
SigMF metadata, collections and archives; Midas BLUE conversion; non-conforming datasets annotated in place
Datatypes
All 28 SigMF datatypes, real or complex, either endianness
Validation
Compile-time and runtime checks on dates (ISO 8601), versions, DOIs and geolocation; SHA-512 dataset verification
Runtime
Memory-safe, no garbage collector, no runtime dependencies
Licensing terms on request.
See it on your network.
Tell us the enclave, the partners you need to federate with, or the recordings you need converted — we'll set up a demo against that.