Chapter 4. Veil2 Concepts

The following concepts are crucial to a full understanding of Veil2:

This looks like a lot to understand, but you don't need to grasp it all at once. Once you fully understand privileges and scopes, the rest can be dealt with as the need arises. Few applications will need all of the features provided by Veil2, and you can probably ignore the stuff you don't think you need.

4.1. Privileges

Privileges are the atomic units of access control, limiting access to specific data or operations. By convention, most privileges are named <action> <object>. Actions will include:

  • select;
  • insert;
  • update;
  • delete;
  • execute.

Objects will usually be the names of tables and, for execute actions, the names of specific pieces of functionality. Note that Veil2 takes no notice of privilege names, using only the privilege_id. It is up to the implementation to ensure that each privilege is used in a manner consistent with its name.

Privileges are not assigned directly to users. Instead they are assigned through roles, which are essentially collections of privileges.

A typical privilege might be select parties which we could assume would allow select access to the parties table. Note that every privilege in Veil2 applies in a specific scope, which is based on the context of the role assignment of the role providing that privilege.

A Veil2-based security system is likely to have tens or hundreds of distinct privileges.

4.2. Security Contexts

A security context (or more usually just context) is the user-facing equivalent to a scope. Where scopes apply at the level of individual privileges, contexts apply to the user and the user experience. Specifically, we talk about contexts as they apply to:

  • role assignments;

    Each role that is assigned to a user, whether implicitly or explicitly, is assigned within a given context.

  • authentication;

    Different users of a Veil2-based system may authenticate using different web pages or apps. There may be completely distinct sets of users in the context of different corporate clients, with usernames only having to be unique within the context of each corporation.

  • mapping;

    As described in contextual role mapping, your role to role mappings may be different for different users. The context that is used for a given session's role mappings is known as the mapping context.

  • sessions;

    It may be that although a user authenticates in the context of a corporation, their session exists within the context of a specific subdivision of that corporation. The access rights for the user will be determined from this session context. If they are allowed to create sessions in multiple contexts, their access rights may be different in each one.

In Veil2 there is a scope for every context, and vice versa.

The distinction between scope and context may become clear when we consider that a role can be assigned in a context that has no meaning for that role's privileges. Consider a team-member role assigned in the context of a specific project that contains the select lookups privilege. This privilege allows the accessor select-access to lookup data which is not project-specific. This privilege must operate in a different scope from the context of its assignment, and so its operating scope will need to be promoted (see scope promotion below).

It is largely because privileges may apply in different scopes from their role's assignment context, that contexts and scopes are distinct terms. While this may seem to be semantic pedantry, the opportunities for confusion when discussing scopes and contexts are such that the distinction is useful. The author has been there and resents that he will never get those hours back.

Veil2 provides 2 built-in security contexts:

4.2.1. Global Context

This is a non-relational context. Privileges assigned in global context apply without limitation. If you are assigned a role in global context, all of its privileges will apply in global scope. If you have been assigned the select customer privilege (via a role) in global context, you will be able to see all customer records.

Global Context is powerful and dangerous. It is the level of access control provided by traditional security systems and it should be used with great care.

4.2.2. Personal Context

Personal context is an implied context. Each user has an implicit assignment of the personal context role in this context.

The personal context is all about the application user, ie the person that is using your application. It applies to data that is about that person. This would include their authentication credentials, contact information, etc. The purpose of the personal context is to give users access to their own data, and no-one else’s. Each user has their own personal context.

4.3. Scopes

4.3.1. Scopes As a Concept

Each type of scope represents a distinct type of relationship between your system's users and the various relations (tables and views) in your database: it is these relationships that are the heart of relational security.

If your users have a relationship with an employer, then maybe you will want an employer scope. If they have a relationship with an email domain, then you may need a domain scope. If you have an organizational hierarchy that your users fit into, then you may need an organization or department scope.

Your scope types should naturally fall out from your data model and your access requirements.

4.3.2. Scopes In Practice

A scope describes the applicability of a privilege. Scopes are mostly based upon existing relationships in your data.

Note that for every scope, there is an equivalent security context. Where contexts are user facing and are applied to the assignment of roles, scopes apply at the level of individual privileges and are more of an implementation detail.

A scope may apply to an organization, a department, a project, or whatever you wish. Having a privilege in the scope of one department would give you access rights to data for that department. It would not give you access to equivalent data for other departments.

Some scopes will allow access to large subsets of data, and some to very small subsets. We refer to this as the scope level. A scope that is very restrictive is considered a low-level scope, and one that is not, is a high-level scope. When we talk about scope promotion, this is always from a lower level to a higher level, which is to say that the scope becomes less restrictive, and likely to return a larger set of data.

A built-in scope that is particularly low-level is personal scope. This limits access to data that specifically relates to the accessor (privilege holder). So if user X has the select user privilege in personal scope, they will be able to see their own users record. Whether they can see other users records will depend on whether they have the select users privilege in any other scopes.

4.4. Roles

Roles exist to manage collections of privileges. Because privileges apply at such a low level, managing access by assigning individual privileges is untenable. Instead we manage groups of privileges through roles. Privileges are assigned to roles, and roles are assigned to users. See role assignments; security contexts; and scope promotion, for information on how each privilege's scope is managed.

To make roles more flexible, we allow roles to be assigned to other roles. We call this role-mapping. This allows us to create low-level functional roles that have the privileges necessary to perform a specific low-level task, and we assign these roles to higher-level user roles which can then be assigned to users. By doing this, we minimize the number of different roles that we need to be able to assign to users.

