You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by cl...@apache.org on 2015/07/26 12:53:37 UTC

svn commit: r1692710 - in /jena/site/trunk/content/documentation: permissions/ security/

Author: claude
Date: Sun Jul 26 10:53:36 2015
New Revision: 1692710

URL: http://svn.apache.org/r1692710
Log:
Added permissions documentation.
deleted security documentation.

Added:
    jena/site/trunk/content/documentation/permissions/
    jena/site/trunk/content/documentation/permissions/assembler.mdtext
    jena/site/trunk/content/documentation/permissions/design.mdtext
    jena/site/trunk/content/documentation/permissions/evaluator.mdtext
    jena/site/trunk/content/documentation/permissions/example.mdtext
    jena/site/trunk/content/documentation/permissions/index.mdtext
    jena/site/trunk/content/documentation/permissions/migration2To3.mdtext
Removed:
    jena/site/trunk/content/documentation/security/

Added: jena/site/trunk/content/documentation/permissions/assembler.mdtext
URL: http://svn.apache.org/viewvc/jena/site/trunk/content/documentation/permissions/assembler.mdtext?rev=1692710&view=auto
==============================================================================
--- jena/site/trunk/content/documentation/permissions/assembler.mdtext (added)
+++ jena/site/trunk/content/documentation/permissions/assembler.mdtext Sun Jul 26 10:53:36 2015
@@ -0,0 +1,57 @@
+Title: Jena Permissions - Assembler For a Secured Model
+
+Jena Permissions provides a standard Jena assembler making it easy to use the `SecuredModel` in an Assembler based environment.  To use the permissions assembler the assembler file must contain the lines:
+
+    [] ja:loadClass    "org.apache.jena.permissions.SecuredAssembler" .
+     sec:Model       rdfs:subClassOf  ja:NamedModel .
+
+The secured assembler provides XXXXXXXXXXXx properties for the assembler files.
+
+Assuming we define
+
+     @prefix sec:    <http://apache.org/jena/permissions/Assembler#> .
+
+Then the following resources are defined
+
+`sec:Model` - A secured model.  One against which the security evaluator is running access checks.  All sec:Model instances must have a ja:ModelName to identify it to the `SecurityEvaluator`
+
+`sec:Evaluator` -  An instance of `SecurityEvaluator`.
+
+The following are properties are also defined:
+
+`sec:evaluatorFactory` - Identifies the class name of a factory class that implements a no-argument `getInstance()` method that returns an instance of `SecurityEvaluator`.
+
+`sec:baseModel` - Identifies the ja:Model that is to have permissions applied to it.
+
+`sec:evaluatorImpl` - Identifies an instance of `SecurityEvaluator`.
+
+`sec:evaluatorClass` - Identifies a class that implements `SecurityEvaluator`
+
+`sec:args` - Identifies arguments to the sec:evaluatorClass constructor.
+
+The secured assembler provides two (2) mechanisms to create a secured graph.  The first is to use a `SecurityEvaluator` factory
+
+    my:securedModel rdf:type sec:Model ;
+        sec:baseModel my:baseModel ;
+        ja:modelName "https://example.org/securedBaseModel" ;
+        sec:evaluatorFactory "the.evaluator.factory.class.name" .
+
+In the above example static method `getInstance()` is called on the.evaluator.factory.class.name and the result is used as the SecurityEvaluator.  This is used to create a secured model (`my:securedModel`) that wraps the model  `my:baseModel` and identifies itself to the `SecurityEvaluator` with the URI `"https://example.org/securedBaseModel"`. 
+
+The second mechanism is to use the `sec:Evaluator` method.
+
+    my:secEvaluator rdf:type sec:Evaluator ;
+        sec:args [  
+            rdf:_1 my:secInfoModel ;
+        ] ;
+        sec:evaluatorClass    "your.implementation.SecurityEvaluator" 
+    .
+
+    my:securedModel rdf:type sec:Model ;
+        sec:baseModel my:baseModel ;
+        ja:modelName "https://example.org/securedBaseModel" ;
+        sec:evaluatorImpl  my:secEvaluator .
+
+In the above example `my:secEvaluator` is defined as a `sec:Evaluator` implemented by the class `"your.implementation.SecurityEvaluator"`.  When the instance is constructed the constructor with one (1) argument is used and it is passed `my:secInfoModel` as an argument.  `my:secInfoModel` may be any type supported by the assembler.  If more than one argument is desired then `rdf:_2`, `rdf:_3`, `rdf:_4`, etc. may be added to the `sec:args` list.  The  `"your.implementation.SecurityEvaluator"` with the proper number of arguments will be called.  It is an error to have more than one argument with the proper number of arguments.  
+
+After construction the value of `my:securedModel` is used to construct the `my:securedModel` instance.  This has the same properties as the previous example other than that the `SecurityEvaluator` instance is different.

