-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathtransf-mqtt-v1.0-cs01.html
1166 lines (1161 loc) · 114 KB
/
transf-mqtt-v1.0-cs01.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta name="description" content="This specification describes the use of MQTT as a transfer mechanism for OpenC2 messages.">
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>Specification for Transfer of OpenC2 Messages via MQTT Version 1.0</title>
<link rel="stylesheet" href="https://docs.oasis-open.org/templates/css/markdown-styles-v1.7.3.css" />
</head>
<body>
<h2 id="oasis-logo"><img src="https://docs.oasis-open.org/templates/OASISLogo-v3.0.png" alt="OASIS Logo" /></h2>
<hr style="page-break-before: avoid" />
<h1big id="specification-for-transfer-of-openc2-messages-via-mqtt-version-10">Specification for Transfer of OpenC2 Messages via MQTT Version 1.0</h1big>
<h2 id="committee-specification-01">Committee Specification 01</h2>
<h2 id="19-november-2021">19 November 2021</h2>
<p> </p>
<h4 id="this-stage">This stage:</h4>
<p><a href="https://docs.oasis-open.org/openc2/transf-mqtt/v1.0/cs01/transf-mqtt-v1.0-cs01.md">https://docs.oasis-open.org/openc2/transf-mqtt/v1.0/cs01/transf-mqtt-v1.0-cs01.md</a> (Authoritative) <br />
<a href="https://docs.oasis-open.org/openc2/transf-mqtt/v1.0/cs01/transf-mqtt-v1.0-cs01.html">https://docs.oasis-open.org/openc2/transf-mqtt/v1.0/cs01/transf-mqtt-v1.0-cs01.html</a> <br />
<a href="https://docs.oasis-open.org/openc2/transf-mqtt/v1.0/cs01/transf-mqtt-v1.0-cs01.pdf">https://docs.oasis-open.org/openc2/transf-mqtt/v1.0/cs01/transf-mqtt-v1.0-cs01.pdf</a></p>
<h4 id="previous-stage">Previous stage:</h4>
<p><a href="https://docs.oasis-open.org/openc2/transf-mqtt/v1.0/csd04/transf-mqtt-v1.0-csd04.md">https://docs.oasis-open.org/openc2/transf-mqtt/v1.0/csd04/transf-mqtt-v1.0-csd04.md</a> (Authoritative) <br />
<a href="https://docs.oasis-open.org/openc2/transf-mqtt/v1.0/csd04/transf-mqtt-v1.0-csd04.html">https://docs.oasis-open.org/openc2/transf-mqtt/v1.0/csd04/transf-mqtt-v1.0-csd04.html</a> <br />
<a href="https://docs.oasis-open.org/openc2/transf-mqtt/v1.0/csd04/transf-mqtt-v1.0-csd04.pdf">https://docs.oasis-open.org/openc2/transf-mqtt/v1.0/csd04/transf-mqtt-v1.0-csd04.pdf</a></p>
<h4 id="latest-stage">Latest stage:</h4>
<p><a href="https://docs.oasis-open.org/openc2/transf-mqtt/v1.0/transf-mqtt-v1.0.md">https://docs.oasis-open.org/openc2/transf-mqtt/v1.0/transf-mqtt-v1.0.md</a> (Authoritative) <br />
<a href="https://docs.oasis-open.org/openc2/transf-mqtt/v1.0/transf-mqtt-v1.0.html">https://docs.oasis-open.org/openc2/transf-mqtt/v1.0/transf-mqtt-v1.0.html</a> <br />
<a href="https://docs.oasis-open.org/openc2/transf-mqtt/v1.0/transf-mqtt-v1.0.pdf">https://docs.oasis-open.org/openc2/transf-mqtt/v1.0/transf-mqtt-v1.0.pdf</a></p>
<h4 id="technical-committee">Technical Committee:</h4>
<p><a href="https://www.oasis-open.org/committees/openc2/">OASIS Open Command and Control (OpenC2) TC</a></p>
<h4 id="chair">Chair:</h4>
<p>Duncan Sparrell (<a href="mailto:duncan@sfractal.com">duncan@sfractal.com</a>), <a href="http://www.sfractal.com/">sFractal Consulting</a></p>
<h4 id="editor">Editor:</h4>
<p>David Lemire (<a href="mailto:david.lemire@hii-tsd.com">david.lemire@hii-tsd.com</a>), <a href="https://www.nsa.gov/">National Security Agency</a></p>
<h4 id="related-work">Related work:</h4>
<p>This specification is related to:</p>
<ul>
<li><em>Open Command and Control (OpenC2) Language Specification Version 1.0</em>. Edited by Jason Romano and Duncan Sparrell. Latest stage: <a href="https://docs.oasis-open.org/openc2/oc2ls/v1.0/oc2ls-v1.0.html">https://docs.oasis-open.org/openc2/oc2ls/v1.0/oc2ls-v1.0.html</a>.</li>
<li><em>Open Command and Control (OpenC2) Specification for Transfer of OpenC2 Messages via HTTPS Version 1.0</em>. Edited by David Lemire. Latest stage: <a href="https://docs.oasis-open.org/openc2/open-impl-https/v1.0/open-impl-https-v1.0.html">https://docs.oasis-open.org/openc2/open-impl-https/v1.0/open-impl-https-v1.0.html</a>.</li>
</ul>
<h4 id="abstract">Abstract:</h4>
<p>Open Command and Control (OpenC2) is a concise and extensible language to enable the command and control of cyber defense components, subsystems and/or systems in a manner that is agnostic of the underlying products, technologies, transport mechanisms or other aspects of the implementation. Message Queuing Telemetry Transport (MQTT) is a widely-used publish / subscribe (pub/sub) transfer protocol. This specification describes the use of MQTT Version 5.0 as a transfer mechanism for OpenC2 messages.</p>
<h4 id="status">Status:</h4>
<p>This document was last revised or approved by the OASIS Open Command and Control (OpenC2) TC on the above date. The level of approval is also listed above. Check the "Latest stage" location noted above for possible later revisions of this document. Any other numbered Versions and other technical work produced by the Technical Committee (TC) are listed at <a href="https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=openc2#technical">https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=openc2#technical</a>.</p>
<p>TC members should send comments on this specification to the TC's email list. Others should send comments to the TC's public comment list, after subscribing to it by following the instructions at the "Send A Comment" button on the TC's web page at <a href="https://www.oasis-open.org/committees/openc2/">https://www.oasis-open.org/committees/openc2/</a>.</p>
<p>This specification is provided under the <a href="https://www.oasis-open.org/policies-guidelines/ipr#Non-Assertion-Mode">Non-Assertion</a> Mode of the OASIS IPR Policy, the mode chosen when the Technical Committee was established. For information on whether any patents have been disclosed that may be essential to implementing this specification, and any offers of patent licensing terms, please refer to the Intellectual Property Rights section of the TC's web page (<a href="https://www.oasis-open.org/committees/openc2/ipr.php">https://www.oasis-open.org/committees/openc2/ipr.php</a>).</p>
<p>Note that any machine-readable content (<a href="https://www.oasis-open.org/policies-guidelines/tc-process#wpComponentsCompLang">Computer Language Definitions</a>) declared Normative for this Work Product is provided in separate plain text files. In the event of a discrepancy between any such plain text file and display content in the Work Product's prose narrative document(s), the content in the separate plain text file prevails.</p>
<h4 id="key-words">Key words:</h4>
<p>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [<a href="#rfc2119">RFC2119</a>] and [<a href="#rfc8174">RFC8174</a>] when, and only when, they appear in all capitals, as shown here.</p>
<h4 id="citation-format">Citation format:</h4>
<p>When referencing this specification the following citation format should be used:</p>
<p><strong>[OpenC2-MQTT-v1.0]</strong></p>
<p><em>Specification for Transfer of OpenC2 Messages via MQTT Version 1.0</em>. Edited by David Lemire. 19 November 2021. OASIS Committee Specification 01. <a href="https://docs.oasis-open.org/openc2/transf-mqtt/v1.0/cs01/transf-mqtt-v1.0-cs01.html">https://docs.oasis-open.org/openc2/transf-mqtt/v1.0/cs01/transf-mqtt-v1.0-cs01.html</a>. Latest stage: <a href="https://docs.oasis-open.org/openc2/transf-mqtt/v1.0/transf-mqtt-v1.0.html">https://docs.oasis-open.org/openc2/transf-mqtt/v1.0/transf-mqtt-v1.0.html</a></p>
<h4 id="notices">Notices:</h4>
<p>Copyright © OASIS Open 2021. All Rights Reserved.</p>
<p>Distributed under the terms of the OASIS <a href="https://www.oasis-open.org/policies-guidelines/ipr/">IPR Policy</a>.</p>
<p>The name "OASIS" is a trademark of <a href="https://www.oasis-open.org/">OASIS</a>, the owner and developer of this specification, and should be used only to refer to the organization and its official outputs.</p>
<p>For complete copyright information please see the Notices section in an Appendix below.</p>
<hr />
<h1 id="table-of-contents">Table of Contents</h1>
<ul type="none">
<li><a href="#1-introduction">1 Introduction</a>
<ul type="none">
<li><a href="#11-changes-from-earlier-versions">1.1 Changes from Earlier Versions</a></li>
<li><a href="#12-glossary">1.2 Glossary</a>
<ul type="none">
<li><a href="#121-definitions-of-terms">1.2.1 Definitions of terms</a></li>
<li><a href="#122-acronyms-and-abbreviations">1.2.2 Acronyms and abbreviations</a></li>
<li><a href="#123-document-conventions">1.2.3 Document conventions</a>
<ul type="none">
<li><a href="#1231-naming-conventions">1.2.3.1 Naming Conventions</a></li>
<li><a href="#1232-font-colors-and-style">1.2.3.2 Font Colors and Style</a></li>
<li><a href="#1233-mqtt-data-representation">1.2.3.3 MQTT Data Representation</a></li>
</ul></li>
</ul></li>
</ul></li>
<li><a href="#2-operating-model">2 Operating Model</a>
<ul type="none">
<li><a href="#21-publishers-subscribers-and-brokers">2.1 Publishers, Subscribers, and Brokers</a></li>
<li><a href="#22-default-topic-structure">2.2 Default Topic Structure</a>
<ul type="none">
<li><a href="#table-2-1-default-topic-structure">Table 2-1: Default Topic Structure</a></li>
</ul></li>
<li><a href="#23-subscriptions-options">2.3 Subscriptions Options</a></li>
<li><a href="#24-openc2-message-format">2.4 OpenC2 Message Format</a>
<ul type="none">
<li><a href="#241--content-type-and-serialization">2.4.1 Content Type and Serialization</a></li>
<li><a href="#242-openc2-message-structure">2.4.2 OpenC2 Message Structure</a></li>
</ul></li>
<li><a href="#25-quality-of-service">2.5 Quality of Service</a></li>
<li><a href="#26-mqtt-client-identifier">2.6 MQTT Client Identifier</a></li>
<li><a href="#27-keep-alive-interval">2.7 Keep-Alive Interval</a></li>
<li><a href="#28--will-message">2.8 Will Message</a></li>
<li><a href="#29-clean-start-flag">2.9 Clean Start Flag</a>
<ul type="none">
<li><a href="#table-2-2-clean-start-and-session-expiry">Table 2-2: Clean Start and Session Expiry</a></li>
</ul></li>
<li><a href="#210-session-expiry-and-message-expiry-intervals">2.10 Session Expiry and Message Expiry Intervals</a></li>
</ul></li>
<li><a href="#3-protocol-mapping">3 Protocol Mapping</a>
<ul type="none">
<li><a href="#31-connect-control-packet">3.1 CONNECT Control Packet</a></li>
<li><a href="#32-publish-control-packet">3.2 PUBLISH Control Packet</a></li>
<li><a href="#33-subscribe-control-packet">3.3 SUBSCRIBE Control Packet</a></li>
<li><a href="#34-pingreq-control-packet">3.4 PINGREQ Control Packet</a></li>
<li><a href="#35-other-control-packets">3.5 Other Control Packets</a></li>
</ul></li>
<li><a href="#4-conformance">4 Conformance</a></li>
<li><a href="#appendix-a-references">Appendix A: References</a>
<ul type="none">
<li><a href="#a1-normative-references">A.1 Normative References</a></li>
<li><a href="#a2-informative-references">A.2 Informative References</a></li>
</ul></li>
<li><a href="#appendix-b-safety-security-and-privacy-considerations">Appendix B. Safety, Security and Privacy Considerations</a></li>
<li><a href="#appendix-c-acknowledgments">Appendix C: Acknowledgments</a>
<ul type="none">
<li><a href="#c1-special-thanks">C.1 Special Thanks</a></li>
<li><a href="#c2-participants">C.2 Participants</a></li>
</ul></li>
<li><a href="#appendix-d-revision-history">Appendix D: Revision History</a></li>
<li><a href="#appendix-e-examples">Appendix E: Examples</a>
<ul type="none">
<li><a href="#figure-e-1-color-code-for-packet-examples">Figure E-1: Color Code for Packet Examples</a></li>
<li><a href="#e1-example-1-connect-and-subscribe">E.1 Example 1: Connect and Subscribe</a>
<ul type="none">
<li><a href="#figure-e-2-connect-and-subscribe">Figure E-2: Connect and Subscribe</a></li>
</ul></li>
<li><a href="#e2--example-2-command--response-exchange">E.2 Example 2: Command / Response Exchange</a>
<ul type="none">
<li><a href="#figure-e-3-publish-request-and-response">Figure E-3: Publish Request and Response</a></li>
</ul></li>
<li><a href="#e3-example-3-query-consumer-actuator-profiles">E.3 Example 3: Query Consumer Actuator Profiles</a></li>
<li><a href="#e4-openc2-deny-example">E.4 OpenC2 Deny Example</a></li>
<li><a href="#e5-paho-python-client-examples">E.5 Paho Python Client Examples</a></li>
</ul></li>
<li><a href="#appendix-f-notices">Appendix F: Notices</a></li>
</ul>
<hr />
<h1 id="1-introduction">1 Introduction</h1>
<p><em>This section is non-normative.</em></p>
<p>OpenC2 is a suite of specifications that enables command and control of cyber defense systems and components. OpenC2 typically uses a request-response paradigm where a request (i.e., command) is encoded by an OpenC2 Producer (managing application) and transferred to one or more OpenC2 Consumers (managed devices or virtualized functions) using a secure transfer protocol. The Consumers act on the request and respond with status and any other requested information.</p>
<p>This specification describes OpenC2's use of the MQTT publish / subscribe messaging protocol to exchange OpenC2 messages between Producers and Consumers. Version 5 of the MQTT Specification [<a href="#mqtt-v50">MQTT-v5.0</a>] is used as it includes features useful for OpenC2 that are not available in the previous version [<a href="#mqtt-v311">MQTT v3.1.1</a>].</p>
<h2 id="11-changes-from-earlier-versions">1.1 Changes from Earlier Versions</h2>
<p>The following changes have been implemented since WD08:</p>
<ul>
<li>Simplified presentation of protocol requirements in Section 3</li>
<li>Added example illustrating use of paho python MQTT client</li>
<li>Enhanced example graphics to highlight requirements from this specification</li>
<li>Added conformance section</li>
<li>Added prohibition against use of MQTT <code>Response Topic</code> feature</li>
<li>Updated message format to align with current OpenC2 Language Specification</li>
</ul>
<h2 id="12-glossary">1.2 Glossary</h2>
<h3 id="121-definitions-of-terms">1.2.1 Definitions of terms</h3>
<p>The terms defined in Section 1.2, <em>Terminology</em>, of the MQTT v5.0 specification [<a href="#mqtt-v50">MQTT-v5.0</a>] are applicable to this specification.</p>
<p>The following terms defined in Section 1.2, <em>Terminology</em>, of the OpenC2 Language Specification [<a href="#openc2-lang-v10">OpenC2-Lang-v1.0</a>] are applicable to this specification:</p>
<ul>
<li><strong>Command</strong>: A message defined by an action-target pair that is sent from a Producer and received by a Consumer.</li>
<li><strong>Consumer</strong>: A managed device / application that receives Commands. Note that a single device / application can have both Consumer and Producer capabilities.</li>
<li><strong>Message</strong>: A content- and transport-independent set of elements conveyed between Consumers and Producers.</li>
<li><strong>Producer</strong>: A manager application that sends Commands.</li>
<li><strong>Response</strong>: A message from a Consumer to a Producer acknowledging a command or returning the requested resources or status to a previously received request.</li>
</ul>
<h3 id="122-acronyms-and-abbreviations">1.2.2 Acronyms and abbreviations</h3>
<table>
<thead>
<tr class="header">
<th style="text-align: center;">Acronym</th>
<th style="text-align: left;">Meaning</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: center;">AKA</td>
<td style="text-align: left;">Also Known As</td>
</tr>
<tr class="even">
<td style="text-align: center;">AP</td>
<td style="text-align: left;">Actuator Profile</td>
</tr>
<tr class="odd">
<td style="text-align: center;">JSON</td>
<td style="text-align: left;">JavaScript Object Notation</td>
</tr>
<tr class="even">
<td style="text-align: center;">MQTT</td>
<td style="text-align: left;">Message Queuing Telemetry Transport</td>
</tr>
<tr class="odd">
<td style="text-align: center;">RFC</td>
<td style="text-align: left;">Request For Comment</td>
</tr>
</tbody>
</table>
<h3 id="123-document-conventions">1.2.3 Document conventions</h3>
<h4 id="1231-naming-conventions">1.2.3.1 Naming Conventions</h4>
<ul>
<li>All MQTT control packet names are in ALL CAPS (e.g., CONNECT, PINGREQ)</li>
<li>All MQTT property names are in Initial Cap and use a fixed-width font (e.g., <code>User Property</code>).</li>
</ul>
<h4 id="1232-font-colors-and-style">1.2.3.2 Font Colors and Style</h4>
<p>The following color, font and font style conventions are used in this document:</p>
<ul>
<li>A <code>fixed-width font</code> is used for all type names, property names, and literals.</li>
</ul>
<h4 id="1233-mqtt-data-representation">1.2.3.3 MQTT Data Representation</h4>
<p>Section 1.5 of the MQTT v5.0 specification [<a href="#mqtt-v50">MQTT-v5.0</a>] defines data types relevant to the protocol. Implementations of this specification are assumed to encode and decode those data types as defined in the MQTT specification.</p>
<p>In this specification, the UTF-8 String Pair data type ([<a href="#mqtt-v50">MQTT-v5.0</a>], section 1.5.7) is of particular interest, as MQTT v5.0 User Properties are utilized. Within this document, the representation for a UTF-8 String Pair User Property is <code>"key":"value"</code>.</p>
<p>Per the MQTT specification sections 1.5.4 and 1.5.7 each string is encoded with a 2-byte length followed by the UTF-8 encoding of the string, so the general form of a User Property as a UTF-8 String Pair is:</p>
<ul>
<li>1-byte identifier for User Property <code>[0x26]</code></li>
<li>2-byte length of first string</li>
<li>UTF-8 encoding of first string</li>
<li>2-byte length of second string</li>
<li>UTF-8 encoding of second string</li>
</ul>
<p>For the "key:value" example above, the encoding would be:</p>
<pre><code>[0x26][0x00][0x03]key[0x00][0x05]value
</code></pre>
<hr />
<h1 id="2-operating-model">2 Operating Model</h1>
<p><em>This section is non-normative in its entirety.</em></p>
<p>This section provides an overview of the approach to employing MQTT as a message transfer protocol for OpenC2 messages.</p>
<h2 id="21-publishers-subscribers-and-brokers">2.1 Publishers, Subscribers, and Brokers</h2>
<p>When transferring OpenC2 Request (AKA command) and Response messages via MQTT, both Producers and Consumers act as both publishers and subscribers:</p>
<ul>
<li>Producers publish Requests and subscribe to receive Responses</li>
<li>Consumers subscribe to receive Requests and publish Responses</li>
</ul>
<p>The MQTT client software used by Producers and Consumers and all MQTT brokers used for OpenC2 message transfer are beyond the scope of this specification, but are assumed to be conformant with the MQTT v5.0 specification [<a href="#mqtt-v50">MQTT-v5.0</a>]. In the context of OpenC2, and in accordance with the Terminology section (1.2) of [<a href="#mqtt-v50">MQTT-V5.0</a>]:</p>
<ul>
<li>MQTT Brokers are Servers</li>
<li>OpenC2 Producers and Consumer are Clients</li>
</ul>
<p>Brokers facilitate the transfer of OpenC2 messages but in their role as Brokers do not act in any OpenC2 role.</p>
<h2 id="22-default-topic-structure">2.2 Default Topic Structure</h2>
<p>The MQTT topic structure described in Table 2-1 is used to exchange OpenC2 messages. The "oc2" prefix on the topic names segregates OpenC2-related topics from other topics that might exist on the same broker. Topic name components in brackets (e.g., <code>[actuator_profile]</code>) are placeholders for specific values that would be used in implementation. For example, a device that implements the Stateless Packeting Filter AP would subscribe to <code>oc2/cmd/ap/slpf</code>. In addition, each Consumer subscribes to its own device-specific topic using a device identifier (annotated as <code>[device_id]</code>) that is assumed to be known to the OpenC2 Producer(s) that can command that Consumer. The determination of device identifiers is beyond the scope of this specification.</p>
<h4 id="table-2-1-default-topic-structure">Table 2-1: Default Topic Structure</h4>
<table>
<thead>
<tr class="header">
<th>Topic</th>
<th>Purpose</th>
<th style="text-align: center;">Producer</th>
<th style="text-align: center;">Consumer</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>oc2/cmd/all</code></td>
<td>Used to send OpenC2 commands to all devices connected to this MQTT fabric.</td>
<td style="text-align: center;">Pub</td>
<td style="text-align: center;">Sub</td>
</tr>
<tr class="even">
<td><code>oc2/cmd/ap/[actuator_profile]</code></td>
<td>Used to send OpenC2 commands to all instances of specified Actuator Profile.</td>
<td style="text-align: center;">Pub</td>
<td style="text-align: center;">Sub</td>
</tr>
<tr class="odd">
<td><code>oc2/cmd/device/[device_id]</code></td>
<td>Used to send OpenC2 commands to a specific device. Routing to APs within the device is a local matter.</td>
<td style="text-align: center;">Pub</td>
<td style="text-align: center;">Sub</td>
</tr>
<tr class="even">
<td><code>oc2/rsp</code></td>
<td>Used to return OpenC2 response messages.</td>
<td style="text-align: center;">Sub</td>
<td style="text-align: center;">Pub</td>
</tr>
<tr class="odd">
<td><code>oc2/rsp/[producer_id]</code></td>
<td>Used to return OpenC2 response messages to a specific producer.</td>
<td style="text-align: center;">Sub</td>
<td style="text-align: center;">Pub</td>
</tr>
</tbody>
</table>
<p>In order to receive commands intended for its security functions, a Consumer device connected to the broker would subscribe using the following topic filters:</p>
<ul>
<li><code>oc2/cmd/all</code> to receive commands intended for all devices</li>
<li><code>oc2/cmd/ap/[acutator_profile]</code> for all actuator profiles the device implements</li>
<li><code>oc2/cmd/device/[device_id]</code> for that device's ID</li>
</ul>
<p>In order to receive responses to the commands it sends, a Producer connected to the broker would subscribe using the following topic filters:</p>
<ul>
<li><code>oc2/rsp</code></li>
<li><code>oc2/rsp/[producer_id]</code></li>
</ul>
<p>A Producer subscribing to <code>oc2/rsp/#</code> would receive all response messages published through the broker to any specific <code>[producer-id]</code>, regardless of whether the response was to a command originated by the subscribing producer.</p>
<p>The inclusion of predefined response topics in the default topic scheme eliminates any need for an OpenC2 Producer to use the PUBLISH control packet's <code>Response Topic</code> header (described in <a href="#mqtt-v50">MQTTv5</a> sections 3.3.2.3.5 and 4.10) to inform Consumers where to direct reply messages. The <code>Response Topic</code> field is not used for OpenC2 messaging over MQTT.</p>
<p>Topic wildcards are not normally utilized for OpenC2 but their use is not precluded. For example, implementers of OpenC2 Consumers might elect to use a wildcard to subscribe to the command topics for all actuator profiles (<code>oc2/cmd/ap/#</code>) and filter received messages at the Consumer to identify relevant messages. An OpenC2 traffic logger might subscribe to <code>oc2/#</code>.</p>
<hr />
<p><strong>Non-normative Subscription Example</strong></p>
<p>A notional OpenC2 Consumer that implements actuator profiles <code>alpha</code> and <code>iota</code> and has a device identifier of <code>zulu</code> would subscribe using the following topic filters:</p>
<ul>
<li><code>oc2/cmd/all</code></li>
<li><code>oc2/cmd/ap/alpha</code></li>
<li><code>oc2/cmd/ap/iota</code></li>
<li><code>oc2/cmd/device/zulu</code></li>
</ul>
<p>A notional OpenC2 Producer with a device identifier of <code>omega</code> would subscribe using the following topic filters:</p>
<ul>
<li><code>oc2/rsp</code></li>
<li><code>oc2/rsp/omega</code></li>
</ul>
<p><strong>Non-normative Publishing Examples</strong></p>
<p>Under typical circumstances, the publishing of OpenC2 commands is either a 1:<em>n</em> situation (one Producer commanding multiple Consumers) or a 1:1 situation (one Producer commands a specific Consumer). The publishing of responses represents the reverse situation, where responses published by potentially numerous Consumers are all directed to a single Producer.</p>
<p>A notional OpenC2 Producer wishing to command all Consumers that implement actuator profile <code>iota</code> would publish the command to:</p>
<ul>
<li><code>oc2/cmd/ap/iota</code></li>
</ul>
<p>A notional OpenC2 Producer wishing to command the individual Consumer with identity <code>zulu</code> would publish the command to:</p>
<ul>
<li><code>oc2/cmd/device/zulu</code></li>
</ul>
<p>Additional examples of publishing exchanges can be found in <a href="#appendix-e-examples">Appendix E</a>.</p>
<h2 id="23-subscriptions-options">2.3 Subscriptions Options</h2>
<p>For each <code>Topic Filter</code> in the SUBSCRIBE control packet the Client specifies a set of <code>Subscription Options</code> (<a href="#mqtt-v50">MQTT-V5.0</a> specification section 3.8.3.1). The available options are:</p>
<ul>
<li><code>Maximum QoS</code>: the maximum QoS level at which the Server can send Application Messages to the Client</li>
<li><code>No Local</code>: controls whether messages the Client publishes to this topic are published back to them</li>
<li><code>Retain as Published</code>: Controls the setting of the <code>retain</code> flag in messages forwarded under this subscription</li>
<li><code>Retain Handling</code>: Specifies how retained messages present on the Broker when the subscription is established are handled</li>
</ul>
<p>The following values are recommended for <code>Subscription Options</code> for OpenC2 applications:</p>
<ul>
<li><code>Maximum QoS</code>: 2 -- allow the publisher to set the QoS level of the message</li>
<li><code>No Local</code>: 1 -- do not receive back messages published by this Client on this topic</li>
<li><code>Retain as Published</code>: 1 -- respect the publisher's retain setting value when forwarding messages</li>
<li><code>Retain Handling</code>: 0 -- broker should send any retained messages when the subscription is established</li>
</ul>
<h2 id="24-openc2-message-format">2.4 OpenC2 Message Format</h2>
<p>This section describes how OpenC2 messages are represented in MQTT PUBLISH control packets.</p>
<h3 id="241-content-type-and-serialization">2.4.1 Content Type and Serialization</h3>
<p>OpenC2 messages are conveyed in the payload of MQTT PUBLISH control packets. As described in the <a href="#mqtt-v50">MQTT-V5.0</a> specification section 3.3.3: "the content and format of the data is application specific" and therefore meaningless to the Broker. OpenC2 uses the following MQTT PUBLISH control packet properties to convey essential information about the message to the recipient:</p>
<ul>
<li><p><code>Payload Format Indicator [Property 0x01]</code>: This property is used to distinguish binary vs. UTF-8 encoded strings for the payload format, as specified in section 3.3.2.3.2 of the MQTT specification, and should be set as appropriate for the message serialization used.</p></li>
<li><p><code>Content Type [Property 0x03]</code>: a UTF-8 Encoded String describing the content of the Application Message. For OpenC2 messages, the string <code>"application/openc2"</code> is used.</p></li>
<li><p><code>User Property [Property 0x26]</code>: two User Properties (UTF-8 string pairs) are defined to further specify the message format:</p>
<ul>
<li>Key: <code>"msgType"</code>: a UTF-8 string used to identify the type of OpenC2 message, as described in section 3.2 of the OpenC2 Language Specification. Legal values are:
<ul>
<li><code>"req"</code> (request),</li>
<li><code>"rsp"</code> (response), or</li>
<li><code>"ntf"</code> (notification)</li>
</ul></li>
<li>Key: <code>"encoding"</code>: a UTF-8 string used to identify the specific text or binary encoding of the message. Legal values are:
<ul>
<li><code>"json"</code>, and</li>
<li><code>"cbor"</code></li>
</ul></li>
</ul></li>
</ul>
<p>The specifics of serializing OpenC2 messages are defined in other OpenC2 specifications.</p>
<h3 id="242-openc2-message-structure">2.4.2 OpenC2 Message Structure</h3>
<p>OpenC2 messages transferred using MQTT utilize the <code>OpcenC2-Message</code> structure defined in Section 3.2 of <a href="#openc2-lang-v10">OpenC2-Lang-v1.0</a>.</p>
<pre><code>Message = Record
1 headers Headers optional
2 body Body
3 signature String optional
Headers = Map{1..*}
1 request_id String optional
2 created ls:Date-Time optional
3 from String optional
4 to String [0..*]
Body = Choice
1 openc2 OpenC2-Content
OpenC2-Content = Choice
1 request OpenC2-Command
2 response OpenC2-Response
3 notification OpenC2-Event
</code></pre>
<p>A Producer sending an OpenC2 request <em>always</em> includes its identifier in the message headers <code>from</code> field, allowing receiving Consumers to know the origin of the request. A Consumer sending a response to an OpenC2 request <em>always</em> includes its identifier in the message headers <code>from</code> field, allowing responses to the same request from different Consumers to be identified by the Producer receiving the responses.</p>
<p>When publishing an OpenC2 request, the Producer can use the message headers <code>to</code> field as a filter to provide finer-grained control over which Consumers should process any particular message than is provided by the MQTT Topic Structure and Client topic subscriptions. Consumers have no requirement to populate the message headers <code>to</code> field.</p>
<h2 id="25-quality-of-service">2.5 Quality of Service</h2>
<p><a href="#mqtt-v50">MQTT-v5.0</a> Section 4.3, <em>Quality of Service Levels and Protocol Flows</em>, defines three quality of service (QoS) levels:</p>
<ul>
<li><strong>QoS 0: "At most once"</strong>, where messages are delivered according to the best efforts of the operating environment. Message loss can occur.</li>
<li><strong>QoS 1: "At least once"</strong>, where messages are assured to arrive but duplicates can occur.</li>
<li><strong>QoS 2: "Exactly once"</strong>, where message are assured to arrive exactly once.</li>
</ul>
<p>QoS 1 is appropriate for most OpenC2 applications and should be specified as the default. Implementers have the option of electing to use QoS 2 where the additional overhead is justified by application requirements. QoS 0 is not recommended for use in OpenC2 messaging.</p>
<p>In accordance with the above, the requirements of <a href="#mqtt-v50">MQTT-v5.0</a> Section 4.3.2, <em>QoS 1: At least once delivery</em>, apply to OpenC2 Producers and Consumers when publishing messages to the MQTT broker.</p>
<p>As described in <a href="#mqtt-v50">MQTT-v5.0</a> Section 4.6, <em>Message Ordering</em>, the use of QoS 1 assures that "the final copy of each message received by the subscribers will be in the order that they were published" but does not preclude the possibility of duplicate message delivery. OpenC2 Producers and Consumers implementations should be prepared to respond sensibly if duplicate requests or responses are received.</p>
<h2 id="26-mqtt-client-identifier">2.6 MQTT Client Identifier</h2>
<p>As described in <a href="#mqtt-v50">MQTT-v5.0</a>, Section 3.1, <em>CONNECT – Connection Request</em>, the Client Identifier (<code>ClientID</code>) is a required field in the CONNECT control packet. Further requirements are contained in Section 3.1.3.1, <em>Client Identifier (ClientID)</em>, which defines the <code>ClientID</code> as a UTF-8 string between 1 and 23 bytes long containing only letters and numbers (MQTT servers may accept longer <code>ClientIDs</code>). The MQTT specification also permits brokers to accept CONNECT control packets without a <code>ClientID</code>, in which case the broker assigns its own <code>ClientID</code> to the connection, which the client is obligated to use. <a href="#mqtt-v50">MQTT-v5.0</a> provides no further definition regarding the format or assignment of <code>ClientIDs</code>.</p>
<p>The <code>ClientID</code> serves to identify the client to the broker so that the broker can maintain state information about the client. The <code>ClientID</code> has no meaning in the context of OpenC2, it is only meaningful to the MQTT client and broker involved in the connection.</p>
<p>OpenC2 Producers and Consumers using MQTT for message transfer should generate and store a random <code>ClientID</code> value that meets the constraints specified in <a href="#mqtt-v50">MQTT-v5.0</a> Section 3.1.3.1, and retain that value for use when establishing connections to a broker. This <code>ClientID</code> should be generated prior to any connection to an MQTT broker, potentially as part of an initialization process. The <code>ClientID</code> for an OpenC2 Consumer is not required to have any meaningful relationship to any identity by which a Producer identifies that Consumer in OpenC2 messages.</p>
<p>As described in <a href="#mqtt-v50">MQTT-v5.0</a> Section 3.1.3.1, if a broker receives a CONNECT control packet with a zero-byte-length ClientID, the broker must generate a ClientID and return it to the connecting client in the associated CONNACK packet for the client's use. When using MQTT to transfer OpenC2 messages, the preferred behavior is for the client supporting the OpenC2 Producer or Consumer to generate its own ClientID.</p>
<h2 id="27-keep-alive-interval">2.7 Keep-Alive Interval</h2>
<p>The MQTT CONNECT control packet includes a <code>Keep Alive</code> property (<a href="#mqtt-v50">MQTT-v5.0</a> section 3.1.2.10) that defines a time interval within which a Client connected to a Broker is expected to send a control packet of any type to the Broker to prevent the Broker from disconnecting from the Client. The PINGREQ control packet can be sent if the Client has no other traffic to process. The MQTT specification notes that "The actual value of the Keep Alive is application specific; typically this is a few minutes. The maximum value is 18 hours 12 minutes and 15 seconds." Per the MQTT specification the Broker will close the network connection if 1.5 times the <code>Keep Alive</code> interval has passed without receiving a control packet from the Client.</p>
<p>This transfer specification leaves the selection of a <code>Keep Alive</code> interval to the implementer but defines a value of 5 minutes (300 seconds) as the maximum value for <em>conformant</em> implementations. For reliability, it is recommended that an OpenC2 client send an MQTT PINGREQ when 95% of the <code>Keep Alive</code> interval has expired without any other control packets being exchanged.</p>
<h2 id="28-will-message">2.8 Will Message</h2>
<p>The CONNECT control packet, described in <a href="#mqtt-v50">MQTT-v5.0</a>, Section 3.1, provides a <code>Will Message</code> feature that enables connected clients to store a message on the broker to be published to a client-specified topic when the client's network connection is closed. OpenC2 does not use the MQTT <code>Will Message</code> feature.</p>
<h2 id="29-clean-start-flag">2.9 Clean Start Flag</h2>
<p>As described in <a href="#mqtt-v50">MQTT-v5.0</a>, section 3.1.2.4, <em>Clean Start</em>, the MQTT CONNECT control packet includes a flag, <code>Clean Start</code>, that tells the broker whether the client, identified by its ClientID as described in <a href="#26-mqtt-client-identifier">Section 2.6</a>, desires a new session (<code>Clean Start</code> equals <code>1</code> [<em>true</em>]). In MQTT the setting of the <code>Clean Start</code> flag and the value of the <code>Session Expiry Interval</code> from the most recent CONNECT packet are relevant to how the broker handles client state. The behavior is summarized in Table 2-2.</p>
<h4 id="table-2-2-clean-start-and-session-expiry">Table 2-2: Clean Start and Session Expiry</h4>
<table border="4 px">
<thead>
<tr>
<th></th>
<th></th>
<th colspan="2" align="center">Session Expiry Interval Exceeded</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
<td align="center"><b>Yes</b></td>
<td align="center"><b>No</b></td>
</tr>
<tr>
<td rowspan="2" align="center"><b>Clean<br>Start<br>Flag</b></td>
<td>True (1)</td>
<td><ul>
<li>No prior state to discard<li>New subscriptions required
</ul></td>
<td><ul><li>Prior state discarded<li>New subscriptions required</ul></td>
</tr>
<tr>
<td>False (0)</td>
<td><ul><li>No prior state to discard<li>New subscriptions required</ul></td>
<td><ul><li>Prior state retained<li>Previous subscriptions retained<li>Buffered messages delivered</td>
</tr>
</tbody>
</table>
<p>OpenC2 clients should <em>not</em> request a clean start when connecting to the broker. The use of <code>Clean Start</code> = <code>false</code> allows the broker to retain the client's subscriptions, and deliver buffered messages that have accumulated while the client was disconnected. However, OpenC2 implementers using MQTT should be aware that MQTT broker resource constraints and <code>Message Expiry Interval</code> settings from Producers may cause older traffic to be discarded if clients are disconnected for extended periods.</p>
<h2 id="210-session-expiry-and-message-expiry-intervals">2.10 Session Expiry and Message Expiry Intervals</h2>
<p>The MQTT v5.0 CONNECT control packet includes a <code>Session Expiry Interval</code> property that informs the broker how long the Client's session state is to be retained when the session is disconnected. The MQTT v5.0 PUBLISH control packet includes a <code>Message Expiry Interval</code> property that specifies the lifetime of the Application Message in seconds. This transfer specification makes no recommendations regarding appropriate values for either expiry interval. Implementers are encouraged to evaluate their use cases to define reasonable values for these properties.</p>
<hr />
<h1 id="3-protocol-mapping">3 Protocol Mapping</h1>
<p>This section defines specific requirements for populating MQTT control packets. Values for fields and properties not specified herein are to be populated as defined in the <a href="#mqtt-v50">MQTT v5.0</a> specification, or as determined by the implementer where applicable.</p>
<h2 id="31-connect-control-packet">3.1 CONNECT Control Packet</h2>
<p>OpenC2 Producers and Consumers MUST create and transmit the CONNECT control packet, as specified in the <a href="#mqtt-v50">MQTT v5.0</a> specification section 3.1, to establish a connection to the MQTT Broker.</p>
<p>OpenC2 Producers and Consumers MUST populate the following CONNECT control packet fields as specified:</p>
<ul>
<li><code>Clean Start</code> = FALSE</li>
<li><code>Will Flag</code> = FALSE</li>
<li><code>Will QoS</code> = 0 (zero)</li>
<li><code>Will Retain</code> = FALSE</li>
<li><code>Keep Alive</code> = Number <= 300 (seconds)</li>
<li><code>Client Identifier</code> = client-generated identifier string</li>
</ul>
<p>OpenC2 Producers and Consumers MUST NOT populate any of the CONNECT payload fields related to the MQTT <code>Will Message</code>.</p>
<p>This specification makes no recommendations regarding values for the following CONNECT properties:</p>
<ul>
<li><code>Authentication Method</code></li>
<li><code>Authentication Data</code></li>
<li><code>Request Problem Information</code></li>
<li><code>Receive Maximum</code></li>
<li><code>Session Expiry</code></li>
<li><code>Topic Alias Maximum</code></li>
<li><code>Maximum Packet Size</code></li>
<li><code>Username flag</code></li>
<li><code>Password flag</code></li>
</ul>
<h2 id="32-publish-control-packet">3.2 PUBLISH Control Packet</h2>
<p>OpenC2 Producers and Consumers MUST create and transmit the PUBLISH control packet, as specified in the <a href="#mqtt-v50">MQTT v5.0</a> specification section 3.3, to publish messages using the MQTT broker.</p>
<p>Topic selection for publishing OpenC2 request and response messages MUST apply the default topic structure principles described in <a href="#22-default-topic-structure">Section 2.2</a> of this specification.</p>
<p>OpenC2 Producers and Consumers MUST populate the following PUBLISH control packet fields as specified:</p>
<ul>
<li><code>QoS</code> = <code>1</code> (minimum, 2 of so determined by the implementer)</li>
<li><code>Retain</code> = <code>0</code> (FALSE)</li>
<li><code>Payload Format Indicator</code>
<ul>
<li>for binary message encodings = <code>0</code></li>
<li>for UTF-8 message encodings = <code>1</code></li>
</ul></li>
<li>Content Type = <code>"application/openc2"</code></li>
<li>User Property for message type = <code>"msgType":[type]</code> where
<ul>
<li><code>[type]</code> = <code>"req"</code> when publishing OpenC2 requests</li>
<li><code>[type]</code> = <code>"rsp"</code> when publishing OpenC2 responses</li>
<li><code>[type]</code> = <code>"ntf"</code> when publishing OpenC2 notifications</li>
</ul></li>
<li>User Property for message encoding = <code>"encoding":[encoding]</code> where
<ul>
<li><code>[encoding]</code> = <code>"json"</code> for JSON-encoded messages using UTF-8</li>
<li><code>[encoding]</code> = <code>"cbor"</code> for CBOR-encoded binary messages</li>
</ul></li>
</ul>
<p>OpenC2 Producers and Consumers MUST populate the PUBLISH control packet payload with an OpenC2 message of type specified by the <code>"msgType":[type]</code> User Property, encoded as specified by the <code>"encoding":[encoding]</code> User Property.</p>
<p>OpenC2 Producers and Consumers MUST populate the <code>from:</code> field of the OpenC2 message with the identity of the publisher of the message, as described in <a href="#242-openc2-message-structure">Section 2.4.2</a>.</p>
<p>OpenC2 Producers MUST NOT use the MQTT PUBLISH control packet's <code>Response Topic</code> header when publishing OpenC2 request messages. OpenC2 Consumers MUST publish responses to the defined response topics described in <a href="#22-default-topic-structure">Section 2.2</a>.</p>
<blockquote>
<p>NOTE: the preceding prohibition applies only to the use of <code>Response Topic</code> in OpenC2 messaging and does not apply to other MQTT messaging by clients associated with OpenC2 Producers and Consumers.</p>
</blockquote>
<p>This specification makes no recommendations regarding values for the following PUBLISH control packet properties:</p>
<ul>
<li><code>Message Expiry Interval</code></li>
<li><code>Correlation Data</code></li>
<li><code>Subscription Identifier</code></li>
<li><code>Topic Alias</code></li>
</ul>
<h2 id="33-subscribe-control-packet">3.3 SUBSCRIBE Control Packet</h2>
<p>Producers and Consumers MUST use the SUBSCRIBE control packet, as specified in the <a href="#mqtt-v50">MQTT v5.0</a> specification section 3.8 to subscribe to a set of topics consistent with the default topic structure defined in <a href="#22-default-topic-structure">Section 2.2</a> of this specification. This means that:</p>
<ul>
<li>Consumers SHALL subscribe to
<ul>
<li>topics for all actuator profiles the Consumer implements,</li>
<li>the all-commands topic (<code>oc2/cmd/all</code>), and</li>
<li>an individual topic for that Consumer device (<code>oc2/cmd/device/[device_id]</code>).</li>
</ul></li>
<li>Producers SHALL subscribe to the general response topic (<code>oc2/rsp</code>).</li>
<li>Producers SHOULD subscribe to their individual response topic (<code>oc2/rsp/[producer_id]</code>)</li>
</ul>
<p>When subscribing to topics OpenC2 Producers and Consumers SHOULD populate subscription options for each topic as follows:</p>
<ul>
<li><code>Maximum QoS: 2</code></li>
<li><code>No Local: 1 (true)</code></li>
<li><code>Retain as Published: 1</code></li>
<li><code>Retain Handling: 0</code></li>
</ul>
<p>As defined in <a href="#25-quality-of-service">Section 2.5</a> of this specification, subscribers MUST specify a <code>Maximum QoS</code> level of at least <code>1</code> when subscribing to topics. Implementers SHOULD allow for a <code>Maximum QoS</code> of <code>2</code> if supported by their implementation. As noted in <a href="#25-quality-of-service">Section 2.5</a>, when messages are published with a QoS of <code>1</code> receiving clients should be prepared to handle the possibility of receiving duplicate messages.</p>
<p>This specification makes no recommendations regarding values for the following SUBSCRIBE properties:</p>
<ul>
<li><code>Subscription Identifier</code></li>
</ul>
<h2 id="34-pingreq-control-packet">3.4 PINGREQ Control Packet</h2>
<p>OpenC2 Producers and Consumers MUST send a PINGREQ control packet to all MQTT brokers with which they are connected if they have not processed any other control packets with 95% of the keep-alive interval defined by the implementer. If the implementer has not otherwise specified a keep-alive interval, 95% of the value specified in <a href="#27-keep-alive-interval">Section 2.7</a> of this specification shall be used.</p>
<h2 id="35-other-control-packets">3.5 Other Control Packets</h2>
<p>This specification makes no requirements or recommendations regarding the use of the following MQTT control packets:</p>
<ul>
<li>CONNACK</li>
<li>PUBACK</li>
<li>PUBREC</li>
<li>PUBREL</li>
<li>PUBCOMP</li>
<li>SUBACK</li>
<li>UNSUBSCRIBE</li>
<li>UNSUBACK</li>
<li>PINGRESP</li>
<li>DISCONNECT</li>
<li>AUTH</li>
</ul>
<p>As required OpenC2 Producers and Consumers MUST create and transmit or receive and process these control packets as specified in their respective sections of the <a href="#mqtt-v50">MQTTv5.0</a> specification.</p>
<hr />
<h1 id="4-conformance">4 Conformance</h1>
<p>An OpenC2 MQTT client conforms to this specification only if it satisfies all of the statements below:</p>
<ol>
<li>Satisfies the conformance requirements for an MQTT Client as defined in Section 7.1.2, <em>MQTT Client Conformance Clause</em>, of the <a href="#mqtt-v50">MQTTv5.0</a> specification.</li>
<li>Satisfies all of the MUST / SHALL requirements in <a href="#3-protocol-mapping">Section 3, <em>Protocol Mapping</em></a> of this specification.</li>
<li>Satisfies all of the MUST / SHALL requirements in <a href="#appendix-b-safety-security-and-privacy-considerations">Appendix B. <em>Safety, Security and Privacy Considerations</em></a> of this specification.</li>
</ol>
<hr />
<h1 id="appendix-a-references">Appendix A. References</h1>
<p>This appendix contains the normative and informative references that are used in this document. Normative references are specific (identified by date of publication and/or edition number or version number) and Informative references are either specific or non-specific.</p>
<p>While any hyperlinks included in this appendix were valid at the time of publication, OASIS cannot guarantee their long-term validity.</p>
<h2 id="a1-normative-references">A.1 Normative References</h2>
<p>The following documents are referenced in such a way that some or all of their content constitutes requirements of this document.</p>
<h6 id="rfc2119">[RFC2119]</h6>
<p>Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <a href="http://www.rfc-editor.org/info/rfc2119">http://www.rfc-editor.org/info/rfc2119</a>.</p>
<h6 id="rfc5246">[RFC5246]</h6>
<p>Dierks, T. and E. Rescorla, "The Transport Layer Security (TLS) Protocol Version 1.2", RFC 5246, DOI 10.17487/RFC5246, August 2008, <<a href="https://www.rfc-editor.org/info/rfc5246">https://www.rfc-editor.org/info/rfc5246</a>>.</p>
<h6 id="rfc7525">[RFC7525]</h6>
<p>Sheffer, Y., Holz, R., and P. Saint-Andre, "Recommendations for Secure Use of Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS)", BCP 195, RFC 7525, DOI 10.17487/RFC7525, May 2015, <a href="https://www.rfc-editor.org/info/rfc7525">https://www.rfc-editor.org/info/rfc7525</a>.</p>
<h6 id="rfc7540">[RFC7540]</h6>
<p>Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext Transfer Protocol Version 2 (HTTP/2)", RFC 7540, DOI 10.17487/RFC7540, May 2015, <a href="https://www.rfc-editor.org/info/rfc7540">https://www.rfc-editor.org/info/rfc7540</a>.</p>
<h6 id="rfc8174">[RFC8174]</h6>
<p>Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, <a href="http://www.rfc-editor.org/info/rfc8174">http://www.rfc-editor.org/info/rfc8174</a>.</p>
<h6 id="rfc8259">[RFC8259]</h6>
<p>Bray, T., ed., "The JavaScript Object Notation (JSON) Data Interchange Format", STD 90, RFC 8259, DOI 10.17487/RFC8259, December 2017, <a href="http://www.rfc-editor.org/info/rfc8259">http://www.rfc-editor.org/info/rfc8259</a></p>
<h6 id="rfc8446">[RFC8446]</h6>
<p>Rescorla, E., "The Transport Layer Security (TLS) Protocol Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018, <<a href="http://www.rfc-editor.org/info/rfc8446">http://www.rfc-editor.org/info/rfc8446</a>></p>
<h6 id="openc2-lang-v10">[OpenC2-Lang-v1.0]</h6>
<p><em>Open Command and Control (OpenC2) Language Specification Version 1.0</em>. Edited by Jason Romano and Duncan Sparrell. Latest version: <a href="https://docs.oasis-open.org/openc2/oc2ls/v1.0/oc2ls-v1.0.html">https://docs.oasis-open.org/openc2/oc2ls/v1.0/oc2ls-v1.0.html</a>.</p>
<h6 id="mqtt-v50">[mqtt-v5.0]</h6>
<p>MQTT Version 5.0. Edited by Andrew Banks, Ed Briggs, Ken Borgendale, and Rahul Gupta. 07 March 2019. OASIS Standard. <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html">https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html</a>. Latest version: <a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html">https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html</a>.</p>
<h2 id="a2-informative-references">A.2 Informative References</h2>
<h6 id="rfc3552">[RFC3552]</h6>
<p>Rescorla, E. and B. Korver, "Guidelines for Writing RFC Text on Security Considerations", BCP 72, RFC 3552, DOI 10.17487/RFC3552, July 2003, <a href="https://www.rfc-editor.org/info/rfc3552">https://www.rfc-editor.org/info/rfc3552</a>.</p>
<h6 id="iacd">[IACD]</h6>
<p>M. J. Herring, K. D. Willett, "Active Cyber Defense: A Vision for Real-Time Cyber Defense," Journal of Information Warfare, vol. 13, Issue 2, p. 80, April 2014.<br>Willett, Keith D., "Integrated Adaptive Cyberspace Defense: Secure Orchestration", International Command and Control Research and Technology Symposium, June 2015.</p>
<h6 id="mqtt-v311">[mqtt-v3.1.1]</h6>
<p>MQTT Version 3.1.1. Edited by Andrew Banks and Rahul Gupta. 29 October 2014. OASIS Standard. <a href="http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html">http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html</a>. Latest version: <a href="http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html">http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html</a>.</p>
<h6 id="openc2-slpf-v10">[OpenC2-SLPF-v1.0]</h6>
<p>Open Command and Control (OpenC2) Profile for Stateless Packet Filtering Version 1.0. Edited by Joe Brule, Duncan Sparrell and Alex Everett. 11 July 2019. Committee Specification 01. <a href="https://docs.oasis-open.org/openc2/oc2slpf/v1.0/cs01/oc2slpf-v1.0-cs01.html">https://docs.oasis-open.org/openc2/oc2slpf/v1.0/cs01/oc2slpf-v1.0-cs01.html</a>. Latest version: <a href="https://docs.oasis-open.org/openc2/oc2slpf/v1.0/oc2slpf-v1.0.html">https://docs.oasis-open.org/openc2/oc2slpf/v1.0/oc2slpf-v1.0.html</a>.</p>
<h6 id="sparkplug-b">[Sparkplug-B]</h6>
<p>Eclipse Foundation, "Sparkplug (TM) MQTT Topic & Payload Definition", Version 2.2, October 2019, <a href="https://www.eclipse.org/tahu/spec/Sparkplug%20Topic%20Namespace%20and%20State%20ManagementV2.2-with%20appendix%20B%20format%20-%20Eclipse.pdf">https://www.eclipse.org/tahu/spec/Sparkplug%20Topic%20Namespace%20and%20State%20ManagementV2.2-with%20appendix%20B%20format%20-%20Eclipse.pdf</a></p>
<h6 id="paho">[Paho]</h6>
<p>Eclipse Foundation Paho MQTT Client Library, <a href="https://www.eclipse.org/paho/">https://www.eclipse.org/paho/</a></p>
<hr />
<h1 id="appendix-b-safety-security-and-privacy-considerations">Appendix B. Safety, Security and Privacy Considerations</h1>
<p>For operational use transferring OpenC2 messages, all connections between OpenC2 endpoint (i.e., Producer and Consumer) MQTT clients and brokers MUST use Transport Layer Security (TLS). Endpoint MQTT clients and MQTT brokers used for OpenC2 messaging MUST support TLS version 1.2 [<a href="#rfc5246">RFC5246</a>] connections or higher for confidentiality, integrity, and authentication when sending OpenC2 Messages over MQTT, and SHOULD support TLS Version 1.3 [<a href="#rfc8446">RFC8446</a>] or higher connections.</p>
<p>OpenC2 endpoint MQTT clients and MQTT brokers MUST NOT support any version of TLS prior to v1.2 and MUST NOT support any version of Secure Sockets Layer (SSL).</p>
<p>The implementation and use of TLS SHOULD align with the best currently available security guidance, such as that provided in [<a href="#rfc7525">RFC7525</a>]/BCP 195.</p>
<p>The TLS session MUST use non-NULL ciphersuites for authentication, integrity, and confidentiality. Sessions MAY be renegotiated within these constraints.</p>
<p>OpenC2 endpoint MQTT clients supporting TLS v1.2 MUST NOT use any of the blacklisted ciphersuites identified in Appendix A of [<a href="#rfc7540">RFC7540</a>].</p>
<p>OpenC2 endpoint MQTT clients supporting TLS 1.3 MUST NOT implement zero round trip time resumption (0-RTT).</p>
<p>This specification recommends that the mechanisms available in MQTT v5.0 be given preference for implementing enhanced authentication of OpenC2 endpoints.</p>
<p>OpenC2 messaging over unsecured MQTT connections SHOULD be restricted to non-operational testing purposes.</p>
<hr />
<h1 id="appendix-c-acknowledgments">Appendix C. Acknowledgments</h1>
<h2 id="c1-special-thanks">C.1 Special Thanks</h2>
<p>The editor thanks the members of the Huntington-Ingalls Industries OpenC2 software team for their assistance with prototyping the capabilities defined in this specification:</p>
<ul>
<li>Jerome Czachor, Huntington-Ingalls Industries</li>
<li>Ha Ram Yoon, Huntington-Ingalls Industries</li>
<li>Mason Mirarchi, Praxis Engineering</li>
<li>Patrick Connole, Praxis Engineering</li>
</ul>
<h2 id="c2-participants">C.2 Participants</h2>
<p>The following OpenC2 TC members are acknowledged for providing comments, suggested text, and/or participation in CSD ballots or face-to-face meetings during the development of this specification:</p>
<ul>
<li>Michelle Barry, AT&T</li>
<li>Joe Brule, National Security Agency</li>
<li>Marco Caselli, Siemens AG</li>
<li>Toby Considine, University of North Carolina at Chapel Hill</li>
<li>Martin Evandt, University of Oslo</li>
<li>Alex Everett, University of North Carolina at Chapel Hill</li>
<li>David Girard, Trend Micro</li>
<li>John-Mark Gurney, Copado</li>
<li>Stephanie Hazlewood, IBM</li>
<li>Christian Hunt, Copado</li>
<li>Dan Johnson, sFractal Consulting LLC</li>
<li>David Kemp, National Security Agency</li>
<li>Anthony Librera, AT&T</li>
<li>Patrick Maroney, AT&T</li>
<li>Daniel Martinez, Huntington Ingalls Industries</li>
<li>Vasileios Mavroeidis, University of Oslo</li>
<li>Chris Ricard, Financial Services Information Sharing and Analysis Center (FS-ISAC)</li>
<li>Daniel Riedel, Copado</li>
<li>Michael Rosa, National Security Agency</li>
<li>Duane Skeen, Northrop Grumman</li>
<li>Calvin Smith, Northrop Grumman</li>
<li>Duncan Sparrell, sFractal Consulting LLC</li>
<li>Michael Stair, AT&T</li>
<li>Andrew Storms, Copado</li>
<li>Gerald Stueve, Fornetix</li>
<li>Bill Trost, AT&T</li>
<li>Drew Varner, NineFX, Inc.</li>
</ul>
<hr />
<h1 id="appendix-d-revision-history">Appendix D. Revision History</h1>
<table>
<thead>
<tr class="header">
<th style="text-align: left;">Revision</th>
<th style="text-align: left;">Date</th>
<th style="text-align: left;">Editor</th>
<th style="text-align: left;">Changes Made</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">WD01</td>
<td style="text-align: left;">2020-05-14</td>
<td style="text-align: left;">David Lemire</td>
<td style="text-align: left;">Initial working draft</td>
</tr>
<tr class="even">
<td style="text-align: left;">WD02</td>
<td style="text-align: left;">2020-06-02</td>
<td style="text-align: left;">David Lemire</td>
<td style="text-align: left;">Updates Operating Model section (2.0) and list of questions to be resolved.</td>
</tr>
<tr class="odd">
<td style="text-align: left;">WD03</td>
<td style="text-align: left;">2020-06-15</td>
<td style="text-align: left;">David Lemire</td>
<td style="text-align: left;">Further updates Operating Model section (2.0) and list of questions to be resolved. Initial presentation of example operating sequences and message. Presented as a CSD candidate at the 17 June 2020 TC meeting.</td>
</tr>
<tr class="even">
<td style="text-align: left;">WD03 / CSD01</td>
<td style="text-align: left;">2020-07-07</td>
<td style="text-align: left;">David Lemire</td>
<td style="text-align: left;">WD03 approved by OpenC2 TC as CSD01</td>
</tr>
<tr class="odd">
<td style="text-align: left;">WD04</td>
<td style="text-align: left;">2020-09-15</td>
<td style="text-align: left;">David Lemire</td>
<td style="text-align: left;">Further updates Operating Model section (2.0) and list of questions to be resolved. Updated presentation of example operating sequences and messages. Initial presentation of specifics for MQTT control packet types. Presented as a CSD candidate at the 16 September 2020 TC meeting.</td>
</tr>
<tr class="even">
<td style="text-align: left;">WD04 / CSD02</td>
<td style="text-align: left;">2020-09-24</td>
<td style="text-align: left;">David Lemire</td>
<td style="text-align: left;">WD04 approved as CSD02 by electronic ballot</td>
</tr>
<tr class="odd">
<td style="text-align: left;">WD05</td>
<td style="text-align: left;">2021-01-19</td>
<td style="text-align: left;">David Lemire</td>
<td style="text-align: left;">Specification updated to use MQTT v5.0 in place of MQTT v3.1.1.</td>
</tr>
<tr class="even">
<td style="text-align: left;">WD06</td>
<td style="text-align: left;">2021-02-08</td>
<td style="text-align: left;">David Lemire</td>
<td style="text-align: left;">Refinements from WD05. Candidate for CSD at February 2021 TC meeting. Was uploaded without updating revision history</td>
</tr>
<tr class="odd">
<td style="text-align: left;">WD07</td>
<td style="text-align: left;">2021-02-08</td>
<td style="text-align: left;">David Lemire</td>
<td style="text-align: left;">Revision History table and WD number updated.</td>
</tr>
<tr class="even">
<td style="text-align: left;">CSD03</td>
<td style="text-align: left;">2021-02-25</td>
<td style="text-align: left;">David Lemire</td>
<td style="text-align: left;">Publication of CSD03 based on WD07.</td>
</tr>
<tr class="odd">
<td style="text-align: left;">WD08</td>
<td style="text-align: left;">2021-04-15</td>
<td style="text-align: left;">David Lemire</td>
<td style="text-align: left;">Restructured to new OASIS template;<br> Added "DENY" example;<br> Remove unncessary level of indenture in Section 3;<br> Move topic wildcard discussion to Section 2.2;<br> Numerous small edits</td>
</tr>
<tr class="even">
<td style="text-align: left;">WD09</td>
<td style="text-align: left;">2021-08-13</td>
<td style="text-align: left;">David Lemire</td>
<td style="text-align: left;">Simplified presentation of protocol requirements in Section 3;<br>Added paho python client example;<br>Removed operating model working questions;<br>Enhanced example graphics to highlight requirements from this specification;<br>Added conformance section;<br>Added prohibition against use of MQTT <code>Response Topic</code> feature;<br>Populated Appendix C. Acknowledgments;<br> Numerous small edits and corrections</td>
</tr>
<tr class="odd">
<td style="text-align: left;">WD10</td>
<td style="text-align: left;">2021-10-13</td>
<td style="text-align: left;">David Lemire</td>
<td style="text-align: left;">Incorporates non-material changes based on public review comments for CSD04 (based on WD09).</td>
</tr>
</tbody>
</table>
<hr />
<h1 id="appendix-e-examples">Appendix E. Examples</h1>
<p><em>This appendix is non-normative in its entirety.</em></p>
<p>MQTT control packet examples in this appendix present packet contents relevant to the function(s) being illustrated but do not include all required control packet contents (e.g., computed length fields are not listed, bitmapped flags are written out to convey intent rather than presented as bitmaps). Packet examples use a color code to distinguish fields populated based on requirements contained in this specification from fields left to the implementer's discretion or based on requirements from the <a href="#mqtt-v50">MQTTv5.0</a> specification, as follows:</p>
<ul>
<li>Green background and <code>(r)</code> appended to the field name in control packet illustrations indicates the value for that field is <em>required</em>, based on MUST/SHALL requirements contained in this specification.</li>
<li>Yellow background and <code>(s)</code> appended to the field name in control packet illustrations indicates the value for that field is <em>suggested</em>, based on MAY/SHOULD requirements contained in this specification.</li>
<li>White background in control packet illustrations indicates that the value should be determined by the implementor, guided by the <a href="#mqtt-v50">MQTTv5.0</a> specification.</li>
</ul>
<p>This notation is illustrated in Figure E-1.</p>
<h4 id="figure-e-1-color-code-for-packet-examples">Figure E-1: Color Code for Packet Examples</h4>
<p><img src="./images/e0-color-code.png" alt="Color Code" /></p>
<p>The OpenC2 Language Specification defines the <code>from</code> and <code>to</code> fields in OpenC2 messages as strings containing "Authenticated identifier of the creator of or authority for execution of a message." No further definition is provided regarding the content of the <code>from</code> and <code>to</code> strings. The examples in this Appendix populate these fields with notional Producer and Consumer email addresses for convenience and readability.</p>
<p>The message format in the OpenC2 Language Specification includes a <code>request_id</code> used to distinguish messages, and the recommended content for the <code>request_id</code> is a UUID v4. The examples in this appendix use <code>uuid_x</code>, where <code>x</code> is a number, as a shorthand for actual UUIDs, which should be used in operation.</p>
<h2 id="e1-example-1-connect-and-subscribe">E.1 Example 1: Connect and Subscribe</h2>
<p>This example illustrates the message flows involved in the process of a Producer (i.e., an Orchestrator) and a Consumer each connecting to the MQTT broker as clients and subscribing to the appropriate channels for each, in accordance with the default topic model. The message flows are depicted in Figure E-2. The Producer is assigned the username <code>orch01</code>. The Consumer is assigned the username <code>zulu01</code> and supports the notional actuator profiles <code>alpha</code> and <code>iota</code>. No OpenC2-specific content appears in any of the messages required for this example.</p>
<p>This example illustrates the following aspects of the operating model:</p>
<ul>
<li>Client and broker roles, <a href="#21-publishers-subscribers-and-brokers">Section 2.1</a></li>
<li>Default topic structure, <a href="#22-default-topic-structure">Section 2.2</a></li>
<li>Subscription options settings, <a href="#23-subscriptions-options">Section 2.3</a></li>
<li>Randomly generated MQTT ClientID, <a href="#26-mqtt-client-identifier">Section 2.6</a></li>
<li>Recommended 5 minute keep-alive interval, <a href="#27-keep-alive-interval">Section 2.7</a></li>
<li>No use of MQTT "will" messages, <a href="#28--will-message">Section 2.8</a></li>
<li>Clean Start flag set to false, <a href="#29-clean-start-flag">Section 2.9</a></li>
<li>Optional use of username and password, <a href="#31-connect-control-packet">Section 3.1</a></li>
</ul>
<h4 id="figure-e-2-connect-and-subscribe">Figure E-2: Connect and Subscribe</h4>
<p><img src="./images/e1-seq-con_sub.png" alt="Connect and Subscribe Sequence" /></p>
<p>The Producer and Consumer CONNECT packets for this example are as follows; the optional username and password fields of the CONNECT packets are populated in this example:</p>
<p><img src="./images/e1-pkt-connect-packets.png" alt="Producer and Consumer Connect Cackets" /></p>
<p>The Consumer SUBSCRIBE and Broker SUBACK packets for this example are shown below; <code>Subscription Options</code> are populated as specified in <a href="#33-subscribe-control-packet">section 3.3</a> of this specification:</p>
<p><img src="./images/e1-pkt-sub-and-suback.png" alt="SUBSCRIBE and SUBACK" /></p>
<h2 id="e2-example-2-command--response-exchange">E.2 Example 2: Command / Response Exchange</h2>
<p>This example illustrates the message flows that occur for a notional but common process of an OpenC2 Producer publishing an OpenC2 request to multiple Consumers. The focus of this example is the use of MQTT PUBLISH and PUBACK control packets for the message flows. No meaningful OpenC2 content appears in any of the messages in this example.</p>
<p>In the example an OpenC2 Producer publishes a command to the channel for a notional actuator profile, <code>iota</code>. The example assumes the existence of two notional Consumers identified as <code>Xray</code> and <code>Zulu</code> that both implement the <code>iota</code> AP, and that both Consumers are subscribed to the corresponding command topic <code>oc2/cmd/ap/iota</code>. The example messages first show the exchange between the Producer publishing the Openc2 request and the MQTT broker. A similar exchange then occurs between the broker and every Consumer device subscribed to the <code>oc2/cmd/ap/iota</code> topic to distribute the command to the intended recipients. While the OpenC2 request in this example is only notional, the example assumes the <code>response_requested</code> argument is omitted from the request message so the consumers exhibit the OpenC2 default behavior of sending a complete response.</p>
<p>The command and response messages in the sequence diagram shown in Figure E-3 are published with a QoS of 1, which requires the recipient to respond to the PUBLISH packet with a PUBACK packet.</p>
<p>This example illustrates the following aspects of the operating model:</p>
<ul>
<li>Default topic structure, <a href="#22-default-topic-structure">Section 2.2</a></li>
<li>Properties to convey OpenC2 message type and serialization, <a href="#24-openc2-message-format">Section 2.4</a></li>
<li>Recommended use of QoS 1, <a href="#25-quality-of-service">Section 2.5</a></li>
<li>PUBLISH control packet flags, <a href="#33-publish-control-packet">Section 3.3</a></li>
</ul>
<h4 id="figure-e-3-publish-request-and-response">Figure E-3: Publish Request and Response</h4>
<p><img src="./images/e2-seq-req_rsp.png" alt="Basic Interaction Sequence" /></p>
<p>The PUBLISH and PUBACK control packets for the command portion of this example are illustrated below. The packet contents between the Producer and the Broker, and between the Broker and the Consumers are the same in each PUBLISH / PUBACK exchange, with the exception that the <code>packetId</code> field will differ for each of the three publishing exchanges in Figure E-3, as that value is assigned by the initiator of each exchange. The payload of <code>"(JSON-encoded openc2 request)"</code> is a placeholder for a meaningful OpenC2 request message.</p>
<p><img src="./images/e2-pkt-pub-and-puback.png" alt="PUBLISH and PUBACK" /></p>
<h2 id="e3-example-3-query-consumer-actuator-profiles">E.3 Example 3: Query Consumer Actuator Profiles</h2>
<p>This example illustrates the packaging of OpenC2 requests in MQTT PUBLISH control packets. The scenario is a request containing an OpenC2 <code>query</code> action sent over MQTT to retrieve the list of actuator profiles supported by a set of Consumers. This example includes three Consumers that implement several different actuator profiles, as follows:</p>
<ul>
<li>Consumer #1 implements the stateless packet filtering AP (<code>slpf</code>)</li>
<li>Consumer #2 implements the stateless packet filtering and intrusion detection system APs (<code>slpf</code> and <code>ids</code>)</li>
<li>Consumer #3 implements the endpoint detection and response and software bill of materials (SBOM) APs (<code>edr</code> and <code>sbom</code>)</li>
</ul>
<p><strong>NOTES:</strong></p>
<ol>
<li>No sequence diagram is included as the PUBLISH / PUBACK sequences among Producers, Consumers, and Brokers are similar to those illustrated in Example 2. This example only includes the PUBLISH control packets containing the OpenC2 request and response messages.</li>
<li>The <code>response_requested</code> argument is omitted from the <code>query</code> request message so the Consumers exhibit the default behavior of sending a complete response.</li>
</ol>
<p>This example illustrates the following aspects of the operating model:</p>
<ul>
<li>Default topic structure, <a href="#22-default-topic-structure">Section 2.2</a></li>
<li>Packaging of OpenC2 messages in PUBLISH control packet payloads, <a href="#24-openc2-message-format">Section 2.4</a></li>
<li>Properties to convey OpenC2 message type and serialization, <a href="#24-openc2-message-format">Section 2.4</a></li>
<li>Recommended use of QoS 1, <a href="#25-quality-of-service">Section 2.5</a></li>
<li>PUBLISH control packet flags, <a href="#32-publish-control-packet">Section 3.2</a></li>
</ul>
<p>The Producer initiates this process by publishing a <code>query</code> request to <code>oc2/cmd/all</code>. The OpenC2 request message contents and corresponding MQTT PUBLISH control packet are shown below, followed by the Consumer replies. The PUBLISH control packet fields and OpenC2 message content that varies among the packets is shown in red in the packet examples for clarity, and the JSON nessages in the control packet payloads use condensed formatting (white space minimized).</p>
<h3 id="query-action----producer-to-consumers">Query Action -- Producer to Consumers</h3>
<p>The following OpenC2 request message is published by the Producer and delivered to all Consumers subscribed to <code>oc2/cmd/all</code>.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode json"><code class="sourceCode json"><a class="sourceLine" id="cb3-1" title="1"><span class="fu">{</span></a>
<a class="sourceLine" id="cb3-2" title="2"> <span class="dt">"headers"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb3-3" title="3"> <span class="dt">"request_id"</span><span class="fu">:</span> <span class="st">"uuid_1"</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb3-4" title="4"> <span class="dt">"created"</span><span class="fu">:</span> <span class="dv">1610483630</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb3-5" title="5"> <span class="dt">"from"</span><span class="fu">:</span> <span class="st">"Producer1@example.com"</span></a>
<a class="sourceLine" id="cb3-6" title="6"> <span class="fu">},</span></a>
<a class="sourceLine" id="cb3-7" title="7"> <span class="dt">"body"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb3-8" title="8"> <span class="dt">"openc2"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb3-9" title="9"> <span class="dt">"request"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb3-10" title="10"> <span class="dt">"action"</span><span class="fu">:</span> <span class="st">"query"</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb3-11" title="11"> <span class="dt">"target"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb3-12" title="12"> <span class="dt">"features"</span><span class="fu">:</span> <span class="ot">[</span></a>
<a class="sourceLine" id="cb3-13" title="13"> <span class="st">"profiles"</span></a>
<a class="sourceLine" id="cb3-14" title="14"> <span class="ot">]</span></a>
<a class="sourceLine" id="cb3-15" title="15"> <span class="fu">}</span></a>
<a class="sourceLine" id="cb3-16" title="16"> <span class="fu">}</span></a>
<a class="sourceLine" id="cb3-17" title="17"> <span class="fu">}</span></a>
<a class="sourceLine" id="cb3-18" title="18"> <span class="fu">}</span></a>
<a class="sourceLine" id="cb3-19" title="19"><span class="fu">}</span></a></code></pre></div>
<p><img src="./images/e3-pkt-producer-req.png" alt="Producer Request" /></p>
<h3 id="query-response----consumers-to-producer">Query Response -- Consumers to Producer</h3>
<p>The consumer responses are as follows:</p>
<p><em>Consumer 1:</em></p>
<p>The following OpenC2 response message is published by Consumer 1 and delivered to the Producer on the <code>oc2/rsp</code> topic.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode json"><code class="sourceCode json"><a class="sourceLine" id="cb4-1" title="1"><span class="fu">{</span></a>
<a class="sourceLine" id="cb4-2" title="2"> <span class="dt">"headers"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb4-3" title="3"> <span class="dt">"request_id"</span><span class="fu">:</span> <span class="st">"uuid_1"</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb4-4" title="4"> <span class="dt">"created"</span><span class="fu">:</span> <span class="dv">1610483633</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb4-5" title="5"> <span class="dt">"from"</span><span class="fu">:</span> <span class="st">"Consumer1@example.com"</span></a>
<a class="sourceLine" id="cb4-6" title="6"> <span class="fu">},</span></a>
<a class="sourceLine" id="cb4-7" title="7"> <span class="dt">"body"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb4-8" title="8"> <span class="dt">"openc2"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb4-9" title="9"> <span class="dt">"response"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb4-10" title="10"> <span class="dt">"status"</span><span class="fu">:</span> <span class="dv">200</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb4-11" title="11"> <span class="dt">"results"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb4-12" title="12"> <span class="dt">"profiles"</span><span class="fu">:</span> <span class="ot">[</span></a>
<a class="sourceLine" id="cb4-13" title="13"> <span class="st">"slpf"</span></a>
<a class="sourceLine" id="cb4-14" title="14"> <span class="ot">]</span></a>
<a class="sourceLine" id="cb4-15" title="15"> <span class="fu">}</span></a>
<a class="sourceLine" id="cb4-16" title="16"> <span class="fu">}</span></a>
<a class="sourceLine" id="cb4-17" title="17"> <span class="fu">}</span></a>
<a class="sourceLine" id="cb4-18" title="18"> <span class="fu">}</span></a>
<a class="sourceLine" id="cb4-19" title="19"><span class="fu">}</span></a></code></pre></div>
<p><img src="./images/e3-pkt-cnsmr1-rsp.png" alt="Consumer 1 Response" /></p>
<p><em>Consumer 2:</em></p>
<p>The following OpenC2 response message is published by Consumer 2 and delivered to the Producer on the <code>oc2/rsp</code> topic.</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode json"><code class="sourceCode json"><a class="sourceLine" id="cb5-1" title="1"><span class="fu">{</span></a>
<a class="sourceLine" id="cb5-2" title="2"> <span class="dt">"headers"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb5-3" title="3"> <span class="dt">"request_id"</span><span class="fu">:</span> <span class="st">"uuid_1"</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb5-4" title="4"> <span class="dt">"created"</span><span class="fu">:</span> <span class="dv">1610483632</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb5-5" title="5"> <span class="dt">"from"</span><span class="fu">:</span> <span class="st">"Consumer2@example.com"</span></a>
<a class="sourceLine" id="cb5-6" title="6"> <span class="fu">},</span></a>
<a class="sourceLine" id="cb5-7" title="7"> <span class="dt">"body"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb5-8" title="8"> <span class="dt">"openc2"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb5-9" title="9"> <span class="dt">"response"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb5-10" title="10"> <span class="dt">"status"</span><span class="fu">:</span> <span class="dv">200</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb5-11" title="11"> <span class="dt">"results"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb5-12" title="12"> <span class="dt">"profiles"</span><span class="fu">:</span> <span class="ot">[</span></a>
<a class="sourceLine" id="cb5-13" title="13"> <span class="st">"slpf"</span><span class="ot">,</span></a>
<a class="sourceLine" id="cb5-14" title="14"> <span class="st">"ids"</span></a>
<a class="sourceLine" id="cb5-15" title="15"> <span class="ot">]</span></a>
<a class="sourceLine" id="cb5-16" title="16"> <span class="fu">}</span></a>
<a class="sourceLine" id="cb5-17" title="17"> <span class="fu">}</span></a>
<a class="sourceLine" id="cb5-18" title="18"> <span class="fu">}</span></a>
<a class="sourceLine" id="cb5-19" title="19"> <span class="fu">}</span></a>
<a class="sourceLine" id="cb5-20" title="20"><span class="fu">}</span></a></code></pre></div>
<p><img src="./images/e3-pkt-cnsmr2-rsp.png" alt="Consumer 2 Response" /></p>
<p><em>Consumer 3:</em></p>
<p>The following OpenC2 response message is published by Consumer 2 and delivered to the Producer on the <code>oc2/rsp</code> topic.</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode json"><code class="sourceCode json"><a class="sourceLine" id="cb6-1" title="1"><span class="fu">{</span></a>
<a class="sourceLine" id="cb6-2" title="2"> <span class="dt">"headers"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb6-3" title="3"> <span class="dt">"request_id"</span><span class="fu">:</span> <span class="st">"uuid_1"</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb6-4" title="4"> <span class="dt">"created"</span><span class="fu">:</span> <span class="dv">1610483632</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb6-5" title="5"> <span class="dt">"from"</span><span class="fu">:</span> <span class="st">"Consumer3@example.com"</span></a>
<a class="sourceLine" id="cb6-6" title="6"> <span class="fu">},</span></a>
<a class="sourceLine" id="cb6-7" title="7"> <span class="dt">"body"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb6-8" title="8"> <span class="dt">"openc2"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb6-9" title="9"> <span class="dt">"response"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb6-10" title="10"> <span class="dt">"status"</span><span class="fu">:</span> <span class="dv">200</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb6-11" title="11"> <span class="dt">"results"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb6-12" title="12"> <span class="dt">"profiles"</span><span class="fu">:</span> <span class="ot">[</span></a>
<a class="sourceLine" id="cb6-13" title="13"> <span class="st">"edr"</span><span class="ot">,</span></a>
<a class="sourceLine" id="cb6-14" title="14"> <span class="st">"sbom"</span></a>
<a class="sourceLine" id="cb6-15" title="15"> <span class="ot">]</span></a>
<a class="sourceLine" id="cb6-16" title="16"> <span class="fu">}</span></a>
<a class="sourceLine" id="cb6-17" title="17"> <span class="fu">}</span></a>
<a class="sourceLine" id="cb6-18" title="18"> <span class="fu">}</span></a>
<a class="sourceLine" id="cb6-19" title="19"> <span class="fu">}</span></a>
<a class="sourceLine" id="cb6-20" title="20"><span class="fu">}</span></a>
<a class="sourceLine" id="cb6-21" title="21"></a></code></pre></div>
<p><img src="./images/e3-pkt-cnsmr3-rsp.png" alt="Consumer 3 Response" /></p>
<h2 id="e4-openc2-deny-example">E.4 OpenC2 Deny Example</h2>
<p>This example illustrates the execution of a common OpenC2 requests using MQTT PUBLISH control packets. The example is a <code>deny</code> action for a particular IP connection, as described in the <a href="#openc2-slpf-v10">Stateless Packet Filtering AP</a>, Section A.1.1. This example primarily indicates the content of the PUBLISH control packets. For simplicity the exchange illustrated only includes one Producer and one Consumer.</p>
<p><strong>NOTES:</strong></p>
<ol>
<li>No sequence diagram is included as the PUBLISH / PUBACK sequences among Producer, Consumer, and Broker are similar to those illustrated in Example 2. This example only includes the PUBLISH control packets containing the OpenC2 request and response messages.</li>
<li>The <code>response_requested</code> argument is omitted from the <code>query</code> request message so the Consumers exhibit the default behavior of sending a complete response.</li>
</ol>
<p>This example illustrates the following aspects of the operating model:</p>
<ul>
<li>Default topic structure, <a href="#22-default-topic-structure">Section 2.2</a></li>
<li>Packaging of OpenC2 messages in PUBLISH control packet payloads, <a href="#24-openc2-message-format">Section 2.4</a></li>
<li>Properties to convey OpenC2 message type and serialization, <a href="#24-openc2-message-format">Section 2.4</a></li>
<li>Recommended use of QoS 1, <a href="#25-quality-of-service">Section 2.5</a></li>
<li>PUBLISH control packet flags, <a href="#32-publish-control-packet">Section 3.2</a></li>
</ul>
<p>The Producer initiates this process by publishing a <code>deny</code> request to <code>oc2/cmd/slpf</code>. The OpenC2 request message contents and corresponding MQTT PUBLISH control packet are shown below, followed by the Consumer reply.The JSON nessages in the control packet payloads use condensed formatting (white space minimized).</p>
<h3 id="deny-action----producer-to-consumer">Deny Action -- Producer to Consumer</h3>
<p>The following OpenC2 request message is published by the Producer and delivered to all Consumers subscribed to <code>oc2/cmd/slpf</code>.</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode json"><code class="sourceCode json"><a class="sourceLine" id="cb7-1" title="1"></a>
<a class="sourceLine" id="cb7-2" title="2"><span class="fu">{</span></a>
<a class="sourceLine" id="cb7-3" title="3"> <span class="dt">"headers"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb7-4" title="4"> <span class="dt">"request_id"</span><span class="fu">:</span> <span class="st">"uuid_2"</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb7-5" title="5"> <span class="dt">"created"</span><span class="fu">:</span> <span class="dv">1610483630</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb7-6" title="6"> <span class="dt">"from"</span><span class="fu">:</span> <span class="st">"Producer1@example.com"</span></a>
<a class="sourceLine" id="cb7-7" title="7"> <span class="fu">},</span></a>
<a class="sourceLine" id="cb7-8" title="8"> <span class="dt">"body"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb7-9" title="9"> <span class="dt">"openc2"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb7-10" title="10"> <span class="dt">"request"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb7-11" title="11"> <span class="dt">"action"</span><span class="fu">:</span> <span class="st">"deny"</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb7-12" title="12"> <span class="dt">"target"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb7-13" title="13"> <span class="dt">"ipv4_connection"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb7-14" title="14"> <span class="dt">"protocol"</span><span class="fu">:</span> <span class="st">"tcp"</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb7-15" title="15"> <span class="dt">"src_addr"</span><span class="fu">:</span> <span class="st">"1.2.3.4"</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb7-16" title="16"> <span class="dt">"src_port"</span><span class="fu">:</span> <span class="dv">10996</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb7-17" title="17"> <span class="dt">"dst_addr"</span><span class="fu">:</span> <span class="st">"198.2.3.4"</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb7-18" title="18"> <span class="dt">"dst_port"</span><span class="fu">:</span> <span class="dv">80</span></a>
<a class="sourceLine" id="cb7-19" title="19"> <span class="fu">}</span></a>
<a class="sourceLine" id="cb7-20" title="20"> <span class="fu">},</span></a>
<a class="sourceLine" id="cb7-21" title="21"> <span class="dt">"args"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb7-22" title="22"> <span class="dt">"start_time"</span><span class="fu">:</span> <span class="dv">1534775460000</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb7-23" title="23"> <span class="dt">"duration"</span><span class="fu">:</span> <span class="dv">500</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb7-24" title="24"> <span class="dt">"response_requested"</span><span class="fu">:</span> <span class="st">"ack"</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb7-25" title="25"> <span class="dt">"slpf"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb7-26" title="26"> <span class="dt">"drop_process"</span><span class="fu">:</span> <span class="st">"none"</span></a>
<a class="sourceLine" id="cb7-27" title="27"> <span class="fu">}</span></a>
<a class="sourceLine" id="cb7-28" title="28"> <span class="fu">},</span></a>
<a class="sourceLine" id="cb7-29" title="29"> <span class="dt">"actuator"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb7-30" title="30"> <span class="dt">"slpf"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb7-31" title="31"> <span class="dt">"asset_id"</span><span class="fu">:</span> <span class="st">"30"</span></a>
<a class="sourceLine" id="cb7-32" title="32"> <span class="fu">}</span></a>
<a class="sourceLine" id="cb7-33" title="33"> <span class="fu">}</span></a>
<a class="sourceLine" id="cb7-34" title="34"> <span class="fu">}</span></a>
<a class="sourceLine" id="cb7-35" title="35"> <span class="fu">}</span></a>
<a class="sourceLine" id="cb7-36" title="36"> <span class="fu">}</span></a>
<a class="sourceLine" id="cb7-37" title="37"><span class="fu">}</span></a>
<a class="sourceLine" id="cb7-38" title="38"></a></code></pre></div>
<p><img src="./images/e4-pkt-producer-req.png" alt="Producer Request" /></p>
<h3 id="deny-response----consumer-to-producer">Deny Response -- Consumer to Producer</h3>
<p>The following OpenC2 response message is published by the Consumer 1 and delivered to the Producer on the <code>oc2/rsp</code> topic.</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode json"><code class="sourceCode json"><a class="sourceLine" id="cb8-1" title="1"><span class="fu">{</span></a>
<a class="sourceLine" id="cb8-2" title="2"> <span class="dt">"headers"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb8-3" title="3"> <span class="dt">"request_id"</span><span class="fu">:</span> <span class="st">"uuid_2"</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb8-4" title="4"> <span class="dt">"created"</span><span class="fu">:</span> <span class="dv">1610483633</span><span class="fu">,</span></a>
<a class="sourceLine" id="cb8-5" title="5"> <span class="dt">"from"</span><span class="fu">:</span> <span class="st">"Consumer1@example.com"</span></a>
<a class="sourceLine" id="cb8-6" title="6"> <span class="fu">},</span></a>
<a class="sourceLine" id="cb8-7" title="7"> <span class="dt">"body"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb8-8" title="8"> <span class="dt">"openc2"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb8-9" title="9"> <span class="dt">"response"</span><span class="fu">:</span> <span class="fu">{</span></a>
<a class="sourceLine" id="cb8-10" title="10"> <span class="dt">"status"</span><span class="fu">:</span> <span class="dv">102</span></a>
<a class="sourceLine" id="cb8-11" title="11"> <span class="fu">}</span></a>
<a class="sourceLine" id="cb8-12" title="12"> <span class="fu">}</span></a>
<a class="sourceLine" id="cb8-13" title="13"> <span class="fu">}</span></a>
<a class="sourceLine" id="cb8-14" title="14"><span class="fu">}</span></a></code></pre></div>
<p><img src="./images/e4-pkt-cnsmr1-rsp.png" alt="Consumer 1 Response" /></p>
<h2 id="e5-paho-python-client-examples">E.5 Paho Python Client Examples</h2>
<p>This set of examples illustrates the use of the <a href="#paho">paho python MQTT client</a> to utilize MQTTv5 as described in this specification. The paho client documentation [https://pypi.org/project/paho-mqtt/] currently does not include explanations for how to access MQTTv5 features, so this example has been constructed based on examination of the client source [https://github.com/eclipse/paho.mqtt.python/tree/master/src/paho/mqtt].</p>
<p>As described in the client documentation, the basic approach to using the paho client is:</p>
<ul>
<li>Create a client instance</li>
<li>Connect to a broker using one of the connect*() functions</li>
<li>Call one of the loop*() functions to maintain network traffic flow with the broker</li>
<li>Use subscribe() to subscribe to a topic and receive messages</li>
<li>Use publish() to publish messages to the broker</li>
<li>Use disconnect() to disconnect from the broker</li>
</ul>
<p>The paho client’s MQTTv5 features also depend on the use of the <code>Properties</code> class to specify properties to include in the PUBLISH packet, and the <code>SubscribeOptions</code> class to specify the appropriate options when subscribing to topics.</p>
<p>This example focuses on those aspects of client use that leverage MQTTv5 features, and does not attempt to illustrate a complete working solution.</p>
<h3 id="e51-connecting">E.5.1 Connecting</h3>
<p>This example illustrates the process of connecting to an MQTT broker and subscribing to topic filters appropriate for a client that implements the stateless packet filter actuator profile (AP). The example illustrates the following aspects of the operating model:</p>
<ul>
<li>Randomly generated MQTT ClientID, <a href="#26-mqtt-client-identifier">Section 2.6</a></li>
<li>Recommended 5 minute keep-alive interval, <a href="#27-keep-alive-interval">Section 2.7</a></li>
<li>No use of MQTT "will" messages, <a href="#28-will-message">Section 2.8</a></li>
<li><code>Clean Start</code> flag set to false, <a href="#29-clean-start-flag">Section 2.9</a></li>
<li>Optional use of username and password, <a href="#31-connect-control-packet">Section 3.1</a></li>
<li>Use of TLS 1.2 or higher, <a href="#appendix-b-safety-security-and-privacy-considerations">Appendix B</a></li>
</ul>
<div class="sourceCode" id="cb9"><pre class="sourceCode python"><code class="sourceCode python"><a class="sourceLine" id="cb9-1" title="1"><span class="im">import</span> json</a>
<a class="sourceLine" id="cb9-2" title="2"><span class="im">import</span> ssl</a>
<a class="sourceLine" id="cb9-3" title="3"><span class="im">from</span> typing <span class="im">import</span> Any, Dict</a>
<a class="sourceLine" id="cb9-4" title="4"><span class="im">from</span> paho.mqtt <span class="im">import</span> client <span class="im">as</span> mqtt</a>
<a class="sourceLine" id="cb9-5" title="5"><span class="im">from</span> paho.mqtt.properties <span class="im">import</span> Properties</a>
<a class="sourceLine" id="cb9-6" title="6"></a>
<a class="sourceLine" id="cb9-7" title="7"></a>