You may wish to control what specific user can see in your database. AllegroGraphs has a number of tools for protecting triples from users not authorized to see them, working at different levels.

Permissions can be assigned either to individual users or to roles. The mechanisms are essentially the same both (a user assigned a role simply inherits the permissions of the role just as if the user was given those permissions directly). So in this document, we mostly discuss user permissions and provide examples of those. What we say can be applied to roles as well.

Triple access can be controlled by:

All these methods work, and provide the desired security.

General user permission settings for security

When a user (or role) is created, that user is assigned a set of permissions which control what the user can do. Some of these permissions might allow the user to override what is restricting their access. For example, obviously if the user is made a superuser (who can access and modify all user settings) that user is not bound by any restrictions. But other permissions can also allow access to all triples in not so obvious ways. Here is the dialog that defines a user, with the permissions that might allow overriding restrictions marked up. We advise not giving users such permissions unless you trust the user and understand the implications.

User set up dialog

Every X'ed out choice must not be enabled if the user will be restricted from seeing all triples. The X'ed out items are:

Some users on the machine running AllegroGraph server have effective superuser rights

The agtool program, when it is given a server spec where the server is localhost or 127.1 or even the server name (like if that dns resolves to the server machine) can bypass the HTTP interface to run the command and instead goes right through the hub into the service daemon (if that is supported by the command it needs to execute) and it will do so if the user calling agtool is the user with the same user id as the AllegroGraph server. That allows that user to modify user permissions and make themselves AllegroGraph superusers, like this (Jane_Smith is a user in the attributes example below):

% agtool users permissions --server localhost:10035 Jane_Smith super+ 

