Virtuoso uses the VAL ACL system to control access to named graphs, and to SPARQL in general.
When enabled, these rules are automatically enforced in various Virtuoso interaction including the /sparql
endpoints, and can also be used manually in any other application as described below.
SPARQL access is controlled in two ways:
SELECT
, UPDATE
, or SPONGE
queries.
These ACL rules always apply to the same specific resource URI, urn:virtuoso:access:sparql
, has a scope of oplacl:Query
.
For historical reasons, this ACL is disabled by default, which grants everyone the right to SELECT
, UPDATE
, and SPONGE
.
See below on how to enable the ACL scope, and thus, the evaluation of the rules.
oplacl:PrivateGraphs
.
The Rules can be controlled via two APIs --
Alternatively, one can manually add rules to the private graph matching the realm in which the rules should apply.
Such manual addition means that two properties of each rule, oplacl:hasRealm
and foaf:maker
, which are invisibly and automatically managed by the APIs, must also be manually managed.
Given the default realm --
http://www.openlinksw.com/ontology/acl#DefaultRealm
-- and the default hostname --
{HOST-CNAME}
-- the graph IRI would be --
http://{HOST-CNAME}/acl/graph/rules/http%3A%2F%2Fwww.openlinksw.com%2Fontology%2Facl%23DefaultRealm
-- and the groups would be stored in named graph --
http://{HOST-CNAME}/acl/graph/groups/http%3A%2F%2Fwww.openlinksw.com%2Fontology%2Facl%23DefaultRealm
Note: these defaults can be customized for better readability.
Each set of ACL rules is defined as one ACL scope.
As implied above, there are two ACL scopes in VAL, each with a set of default access modes which are used if ACL rule evaluation has been disabled. The purpose and default configurations of these two scopes are --
oplacl:Query
for general SPARQL access
PREFIX acl: <http://www.w3.org/ns/auth/acl#> PREFIX oplacl: <http://www.openlinksw.com/ontology/acl#> INSERT INTO <urn:virtuoso:val:acl:schema> { oplacl:PrivateGraphs a oplacl:Scope ; rdfs:label "Sparql" ; rdfs:comment """Sparql ACL scopes which contains all ACL rules granting access to specific named graphs. By default ACLs are disabled. System admins can enabled ACLs. There are no default access modes since Virtuoso only applies ACLs to private graphs which should remain private.""" ; oplacl:hasApplicableAccess oplacl:Read , oplacl:Write , oplacl:Sponge . };
oplacl:PrivateGraphs
for access to specific private graphs
PREFIX acl: <http://www.w3.org/ns/auth/acl#> PREFIX oplacl: <http://www.openlinksw.com/ontology/acl#> INSERT INTO <urn:virtuoso:val:acl:schema> { oplacl:Query a oplacl:Scope ; rdfs:label "SQL" ; rdfs:comment """SQL ACL scopes which contains all ACL rules granting permission to perform SQL operations or SPARQL operations in general. The latter is complemented by the sparql scope which contains rules for named graph access.""" ; oplacl:hasApplicableAccess oplacl:Read , oplacl:Write , oplacl:Sponge ; oplacl:hasDefaultAccess oplacl:Read , oplacl:Write , oplacl:Sponge . };
A scope can be explicitly enabled or disabled in any given realm.
By default, they are neither, which means that it is up to the application to decide.
Given the default realm oplacl:DefaultRealm
, the evaluation of ACLs for private graphs could be disabled as follows:
SPARQL PREFIX oplacl: <http://www.openlinksw.com/ontology/acl#> WITH <urn:virtuoso:val:config> DELETE { oplacl:DefaultRealm oplacl:hasEnabledAclScope oplacl:PrivateGraphs . } INSERT { oplacl:DefaultRealm oplacl:hasDisabledAclScope oplacl:PrivateGraphs . };
To enable the evalution of general SPARQL access rules in the default realm one would use:
SPARQL PREFIX oplacl: <http://www.openlinksw.com/ontology/acl#> WITH <urn:virtuoso:val:config> DELETE { oplacl:DefaultRealm oplacl:hasDisabledAclScope oplacl:Query . } INSERT { oplacl:DefaultRealm oplacl:hasEnabledAclScope oplacl:Query . };
In the following examples --
oplacl:DefaultRealm
is used for creating the ACL resources.
{HOST-CNAME}
is used as a placeholder for the default hostname of the system on which the ACL resource are created.
SPARQL PREFIX oplacl: <http://www.openlinksw.com/ontology/acl#> PREFIX acl: <http://www.w3.org/ns/auth/acl#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> WITH <http://{HOST-CNAME}/acl/graph/rules/http%3A%2F%2Fwww.openlinksw.com%2Fontology%2Facl%23DefaultRealm> INSERT { <{RULE-IRI}> a acl:Authorization ; foaf:maker <{ADMIN-IRI}> ; oplacl:hasAccessMode oplacl:Read ; acl:accessTo <urn:virtuoso:access:sparql> ; acl:agentClass foaf:Agent ; oplacl:hasScope oplacl:Query ; oplacl:hasRealm oplacl:DefaultRealm . };
SPARQL PREFIX oplacl: <http://www.openlinksw.com/ontology/acl#> PREFIX acl: <http://www.w3.org/ns/auth/acl#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> WITH <http://{HOST-CNAME}/acl/graph/rules/http%3A%2F%2Fwww.openlinksw.com%2Fontology%2Facl%23DefaultRealm> INSERT { <{RULE-IRI}> a acl:Authorization ; foaf:maker <{ADMIN-IRI}> ; oplacl:hasAccessMode oplacl:GrantSponge ; acl:accessTo <urn:virtuoso:access:sparql> ; acl:agent <{AGENT-IRI}> ; oplacl:hasScope oplacl:Query ; oplacl:hasRealm oplacl:DefaultRealm . };
There are two types of groups:
SPARQL PREFIX oplacl: <http://www.openlinksw.com/ontology/acl#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> WITH <http://{HOST-CNAME}/acl/graph/groups/http%3A%2F%2Fwww.openlinksw.com%2Fontology%2Facl%23DefaultRealm> INSERT { <{GROUP-IRI}> a foaf:Group, oplacl:StaticGroup ; foaf:name "Some people" ; foaf:maker <{ADMIN-IRI}> ; foaf:member <{AGENT-IRI-1}> , [...] <{AGENT-IRI-N}> . };
The Required Group in a conditional group which includes every authenticated NetID?:
SPARQL PREFIX oplacl: <http://www.openlinksw.com/ontology/acl#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> WITH <http://{HOST-CNAME}/acl/graph/groups/http%3A%2F%2Fwww.openlinksw.com%2Fontology%2Facl%23DefaultRealm> INSERT { <{GROUP-IRI}> a oplacl:ConditionalGroup ; foaf:name "Valid Identifiers" ; foaf:maker <{ADMIN-IRI}> ; oplacl:hasCondition [ a oplacl:GroupCondition, oplacl:GenericCondition ; oplacl:hasCriteria oplacl:NetID ; oplacl:hasComparator oplacl:IsNotNull ; oplacl:hasValue 1 ] . };
The Required Group in a conditional group which includes every authenticated NetID?:
SPARQL PREFIX oplacl: <http://www.openlinksw.com/ontology/acl#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> WITH <http://{HOST-CNAME}/acl/graph/groups/http%3A%2F%2Fwww.openlinksw.com%2Fontology%2Facl%23DefaultRealm> INSERT { <{GROUP-IRI}> a oplacl:ConditionalGroup ; foaf:name "Valid WebIDs" ; foaf:maker <{ADMIN-IRI}> ; oplacl:hasCondition [ a oplacl:GroupCondition, oplacl:GenericCondition ; oplacl:hasCriteria oplacl:WebIDVerified ; oplacl:hasComparator oplacl:EqualTo ; oplacl:hasValue 1 ] . };
The Required Group in a conditional group which includes every valid X.509 certificate:
SPARQL PREFIX oplacl: <http://www.openlinksw.com/ontology/acl#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> WITH <http://{HOST-CNAME}/acl/graph/groups/http%3A%2F%2Fwww.openlinksw.com%2Fontology%2Facl%23DefaultRealm> INSERT { <{GROUP-IRI}> a oplacl:ConditionalGroup ; foaf:name "Valid X.509 Certificates" ; foaf:maker <{ADMIN-IRI}> ; oplacl:hasCondition [ a oplacl:GroupCondition, oplacl:GenericCondition ; oplacl:hasCriteria oplacl:CertVerified ; oplacl:hasComparator oplacl:EqualTo ; oplacl:hasValue 1 ] . };
Query conditions consist of a query which supports two variables which are replaced with the profile graph and the personal URI respectively.
SPARQL PREFIX oplacl: <http://www.openlinksw.com/ontology/acl#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> WITH <http://{HOST-CNAME}/acl/graph/groups/http%3A%2F%2Fwww.openlinksw.com%2Fontology%2Facl%23DefaultRealm> INSERT { <{GROUP-IRI}> a oplacl:ConditionalGroup ; foaf:name "Valid WebIDs" ; foaf:maker <{ADMIN-IRI}> ; oplacl:hasCondition [ a oplacl:GroupCondition, oplacl:GenericCondition ; oplacl:hasCriteria oplacl:WebIDVerified ; oplacl:hasComparator oplacl:EqualTo ; oplacl:hasValue 1 ] , [ a oplacl:GroupCondition, oplacl:QueryCondition ; oplacl:hasQuery """ASK WHERE { GRAPH ^{graph}^ { ^{uri}^ a foaf:Person } }""" ] };
Once the group has been created it can be referenced in a new Authorization that provides members with the ability to grant Sponge privileges to others so that they too can use the Sponger functionality via SPARQL based data access:
SPARQL PREFIX oplacl: <http://www.openlinksw.com/ontology/acl#> PREFIX acl: <http://www.w3.org/ns/auth/acl#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> WITH <http://{HOST-CNAME}/acl/graph/rules/http%3A%2F%2Fwww.openlinksw.com%2Fontology%2Facl%23DefaultRealm> INSERT { <{RULE-IRI}> a acl:Authorization ; foaf:maker <{ADMIN-IRI}> ; oplacl:hasAccessMode oplacl:Sponge ; acl:accessTo <urn:virtuoso:access:sparql> ; acl:agent <{GROUP-IRI}> ; oplacl:hasScope oplacl:Query ; oplacl:hasRealm oplacl:DefaultRealm . };
Once the group has been created it can be referenced in a new Authorization that provides members with Write (Insert, Update, and Delete) privileges via SPARQL data access:
SPARQL PREFIX oplacl: <http://www.openlinksw.com/ontology/acl#> PREFIX acl: <http://www.w3.org/ns/auth/acl#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> WITH <http://{HOST-CNAME}/acl/graph/rules/http%3A%2F%2Fwww.openlinksw.com%2Fontology%2Facl%23DefaultRealm> INSERT { <{RULE-IRI}> a acl:Authorization ; foaf:maker <{ADMIN-IRI}> ; oplacl:hasAccessMode oplacl:Write ; acl:accessTo <urn:virtuoso:access:sparql> ; acl:agent <{GROUP-IRI}> ; oplacl:hasScope oplacl:Query ; oplacl:hasRealm oplacl:DefaultRealm . };
SPARQL PREFIX oplacl: <http://www.openlinksw.com/ontology/acl#> PREFIX acl: <http://www.w3.org/ns/auth/acl#> WITH <http://HOST/acl/graph/rules/http%3A%2F%2Fwww.openlinksw.com%2Fontology%2Facl%23DefaultRealm> INSERT { <{RULE-IRI}> a acl:Authorization ; foaf:maker <{ADMIN-IRI}> ; oplacl:hasAccessMode oplacl:Read ; acl:accessTo <{NAMED-GRAPH-IRI}> ; acl:agent <{AGENT-IRI}> ; oplacl:hasScope oplacl:PrivateGraphs ; oplacl:hasRealm oplacl:DefaultRealm . };