Skip to content

plugin sdk custom privileges

Andre Lafleur edited this page Dec 11, 2025 · 1 revision

Privileges in Security Center are permissions that control what users can do and see in the system. They define everything from basic access to applications to specific actions like viewing video, operating doors, or modifying system settings. Administrators assign these privileges to users or user groups to enforce security policies and ensure people only access features relevant to their role.

Implementing custom privileges enables you to assign specific permissions to non-admin users, controlling their access to your custom features based on their assigned privileges.

Custom privileges can be used to control access to:

  • Custom Entities - View, modify, add, or delete custom entity types
  • Custom Tasks - Access to custom tasks
  • Features - Any custom functionality within your integration

Implementing custom privileges

To implement custom privileges, you must:

  1. Define privileges in an XML file
  2. Assign and check privileges from your integration

1. Define privileges in an XML file

Create a file named [YourAssemblyName].privileges.xml where [YourAssemblyName] matches either your Plugin (server module) or Workspace module (client module) DLL name without the .dll extension.

Security Center automatically discovers privilege files using this pattern:

  • Looks for files named *.privileges.xml
  • Expects a corresponding .dll file with the same base name
  • If MyIntegration.privileges.xml exists, Security Center looks for MyIntegration.dll
  • If the DLL doesn't exist, the privilege file is ignored

Example: If your DLL is MyIntegration.dll, create MyIntegration.privileges.xml

XML Structure

<?xml version="1.0" encoding="utf-16"?>
<ModulePrivileges>
  <Resources fallbackLanguage="en">
    <Image name="CustomEntityIcon" type="Base64">iVBORw0KGgoAAAANSUhEUgAA...==</Image>
  </Resources>
  <Privileges>
    <!-- Custom Entity Privileges -->
    <Privilege id="{12345678-1234-1234-1234-123456789ABC}" parentId="{38ACC600-4A32-44ff-8DF5-0797D888930B}" type="Group" description="My Custom Entity" detail="Controls access to custom entity features" priority="1" image="CustomEntityIcon" />
    <Privilege id="{11111111-1111-1111-1111-111111111111}" parentId="{12345678-1234-1234-1234-123456789ABC}" type="Entity" description="View custom entity properties" detail="Allows users to view the configuration and properties of custom entities" priority="1" image="Eye" />
    <Privilege id="{22222222-2222-2222-2222-222222222222}" parentId="{11111111-1111-1111-1111-111111111111}" type="Entity" description="Modify custom entity properties" detail="Allows users to edit and update custom entity configurations" priority="2" image="Edit" />
    <Privilege id="{33333333-3333-3333-3333-333333333333}" parentId="{22222222-2222-2222-2222-222222222222}" type="Entity" description="Add custom entities" detail="Allows users to create new custom entities" priority="3" image="Add" />
    <Privilege id="{44444444-4444-4444-4444-444444444444}" parentId="{22222222-2222-2222-2222-222222222222}" type="Entity" description="Remove custom entities" detail="Allows users to delete existing custom entities" priority="4" image="Remove" />
    
    <!-- Task/Page Privileges -->
    <Privilege id="{87654321-1234-1234-1234-123456789ABC}" parentId="{38ACC600-4A32-44ff-8DF5-0797D888930B}" type="Group" description="Custom Tasks" detail="Access to custom task functionality" priority="2" />
    <Privilege id="{77777777-7777-7777-7777-777777777777}" parentId="{87654321-1234-1234-1234-123456789ABC}" type="Task" description="Access custom report" detail="Allows users to view and generate custom reports" priority="1">
      <Description language="fr" type="Embedded">Accès au rapport personnalisé</Description>
    </Privilege>
    <Privilege id="{88888888-8888-8888-8888-888888888888}" parentId="{87654321-1234-1234-1234-123456789ABC}" type="Task" description="Access configuration page" detail="Allows users to access the custom configuration interface" priority="2" />
  </Privileges>
