Skip to main content
Kinetic Community

KSL Reference

 

This article covers the low-level details of the Kinetic Security Language, how it is implemented, and how to write complex security policies.

Summary

The Kinetic Security Language (KSL) was introduce in Kinetic Task 3.0, and is used as a strategy for defining and managing access control.  For an overview of KSL in Kinetic Task, please see the Getting Started with KSL article in the Kinetic Task 3.0 User Guide.

This article is intended for those who want a deep understanding of KSL and how to write complex policies.  For a collection of pre-written policies, plase see the KSL Snippits article in the Kinetic Task Resources section.

 

Policy Rules and Messages

Policy Rules

The policy rule defines logic to specify whether access should be allowed or denied.  Just like a task node connectors in the Kinetic Task Tree Builder, policy rules are defined using the Ruby programming language and evaluated using JRuby (an implementation of the Ruby programming language that runs within a Java virtual machine).  For more information about Ruby, please see the Ruby Resources page in the Kinetic Task Resources section.

The policy rule can be a simple, one line Ruby expression or be more complex with multiple lines of Ruby code.  The only requirement is that the policy rule evalutes to either true (indicating the requester should be granted access to the resource) or false (indicating the requester should be denied access to the resource).

The simplest example of a policy rule would be:

false

This rule will always evaluate to false, and thusly prevents all access to the resource.  Another example could be:

@request.remote_addr == '127.0.0.1'

This simple expression will only evaluate to true if the request is originating from the local machine and being sent over the loopback device (IE the resource is being accessed using the IP address 127.0.0.1).  A more complex rule, which allows access to a range of IP addresses, could be:

require 'ipaddr'
range = IPAddr.new('192.168.1.0/24')
range.include?(@request.remote_addr)

In this example, the policy rule is loading the 'ipaddr' library, which defines the IPAddr helper class.  An object is instantiated from the IPAddr class on the second line, and the include? instance method is called on the last line, which returns the result.  The policy rule evaluates to the result of the last expression executed, or in this case the result of range.include?(@request.remote_addr).  This expression returns a boolean value (true or false) indicating whether the originating IP address is in the range.  The usage of libraries is explored further in the Example Shared Libraries/Variables section below.

 

Policy Messages

The policy messages define the text that is returned if access is being denied.  Similar to policy rules, policy messages leverage the Ruby programming language and JRuby platform.  However, the policy message is interpreted using ERB rather than as pure Ruby code.  ERB is an implementation of eRuby (Embedded Ruby), which is a templating system very similar to ASP, JSP, or PHP.  This is the exact same strategy that is used in Kinetic Task tree node parameters.

Below is a simple example of a policy message that leverages ERB tags to insert dynamic content:

request does not originate from IP whitelist (<%= @request.remote_addr %>)

The above policy message sample combines static and dynamic content.  The text between the <%= and %> tags is evaluated as a Ruby code and inserts the results of the expression as dynamic content.  In the case of this statement, the IP address that the request originated from (IE the value of the remote_addr accessor on the @request variable) is inserted between the parenthesis.

The same variables exposed to the policy rule, which are defined based on the policy type, are also exposed to the policy message.  Additionally, any libraries that are loaded by the policy rule, including those loaded from /WEB-INF/data/ksl, and any variables defined in the policy rule are available in the message. 

 

Shared Libraries/Variables

Lets look at the last policy rule example again, which illustrates the ability to use a library in the policy rule:

require 'ipaddr'
range = IPAddr.new('192.168.1.0/24')
range.include?(@request.remote_addr)

In the case of this example, the 'ipaddr' library is a standard library, meaning that the library is packaged with the core Ruby language (for a list of standard libraries in Ruby, see http://ruby-doc.org/stdlib-1.8.7/).  In some cases, it may be beneficial to include a non-standard or custom library.  In these cases, the library or ruby script can be included in a 'ksl' subdirectory of the Kinetic Task data directory, which is /WEB-INF/data by default (for more information on the Kinetic Task data directory, see Chapter 4 - Advanced Configuration of the Kinetic Task User Guide).

The following snippits show a complex policy that leverages ArsModels to query a Remedy form for a blacklist entry and uses the 'Blacklist Reason' field value for the message if the entry exists:

/WEB-INF/data/ksl/sample.rb

# Requires the ArsModels library
require 'ars_models'
# Attempts to retrieve a Remedy record from the SEC_NetworkBlacklist form that
# matches the passed IP address.  This will return +nil+ if there is not a
# matching record.
def lookup_blacklist(ip_address)
  context = ArsModels::Context.new(:username => 'Demo', :server => '127.0.0.1', :port => 3000)
  form = ArsModels::Form.find('SEC_NetworkBlacklist', :context => context)
  return form.find_entry(:single, :conditions => %|'IP Address' = "#{ip_address}"|)
end

Policy Rule

require 'sample'
@blacklist_record = lookup_blacklist(@request.remote_addr)
return @blacklist_record == nil

Policy Message

<%= @blacklist_record['Blacklist Reason'] %>

We can see from the above three snippits that the polcy rule is loading the sample.rb file, which defines the method lookup_blacklist.  The lookup_blacklist method is then called in the policy rule, and the result is stored in the @blacklist_record variable.  If the @blacklist_record variable is not nil, indicating that there a blacklist record was found, the policy rule denies access and the @blacklist_record variable is used in the message to output the blacklist reason.

 

API Access Variables

The following variables are exposed to API Access policy rules and messages (IE, policies that have a policy type of 'API Access').

@request

The @request variable represents the network request made to the Task API and is instance of the javax.servlet.http.HttpServletRequest Java class.  There are two pertinent methods that can be used for security policies:

@request.remote_addr
The @request.remote_addr accessor returns the IP address that the request originated from as a String.  This is useful for restricting access to specific machines or networks.  The remote_addr accessor corresponds to the HttpServletRequest getRemoteAddr() method.

@request.get_header(name)
The @request.get_header method returns the value HTTP header with the corresponding name as a String.  This is useful for restricting access based on pre-shared security tokens or for passing other values that could be used as lookups.  The get_header method corresponds to the HttpServletRequest getHeader() method.