OIO Basic Privilege Profile

OIO Basic Privilege Profile (OIO BPP) is an extension to SAML that describes how privileges can be expressed as attibutes in SAML assertions. The current version of the specification is 1.1 which includes support for constraints on privileges; you can read more about OIO BPP here (Danish only), or download the spec from here which is in English. There are two top-level forms of OIO BPP, allowing applications to choose from a Simple or Intermediate model for the privileges. In the case of the Intemediate model, constraints on privileges can also be specified (if using v1.1 of the profile).

An example of OIO BPP using Intermediate model with constraints, taken from the specification, is

<?xml version="1.0" encoding="UTF-8"?>
<bpp:PrivilegeList xmlns:bpp="http://itst.dk/oiosaml/basic_privilege_profile" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <PrivilegeGroup Scope="urn:dk:gov:saml:cvrNumberIdentifier:12345678">
    <Constraint Name="urn:dk:kombit:KLE">25.*</Constraint>
    <Constraint Name="urn:dk:kombit:sensitivity">3</Constraint>
    <Privilege>urn:dk:kombit:system_xyz:view_case</Privilege>
  </PrivilegeGroup>
</bpp:PrivilegeList>

When OIO BPP Intermediate is transmitted in SAML responses it should be converted to bytes using UTF-8, base64 encoded, and set as the value for a SAML attribute with name dk:gov:saml:attribute:Privileges_intermediate.
If you find yourself decoding OIO BPP in .NET code, you might also be interested in the nuget package Kombit.Samples.BasicPrivilegeProfileParser.
However, dealing with OIO BPP in C# is straightforward.

Encoding and Decoding OIO BPP with C#

XNamespace bpp = "http://itst.dk/oiosaml/basic_privilege_profile";
XElement privileges = new XElement(bpp + "PrivilegeList",
  new XAttribute(XNamespace.Xmlns + "bpp", "http://itst.dk/oiosaml/basic_privilege_profile"),
  new XAttribute(XNamespace.Xmlns + "xsi", "http://www.w3.org/2001/XMLSchema-instance"),
  new XElement("PrivilegeGroup",
    new XAttribute("Scope", "urn:dk:gov:saml:cvrNumberIdentifier:12345678"),
    new XElement("Constraint",
      new XAttribute("Name", "urn:dk:kombit:KLE"),
      "25.*"),
    new XElement("Constraint",
      new XAttribute("Name", "urn:dk:kombit:sensitivity"),
      "3"
    ),
    new XElement("Privilege", "urn:dk:kombit:system_xyz:view_case")
  )
);

var base64Privileges = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(privileges.ToString()));
base64Privileges.Dump("Encoded OIO BPP");

var decodedPrivileges = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(base64Privileges));
var decodedPrivilegesXml = System.Xml.Linq.XElement.Parse(decodedPrivileges);
decodedPrivilegesXml.Dump("Decoded OIO BPP");
Encoded OIO BPP
PGJwcDpQcml2aWxlZ2VMaXN0IHhtbG5zOmJwcD0iaHR0cDovL2l0c3QuZGsvb2lvc2FtbC9iYXNpY19wcml2aWxlZ2VfcHJvZmlsZSIgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSI+DQogIDxQcml2aWxlZ2VHcm91cCBTY29wZT0idXJuOmRrOmdvdjpzYW1sOmN2ck51bWJlcklkZW50aWZpZXI6MTIzNDU2NzgiPg0KICAgIDxDb25zdHJhaW50IE5hbWU9InVybjpkazprb21iaXQ6S0xFIj4yNS4qPC9Db25zdHJhaW50Pg0KICAgIDxDb25zdHJhaW50IE5hbWU9InVybjpkazprb21iaXQ6c2Vuc2l0aXZpdHkiPjM8L0NvbnN0cmFpbnQ+DQogICAgPFByaXZpbGVnZT51cm46ZGs6a29tYml0OnN5c3RlbV94eXo6dmlld19jYXNlPC9Qcml2aWxlZ2U+DQogIDwvUHJpdmlsZWdlR3JvdXA+DQo8L2JwcDpQcml2aWxlZ2VMaXN0Pg==
Decoded OIO BPP
<bpp:PrivilegeList xmlns:bpp="http://itst.dk/oiosaml/basic_privilege_profile" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <PrivilegeGroup Scope="urn:dk:gov:saml:cvrNumberIdentifier:12345678">
    <Constraint Name="urn:dk:kombit:KLE">25.*</Constraint>
    <Constraint Name="urn:dk:kombit:sensitivity">3</Constraint>
    <Privilege>urn:dk:kombit:system_xyz:view_case</Privilege>
  </PrivilegeGroup>
</bpp:PrivilegeList>