Added: jena/site/trunk/content/documentation/permissions/design.mdtext
URL: http://svn.apache.org/viewvc/jena/site/trunk/content/documentation/permissions/design.mdtext?rev=1692710&view=auto
==============================================================================
--- jena/site/trunk/content/documentation/permissions/design.mdtext (added)
+++ jena/site/trunk/content/documentation/permissions/design.mdtext Sun Jul 26 10:53:36 2015
@@ -0,0 +1,68 @@
+Title: Jena Permissions - Design
+
+Jena-permissions is designed to allow integrators to implement almost any security policy.  Fundamentally it works by implementing dynamic proxies on top of the Jena Graph and Model interfaces as well as objects returned by those interfaces.  The proxy verifies that the actions on those objects are permitted by the policy before allowing the actions to proceed.
+
+The graph or model is created by the `org.apache.jena.permissions.Factory` object by wrapping a Graph or Model implementation and associating it with a URI (`graphIRI`) and a SecurityEvaluator implementation.  The `graphIRI` is the URI that will be used to identify the graph/model to the security evaluator.
+
+The SecurityEvaluator is an object implemented by the integrator to perform the necessary permission checks.  A discussion of the SecurityEvaluator implementation can be found in the <a href="evaluator.html">Security Evaluator</a> documentation.
+
+Access to methods in secured objects are determined by the CRUD (Create, Read, Update and Delete) permissions assigned to the user.
+
+The system is designed to allow shallow (graph/model level) or deep (triple/statement level) decisions.
+
+When a secured method is called the system performs the following checks in order:
+
+* Determines if the user has proper access to the underlying graph/model.  Generally the required permission is Update (for add or delete methods), or Read.
+
+* If the user has access to the graph/model determine if the user has permission to execute the method against **all** triples/statements in the graph/model.  This is performed by calling `SecurityEvaluator.evaluate(principal, action, graphIRI, Triple.ANY)`.  If the evaluator returns `true` then the action is permitted.  This is general case for shallow permission systems.  For deep permissions systems `false` may be returned.
+
+* if the user does not have permission to execute the method against **all** triples/statements the `SecurityEvaluator.evaluate(principal, action, graphIRI, triple)` method is called with the specific triple (note special cases below).  If the evaluator returns `true` the action is permitted, otherwise a properly detailed PermissionDeniedException is thrown.
+
+Special Cases
+=============
+SecurityEvaluator.FUTURE
+------------------------
+
+There are a couple of special cases where the Node/Resource is not known when the permission check is made.  An example is the creation of a RDF List object.  For example to create an empty list the following triple/statement must be constructed:
+
+    _:b1 rdf:first rdf:nil .
+    
+However, the permissions system can not know the value of `_:b1` until after the triple/statement is constructed and added to the graph/model.  To handle this situation the permissions system asks the evaluator to evaluate the triple: `(SecurityEvaluator.FUTURE, RDF.first, RDF.nill)`  Similar situations are found when adding to a list, creating reified statements, RDF alt objects, RDF sequences, or RDF anonymous resources of a specific type.
+
+SecurityEvaluator.VARIABLE
+--------------------------
+The `Node.ANY` node is used to identify the case where any node may be returned.  Specifically it asks can the user perform the action on **All** the nodes in this position in the triple.  For example:
+
+     Node.ANY RDF:type FOAF:Person
+     
+asks if the operation can be performed on all of the nodes of type FOAF:Person.
+
+The `SecurityEvaluator.VARIABLE` differs from `Node.ANY` in that the system is asking if there are any prohibitions not if the user may perform. Thus queries with the `VARIABLE` type node should return `true` where `ANY`
+returns `false`. In general this type is used in query evaluation to determine if triple level filtering of results must be performed.  Thus:
+
+     SecurityEvaluator.VARIABLE RDF:type FOAF:Person
+     
+asks if there are any restrictions against the user performing the action against all triples of type FOAF:Person.  The assumption is that checking for restrictions may be a faster check than checking for all access.  Note that by returning `true` the permissions system will check each explicit triple for access permissions.  So if the system can not determine if there are access restrictions it is safe to return `true`.
+
+Objects Returned from Secured Objects
+=====================================
+
+Models and Graphs often return objects from methods.  For example the `model.createStatement()` returns a `Statement` object.  That object holds a reference to the model and performs operations against the model (for example `Statement.changeLiteralObject()`).  Since permissions provides a dynamic wrapper around the base model to create the secured model, returning the model `Statement` would return an object that no longer has any permissions applied.  Therefore the permissions system creates a `SecuredStatement` that applies permission checks to all operations before calling the base `Statement` methods.
+
+All secured objects return secured objects if those objects may read or alter the underlying graph/model.
+
+All secured objects are defined as interfaces and are returned as dynamic proxies.
+
+All secured objects have concrete implementations.  These implementations must remain concrete to ensure that we handle all cases where returned objects may alter the the underlying graph/model.
+
+Secured Listeners
+-----------------
+Both the Graph and the Model interfaces provide a listener framework.  Listeners are attached to the graph/model and changes to the graph/model are reported to them.  In order to ensure that listeners do not leak information, the principal that was active when the listener was attached is preserved in a `CachedSecurityEvaluator` instance.  This security evaluator implementation, wraps the original implementation and retains the current user.  Thus when the listener performs the permission checks the original user is used not the current user.  This is why the SecurityEvaluator **must** use the `principal` parameters and not call `getPrinciapl()` directly during evaluation calls.
+
+Proxy Implementation
+====================
+The proxy implementation is uses a reflection `InvocationHandler` strategy.  This strategy results in a proxy that implements all the interfaces of the original object.  The original object along with its `InvocationHandler` instance are kept together in an `ItemHolder` instance variable in the secured instance.  When the invoker is called it determines if the called method is on the secured interface or not.  If the method is on the secured interface the invocation handler method is called, otherwise the method on the base class is called.
+
+
+
+

