Home

Awesome

<img src="/src/icon.png" height="30px"> Australian Protective Markings

Build status NuGet Status

A dotnet representation of Protective Markings defined in the Australian Protective Security Policy Framework

See Milestones for release notes.

Spec:

NuGet package

Model

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:

RenderEmailSubjectSuffix

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.

Minimum content

<!-- snippet: RenderEmailSubjectSuffixMinimum -->

<a id='snippet-RenderEmailSubjectSuffixMinimum'></a>

var marking = new ProtectiveMarking
{
    Classification = Classification.TopSecret
};
var result = marking.RenderEmailSubjectSuffix();

<sup><a href='/src/Tests/Samples.cs#L9-L17' title='Snippet source file'>snippet source</a> | <a href='#snippet-RenderEmailSubjectSuffixMinimum' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

Results in:

<!-- snippet: Samples.RenderEmailSubjectSuffixMinimum.verified.txt -->

<a id='snippet-Samples.RenderEmailSubjectSuffixMinimum.verified.txt'></a>

[SEC=TOP-SECRET]

<sup><a href='/src/Tests/Samples.RenderEmailSubjectSuffixMinimum.verified.txt#L1-L1' title='Snippet source file'>snippet source</a> | <a href='#snippet-Samples.RenderEmailSubjectSuffixMinimum.verified.txt' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

Full content

<!-- snippet: RenderEmailSubjectSuffixFull -->

<a id='snippet-RenderEmailSubjectSuffixFull'></a>

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();

<sup><a href='/src/Tests/Samples.cs#L25-L49' title='Snippet source file'>snippet source</a> | <a href='#snippet-RenderEmailSubjectSuffixFull' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

Results in:

<!-- snippet: Samples.RenderEmailSubjectSuffixFull.verified.txt -->

<a id='snippet-Samples.RenderEmailSubjectSuffixFull.verified.txt'></a>

[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]

<sup><a href='/src/Tests/Samples.RenderEmailSubjectSuffixFull.verified.txt#L1-L1' title='Snippet source file'>snippet source</a> | <a href='#snippet-Samples.RenderEmailSubjectSuffixFull.verified.txt' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

RenderEmailHeader

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

Minimum content

<!-- snippet: RenderEmailHeaderMinimum -->

<a id='snippet-RenderEmailHeaderMinimum'></a>

var marking = new ProtectiveMarking
{
    Classification = Classification.TopSecret
};
var result = marking.RenderEmailHeader();

<sup><a href='/src/Tests/Samples.cs#L57-L65' title='Snippet source file'>snippet source</a> | <a href='#snippet-RenderEmailHeaderMinimum' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

Results in:

<!-- snippet: Samples.RenderEmailHeaderMinimum.verified.txt -->

<a id='snippet-Samples.RenderEmailHeaderMinimum.verified.txt'></a>

VER=2018.4, NS=gov.au, SEC=TOP-SECRET

<sup><a href='/src/Tests/Samples.RenderEmailHeaderMinimum.verified.txt#L1-L1' title='Snippet source file'>snippet source</a> | <a href='#snippet-Samples.RenderEmailHeaderMinimum.verified.txt' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

Full content

<!-- snippet: RenderEmailHeaderFull -->

<a id='snippet-RenderEmailHeaderFull'></a>

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();

<sup><a href='/src/Tests/Samples.cs#L73-L97' title='Snippet source file'>snippet source</a> | <a href='#snippet-RenderEmailHeaderFull' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

Results in:

<!-- snippet: Samples.RenderEmailHeaderFull.verified.txt -->

<a id='snippet-Samples.RenderEmailHeaderFull.verified.txt'></a>

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

<sup><a href='/src/Tests/Samples.RenderEmailHeaderFull.verified.txt#L1-L1' title='Snippet source file'>snippet source</a> | <a href='#snippet-Samples.RenderEmailHeaderFull.verified.txt' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

ApplyProtectiveMarkings

Extension method to apply protective markings to a MailMessage

<!-- snippet: ApplyProtectiveMarkings -->

<a id='snippet-ApplyProtectiveMarkings'></a>

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);

<sup><a href='/src/Tests/Samples.cs#L150-L170' title='Snippet source file'>snippet source</a> | <a href='#snippet-ApplyProtectiveMarkings' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

Results in:

<!-- snippet: Samples.ApplyProtectiveMarkings.verified.txt -->

<a id='snippet-Samples.ApplyProtectiveMarkings.verified.txt'></a>

{
  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
}

<sup><a href='/src/Tests/Samples.ApplyProtectiveMarkings.verified.txt#L1-L10' title='Snippet source file'>snippet source</a> | <a href='#snippet-Samples.ApplyProtectiveMarkings.verified.txt' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

RenderDocumentHeaderAndFooter

RenderDocumentHeaderAndFooter generated a header and footer for a document.