</ModulePrivileges>

All privileges are defined using <Privilege> elements with the following attributes:

  • id: Unique GUID for the privilege
  • description: Short description text shown in privilege lists
  • detail: Optional detailed description shown as a tooltip (more explanatory than description)
  • type: Privilege type (see Privilege Types below)
  • parentId: Parent privilege GUID (creates hierarchy)
  • priority: Number used to sort items under the same parent (privileges with the same priority are sorted alphabetically)
  • image: Icon name referencing custom images or built-in icons
  • hierarchical: Optional boolean for entity privileges that apply to hierarchical entities
  • hidden: Optional boolean to hide privileges from the UI

Description

Add translated descriptions for international deployments:

<Privilege id="{12345678-1234-1234-1234-123456789ABC}" parentId="{38ACC600-4A32-44ff-8DF5-0797D888930B}" type="Task" description="English Description">
  <Description language="fr" type="Embedded">Description française</Description>
  <Description language="es" type="Embedded">Descripción en español</Description>
</Privilege>

Type

  • Group: A container for organizing related privileges. Groups cannot be used for actual permission checking, they only help organize privileges in the Config Tool interface.

  • Task: A permission for general functionality like viewing reports or accessing configuration pages. These permissions apply system-wide.

  • Entity: A permission for specific entity operations like viewing, modifying, adding, or deleting particular types of entities (cameras, doors, custom entities, etc.).

ParentId

To find the appropriate parent privileges for your custom privileges, you need to identify them from your Security Center system. Here's how to find parent privilege GUIDs:

  1. Open Config Tool and navigate to System > Users and User Groups > Privileges
  2. Press Ctrl+Shift+G to display GUIDs next to privilege names
  3. Explore the privilege hierarchy to understand the existing structure and find where your privileges logically belong
  4. Use the GUIDs you find in your XML file

Selection Guidelines:

  1. Examine the existing privilege tree structure in Config Tool to understand how privileges are organized
  2. Choose a parent that logically fits your privilege's purpose and functionality
  3. Look for similar existing privileges and see where they're placed in the hierarchy
  4. Consider creating a new group under an appropriate parent if your privileges don't fit existing categories
  5. Test the hierarchy to ensure it makes sense from a user experience perspective

Priority

The priority attribute controls the display order of privileges within the same parent group. Understanding priority behavior is important for organizing your privilege hierarchy:

Sorting Logic:

  1. Lower numbers have higher priority - privileges with priority 1 appear before priority 2
  2. Alphabetical fallback - when privileges have the same priority, they're sorted alphabetically by description
  3. Special handling - fallback privileges always appear last, regardless of priority value

Example Priority Usage:

<!-- These will appear in this order under the same parent -->
<Privilege priority="1" description="View entities" />      <!-- Appears first -->
<Privilege priority="1" description="Add entities" />       <!-- Second (alphabetical) -->
<Privilege priority="1" description="Delete entities" />    <!-- Third (alphabetical) -->
<Privilege priority="2" description="Advanced settings" />  <!-- Fourth (lower priority) -->

Image

Security Center supports two types of images for privileges with graceful fallback handling:

Built-in Icons (recommended for common operations):

<Privilege id="{22222222-2222-2222-2222-222222222222}" ... image="Edit" />
<Privilege id="{33333333-3333-3333-3333-333333333333}" ... image="Add" />
<Privilege id="{44444444-4444-4444-4444-444444444444}" ... image="Remove" />

Custom Base64 Images:

<Resources fallbackLanguage="en">
  <Image name="CustomEntityIcon" type="Base64">iVBORw0KGgoAAAANSUhIfzAAAAdgAAAHY...==</Image>
  <Image name="TaskIcon" type="Base64">iVBORw0KGgoAAAAXBIWXEAmpwYUk0AAlA...==</Image>
</Resources>

Reference these images using the image attribute:

