The Directory API (Early Access)

Note The Directory API is an Early Access Feature. For access, please contact your SGNL Account Team.

The Directory API represents a powerful extension of SGNL’s Access Service suite, designed to address complex organizational data requirements that go beyond simple authorization decisions. While the other Access APIs answer questions about permissions and access, the Directory API answers a more nuanced question:

For this Principal performing this Action on this Asset - tell me about this Principal

The Directory API enables organizations to expose and return complex structures of the SGNL graph while maintaining the hierarchical relationships between entities. This makes it particularly valuable for organizations with custom entitlement stores, complex role hierarchies, or intricate node relationships that need to be preserved in API responses.

Key Capabilities

The Directory API maintains the structure of SGNL’s graph directory when returning responses, enabling organizations to:

  • Preserve Graph Relationships: Return structured data that maintains the connections between users, roles, applications, and permissions
  • Custom Entitlement Support: Work seamlessly with complex entitlement stores and custom authorization models
  • Policy-Aware Filtering: Leverage SGNL’s policy engine to ensure only authorized principals can access directory information
  • Contextual Filtering: Apply dynamic filters based on request context to return only relevant data
  • Versioned Configurations: Maintain multiple directory configurations and iterate safely

Configuration Requirements

Prerequisites

  • A SGNL Client
  • A SGNL User Account with Admin privileges
  • At least 1 system of record integrated to SGNL, containing principals and their relationships
  • A Protected System configured with an Authentication Token
  • Directory configuration defining the graph structure to be returned

Setting Up a Directory Configuration

To get started with a new Directory:

  1. Load the SGNL Consonle and click through to a Protected System you have configured with at least one policy, allowing access for a test principal configured in the SoR in your request config
  2. From the tabs at the top of the Protected System, select ‘Directory’
  3. Select ‘Add Configuration’ to add a new Directory Configuration
  4. Select the starting principal, i.e. the node type that matches incoming principal IDs (e.g., Entra ID users)
  5. Next, specify the graph structure you want to return, that is, relationships from the Principal, through various nodes in the graph via relationships Note In the current iteration, SGNL requires relationships are consistently directed outward from the Principal, through nodes
  6. Give each of the Nodes you select a name, this nodeName will be the key name in the json response that includes that object

Directory Configuration Example

  1. Once you have established the necessary sub-graph structure, select ‘Add Selected Objects’

Directory Configuration Example

  1. You can now click on individual nodes to add conditions, based on incoming request context (either well-known fields, or custom fields), or data you enter

Directory Configuration Example

  1. Once complete, save the version
  2. Ensure you have an Authentication Token, or generate a new Token to test the Directory

Each directory configuration is versioned, allowing for safe iteration and rollback capabilities.

API Usage

Basic Directory Query

cURL Request

curl --location 'https://{clientName}.sgnlapis.cloud/access/v2/directory/query?directoryId={directoryId}' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {Protected System Authentication Token}' \
--data-raw '{
    "principal": {
        "id": "john.doe@example.com",
        "ipAddress": "192.168.1.100"
    },
    "query": {
        "action": "access",
        "assetId": "corporate-directory"
    },
    "context": {
        "appName": "EmployeePortal",
        "requestSource": "web"
    }
}'

cURL Response

{
    "evaluationDuration": 15,
    "issuedAt": "2024-07-24T09:40:24.470844489Z",
    "results": [
        {
            "accountEnabled": true,
            "applications": [
                {
                    "appId": "101",
                    "appName": "HR_System",
                    "appStatus": "active",
                    "roles": [
                        {
                            "appId": "101",
                            "roleId": "1001",
                            "roleName": "Employee",
                            "roleStatus": "active",
                            "description": "Standard employee access",
                            "permissions": [
                                {
                                    "appId": "101",
                                    "roleId": "1001",
                                    "permissionId": "10001",
                                    "permissionName": "ViewProfile",
                                    "permissionStatus": "active"
                                },
                                {
                                    "appId": "101",
                                    "roleId": "1001",
                                    "permissionId": "10002",
                                    "permissionName": "UpdateContact",
                                    "permissionStatus": "active"
                                }
                            ]
                        },
                        {
                            "appId": "101",
                            "roleId": "1002",
                            "roleName": "Manager",
                            "roleStatus": "active",
                            "description": "Management privileges",
                            "permissions": [
                                {
                                    "appId": "101",
                                    "roleId": "1002",
                                    "permissionId": "10003",
                                    "permissionName": "ViewReports",
                                    "permissionStatus": "active"
                                }
                            ]
                        }
                    ],
                    "systemId": "hr-001"
                }
            ],
            "businessPhones": ["+1-555-123-1234"],
            "createdDateTime": "2024-01-15T08:30:00Z",
            "department": "Engineering",
            "displayName": "John Doe",
            "givenName": "John",
            "id": "550e8400-e29b-41d4-a716-446655440000",
            "mail": "john.doe@example.com",
            "mailNickname": "john.doe",
            "surname": "Doe",
            "userPrincipalName": "john.doe@example.com",
            "userType": "Member"
        }
    ]
}

