ISecureObject Overview

The primary interface for Suplex is a hierarchy of ISecureObjects, where each ISecureObject carries a SecurityDescriptor, which, as a structure, describes the security disposition of the object itself. By analogy, an ISecureObject can be thought of like a directory on a computer - the directory metadata contains a description of who has what kind of access, and how that access was granted (or denied) - either by directly-applied permissions or through inheritance.

At runtime, security information is selected from a Suplex data store and then used to populate the SecurityDescriptor of an ISecureObject. The SecurityDescriptor carries two lists: the DiscretionaryAccessControlList (Dacl), which is a list of permissions, and the SystemAccessControlList (Sacl), which is a list of audit entries. The items in the ACLs are called AccessControlEntries (Aces), where each Ace specifies who has what kind of access, and whether that access is audited.

ISecureObject

Suplex ships with a default implementation for ISecureObject, SecureObject, but implementing the interface on your own classes is designed to be easy - all the methods of ISecureObject are implemented as extension methods, so you only need to implement the properties. In doing so, implement Parent/Children as strongly-typed to your class and use the default ISecurityDescriptor implementation, SecurityDescriptor.

Properties

The properties supporting an ISecureObject are just enough to identify it in a datastore and represent its hierarchy.

Field/Method Type Required Description
UId Guid Yes Primary key in the datastore, a GUID to support replication amongst stores.
UniqueName string Yes Human-identifiable name for an object, should be unique within a hierarchy.
ParentUId Nullable Guid No The GUID of the current ISecureObject's Parent, if there is a Parent.
Parent ISecureObject No The current ISecureObject's Parent, if there is a Parent.
Children List No A collection of the current object's child-ISecureObjects, if there are any.
Security ISecurityDescriptor Yes The SecurityDescriptor for the ISecureObject contains a description of the security disposition.

Key Methods

Method Return Value Description
EvalSecurity() SecurityResults Recursively calculates the security results for the current object and all descendants.
FindChild<T>( uniqueName ) T, where T : ISecureObject Recursively searches the Children hierarchy for a matching: child.UniqueName.Equals( uniqueName, StringComparison.OrdinalIgnoreCase ) )

Example Code

//Calculate SecurityResults for the object hierarchy
SecurityResults results = secureObject.EvalSecurity();

//Find a child
SecureObject childObject = secureObject.FindChild<SecureObject>( "uniqueName" );

ISecurityDescriptor

Field Type Required Description
DaclAllowInherit bool Yes Specifies if the Dacl can inherit permission Aces from parent-ISecureObject-Dacls. Default is true.
SaclAllowInherit bool Yes Specifies if the Sacl can inherit audit Aces from parent-ISecureObject-Sacls. Default is true.
SaclAuditTypeFilter AuditType Yes Specifies the granularity of Audit messages. See below for detail. Default is SuccessAudit | FailureAudit | Information | Warning | Error
Dacl IDiscretionaryAcl Yes A list of permission Aces for the current ISecureObject. At runtime, inheritable permission Aces are evaluated as part of the current Dacl.
Sacl ISystemAcl Yes A list of audit Aces for the current ISecureObject. At runtime, inheritable audit Aces are evaluated as part of the current Sacl.
Results SecurityResults Yes System-generated list of resultant security, calculated post-eval.
[Flags]
public enum AuditType
{
    SuccessAudit = 1,
    FailureAudit = 2,
    Information = 4,
    Warning = 8,
    Error = 16,
    Detail = 32
}

Example Code

//create a new SecureObject
SecureObject secureObject = new SecureObject() { UniqueName = "uniqueName" };
//block inheritance of Dacl Aces from parent objects
secureObject.Security.DaclAllowInherit = false;
//populate the Dacl
secureObject.Security.Dacl = new DiscretionaryAcl
{
    new AccessControlEntry<FileSystemRight>
    {
        Allowed = true,
        Right = FileSystemRight.FullControl
    },
    //this is an explicit-Deny Ace, and will not be inherited to child Dacls
    new AccessControlEntry<FileSystemRight>
    {
        //explicit Deny, overrides Execute, List from FullControl above
        Allowed = false,
        Right = FileSystemRight.Execute | FileSystemRight.List,
        //will not be inherited to child Dacls
        Inheritable = false
    },
    new AccessControlEntry<UIRight>
    {
        Right = UIRight.Operate | UIRight.Visible
    }
};

AccessControlLists (Acls)

DiscretionaryAcl (Dacl (Permissions, Rights))

The Discretionary Access Control List is a collection of IAccessControlEntry (Aces). A Dacl specifies whether specific permissions are granted/denied to an object.

SystemAcl (Sacl)

The System Access Control List is a collection of IAccessControlEntryAudit (AuditAces). A Sacl specifies what permissions (as specified in the Dacl) will generate audit records.

IAccessControlEntry<T> (Ace)

Field Type Required Description
UId Guid Yes Primary key in the datastore, a GUID to support replication amongst stores.
Allowed bool Yes A value of true grants access to a permission, and a value of false explicitly denies access to a permission. Important: An explicit deny always overrides a grant.
Inheritable bool Yes Specifies whether the current Ace will propagate to child Dacls.
InheritedFrom Nullable Guid No System-populated at runtime; the UId of the original Ace from which the current entry was created, <null> if provisioned directly, or Guid.Empty if dynamically created by an AceConverter.
TrusteeUId Nullable Guid No* The UId of the User or Group to which the Ace is assigned. When the containing Acl is evaluated, any Aces present will be included in the resultant security calculation. Strictly speaking, Trustee-free Aces could be inserted into an Acl at runtime and evaluated safely.
Right T Yes T can be any Enum with a Flags attribute, such that individual rights can be combined for a single permission entry. Built-in Rights enums are shown below.