<Privilege id="{12345678-1234-1234-1234-123456789ABC}" ... image="CustomEntityIcon" />

Image Handling Details:

  • Built-in icons: Reference directly by name (Edit, Add, Remove, etc.). No Resources section needed
  • Custom images: Define in Resources section with type="Base64", then reference by name
  • Graceful fallback: If an image reference fails or the file can't be found, Security Center automatically uses a default privilege icon
  • Mixed approach: You can use both built-in and custom images in the same XML file

2. Assign and check privileges

To check if a user has a specific privilege, you use the SecurityManager.IsPrivilegeGranted() method. How you access SecurityManager depends on where you're writing your code:

In PageDescriptor subclasses:

public override bool HasPrivilege()
{
    // m_sdk is a protected field inherited from PageDescriptor
    return m_sdk.SecurityManager.IsPrivilegeGranted(myPrivilege);
}

In other Workspace SDK classes:

 Workspace.Sdk.SecurityManager.IsPrivilegeGranted(myPrivilege);

GUID Management Best Practices

Create a dedicated constants class to manage all your privilege GUIDs consistently:

public static class MyIntegrationPrivileges
{
    // Custom Entity Group
    public static class CustomEntity
    {
        public static SdkPrivilege Group { get; } = new(new Guid("12345678-1234-1234-1234-123456789ABC"));
        public static SdkPrivilege View { get; } = new(new Guid("11111111-1111-1111-1111-111111111111"));
        public static SdkPrivilege Modify { get; } = new(new Guid("22222222-2222-2222-2222-222222222222"));
        public static SdkPrivilege Add { get; } = new(new Guid("33333333-3333-3333-3333-333333333333"));
        public static SdkPrivilege Delete { get; } = new(new Guid("44444444-4444-4444-4444-444444444444"));
    }

    // Task Privileges
    public static class Tasks
    {
        public static SdkPrivilege Group { get; } = new(new Guid("87654321-1234-1234-1234-123456789ABC"));
        public static SdkPrivilege AccessReport { get; } = new(new Guid("77777777-7777-7777-7777-777777777777"));
        public static SdkPrivilege AccessConfiguration { get; } = new(new Guid("88888888-8888-8888-8888-888888888888"));
    }
}

Benefits of This Approach:

  • Centralized GUID management
  • Compile-time checking
  • Easy refactoring
  • Clear organization by feature area

Privilege Naming Conventions

Follow these naming conventions for consistency:

Description (shown in privilege lists):

  • Use clear, concise action-oriented language
  • Start with a verb when possible
  • Examples: "View custom entities", "Modify custom entity properties", "Access custom report"

Detail (shown as tooltips):

  • Always start with "Allows users to..." or "Controls access to..."
  • Provide specific context about what the privilege enables
  • Examples: "Allows users to view the configuration and properties of custom entities"

XML Naming Pattern:

<!-- Group privileges -->
<Privilege description="My Custom Integration" detail="Controls access to custom integration features" />

<!-- Entity privileges (CRUD pattern) -->
<Privilege description="View [entity name]" detail="Allows users to view [entity name] properties and configuration" />
<Privilege description="Modify [entity name]" detail="Allows users to edit and update [entity name] settings" />
<Privilege description="Add [entity name]" detail="Allows users to create new [entity name] instances" />
<Privilege description="Delete [entity name]" detail="Allows users to remove existing [entity name] instances" />

<!-- Task privileges -->
<Privilege description="Access [feature name]" detail="Allows users to access and use [feature name] functionality" />

Consistency Rules:

  1. Use sentence case for descriptions
  2. Keep descriptions under 50 characters when possible
  3. Make details descriptive but concise (under 100 characters)
  4. Use consistent terminology across your integration

Custom Entities