This does not work when run on a different machine (running on while the AllegroGraph server is

% agtool users permissions --server Jane_Smith super+  
An error occured when trying to send http request to AllegroGraph server at http://machine1com:10035  
No anonymous access allowed.  

This access is unlikely to actually cause problems as typically the AllegroGraph server is run either by the special agraph user or by someone with AllegroGraph superuser rights anyway.

Restricting access to an entire catalog or repo

When a new user is created, they do not have read or write permission in any catalog or repository. Such permissions are created (by the superusers adminstrator who set up the user's account) in this portion of the user setup dialog (the image is from the New Webview):

Setting user accesss permissions

You can specify the catalog/repos that the user can access and then the user cannot access others.

The access rules are simple: you can allow access to a particular repos in a catalog, all repos in a catalog or no repos in catalog. Suppose a catalog has 20 repos, and you want user22 to have r/w access to 19 but not to the 20th. Then you have to list all 19 to allow access to them, leaving out the 20th to prevent access. (There is no way to simply deny access to a single repo.)

This works best if you organize repos into catalogs based on desired access. Consider three catalogs: root, admin, management. Every user can be given access to root; managers and administrators to admin, and managers only to management.

Restricting access triples based on subject, obejct, predicate, or graph

Lower down on the same dialog which gives access to specific catalogs and repos is this portion:

Setting a security filter

This allows setting access permission based on values of the subject, predicate, object, or graph value. For example, if the database has triples that show people's salaries, access can be restricted in this way:

Guarding has-salary triples

(This would likely be set for roles, with the higher-management role having access and all other employment-level roles disallowed access.)

This security method works best for fairly simple security schemes where classes of users are easily categorized into a few sets that can or cannot see a few things (where things means all triples with this predicate or that subject).

If the graph is not used for any other purpose, it can provide secuity at the triple level, assigning distinctive graph values for triples that groups can or cannot see, but if access gets at all complex, you need too many graph values and too many security value entries to make conveniently. And the graph slot is rarely available for a single purpose.

Restricting access triples based on attributes

Finally, you can use attribute for triple security. AllegroGraph has long support triple-level security using triple attributes but until release 8.0.0 it was necessary to have queries managed by an external program which would take a query, examine the user attributes which the external program maintained, and construct a suitable query prefix with would filter the query results based on the triple attributes stored by AllegroGraph and the user attribute values known to the external program, filtering the results using a stored static filter associated with the repo. This was (and is) an effective system from triple security but needing an external controlling program which placed a burden on users and administrators.

That system has now been moved into AllegroGraph. There are now per-repo user-specific attributes which can be used with repo-specific attributes to filter query results so the user will only see appropriate triples. User attributes can be set in various ways, the easiest being with agtool define-attribute.

This method is by far the most powerful and the most flexible. Almost any security scheme you can think of can be implemented. Because it depends on filters of arbitrary complexity, which can be changed at any time; on user attributes, which too can be changed at any time; and triple attributes (which are admittedly harder to change but can be changed), you are provided with very fine control over what triples can be accesed and by whom.

We will describe triple security using attributes in detail in the remainder of this document.

Triple security using attributes introduction

Triple attributes are described in the Triple Attributes document. They have many uses aside from security and no one use interferes with other uses (unlike, say, using the graph for security suggested above).

Attributes can be assigned to triples (when the triple is loaded), to users and roles (at any time by a superuser administrator). User attributes are on a per-repo basis (triple attributes are obviously per repo as triples exist in only one repo). There can also be a repo static filter (again defined by a superuser administrator and modifiable at any time). When a user tries to access a triple, the system compares the user's attributes with the triple's attributes using the static filter and grants access or denies it beased on the results. ("Denies access" means that from the user's point of view, the triple does not exist. The user is not informed that they have been denied access.)

Attributes must be defined before they can be assigned to a triple or a user. Triples can only be assigned attribute values when they are created. If the attributes of a triple need to be changed, the triple must be written out, deleted, and reloaded. As said above, user attributes can be assigned at any time. See Data Import for information on specifying attributes in nqx files (NQuad files including attributes).

See the agtool General Command Utility document for information on defining attributes with agtool and assigning them to users. Attributes and static filters can also be defined from menus in New WebView and Traditional WebView.

Attribute definitions (that is, name, type, and possible values) and static filters are attributes of repos. Every repo can have it own set of attributes and excepting Multimaster replication and FedShard (tm), repos do not inherit attribute or static filter values from other repos.

A triple security example

Suppose we have a single repo and we have these attributes defined:

At first our desired rules are (we do not use ordering at first):

There are 5 users:

We have a company repo.

Here are the attribute definitions:

% agtool define-attribute --allowed-values 1,2,3 --ordered true \  
  --maximum-number 1 super:pass@myhost:10035/company science-level  
% agtool define-attribute --allowed-values 1,2,3 --ordered true \  
  --maximum-number 1 super:pass@myhost:10035/company admin-level  
% agtool define-attribute --allowed-values science,admin,manager \  
  --minimum-number 1 super:pass@myhost:10035/company employee-type 

And here is the NQX file

<> <> "100000" {"admin-level": "3"} .  
<> <> "Accountant" {"admin-level": "1"} .  
<> <> "SA" {"admin-level": "1"} .  
<> <> "Chemist" {"admin-level": "1"} .  
<> <> <> {"science-level": "1"} .  
<> <> <> {"science-level": "3"} .  
<> <> <> {"science-level": "4"} . 

Now we give attribute values to our users (only a superuser can set the attributes for a user):

% agtool users set-attributes --server super:pass@host:10035 Jane_Smith :company '{"employee-type": "manager"}'  
% agtool users set-attributes --server super:pass@host:10035 Fred_Hernandez :company '{"employee-type": "admin"}'  
% agtool users set-attributes --server super:pass@host:10035 Vijay_Singh :company '{"employee-type": ["science","admin"]}'  
% agtool users set-attributes --server super:pass@host:10035 Bill_Jones :company '{"employee-type": "science"}'  

Note that Bobby_Smith did not get any attribute values.

Finally we set a static filter:

(or (equal triple.admin-level "1") (equal "1") (equal user.employee-type "manager") (and (or (equal "1") (equal "2") (equal "3")) (subset "science" user.employee-type)) (and (attribute-contains-one-of ("1" "2" "3") triple.admin-level) (subset "admin" user.employee-type)))

Now let us see who can see what:

Bill Jones can see

Fred_Hernandez     position     "Accountant"  
Vijay_Singh        position     "SA"  
Vijay_Singh        position     "Chemist"  
water              isa          liquid  
secret-sauce       made-from    mulberry 

Vijay Singh sees all of those (because he is in science) and also

Jane_Smith         salary       "100000" 

because he is also in admin. Jane Smith also sees all those because she is a maneger. Fred Hernadez does not see the secret-sauce triple but does see Jane Smith's salary. Finally, Bobby Smith see these (any user can see those):

Fred_Hernandez     position     "Accountant"  
Vijay_Singh        position     "SA"  
Vijay_Singh        position     "Chemist"  
water              isa          liquid 

Triples without attributes

We add the following triple to company:

<> <> "California" 

So who can see that triple? It has no attributes to compare so you might think everyone, but in fact, only Jane_Smith can see it (a user with employee-type "manager" can see every triple. But the rest of the rules compare the triple attributes with user attributes and the comparicon fails because the triple does not have any attributes.

If you want all users to see all triples without attributes, add this to the security filter (after the or):


Attributes and SPARQL INSERT

You typically assign attributes at load time or when a triple is added using the WebView interface. Attributes must be specified when a triple is added. Here are the current triples in the repo:

s         p    o     attributes  
data1    pred  22   {"att1": "yes"}  
data2    pred  44   {"att2": "yes"} 

Triples can be added during a SPARQL INSERT operation. Here is a SPARQL INSERT command:

Here is a simple INSERT query:

insert {  
      ?s <> ?o . }  
      where {  
      ?s <> ?o } 

That will insert two new triples

data1 newpred 22  
data2 newpred 44 

but those triples will not have attributes.

This is a problem if you want to protect the new triples similarly to the triples they we created from. You can however cause the new triples to get the same attributes as the triples which caused them to be inserted with the following revised SPARQL INSERT query:

PREFIX attr: <>  
    INSERT {  
      attribute ?attr { ?s <> ?o . }  
    } WHERE {  
      ?attr attr:attributes (?s <> ?o ) 

results in

s       p         o      attributes  
data01  pred      22   {"att1": "yes"}  
data02  pred      44   {"att2": "yes"}  
data02  newpred   44   {"att2": "yes"}  
data01  newpred   22   {"att1": "yes"}