See: PSPF: Sensitive and classified information - Applying text-based protective markings

<!-- snippet: RenderDocumentHeaderAndFooter -->

<a id='snippet-RenderDocumentHeaderAndFooter'></a>

var marking = new ProtectiveMarking
{
    Classification = Classification.Secret,
    LegislativeSecrecy = true,
    Caveats = new()
    {
        Cabinet = true,
        Austeo = true
    }
};
var (header, footer) = marking.RenderDocumentHeaderAndFooter();

<sup><a href='/src/Tests/Samples.cs#L190-L204' title='Snippet source file'>snippet source</a> | <a href='#snippet-RenderDocumentHeaderAndFooter' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

Results in:

Header:

SECRET//AUSTEO//CABINET
Legislative-Secrecy

Footer:

Legislative-Secrecy
SECRET//AUSTEO//CABINET

ParseEmailHeader

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.

Minimum content

<!-- snippet: ParseEmailHeaderMinimumOmit -->

<a id='snippet-ParseEmailHeaderMinimumOmit'></a>

var protectiveMarking = Parser.ParseProtectiveMarking("SEC=OFFICIAL:Sensitive");

<sup><a href='/src/Tests/Samples.cs#L105-L109' title='Snippet source file'>snippet source</a> | <a href='#snippet-ParseEmailHeaderMinimumOmit' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

Results in:

<!-- snippet: Samples.ParseEmailHeaderMinimumOmit.verified.txt -->

<a id='snippet-Samples.ParseEmailHeaderMinimumOmit.verified.txt'></a>

{
  Classification: OfficialSensitive,
  Caveats: null,
  Expiry: null,
  PersonalPrivacy: false,
  LegalPrivilege: false,
  LegislativeSecrecy: false,
  Comment: null,
  AuthorEmail: null
}

<sup><a href='/src/Tests/Samples.ParseEmailHeaderMinimumOmit.verified.txt#L1-L10' title='Snippet source file'>snippet source</a> | <a href='#snippet-Samples.ParseEmailHeaderMinimumOmit.verified.txt' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

Omit Version and Namespace

The version and namespace is hard coded in the spec. Both can be omitted when parsing.

<!-- snippet: ParseEmailHeaderMinimumOmit -->

<a id='snippet-ParseEmailHeaderMinimumOmit'></a>

var protectiveMarking = Parser.ParseProtectiveMarking("SEC=OFFICIAL:Sensitive");

<sup><a href='/src/Tests/Samples.cs#L105-L109' title='Snippet source file'>snippet source</a> | <a href='#snippet-ParseEmailHeaderMinimumOmit' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

Full content

<!-- snippet: ParseEmailHeaderFull -->

<a id='snippet-ParseEmailHeaderFull'></a>

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");

<sup><a href='/src/Tests/Samples.cs#L178-L182' title='Snippet source file'>snippet source</a> | <a href='#snippet-ParseEmailHeaderFull' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

Results in:

<!-- snippet: Samples.ParseEmailHeaderFull.verified.txt -->

<a id='snippet-Samples.ParseEmailHeaderFull.verified.txt'></a>

{
  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
}

<sup><a href='/src/Tests/Samples.ParseEmailHeaderFull.verified.txt#L1-L28' title='Snippet source file'>snippet source</a> | <a href='#snippet-Samples.ParseEmailHeaderFull.verified.txt' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

Newlines

For readability, newlines are allowed to delineate key value pairs:

<!-- snippet: ParseEmailHeaderFullNewlines -->

<a id='snippet-ParseEmailHeaderFullNewlines'></a>

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
    """);

<sup><a href='/src/Tests/Samples.cs#L216-L236' title='Snippet source file'>snippet source</a> | <a href='#snippet-ParseEmailHeaderFullNewlines' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

OfficeDocHelper

Protective markings can be applied to an office document (docx, xlsx, pptx) using OfficeDocHelper.

A custom property named X-Protective-Marking will be added.

<!-- snippet: OfficeDocHelperStream -->

<a id='snippet-OfficeDocHelperStream'></a>

var marking = new ProtectiveMarking
{
    Classification = Classification.TopSecret
};
await OfficeDocHelper.Patch(stream, marking);

<sup><a href='/src/Tests/Samples.cs#L280-L288' title='Snippet source file'>snippet source</a> | <a href='#snippet-OfficeDocHelperStream' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet --> <!-- snippet: OfficeDocHelperFile -->

<a id='snippet-OfficeDocHelperFile'></a>

var marking = new ProtectiveMarking
{
    Classification = Classification.TopSecret
};
await OfficeDocHelper.Patch(filePath, marking);

<sup><a href='/src/Tests/Samples.cs#L294-L302' title='Snippet source file'>snippet source</a> | <a href='#snippet-OfficeDocHelperFile' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet --> <img src="/src/docxWithProps.png" width="400px">

Icon

Icon Protect from The Noun Project.