Simplify complex authorization logic for custom applications and data
Custom applications, also known as “home grown” applications, are designed, developed, and deployed for specific organizational needs. These applications are not provided by a generally available product or service which are from a third party provider, but rather are written from scratch using traditional programming languages (e.g. Java, Go, Node.js, C#,C) and user interface frameworks (e.g. REACT, Angular).
Teams frequently build home grown applications for transacting with sensitive data like billing, customer data, and employee information. With the high-value and high-risk nature of this data, compounded with the lack of pre-built and cost of custom-built security for these applications, identity teams find home grown applications a critical piece of a company’s landscape for managing access.
Continuous access management must be considered as a part of an overall zero trust security strategy for custom application development. Here are some points to consider when attempting to externalize access management for a custom application:
For more considerations and best practices for including security in your application development process visit the OWASP authorization cheat sheet.
Continuous access management is the combination of methods, technologies, and business processes used to manage access to applications, infrastructure, or data using a dynamic and real-time authorization check for every request made by a user, device, or application to a resource provider (e.g., Application, Microservice, Database).
This high level diagram depicts relationships between the request client, resource provider, and continuous access management services. This example shows a resource provider protected by a continuous access management enforcer or control point.
In cases where a control point or enforcer is not available, the resource provider may call the continuous access management policy engine directly for a real-time authorization decision.
SGNL provides continuous access management by building a dynamic graph of sanctioned enterprise activity through continuous data ingestion from systems of record. With SGNL, access control is enforced consistently and easily across all protected services, applications, and data using human-readable policies. By using SGNL for custom applications, you can externalize access management to a scalable and modern platform, minimize security exposure, and implement a truly least-privileged approach to securing your custom applications. Here are five benefits of using SGNL:
Using SGNL for your custom applications, you can externalize authorization to a continuous and centralized authorization solution, minimize security exposure, and implement a fine-grained least-privileged approach to securing your applications.
The solution consists of a SGNL policy engine (integration via the access service API), graph directory, data ingest adapters, and human-readable policy used for making authorization decisions. A custom application is configured to send authorization requests to the SGNL access service via the SGNL SDK or REST API. The SGNL access service responds to the custom application with allow or deny decisions considering the context of the authorization request. For example, context may consist of principal data, asset identifier, or network IP address. If the request is denied, the application sends the appropriate response to the caller.
SGNL continuously ingests data from systems of record to a central graph directory via resilient and performant data ingest adapters. This data includes identity data, such as users and groups, and any relevant data required to define access policies, such as ITSM cases, tickets from JIRA, or customers from a CRM.
In this post, we use ServiceNow and Azure Active Directory as the Systems of Record. Azure AD is our Identity Provider system of record, and ServiceNow provides the assigned and active case for the user.
Once the system of record data sources are set up, administrators can quickly author and manage human-readable policies based on the ingested data for granting or denying access to applications, APIs, and sensitive data. By implementing a centralized approach, SGNL provides consistency in centralized policy management, audit logging, and reporting across all assets an organization desires to protect (including APIs).
Instead of implementing complex custom logic in your custom application to evaluate access, you use SGNL to select policy snippets from the user interface and graphically build a human-readable policy. This ensures that any request to the custom application is evaluated against the latest data ingested from systems of record and the policies defined in SGNL.
This policy checks if the principal is a valid Azure AD user, belongs to the engineering organization, and is currently on call. SGNL applies this policy to an incoming access request from the custom application. The application sends the employee identifier, the action (e.g. Modify) they want to take on a case and the case identifier. SGNL will return an “Allow” decision if the employee belongs to the engineering organization and is on-call or a “Deny” decision if either of those conditions fail to match.
A developer may simplify authorization logic for a custom application by delegating complex authorization logic to the SGNL policy engine. The authorization decisions are made by the SGNL policy engine which is calculating policy against continuously ingested data from various systems of record (e.g. Azure AD, ServiceNow). In addition, SGNL automatically creates the appropriate relationships for that ingested data, and it calculates multiple human-readable policies in milliseconds. Below is an example sequence diagram for a custom application authorization request.
In the following Node.js sample code, the application implements a customAppEvaluateAccess() function that is passed an instance of a SGNL client (returned by the getClient() function), the principalId, the case id and the action (e.g. Modify) being performed by the employee. These are passed to the accessEvaluation() function which constructs the queries using helper functions in the SGNL SDK, and calls SGNL’s Access API using the instance of the SGNL client.
Based on the example policy in this post, the API either returns an allow if the user can modify a case or deny if the user does not meet the policy conditions. The custom application can process the response appropriately - either log and allow the access to go through, or log and deny the request.
const sgnl = require("sgnl");
// Build the SGNL Client
sgnlClient = getClient("<<Insert your Protected System Access Token here>>");
// Call SGNL Access API with principal, asset and action to get access decision
result = await customAppEvaluateAccess(
sgnlClient,
"alejandro.bacong@wholesalechips.co",
"Case-4321",
"Modify"
);
// Async function to access evaluation using the client
async function accessEvaluation(client, principal, assetId = "", action = "") {
const p = new sgnl.Principal(principal);
const queries = [];
if (assetId && action) {
queries.push({ assetId, action });
}
const accessRequest = new sgnl.AccessEvaluationRequest(p, queries);
const opts = { accessEvaluationRequest: accessRequest };
return client.accessEvaluation(opts);
}
// Function to get the client instance with the provided access token
function getClient(accessToken) {
const defaultClient = sgnl.ApiClient.instance;
defaultClient.basePath = "<<Insert your Access API URL>>";
defaultClient.authentications["bearerAuth"].accessToken = accessToken;
return new sgnl.AccessEvaluationClient(defaultClient);
}
// Example usage: Call customAppEvaluateAccess() from your custom app code
async function customAppEvaluateAccess(client, employeeId, caseId, action) {
try {
const result = await accessEvaluation(client, employeeId, caseId, action);
console.log(result);
return result;
} catch (error) {
console.error("Error:", error);
}
}
The SGNL SDK sends the following JSON request to the SGNL Access API Service.
{
"principal": {
"id": "alejandro.bacong@wholesalechips.co"
},
"queries": [
{
"assetId": "Case-4321",
"action": "Modify"
}
]
}
SGNL’s Access Service responds with a decision in a JSON format to the SDK. The Allow and Deny decision samples are for illustration purposes.
{
"decisions": [
{
"assetId": "Case-4321",
"action": "Modify",
"decision": "Allow"
}
],
"evaluationDuration": 13,
"issuedAt": "2023-07-20T23:47:06.644306908Z",
"principalId": "alejandro.bacong@wholesalechips.co"
}
{
"decisions": [
{
"assetId": "Case-1234",
"action": "Modify",
"decision": "Deny"
}
],
"evaluationDuration": 23,
"issuedAt": "2023-07-20T23:44:23.912490563Z",
"principalId": "alejandro.bacong@wholesalechips.co"
}
SGNL Access Service supports multiple asset and action queries for a principal. The following JSON response is an example of the response sent for two queries for the principal in the same authorization request.
{
"decisions": [
{
"action": "Modify",
"assetId": "Case-4321",
"decision": "Allow"
},
{
"action": "Modify",
"assetId": "Case-1234",
"decision": "Deny"
}
],
"evaluationDuration": 16,
"issuedAt": "2023-07-20T23:50:14.324374185Z",
"principalId": "alejandro.bacong@wholesalechips.co"
}
For more information on protecting your custom applications and view a step by step guide, visit our SGNL SDK help page.
Using SGNL for custom applications - especially those homegrown applications that contain high-value or high-risk data - organizations can reduce risk, developers can reduce authorization logic complexity, and teams can centralize access management policy in a single platform for making complex, consistent, and continuous authorization decisions.
Schedule time with a SGNLer to see how all this can work in your context.
Want more of the latest identity-first security topics and trends delivered to your inbox? Helpful and insightful content, no fluff.