Contextual Filtering

The Directory API supports powerful filtering capabilities through context parameters. You can filter the returned graph structure based on dynamic values passed in the request context. This is an important feature for optimizing response size and ensuring applications receive only relevant data.

Filtered Request Example

curl --location 'https://{clientName}.sgnlapis.cloud/access/v2/directory/query?directoryId={directoryId}' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {Protected System Authentication Token}' \
--data-raw '{
    "principal": {
        "id": "jane.smith@example.com",
        "deviceId": "device-12345"
    },
    "query": {
        "action": "login",
        "assetId": "application-portal"
    },
    "context": {
        "appName": "HR_System",
        "environment": "production"
    }
}'

This request would return only the roles and permissions for the “HR_System” application, filtered by the context provided.

Custom Transforms

You can also customize the format of both the inbound request and response, depending on the system that is calling SGNL. The Directory API supports Custom Transforms, enabling the request and response to be totally customized to match your application’s expected format.

This powerful feature allows you to adapt the Directory API to work seamlessly with existing systems and applications, ensuring compatibility without requiring changes to your existing integrations.

Policy Integration

The Directory API is fully policy-aware, meaning it evaluates configured policies before returning directory information. This enables organizations to:

  • Risk-Based Access: Deny directory access for compromised or high-risk users
  • Conditional Access: Apply time-based, location-based, or device-based restrictions
  • Role-Based Filtering: Return different levels of detail based on the requesting principal’s role
  • Compliance Controls: Ensure directory access meets regulatory requirements

Policy Example

A common policy might deny directory access for compromised identities:

Deny access to the Directory API for any compromised identity

When this policy is active, users flagged as compromised (e.g., by CrowdStrike or other security tools) will receive a 401 Unauthorized response instead of directory data.

Audit and Logging

All Directory API access requests are automatically logged in SGNL’s Access Logs, providing complete audit trails for compliance and security monitoring. These logs include details about the requesting principal, policy decisions, and access patterns.

Common Use Cases

Identity Provider Integration

IDPs like Okta can use the Directory API to enrich user sessions with detailed role and permission information, enabling more granular authorization decisions at the application level.

Custom Authorization Models

Organizations with complex entitlement systems can expose their authorization hierarchies through the Directory API, allowing applications to understand the full context of a user’s permissions.

Audit and Compliance

The Directory API provides a structured way to query and understand user entitlements across systems, supporting audit processes and compliance reporting.

Just-in-Time Provisioning

Applications can use the Directory API to dynamically provision user access based on their current entitlements and organizational relationships.

Error Handling

Common Response Codes

  • 200 OK: Successful directory query with results
  • 400 Bad Request: Invalid request syntax or missing required parameters
  • 401 Unauthorized: Principal denied access based on policy evaluation
  • 404 Not Found: Directory ID not found or inactive

Error Response Example

{
    "error": {
        "code": 401,
        "internalCode": "SGNL-40100",
        "message": "The user is not authorized to make the request.",
        "status": "UNAUTHORIZED"
    }
}

Best Practices

Directory Configuration

  • Start Simple: Begin with basic relationships and add complexity incrementally
  • Use Descriptive Keys: Choose meaningful names for response keys as they become the API response structure
  • Version Management: Create new versions when making significant changes to preserve existing integrations
  • Relationship Direction: Ensure all relationship arrows point in the same direction (top-down) for optimal performance

Security Considerations

  • Policy-First Design: Always configure appropriate access policies before deploying
  • Least Privilege: Return only the minimum data necessary for the application’s function
  • Regular Reviews: Periodically review directory configurations and access patterns
  • Token Management: Secure and rotate Protected System authentication tokens regularly

The SGNL Directory API documentation can be found on our API Documentation Page.