Introduction

Triplesec has a simple API for read only access to role based access control information contained in a policy store. The returned information is used to make access control decisions on sensitive resources and operations. Applications ask the API whether or not a user, or a role (the user is in), has access to some application resource or is authorized to perform some application specific operation.

Triplesec uses LDAP although the Guardian API can use any kind of authorization (policy) store. The default authorization store is implemented against an LDAP store for several important reasons:

  • LDAP is language neutral and supported in multiple languages on various platforms. The API can be implemented in any language or platform that knows LDAP to enforce the same authorization policy.
  • LDAP connections are inexpensive relative to database connections. Several thousand connections to LDAP servers rather than hundreds of connections to an RDBMS can be supported.
  • LDAP replicates for increased data availability while maintaining the appearance of data localization. A centralized policy store is great however it introduces a single point of failure. High availability is a critical requirement of the policy store.
  • LDAP allows delegated administration. When access control information is centralized for administration, several applications will be managed centrally. Specialized administrators will need to manage different applications. The X.500 administrative model makes it extremely easy to assign different administrators as the authority for managing application policy.

The API is a read only interface regardless of the language that is used. Keeping the policy access API separate from policy management interfaces has several advantages. A clean separation simplifies policy management, tightens security, simplifies auditing and keeps each mechanism highly efficient at doing one specific task very well.

Entities

There are 4 logical entities: Permissions, Roles, Profiles, and an ApplicationPolicy. Here's a little picture to understand the relationships:

Permissions

The Guardian does not attempt to apply application semantics to permissions. Permissions are simply unique labels with a description within the authorization policy store. Permissions are application specific. It is the responsibility of an application to associate a meaning with a permission defined in the system. A content management application for example may have permissions modeled for creating, updating and deleting documents: createDocument, updateDocument, and deleteDocument. These permissions are specific to the content management system and it is up to this application to enforce, hence associate semantics with the permission. The Guardian API is simply used to determine if users have this permission or not.

Roles

Roles are application specific entities just like permissions. Application permissions are granted to application roles. Roles hence group together permissions to implement a Role Based Access Control (RBAC) Model. When users are assigned to roles, they inherit the permissions granted to the role. A RBAC model simplifies the management of authorization profiles by allowing administrators and application designers to manage user security with common assignable roles. There is no need to assign the same set of permissions to each user's profile when a role can be assigned instead to grant permissions in bulk.

Profiles

Guardian provides access to authorization profiles defined for an application. A profile is not the same as a user. Instead it contains a specific authorization configuration for a user. Users can have more than one authorization profile per application if this is desired. Usually a single profile per user will suffice although this may not hold for all applications and users.

A user can have a profile created for the document management system for example. Roles defined for the document management system can be added to the profile. Users are associated with application policy by creating profiles. Once an application profile is created for a user, the user operates in the roles assigned. The profile inherits all permissions granted to assigned roles so applications can ask whether or not a user has a specific permission to perform a function or access a resource. Instead of performing checks for specific permissions, applications can check role assignments on a profile to determine access as well.

Additional permissions can be granted or denied to a user's profile. Often fine grained control over authorization profiles are required to manage exceptions to established roles. User profiles may inherit from several roles yet a few permissions granted by these roles may need to be denied for specific users. Conversely, the user may need additional permissions that are not granted to any predefined roles they are assigned to. As more profiles require these permission tweaks, administrators define new roles for managing policy rather than assigning individual permissions to profiles. The authorization policy for an application eventually reaches equilibrium over time as new roles are defined for ad hoc exceptions. Role discovery and evolution is a natural part of an RBAC model.

ApplicationPolicy

In the real world, authorization policy is almost always application specific. Permissions, roles, and profiles defined for authorization do not apply to all applications. The protected resources and operations change across applications and domains. Guardian' design is based on this fact.

On startup, most applications will access permissions and roles defined by the system. Applications authenticate to access the policy store as unique application principals. The Guardian API and the policy store make certain applications only have read access to their policy details. An application cannot access authorization policy entities defined for other applications. This is often required to comply with several regulatory standards.

After users authenticate, the next natural step for an application is to access a user's authorization profile. The profile is often accessed on demand and applied while the user is logged into an application session.

The Guardian ApplicationPolicy interface allows read only access to the permissions, roles and profiles defined for an application. The application connects via a driver to obtain an ApplicationPolicy instance. If the policy store is not local to the application, the Guardian API implementation may cache all permissions and roles defined for the application but not any of the profiles. At any point profiles may be lazy loaded from the store by requesting a profile from the ApplicationPolicy object. ApplicationPolicy implementations my pool connections and distribute load across replicated authorization policy stores. During a user's session, authorization profiles can be accessed to check for specific permission grants, denials or roles the user is in. These checks are performed by the application to determine if access on a protected resource or operation is allowed.

Guardian Java API

Java was used for the first API implementation. As the API is further stabilized we'll introduce other implementations for Perl, C/C++ and VB.

The default ApplicationPolicy implementation uses JNDI to connect to an LDAP server configured with the Guardian LDAP schema. An ApplicationPolicyFactory is used to get an instance of an ApplicationPolicy. A driver is loaded by an ApplicationPolicyFactory to produce an ApplicationPolicy backed by the LDAP authorization policy store.

Once instantiated an ApplicationPolicy contains all the permissions and roles associated with the application. This information is populated from the store at initialization time. We recommend application developers acquire the ApplicationPolicy on startup.

At runtime profiles can be requested from the ApplicationPolicy. A new request for a profile lazy loads it from the policy store and caches it within the ApplicationPolicy for subsequent permission checks. Profile lookups may occur across multiple policy store replicas for load balancing and availability.

Example Code
// Register a driver
Class.forName( "org.safehaus.triplesec.guardian.ldap.LdapConnectionDriver" );

Properties props = new Properties();

// Set the base DN for the policy database.
props.setProperty(
        "applicationPrincipalDN",
        "appName=mockApplication,ou=applications,dc=example,dc=com" );
// Set the application credentials.
props.setProperty(
        "applicationCredentials",
        "testing" );

// Connect to the policy database and get the policy.
ApplicationPolicy policy = ApplicationPolicyFactory.newInstance(
                "ldap://localhost:10389/dc=example,dc=com", props );

// Get an appropriate profile for the current user.
Profile profile = policy.getProfile( "username" );

// Check permission before you perform 'read' operation.
profile.checkPermission( "read" );

// Insert your 'read' operation code here
...

Conclusions

Guardian is an authorization API for accessing the Triplesec policy store. Applications can use Guardian to manage permissions using an RBAC model. Its API is simple and designed to be as generic as possible for use in any domain. It is ideal for centralized authorization policy management and policy consistency across applications, languages and platforms. Triplesec Guardian meet the needs of several applications by making sure, it, as a centralized resource, is highly available, redundant and load balanced.

  • No labels