Veil2 is a collection of database objects,
    written in C and SQL, that provides an implementation of roles,
    privileges, contexts, scopes and session management that can be
    used to secure your database with relatively little custom
    implementation work.
  
It links to your database through functions, triggers and foreign keys, and provides fast, tested mechanisms to identify, load and test a user's privileges in various scopes.
    It is important to realize at this point that
    Veil2 is not a complete application or a
    product: it cannot be used stand-alone and can only be integrated
    into your database by careful work on your part.  You will need to
    define the links between Veil2 and your
    database schema, and you will need to provide
    Veil2 with customized functions and views to
    make this integration work.
  
    To aid in this, Veil2 allows user-provided
    views and functions to take precedence over the built-in
    system-provided ones.  This mechanism aims to provide maximum
    flexibility while still allowing Veil2 to be
    distributed as a PostgreSQL extension.  This means that future
    Veil2 bug-fixes and upgrades can be easily
    applied to your database without breaking your customizations.
  
There is various documentation to help you with this:
Veil2 creation
      scripts;Veil2 demos.
You should familiarize yourself with at least this document and the demos before starting out on your implementation.
      Veil2 works by:
      
What this means is that when Alice tries to select the user record for Bob, Alice will only see that record if she has been assigned the necessary privilege to view Bob's user record in an appropriate scope. As each user's privilege assignments will be different, each user will see a different subset of data.
The following sections provide more detail on each of the above list items.
	Veil2 provides session management functions
	for both dedicated and
	shared
	database connections.  It is up to you or your application to
	ensure that the session protocols are followed.  If they are
	not, the user will have access to no data at all, or access to
	data based on another user's access rights.
      
	By calling the appropriate session management functions with
	appropriate authentication tokens, a Veil2
	session will be created.  This causes session parameters to be
	set up in secure temporary tables from which they can be
	quickly retrieved.  These session parameters include session
	privileges with one record for each scope in which the user
	has privileges.
      
The set of privileges in each scope is stored in a single bitmap. This is a space-efficient array of numbered bits, with each bit indicating the presence or absence of a privilege. Tests for the presence of a privilege in a bitmap are very fast.
At the start of each session, the user's privileges are determined based upon the roles that have been assigned to them and the contexts of those role assignments. This is a highly optimized process, using pre-built, cached, bitmaps and materialized views. These caches and materialized views are automatically updated as needed.
Each privilege assigned to a user acts within a scope that depends on the context in which it was assigned. Some scopes will allow all records in a table to be seen or manipulated, and some will allow large, small or smaller subsets of data to be seen.
	As stated above, the set of privileges in each scope is stored
	in a bitmap, and tests for the presence of a privilege in the
	bitmap are very fast.  The security rules for a relation will
	typically be defined something like this (from the
	veil2_demo extension):
	
alter table demo.projects enable row level security;
create policy projects__select
    on demo.projects
   for select
 using (   veil2.i_have_global_priv(25)
        or veil2.i_have_priv_in_scope(25, 3, corp_id)
        or veil2.i_have_priv_in_scope(25, 4, org_id)
        or veil2.i_have_priv_in_scope(25, 5, project_id));
	
	Each of the test functions is checking whether the user has
	the privilege, select projects (privilege
	25), to view the current record.  Tests are made in global
	scope, then corp scope (scope type 3) of the owning corp, then
	org scope (scope type 4) of the owning org, and finally in
	project scope (scope type 5) of the project itself.  Each of
	these tests causes a different bitmap in the users session
	privileges to be checked.
      
Although having so many tests performed for each record returned might seem like a significant overhead, in fact it is very small compared with the cost of retrieving the record in the first place and will often be effectively unmeasurable.
	Note that you should not rely solely on your VPD (Virtual
	Private Database) implementation to limit the number of
	records returned from queries to your users.  Your application
	should be constructing where-clauses that
	only return records that your user is entitled to see.  That
	is, your Veil2 implementation should act as
	a final back-stop safety check and not as a (hidden) part of
	your system's functionality.
      
There are 2 reasons for this:
	      Relying on Veil2 to filter unsuitable
	      records means that your where-clauses
	      are essentially incomplete, which in turn means that the
	      RDBMS has not been given all of the information that it
	      needs in order to best optimize your queries.
	    
	      Furthermore, if Veil2 is
	      filtering-out records from the result-set then we are
	      unnecessarily retrieving those records, and are having
	      to process them in order to determine their
	      unsuitability.  This would be a large and unnecessary
	      overhead.
	    
	      If our queries are running slower than they should
	      because Veil2 is having to filter-out
	      unsuitable records, it may be possible for an attacker
	      to use a timing attack to determine the existence of
	      records they are not entitled to see.
	    
For the truly security conscious, you may want to modify the privilege testing functions so that attempts to view records to which you have no access, result in logs being recorded. Note though, that such logs would be essentially unusable and would become a significant overhead if significant numbers of queries required results to be filtered.
Every table and view is given its own individual security definition. For tables, they will be much as shown above but will include definitions for insert, update and delete as well as select.
Views are secured in a similar way, but with the privilege testing functions defined in the view itself. Sometimes using views can improve the performance of the privilege tests as they can be incorporated more deeply within the view, meaning that the tests do not have to be executed for every row used by the view's query.
      Integrating your systems with Veil2 is not a
      trivial task, but it is straightforward.  Once you have
      understood at least the core
      concepts, you can simply follow the steps described in
      the Setting Up A Veil2
      Virtual Private Database - Overview section. 
    
      The following sections describe the major areas that you will
      need to address in order to protect an existing system with
      Veil2.  This is intended as an introduction
      to the process solely in order to give you a feel for what is
      required.
    
	The Veil2-protected database needs to know
	which user is accessing it all times.  It provides a
	session-management protocol for use from web applications.
	Your web application will have to provide handling of this
	session management protocol.  Generally this will be handled
	as triggers or hooks into the database connection pool
	management.
      
	Veil2 has its own view of what roles should
	do and what they should look like.  If your own system uses
	roles for its existing access control purposes, you will have
	to somehow integrate your system's role requirements with
	those of Veil2.  You essentially have two
	choices:
	
	      Bring your roles to Veil2. 
	    
	      Make your roles the source of Veil2
	      roles.  Use triggers and Foreign Key (FK) constraints to
	      make and maintain copies of your roles within
	      Veil2.
	    
	      Refactor your system to only use
	      Veil2 roles. 
	    
The advantage of this is that you will end up with a cleaner system, with fewer moving parts. The downside is that your applications will probably require more refactoring.
	For every type of security context/scope that you wish to provide,
	you will need to provide a link from your existing tables back
	to Veil2.  This will be handled with
	triggers and FK-constraints.  There are examples of how this
	may be done in the demos.
      
	All of your users must be associated with
	Veil2 accessors (users who access your
	database), and any existing credentials must be migrated.
	Again this can be handled by triggers and FK-constraints, and
	the demos provide examples.
      
You will be applying access controls to each relation in your system. Some of them may benefit from data denormalizations to improve the performance of the security tests. Typically you may want to add ownership columns to some of your tables so that ownership can be determined without the need for extra joins. If an access control function has to perform extra queries for each row returned, performance is likely to suffer.
You may need to implement a new authentication system for users. Or the built-in bcrypt implementation may be enough.