Assign the view, modify, add, and delete privileges through CustomEntityTypeDescriptor:

  private void CreateDeviceCustomEntity()
  {
      var config = (SystemConfiguration)Workspace.Sdk.GetEntity(SystemConfiguration.SystemConfigurationGuid);

      var capabilities = CustomEntityTypeCapabilities.CanBeFederated |
                         CustomEntityTypeCapabilities.IsVisible |
                         CustomEntityTypeCapabilities.MaintenanceMode |
                         CustomEntityTypeCapabilities.CreateDelete |
                         CustomEntityTypeCapabilities.MapSupport;

      var descriptor = new CustomEntityTypeDescriptor(AedUnitCustomEntityType.Id, Resources.CustomEntityTypeName,
          capabilities, new Version(1, 0))
      {
          ViewPrivilege = AedUnitCustomPrivilege.View,
          ModifyPrivilege = AedUnitCustomPrivilege.Modify,
          AddPrivilege = AedUnitCustomPrivilege.Add,
          DeletePrivilege = AedUnitCustomPrivilege.Delete,
      };

      config.AddOrUpdateCustomEntityType(descriptor);
  }

Deploy the XML File

For Workspace Modules (client module)

  • Alongside your workspace module DLL (on client machines)
  • In the Security Center installation directory (on server machine and failover servers): C:\Program Files (x86)\Genetec Security Center X.Y\

For Plugins (server module)

  • Alongside your plugin DLL (where the plugin runs)

Testing and Verification

1. Verify Privilege Loading

  1. Open Config Tool
  2. Navigate to System > Users and User Groups
  3. Select a user or user group
  4. Click Privileges tab
  5. Verify your custom privileges appear under the appropriate group

2. Test Privilege Functionality

  1. Create a test user without admin privileges
  2. Assign specific custom privileges to the user
  3. Log in as the test user
  4. Verify the user can only perform actions for which they have privileges.

3. Check Feature Visibility

  1. Users should only see the properties of custom entities if they have the View privilege
  2. Tasks and pages should only appear if users have the corresponding task privileges
  3. Users without specific privileges should not see related UI elements

Troubleshooting

Privileges Not Appearing in Config Tool

Possible Causes:

  • XML file not in the correct location
  • Incorrect file naming
  • XML syntax errors
  • Genetec Server not restarted
  • GUID conflicts

Solutions:

  1. Verify the XML file is deployed to the correct locations
  2. Check file naming matches assembly name exactly
  3. Validate XML syntax.
  4. Restart the Genetec Server service
  5. Ensure unique GUIDs for all privileges

Privileges Appear But Don't Work

Possible Causes:

  • GUID mismatch between XML and code
  • Feature associations not implemented correctly
  • Privilege hierarchy issues

Solutions:

  1. Verify all GUIDs match exactly between XML and code
  2. Confirm all features properly check the privilege using appropriate methods
  3. Check privilege parent relationships in XML

Security Center SDK


Web SDK Developer Guide

  • Getting Started Setup, authentication, and basic configuration for the Web SDK.
  • Referencing Entities Entity discovery, search capabilities, and parameter formats.
  • Entity Operations CRUD operations, multi-value fields, and method execution.
  • Partitions Managing partitions, entity membership, and user access control.
  • Custom Fields Creating, reading, writing, and filtering custom entity fields.
  • Custom Card Formats Managing custom credential card format definitions.
  • Actions Control operations for doors, cameras, macros, and notifications.
  • Events and Alarms Real-time event monitoring, alarm monitoring, and custom events.
  • Incidents Incident management, creation, and attachment handling.
  • Reports Activity reports, entity queries, and historical data retrieval.
  • Performance Guide Optimization tips and best practices for efficient API usage.
  • Reference Entity GUIDs, EntityType enumeration, and EventType enumeration.
  • Under the Hood Technical architecture, query reflection, and SDK internals.
  • Troubleshooting Common error resolution and debugging techniques.

Media Gateway Developer Guide


Web Player Developer Guide

Clone this wiki locally