Example Code

//create a new Ace
//this is an explicit-Deny Ace, and will not be inherited to child Dacls
IAccessControlEntry<FileSystemRight>
    new AccessControlEntry<FileSystemRight>
    {
        //explicit Deny, overrides Execute, List from FullControl above
        Allowed = false,
        Right = FileSystemRight.Execute | FileSystemRight.List,
        //will not be inherited to child Dacls
        Inheritable = false 
    };

Built-in Right-types

Extend Suplex easily by providing your own enums with a Flags attribute.

[Flags]
public enum UIRight
{
    FullControl = 7,
    Operate = 4,
    Enabled = 2,
    Visible = 1
}

[Flags]
public enum RecordRight
{
    FullControl = 31,
    Delete = 16,
    Update = 8,
    Insert = 4,
    Select = 2,
    List = 1
}

[Flags]
public enum FileSystemRight
{
    FullControl = 511,
    Execute = 256,
    Delete = 128,
    Write = 64,
    Create = 32,
    Read = 16,
    List = 8,
    ChangePermissions = 4,
    ReadPermissions = 2,
    TakeOwnership = 1
}

[Flags]
public enum SynchronizationRight
{
    TwoWay = 7,
    Upload = 5,
    Download = 3,
    OneWay = 1
}

IAccessControlEntryAudit (AuditAce)

An IAccessControlEntryAudit ace inherits all the properties from IAccessControlEntry\, but changes the behavior of Allowed and additionally implements Denied, as described below. For both Allowed and Denied, audits apply whether Aces are direct or inherited, and for Denied, whether implicit or explicit.

Field Type Required Description
Allowed bool Yes Specifies whether to audit grants for a permission.
Denied bool Yes Specifies whether to audit explicit denies for a permission.

Example Code

//create a new AuditAce
//this is an explicit-Deny Ace, and will not be inherited to child Dacls
IAccessControlEntryAudit<FileSystemRight>
    new AccessControlEntryAudit<FileSystemRight>
    {
        //will audit if Execute, List are allowed
        Allowed = true,
        //will audit if Execute, List are denied (implicitly or explicitly)
        Denied = true,
        Right = FileSystemRight.Execute | FileSystemRight.List,
        //will not be inherited to child Dacls
        Inheritable = false
    };

IAccessControlEntryConverters<TSource, TTarget> (Permission Converters)

An IAccessControlEntryConverter translates the resultant security for any given Ace/Right into a new Ace/Right of any other Ace type. The new Ace's Allowed property is based on the source-Ace security result, and the new Ace can be configured with standard Inheritable settings.

Field Type Required Description
TSource Right Type Yes Specifies the Right type from which to take the resultant Allowed value.
SourceRight TSource Yes Specifies the Right value from which to take the resultant Allowed value.
TTarget Right Type Yes Specifies the Right type (T) to be used when creating a new IAccessControlEntry\.
TargetRight TTarget Yes Specifies the Right value (of T) for the new Ace.
Inheritable bool Yes Specifies whether the new Ace will propagate to child Dacls. Default is true.
UId Guid No Unique Id for identifying the record in a datastore.

Example Code

//Creates an AceConverter to convert RecordRight.Insert -> UIRight.Enabled,
//  where the resultant AccessAllowed value for RecordRight.Insert becomes
//  the Allowed value for UIRight.Enabled.
IAccessControlEntryConverter converter =
    new AccessControlEntryConverter<RecordRight, UIRight>
{
    SourceRight = RecordRight.Insert,
    TargetRight = UIRight.Enabled,
    Inheritable = true
};

More Information

In effect, AceConverters create new Aces at runtime and inject them into the Dacl. From the example code above, a new Ace with Right => UIRight.Enabled equal to the resultant AccessAllowed value for RecordRight.Insert from the current ISecureObject will be created, inserted, and subsequently evaluated.

this.Security.Dacl.Add(
    new AccessControlEntry<UIRight>
    {
        Allowed = this.Security.Results.GetByTypeRight( RecordRight.Insert ).AccessAllowed,
        Right = UIRight.Enabled
    }
);

Results (SecurityResults)

A dictionary of of SecurityResult entries, set by the system at runtime when a SecurityDescriptor is evaluated. One SecurityResult object will exist in the dictionary for each Right-type, where the SecurityResult object is defined as:

Field Type Required Description
RightName string Yes The name of the permission.
AccessAllowed bool Yes Specifies if access was granted or denied.
AuditSuccess bool Yes Specifies if the permission will be audited for AccessAllowed = true.
AuditFailure bool Yes Specifies if the permission will be audited for AccessAllowed = false.

Example Code

//Calculate SecurityResults for the object hierarchy
secureObject.EvalSecurity();

//Assess 'AccessAllowed' (bool) for the object
secureObject.Security.Results.GetByTypeRight( UIRight.Visible ).AccessAllowed;

//Assess 'AccessAllowed' for a descendant (child) object
secureObject.FindChild<SecureObject>( "uniqueName" ).
    Security.Results.GetByTypeRight( RecordRight.List ).AccessAllowed;