Typical functional roles might include: view order, create order, approve order, etc. These function level roles might then be assigned to user roles such as customer service rep, customer service manager, product manager, etc. Typically you would only assign user level roles to users.

As the roles themselves do not care whether they are functional or user level, there is no limit to how deeply role to role mappings may be nested. This can be useful when you want to create a user-level role that combines the abilities of 2 or more existing user-level roles.

Veil2 does not care how roles are mapped to each other, in fact, you can map Role A to Role B and then Role B to Role A, and Veil2 will handle it just fine; it will just mean that the two roles are equivalent - which is hardly useful. You may want to implement some policies around this for your own system.

4.4.1. Contextual Role Mapping

One of the possible use-cases for Veil2 is to provide Virtual Private Databases in a SaaS environment. As such, it is possible that different clients of such a service might want different user-level roles, and different mappings between them and the base function-level roles.

If you don't need this, you can skip ahead. Although Veil2 provides this as a feature, you don't have to use it and it is not enabled by default.

In Veil2, each role to role mapping is done within a specific mapping context. The default mapping context is global, which means that that role mapping applies to all users. By changing this value we can make role mappings apply at different context levels. Typically, we would set this to operate at the context of a specific SaaS client, so that users for each client would be able to define their own roles and role to role mappings.

More on the implementation of this can be found here.

4.5. Role Assignments

Users are assigned roles in a number of ways, and Veil2 places no limits on the mechanisms that an implementation may choose to use. Assignments may be explicit, implicit or even a combination of the two.

An explicit role assignment would consist of a record associating a role with the user being assigned the role, in a specific context (see security contexts below). This record would be for the sole purpose of assigning the role. This is what makes it explicit.

Implicit role assignments can be made in a number of ways. In Veil2 each user, by default, is assigned the personal context role, in their own personal context as described below. This is done by Veil2 itself, and is not the result of any record relating the role to the user. Note that although the role is assigned by default, it has no privileges. What personal context allows is up to your implementation.

Other forms of implicit role assignment will be through existing data relationships. For instance, we might want project team members to have certain privileges to the data for their projects. This would be done through their assignment to the project as a team member. It is possible that such a membership record would have an explicit role associated with it, but it is equally possible that membership is implied simply by the existence of a team_member record linking the user and the project. In such a case we would create a team member role, and the assignment of this role to team members would be implicit.

More details on this can be found here.

4.6. Scope (and Context) Promotion

Sometimes the context of a role assignment or a session is not entirely appropriate for all of its purposes. In these cases, promotion is necessary.

There are 2 distinct situations where promotion occurs:

  • promotion of scope for privileges;
  • promotion of session context for mapping context.

4.6.1. Promotion Of Scope For Privileges

Privileges may give access to rows in a table, or to specific functionality. Often, a privilege that is needed for a particular role, will apply to an object that exists outside of the context of the role assignment. In such cases, the privilege must be promoted from the context of its assignment to apply in a higher-level scope.

Consider a role, CSR, that has been assigned to a user in customer context for customer Z. This hypothetical role assignment is supposed to give the user the ability to manage customer Z and no other customer. Among the hypothetical privileges for this role are:

  • select customer;
  • update customer;
  • ...;
  • select lookups.

If we assume that select lookups gives the user the ability to view all lookup data, we can see that it doesn’t really apply to the customer context. It is not related to customer-specific data. In fact it should apply the same regardless of who we might be a CSR for. This privilege should be applied in the global scope, but it has been assigned in the customer context for customer Z.

The context for the role assignment makes no sense for this privilege, so it must be promoted to a higher-level scope. In this case, the scope would be that of the global context.

As another example consider that a role that has been assigned in project context provides the select department privilege to view the department details of the department that owns the project. The department details cannot be viewed in project scope, because projects are lower-level things: the department owns the project and not the other way around. The solution is to promote the select department privilege to operate in department scope. Note that if the select project privilege were promoted in the same way, it would allow the user to view all projects for the department.

The level of promotion required for each privilege is specific to the object that the privilege exists to protect. So, each privilege identifies its target scope level. If the privilege is being assigned, via a role assignment, in a lower-level context, then promotion to the higher target scope level will automatically be performed when the user's privileges are first loaded.

4.6.2. Promotion Of Session Context For Mapping Context

The mapping context that we use for contextual role mapping is determined from our session context by promotion.

If the session context is not at the scope level of our target mapping context scope, a superior scope will be used based on the scope hierarchy. Note that global scope is considered the highest level/most superior scope.

4.7. Authentication Contexts

Each accessor (database user) is associated with a specific context within which they authenticate. Typically, this context would represent the organization they work for. When authenticating an accessor, their authentication context must be provided along with their username or other identifier.

What this means is that usernames, etc do not have to be globally unique, but only unique within each authentication context.

If you don't need this, you can choose to allow all accessors to authenticate within the same context, usually the global context.

As described in Contextual Role Mapping above, the role names and role to role mappings that an accessor sees may depend on their authentication context.

More information on this, with examples, can be found here.

4.8. Session Contexts

When a user authenticates, they begin a session, and this session has a context. The session context determines what data the user can see, as though the user is logged in to that context. Often the session context will be the same as the authentication context, but Veil2 does not require this.

For example, consider that our authentication context is at the level of a corporation (so usernames must be unique within the entire corporation), but that we log in to the web-site for a subdivision. Our authentication context would be the corporation context, and the session context would be the subdivision context.

The context of a user's session will determine the access rights for that session. Role assignments in contexts that are unrelated to the session context will be ignored.