A dotnet representation of Protective Markings defined in the Australian Protective Security Policy Framework
See Milestones for release notes.
Spec:
- PSPF: Sensitive and classified information
- PSPF: Sensitive and classified information - Annex F (email clarifications)
- https://nuget.org/packages/AustralianProtectiveMarkings/
- https://nuget.org/packages/Verify.AustralianProtectiveMarkings/
The model for handling a protective marking is AustralianProtectiveMarkings.ProtectiveMarking
.
The ProtectiveMarking
class structure is designed to be serialization friendly. So it can be used as part of data contracts.
All string members follow the convention of:
- Max 128 characters
- Characters allowed: 32-43 / 45-91 / 93-126
- Escape character is
\
. Where:
,\
, and,
can be escaped. A\
not followed by a one of those is treated as a single\
.
Converts a protected marking to text that should be appended to an email subject line.
See "Subject Field Marking" in PSPF: Sensitive and classified information - Annex F (email clarifications)
In this syntax, the protective marking is placed in the subject field of the message (RFC5322 ‘Subject’). As per RFC5322, an Internet email message can have at most one subject field. Allowing for no more than one email protective marking in the subject line minimises confusion and potential conflict.
A Subject Field Marking is less sophisticated than an Internet Message Header Extension as it is possible to manipulate an email’s subject during message generation or transport. However, it is easy to apply as a human user can construct (and interpret) the protective marking without the need for additional tools.
var marking = new ProtectiveMarking
{
Classification = Classification.TopSecret
};
var result = marking.RenderEmailSubjectSuffix();
Results in:
[SEC=TOP-SECRET]
var marking = new ProtectiveMarking
{
Classification = Classification.TopSecret,
Expiry = new()
{
DownTo = Classification.Official,
GenDate = new DateTimeOffset(2020, 10, 1, 0, 0, 0, TimeSpan.Zero)
},
Comment = "the comments",
AuthorEmail = "a@b.com",
LegalPrivilege = true,
Caveats = new()
{
Codeword = "LOBSTER",
ForeignGovernment = "USA caveat",
Cabinet = true,
ExclusiveFor = "person",
Country = Country.Afghanistan
}
};
var result = marking.RenderEmailSubjectSuffix();
Results in:
[SEC=TOP-SECRET, CAVEAT=C:LOBSTER, CAVEAT=FG:USA caveat, CAVEAT=SH:CABINET, CAVEAT=SH:EXCLUSIVE-FOR person, CAVEAT=RI:REL AFG, EXPIRES=2020-10-01, DOWNTO=OFFICIAL, ACCESS=Legal-Privilege]
Converts a protected marking to text that should be added as the value opf the X-Protective-Marking
email header.
See "Internet Message Header Extension" in PSPF: Sensitive and classified information - Annex F (email clarifications)
In this syntax, the protective marking is carried as a custom Internet Message Header Extension ‘X-Protective-Marking’. Allowing for no more than one ‘X-Protective-Marking’ field minimises confusion and potential conflict.
Using an Internet Message Header Extension is more sophisticated than a Subject Field Marking. It is designed for construction and parsing by email agents (clients, gateways and servers) as they have accessto internet message headers. In this way a richer syntax can be used and email agents can perform more complex handling based on the protective marking
var marking = new ProtectiveMarking
{
Classification = Classification.TopSecret
};
var result = marking.RenderEmailHeader();
Results in:
VER=2018.4, NS=gov.au, SEC=TOP-SECRET
var marking = new ProtectiveMarking
{
Classification = Classification.TopSecret,
Expiry = new()
{
DownTo = Classification.Official,
GenDate = new DateTimeOffset(2020, 10, 1, 0, 0, 0, TimeSpan.Zero)
},
Comment = "the comments",
AuthorEmail = "a@b.com",
LegalPrivilege = true,
Caveats = new()
{
Codeword = "LOBSTER",
ForeignGovernment = "USA caveat",
Agao = true,
ExclusiveFor = "person",
Country = Country.Afghanistan
}
};
var result = marking.RenderEmailHeader();
Results in:
VER=2018.4, NS=gov.au, SEC=TOP-SECRET, CAVEAT=C:LOBSTER, CAVEAT=FG:USA caveat, CAVEAT=RI:AGAO, CAVEAT=SH:EXCLUSIVE-FOR person, CAVEAT=RI:REL AFG, EXPIRES=2020-10-01, DOWNTO=OFFICIAL, ACCESS=Legal-Privilege, NOTE=the comments, ORIGIN=a@b.com
Extension method to apply protective markings to a MailMessage
var marking = new ProtectiveMarking
{
Classification = Classification.TopSecret,
LegalPrivilege = true,
Caveats = new()
{
Cabinet = true,
Country = Country.Afghanistan
}
};
var mail = new MailMessage(
from: "from@mail.com",
to: "to@mail.com",
subject: "The subject",
body: "The body");
mail.ApplyProtectiveMarkings(marking);
Results in:
{
From: from@mail.com,
To: to@mail.com,
Subject: The subject [SEC=TOP-SECRET, CAVEAT=SH:CABINET, CAVEAT=RI:REL AFG, ACCESS=Legal-Privilege],
Headers: {
X-Protective-Marking: VER=2018.4, NS=gov.au, SEC=TOP-SECRET, CAVEAT=SH:CABINET, CAVEAT=RI:REL AFG, ACCESS=Legal-Privilege
},
IsBodyHtml: false,
Body: The body
}
RenderDocumentHeaderAndFooter
generated a header and footer for a document.
See: PSPF: Sensitive and classified information - Applying text-based protective markings
var marking = new ProtectiveMarking
{
Classification = Classification.Secret,
LegislativeSecrecy = true,
Caveats = new()
{
Cabinet = true,
Austeo = true
}
};
var (header, footer) = marking.RenderDocumentHeaderAndFooter();
Results in:
Header:
SECRET//AUSTEO//CABINET
Legislative-Secrecy
Footer:
Legislative-Secrecy
SECRET//AUSTEO//CABINET
Parses a X-Protective-Marking
email header.
Also useful for when a protective marking needs to be store in a configuration file. In which case ParseEmailHeader can be used to load that text into a ProtectiveMarking
which can be applied to documents or emails.
var protectiveMarking = Parser.ParseProtectiveMarking("SEC=OFFICIAL:Sensitive");
Results in:
{
Classification: OfficialSensitive,
Caveats: null,
Expiry: null,
PersonalPrivacy: false,
LegalPrivilege: false,
LegislativeSecrecy: false,
Comment: null,
AuthorEmail: null
}
The version and namespace is hard coded in the spec. Both can be omitted when parsing.
var protectiveMarking = Parser.ParseProtectiveMarking("SEC=OFFICIAL:Sensitive");
var protectiveMarking = Parser.ParseProtectiveMarking("VER=2018.4, NS=gov.au, SEC=TOP-SECRET, CAVEAT=C:CodeWord, CAVEAT=FG:USA caveat, CAVEAT=RI:AGAO, CAVEAT=SH:CABINET, CAVEAT=SH:EXCLUSIVE-FOR person, CAVEAT=RI:REL AFG/DZA, EXPIRES=2020-10-01, DOWNTO=OFFICIAL, ACCESS=Legal-Privilege, NOTE=the comments, ORIGIN=a@b.com");
Results in:
{
Classification: TopSecret,
Caveats: {
Codeword: CodeWord,
ForeignGovernment: USA caveat,
ExclusiveFor: person,
CountryCodes: [
Afghanistan,
Algeria
],
Agao: true,
Austeo: false,
DelicateSource: false,
Orcon: false,
Cabinet: true,
NationalCabinet: false
},
Expiry: {
DownTo: Official,
GenDate: 2020-10-01T00:00:00+00:00,
Event: null
},
PersonalPrivacy: false,
LegalPrivilege: true,
LegislativeSecrecy: false,
Comment: the comments,
AuthorEmail: a@b.com
}
For readability, newlines are allowed to delineate key value pairs:
var protectiveMarking = Parser.ParseProtectiveMarking(
"""
VER=2018.4,
NS=gov.au,
SEC=TOP-SECRET,
CAVEAT=C:CodeWord,
CAVEAT=FG:USA caveat,
CAVEAT=RI:AGAO,
CAVEAT=SH:CABINET,
CAVEAT=SH:EXCLUSIVE-FOR person,
CAVEAT=RI:REL AFG/DZA,
EXPIRES=2020-10-01,
DOWNTO=OFFICIAL,
ACCESS=Legal-Privilege,
NOTE=the comments,
ORIGIN=a@b.com
""");
Protective markings can be applied to an office document (docx, xlsx, pptx) using OfficeDocHelper.
A custom property named X-Protective-Marking
will be added.
var marking = new ProtectiveMarking
{
Classification = Classification.TopSecret
};
await OfficeDocHelper.Patch(stream, marking);
var marking = new ProtectiveMarking
{
Classification = Classification.TopSecret
};
await OfficeDocHelper.Patch(filePath, marking);
Icon Protect from The Noun Project.