Added: jena/site/trunk/content/documentation/permissions/evaluator.mdtext
URL: http://svn.apache.org/viewvc/jena/site/trunk/content/documentation/permissions/evaluator.mdtext?rev=1692710&view=auto
==============================================================================
--- jena/site/trunk/content/documentation/permissions/evaluator.mdtext (added)
+++ jena/site/trunk/content/documentation/permissions/evaluator.mdtext Sun Jul 26 10:53:36 2015
@@ -0,0 +1,186 @@
+Title: Jena Permissions - SecurityEvaluator implementation
+
+## Overview
+
+The SecurityEvaluator interface defines the access control operations. It provides the interface between the authentication (answers the question: "who are you?") and the authorization (answers the question: "what can you do?"), as such it provides access to the current principal (user).  The javadocs contain detailed requirements for implementations of the SecurityEvaluator interface, short notes are provided below.
+
+**NOTE** The permissions system caches intermediate results and will only call the evaluator if the answer is not already in the cache.  There is little or advantage to implementing caching in the SecurityEvaluator itself.
+
+### Actions
+
+Principals may perform Create, Read, Update or Delete operations on secured resources.  These operations are defined in the `Action` enum in the SecurtyEvaluator interface.
+
+### Node
+
+The permission system uses the standard Node.ANY to represent a wild-card in a permission check and the standard `Triple.ANY` to represent a triple with wild-cards in each of the three positions: subject, predicate and object.
+
+The permission system introduces two (2) new node types `SecurityEvaluator.VARIABLE`, which represents a variable in a permissions query, and `SecurityEvaluator.FUTURE`, which represents an anonymous node that will be created in the future.
+
+### Evaluator Methods
+ 
+The SecurityEvaluator connects the Jena permissions system with the authentication system used by the application.  The SecurityEvaluator must be able to query the authentication system, or its proxy, to determine who the "current user" is.  In this context the "current user" is the one making the request.  In certain instances (specifically when using listeners on secured graphs and models) the "current user" may not be the user identified by the authentication system at the time of the query. 
+
+The SecurityEvaluator must implement the following methods.  Any of these methods may throw an `AuthenticationRequriedException` if there is no authenticated user. 
+
+Most of these methods have a `principal` parameter.  The value of that parameter is guaranteed to be a value returned from an earlier calls to getPrincipal().  The `principal` parameter, not the "current user" as identified by `getPrincipal()`, should be used for the permissions evaluation.
+
+None of these methods should throw any of the PermissionDeniedException based exceptions.  That is handled in a different layer.
+
+See the <a href="../javadoc/permissions/org/apache/jena/permissions/SecurityEvaluator.html">SecurityEvaluator javadocs</a> for detailed implementation notes. 
+ 
+    public boolean evaluate( Object principal, Action action, Node graphIRI ) throws AuthenticationRequiredException;
+Determine if the action is permitted on the graph.  
+
+    public boolean evaluate( Object principal, Action action, Node graphIRI, Triple triple ) throws AuthenticationRequiredException;
+Determine if the action is allowed on the triple within the graph.
+
+    public boolean evaluate( Object principal, Set<Action> actions, Node graphIRI )throws AuthenticationRequiredException;
+Determine if all actions are allowed on the graph.
+    
+    public boolean evaluate( Object principal, Set<Action> actions, Node graphIRI, Triple triple ) throws AuthenticationRequiredException;            
+Determine if all the actions are allowed on the triple within the graph.            
+
+    public boolean evaluateAny( Object principal, Set<Action> actions, Node graphIRI ) throws AuthenticationRequiredException;
+Determine if any of the actions are allowed on the graph.
+   
+    public boolean evaluateAny( Object principal, Set<Action> actions, Node graphIRI, Triple triple ) throws AuthenticationRequiredException;
+Determine if any of the actions are allowed on the triple within the graph.
+
+    public boolean evaluateUpdate( Object principal, Node graphIRI, Triple from, Triple to ) throws AuthenticationRequiredException;
+Determine if the user is allowed to update the "from" triple to the "to" triple.            
+
+    public Object getPrincipal() throws AuthenticationRequiredException;   
+Returns the current principal or null if there is no current principal.    
+
+## Sample Implementation
+
+This sample is for a graph that contains a set of messages, access to the messages are limited to 
+principals that the messages are to or from.  Any triple that is not a message is not affected. This 
+implementation simply has a `setPrincipal(String name)` method.  A real implementation would request the  user principal or name from the authentication system.  This implementation also requires access to the underlying model to determine if the user has access, however, that is not a requirement of the SecurityEvaluator in general. Determining access from the information provided is an exercise for the implementer. 
+
+Note that this implementation does not vary based on the graph being evaluated (graphIRI).  The `graphIRI` parameter is provided for implementations where such variance is desired. 
+
+See the example jar for another implementation example.
+
+<!-- language: lang-java -->
+    
+    public class ExampleEvaluator implements SecurityEvaluator {
+        
+        private Principal principal;
+        private Model model;
+        private RDFNode msgType = ResourceFactory.createResource( "http://example.com/msg" );
+        private Property pTo = ResourceFactory.createProperty( "http://example.com/to" );
+        private Property pFrom = ResourceFactory.createProperty( "http://example.com/from" );
+        
+        /**
+         * 
+         * @param model The graph we are going to evaluate against.
+         */
+        public ExampleEvaluator( Model model )
+        {
+            this.model = model;
+        }
+        
+        @Override
+        public boolean evaluate(Object principal, Action action, Node graphIRI) {
+            // we allow any action on a graph.
+            return true;
+        }
+    
+        // not that in this implementation all permission checks flow through 
+        // this method.  We can do this because we have a simple permissions 
+        // requirement.  A more complex set of permissions requirement would 
+        // require a different strategy.
+        private boolean evaluate( Object principalObj, Resource r )
+        {
+            Principal principal = (Principal)principalObj;
+            // we do not allow anonymous (un-authenticated) reads of data.
+            // Another strategy would be to only require authentication if the
+            // data being requested was restricted -- but that is a more complex
+            // process and not suitable for this simple example.
+            if (principal == null)
+            {
+                throw new AuthenticationRequiredException();
+            }
+            
+            // a message is only available to sender or recipient
+            if (r.hasProperty( RDF.type, msgType ))
+            {
+                return r.hasProperty( pTo, principal.getName() ) ||
+                        r.hasProperty( pFrom, principal.getName());
+            }
+            return true;    
+        }
+        
+        // evaluate a node.
+        private boolean evaluate( Object principal, Node node )
+        {
+            if (node.equals( Node.ANY )) {
+                // all wildcards are false.  This forces each triple
+                // to be explicitly checked.
+                return false;  
+            }
+            
+            // if the node is a URI or a blank node evaluate it as a resource.
+            if (node.isURI() || node.isBlank()) {
+			     Resource r = model.getRDFNode( node ).asResource();
+			     return evaluate( principal, r );
+		     }
+            
+            return true;
+        }
+        
+        // evaluate the triple by evaluating the subject, predicate and object.
+        private boolean evaluate( Object principal, Triple triple ) {
+            return evaluate( principal, triple.getSubject()) &&
+                    evaluate( principal, triple.getObject()) &&
+                    evaluate( principal, triple.getPredicate());
+        }
+        
+        @Override
+        public boolean evaluate(Object principal, Action action, Node graphIRI, Triple triple) {
+            return evaluate( principal, triple );
+        }
+    
+        @Override
+        public boolean evaluate(Object principal, Set<Action> actions, Node graphIRI) {
+            return true;
+        }
+    
+        @Override
+        public boolean evaluate(Object principal, Set<Action> actions, Node graphIRI,
+                Triple triple) {
+            return evaluate( principal, triple );
+        }
+    
+        @Override
+        public boolean evaluateAny(Object principal, Set<Action> actions, Node graphIRI) {
+            return true;
+        }
+    
+        @Override
+        public boolean evaluateAny(Object principal, Set<Action> actions, Node graphIRI,
+                Triple triple) {
+            return evaluate( principal, triple );
+        }
+    
+        @Override
+        public boolean evaluateUpdate(Object principal, Node graphIRI, Triple from, Triple to) {
+            return evaluate( principal, from ) && evaluate( principal, to );
+        }
+    
+        public void setPrincipal( String userName )
+        {
+            if (userName == null)
+            {
+                principal = null;
+            }
+            principal = new BasicUserPrincipal( userName );
+        }
+        
+        @Override
+        public Principal getPrincipal() {
+            return principal;
+        }
+    
+    }
\ No newline at end of file

Added: jena/site/trunk/content/documentation/permissions/example.mdtext
URL: http://svn.apache.org/viewvc/jena/site/trunk/content/documentation/permissions/example.mdtext?rev=1692710&view=auto
==============================================================================
--- jena/site/trunk/content/documentation/permissions/example.mdtext (added)
+++ jena/site/trunk/content/documentation/permissions/example.mdtext Sun Jul 26 10:53:36 2015
@@ -0,0 +1,144 @@
+Title: Adding Jena-Permissions to Fuseki
+
+## Overview
+
+The goal of this document is to add jena-permissions to a fuseki deployment to restrict access to graph data.  This example will take the jena-permission example application, deploy the data to a fuseki instance and add the jena-permission to achieve the same access restrictions that the example  application has.
+
+To do this you will need a Fuseki installation, the Permissions Packages and a SecurityEvaluator implementation.  For this example we will use the SecurityEvaluator from the Permissions-Examples.
+
+## Set up
+
+This example uses Fuseki 2.3.0, Permissions 3.0.0 and Apache Commons Collections v4. 
+
+Fuseki can be downloaded from: 
+[https://repository.apache.org/content/repositories/snapshots/org/apache/jena/apache-jena-fuseki/]
+
+Jena Permissions jars can be downloaded from: 
+[https://repository.apache.org/content/repositories/snapshots/org/apache/jena/jena-permissions/]
+
+1. Download and unpack Fuseki.  The directory that you unpack Fuseki into will be referred to as the `Fuseki Home` directory for the remainder of this document.
+
+2. Download permissions 3.0.0 jar and 3.0.0 permissions-example jar.
+
+3. Copy the permissions jar and the permissions-example jar into the Fuseki Home directory.  For the rest of this document the permissions jar will be referred to as `permissions.jar` and the permissions-example.jar as `example.jar`
+
+4. Download the Apache Commons Collections v4
+[http://commons.apache.org/proper/commons-collections/download_collections.cgi]
+Uncompress the `commons-collections*.jar` into the `Fuseki Home` directory.
+
+5. Add security jars to the startup script/batch file.
+    * On \*NIX edit fuseki-server script 
+        1. Comment out the line that reads `exec java  $JVM_ARGS -jar "$JAR" "$@"`
+        2. Uncomment the line that reads `\#\#   APPJAR=MyCode.jar`
+        3. Uncomment the line that reads `\#\#   java $JVM_ARGS -cp "$JAR:$APPJAR" org.apache.jena.fuseki.cmd.FusekiCmd "$@"`
+        4. change `MyCode.jar` to `permissions.jar:example.jar:commons-collections*.jar`
+    
+    * On Windows edit fuseki-server.bat file.
+        1. Comment out the line that reads `java -Xmx1200M -jar fuseki-server.jar %*`
+        2. Uncomment the line that reads `@REM  java ... -cp fuseki-server.jar;MyCustomCode.jar org.apache.jena.fuseki.cmd.FusekiCmd %*`
+        3. Change `MyCustomCode.jar` to `permissions.jar;example.jar;commons-collections*.jar`
+
+6. Run the fuseki-server script or batch file.
+
+7. Stop the server. 
+
+8. Extract the example configuration into the newly created `Fuseki Home/run` directory.
+    From the example.jar archive: 
+    * extract `/org/apache/jena/permissions/example/example.ttl` into the `Fuseki Home/run` directory
+    * extract `/org/apache/jena/permissions/example/fuseki/config.ttl` into the `Fuseki Home/run` directory
+    * extract `/org/apache/jena/permissions/example/fuseki/shiro.ini` into the `Fuseki Home/run` directory
+
+9. Run `fuseki-server –config=run/config.ttl` or `fuseki-server.bat –config=run/config.ttl`
+
+## Review of configuration
+
+At this point the system is configured with the following logins:
+
+<table>
+<tr><th>Login</th><th>password</th><th>Access to</th></tr>
+<tr><td>admin</td><td>admin</td><td>Everything</td></tr>
+<tr><td>alice</td><td>alice</td><td>Only messages to or from alice</td></tr>
+<tr><td>bob</td><td>bob</td><td>Only messages to or from bob</td></tr>
+<tr><td>chuck</td><td>chuck</td><td>Only messages to or from chuck</td></tr>
+<tr><td>darla</td><td>darla</td><td>Only messages to or from darla</td></tr>
+</table>
+
+The messages graph is defined in the `run/example.ttl` file.
+
+The `run/shiro.ini` file lists the users and their passwords and configures Fuseki to require authentication to access to the graphs.
+
+The `run/config.ttl` file adds the permissions to the graph as follows by applying the 
+`org.apache.jena.permissions.example.ShiroExampleEvaluator` security evaluator to the message
+graph.
+
+Define all the prefixes 
+
+    @prefix fuseki:  <http://jena.apache.org/fuseki#> .
+    @prefix tdb:     <http://jena.hpl.hp.com/2008/tdb#> .
+    @prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+    @prefix rdfs:    <http://www.w3.org/2000/01/rdf-schema#> .
+    @prefix ja:      <http://jena.hpl.hp.com/2005/11/Assembler#> .
+    @prefix perm:    <http://apache.org/jena/permissions/Assembler#> .
+    @prefix my:     <http://example.org/#> .
+
+
+Load the SecuredAssembler class from the permissions library and define the perm:Model as a subclass of ja:NamedModel.
+
+    [] ja:loadClass    "org.apache.jena.permissions.SecuredAssembler" .
+    perm:Model       rdfs:subClassOf  ja:NamedModel .
+
+
+Define the base model that contains the unsecured data.
+
+    my:baseModel rdf:type ja:MemoryModel;
+        ja:content [ja:externalContent <file:./example.ttl>] 
+        .   
+
+
+Define the secured model.  This is where permissions is applied to the my:baseModel to create a model that has permission restrictions.  Note that it is using the security evaluator implementation (sec:evaluatorImpl) called my:secEvaluator which we will define next.
+
+    my:securedModel rdf:type sec:Model ;
+        perm:baseModel my:baseModel ;
+        ja:modelName "https://example.org/securedModel" ;
+        perm:evaluatorImpl my:secEvaluator .
+
+Define the security evaluator.  This is where we use the example ShiroExampleEvaluator.  For your production environment you will replace "org.apache.jena.security.example.ShiroExampleEvaluator"  with your SecurityEvaluator implementation.  Note that  ShiroExampleEvaluator constructor takes a Model argument.  We pass in the unsecured baseModel so that the evaluator can read it unencumbered.  Your implementation of SecurityEvaluator may have different parameters to meet your specific needs.
+
+    my:secEvaluator rdf:type perm:Evaluator ;
+        perm:args [  
+            rdf:_1 my:baseModel ;
+        ] ;
+        perm:evaluatorClass "org.apache.jena.permissions.example.ShiroExampleEvaluator" .
+
+
+Define the dataset that we will use for in the server.
+
+    my:securedDataset rdf:type ja:RDFDataset ;
+        ja:defaultGraph my:securedModel .
+
+
+Define the fuseki:Server.
+
+    my:fuskei rdf:type fuseki:Server ;
+        fuseki:services (
+            my:service1
+        ) .
+
+Define the service for the fuseki:Service.  Note that the fuseki:dataset served by this server is the secured dataset defined above.
+   
+    my:service1 rdf:type fuseki:Service ;
+        rdfs:label                        "My Secured Data Service" ;
+        fuseki:name                       "myAppFuseki" ;       # http://host:port/myAppFuseki
+        fuseki:serviceQuery               "query" ;    # SPARQL query service
+        fuseki:serviceQuery               "sparql" ;   # SPARQL query service
+        fuseki:serviceUpdate              "update" ;   # SPARQL query service
+        fuseki:serviceUpload              "upload" ;   # Non-SPARQL upload service
+        fuseki:serviceReadWriteGraphStore "data" ;     # SPARQL Graph store protocol (read and write)
+        # A separate ead-only graph store endpoint:
+        fuseki:serviceReadGraphStore      "get" ;      # SPARQL Graph store protocol (read only)
+        fuseki:dataset                   my:securedDataset ;
+    .
+
+
+
+

Added: jena/site/trunk/content/documentation/permissions/index.mdtext
URL: http://svn.apache.org/viewvc/jena/site/trunk/content/documentation/permissions/index.mdtext?rev=1692710&view=auto
==============================================================================
--- jena/site/trunk/content/documentation/permissions/index.mdtext (added)
+++ jena/site/trunk/content/documentation/permissions/index.mdtext Sun Jul 26 10:53:36 2015
@@ -0,0 +1,33 @@
+Title: Jena Permissions - A Permissions wrapper around the Jena RDF implementation
+
+Jena-permissions is a SecurityEvaluator interface and a set of dynamic proxies that apply that interface to Jena Graphs, Models, and associated methods and classes.  It does not implement any specific security policy but provides a framework for developers or integrators to implement any desired policy.
+
+## Documentation
+
+- [Overview](index.html#overview)
+- [Usage Notes](index.html#usage-notes)
+- [Jena Permissions Design](design.html)
+- [Security Evaluator](evaluator.html)
+- [Assembler](assembler.html)
+- [Adding Jena-Permissions to Fuseki](example.html)
+
+## Overview
+
+Jena-permissions transparently intercepts calls to the Graph or Model interface, evaluates access restrictions and either allows or rejects the access.  The system is authentication agnostic and will work with most authentication systems.  The system uses dynamic proxies to wrap any Graph or Model implementation.  The jena-permissions module includes an Assembler module to extend the standard Assembler to include the ability to create secured models and graphs.  A complete example application is also available.
+
+The developer using jena-permissions is required to implement a SecurityEvaluator that provides access to the Principal (User) using the system and also determines if that Principal has the proper access to execute a method.  Through the SecurityEvaluator the developer may apply full CRUD (Create, Read, Update, and Delete) restrictions to graphs and optionally triples within the graphs. 
+
+The javadocs have additional annotations that specify what permissions at graph and triple levels are required for the user to execute the method.
+
+There is an example jar that contains configuration examples for both a stand alone application and a Fuseki configuration option.
+
+## Usage Notes
+
+When the system is correctly configured the developer creates a SecuredGraph by calling `Factory.getInstance( SecurityEvaluator, String, Graph );`. Once created the resulting graph automatically makes the appropriate calls to the SecurityEvaluator before passing any approved requests to the underlying graph.
+
+Secured models are created by calling `Factory.getInstance( SecurityEvaluator, String, Model );` or `ModelFactory.createModelForGraph( SecuredGraph );`
+
+**NOTE:** when creating a model by wrapping a secured graph (e.g. `ModelFactory.createModelForGraph( SecuredGraph );`) the resulting Model does not have the same security requirements that the standard secured model.  For example When creating a list on a secured model calling `model.createList( RDFNode[] );`, the standard secured model verifies that the user has the right to **update** the triples and allows or denies the entire operation accordingly. The wrapped secured graph does not have visibility to the `createList()` command and can only operate on the instructions issued by the `model.createList()` implementation. In the standard implementation the model requests the graph to delete one triple and then insert another. Thus the user must have **delete** and **add** permissions, not the **update** permission.
+
+There are several other cases where the difference in the layer can trip up the security system. In all known cases the result is a tighter security definition than was requested. For simplicity sake we recommend that the wrapped secured graph only be used in cases where access to the graph as a whole is granted/denied. In these cases the user either has all CRUD capabilities or none.
+

Added: jena/site/trunk/content/documentation/permissions/migration2To3.mdtext
URL: http://svn.apache.org/viewvc/jena/site/trunk/content/documentation/permissions/migration2To3.mdtext?rev=1692710&view=auto
==============================================================================
--- jena/site/trunk/content/documentation/permissions/migration2To3.mdtext (added)
+++ jena/site/trunk/content/documentation/permissions/migration2To3.mdtext Sun Jul 26 10:53:36 2015
@@ -0,0 +1,92 @@
+Title: Jena Permissions - Migration notes: Version 2.x to Version 3.x
+
+When Jena moved from version 2 to version 3 there was a major renaming of packages.  One of the packages renamed was the Jena Permsissions package.  It was formerly named Jena Security. There are several changes that need to occur to migrate from jena-security version 2.x to jena-permissions version 3.x
+
+Changes
+=======
+
+Package Rename
+--------------
+
+There are two major changes to package names.
+
+* As with the rest of the Jena code all refrerences to _com.hp.hpl.jena_ have been changed to _org.apache.jena_.  For integrator code this means that a simple rename of the includes is generally all that is required for this.  See the main Migration Notes page for other hints and tips regarding this change.
+
+* Jena Security has been renamed Jena Permissions and the Maven _artifact id_ has been changed to _jena-permissions_ to reflect this change.
+
+* The permissions assembler namespace has been changed to `http://apache.org/jena/permissions/Assembler#`
+
+Exceptions
+==========
+
+Formerly jena-permissions uses a single exception to identify the access restriction violations.  With the tighter integration of permission concepts into the Jena core there are now 7 exceptions.  This change will probably not required modification to the SecurityEvaluator implementation but may require modification to classes that utilize the permissions based object.
+
+All exceptions are runtime exceptions and so do not have to be explicitly caught.  Java docs indicate which methods throw which exceptions.
+
+* Removal of org.apache.jena.permissions.AccessDeniedException.  This is replace by 5 individual exceptions.
+
+* Addition of org.apache.jena.shared.OperationDeniedException.  This exception is a child of the _JenaException_ and is the root of all operation denied states whether through process errors or through permissions violations.
+
+* Addition of org.apache.jena.shared.PermissionDeniedException.  This exception is a child of the _OperationDeniedException_ and is the root of all operations denied through permission violations.  These can be because the object was staticly prohibited from performing an operation (e.g. a read-only graph) or due to the jena-permissions layer.
+
+* Addition of org.apache.jena.shared.AddDeniedException.  This exception is a child of _PermissionDeniedException_ and used to indicate that an attempt was made to add to an unmodifiable object.  It may be thrown by read-only graphs or by the permission layer when a create restriction is violated.
+
+* Addition of org.apache.jena.shared.DeleteDeniedException.  This exception is a child of _PermissionDeniedException_ and used to indicate that an attempt was made to delete from an unmodifiable object.  It may be thrown by read-only graphs or by the permission layer when a delete restriction is violated.
+
+* Addition of org.apache.jena.shared.ReadDeniedException.  This exception is a child of _PermissionDeniedException_ and used to indicate that a read restriction was violated.  
+
+* Addition of org.apache.jena.shared.UpdateDeniedException.  This exception is a child of _PermissionDeniedException_ and used to indicate that a update restriction was violated.  
+
+* Addition of org.apache.jena.shared.AuthenticationRequiredException.  This exception is a child of _OperationDeniedException_ and used to indicate that user authentication is required but has not occurred.  This exception should be thrown when the SecurityEvaluator attempts to evaluate an operation and there is both a permissions restriction and the object returned by getPrincipal() indicates that the user is unauthenticated.
+
+Removal of Classes
+==================
+
+The original "security" code was intended to be graph agnostic and so injected a "shim" layer to convert from graph specific classes to security specific classes.  With the renaming of the package to "permissions" and the tighter integration to the Jena core the "shim" structure has been removed.  This should make the permissions layer faster and cleaner to implement.   
+
+SecNode
+-------
+
+The SecNode class has been removed.  This was effectively a proxy for the Jena Node object and has been replaced with that object.  The SecNode maintained its type (e.g. URI, Literal or Variable) using an internal Enumeration.  The method getType() was used to identify the internal type.  With the Jena node replacement statements of the form
+   
+     if (secNode.getType().equals( SecNode.Type.Literal ))
+     {
+         // do something
+     }
+     
+are replaced with 
+
+     if (node.isLiteral())
+     {
+         // do something
+     }  
+     
+`SecNode.ANY` has been replaced with Node.ANY as it served the same purpose.
+
+`SecNode.FUTURE` has been replaced with `SecurityEvaluator.FUTURE` and is now implemented as a blank node with the label `urn:jena-permissions:FUTURE`.
+
+`SecNode.VARIABLE` has been replaced with `SecurityEvaluator.VARIABLE` and is now implemented as a blank node with the label `urn:jena-permissions:VARIABLE`.
+
+
+SecTriple
+---------
+
+The SecTriple class has been removed.  This was effectively a proxy for the Jena Triple object and has been replaced with that object.
+
+
+Movement of Classes
+===================
+
+SecuredItem
+-----------
+
+The SecuredItem interface was moved from org.apache.jena.permissions.impl to org.apache.jena.
+
+Additional Methods
+==================
+
+SecurityEvaluator
+-----------------
+
+The method `isAuthenticatedUser( Object principal )` has been added.  The SecurityEvaluator should respond `true` if the principal is recognized as an authenticated user.  The `principal` object is guaranteed to have been returend from an earlier `getPrincipal()` call.
+