# Welcome to AuthzForce’s official documentation

This project is part of FIWARE. You will find more information about this FIWARE GE at the Catalogue.

## Introduction

AuthzForce is the reference implementation of the Authorization PDP Generic Enabler (formerly called Access Control GE). Indeed, as mandated by the GE specification, this implementation provides an API to get authorization decisions based on authorization policies, and authorization requests from PEPs. The API follows the REST architecture style, and complies with XACML v3.0. XACML (eXtensible Access Control Markup Language) is a OASIS standard for authorization policy format and evaluation logic, as well as for the authorization decision request/response format. The PDP (Policy Decision Point) and the PEP (Policy Enforcement Point) terms are defined in the XACML standard. This GEri plays the role of a PDP.

To fulfill the XACML architecture, you may need a PEP (Policy Enforcement Point) to protect your application, which is not provided here. For REST APIs, we can use the PEP Proxy (Wilma) available in the FIWARE catalogue.

## Release Notes

The release notes are available on our GitHub release page.

## Features

See the list of features on Github for the current version.

## Installation and Administration Guide

This guide provides the procedure to install the AuthzForce server, including system requirements and troubleshooting instructions.

### Installation via Docker (container image)

See docker/README.md on Github.

### Manual installation via tar.gz

System requirements:

- CPU frequency: 2.6 GHz min

- CPU architecture: i686/x86_64

- RAM: 4GB min

- Disk space: 10 GB min

- File system: ext4

- Operating System: Ubuntu 20.04 or later

- Java environment:

  > - JRE 17 LTS either from OpenJDK or Oracle;

  > - Tomcat 10.x or later.

See tar/README.md on Github.

### Installation via APT (Ubuntu .deb package)

#### System Requirements

The system requirements are the following:

- CPU frequency: 2.6 GHz min

- CPU architecture: i686/x86_64

- RAM: 4GB min

- Disk space: 10 GB min

- File system: ext4

- Operating System: Ubuntu 23.04 or later (Tomcat 10 package not available yet on latest LTS)

- Java environment:

  > - JRE 17 LTS either from OpenJDK or Oracle;

  > - Tomcat 10.x or later.

#### Installation

If you are already using an older version of AuthzForce and wish to migrate your setup to the new version, please backup the folder `/opt/authzforce-ce-server` first because it will be overwritten by the new version, then proceed with the Minimal setup below, to install the new version; finally, proceed with the Upgrade section that follows, to transfer data from the old version.

##### Minimal setup

1. Install a JRE 17 LTS if you don’t have one already, using either of these two methods depending on your JDK preference:

   - For OpenJDK: `$ sudo apt install openjdk-17-jre`

2. Install Tomcat 10 (Ubuntu 23.04 or later): `$ sudo apt install tomcat10`.

3. Each AuthzForce Server version number has the form MAJOR.MINOR.PATH (Semantic Versioning). Identify the latest binary (Ubuntu package with `.deb` extension) release of AuthzForce Server on Maven Central Repository that matches the MAJOR.MINOR version of this documentation. This is the current latest software version to which this documentation version applies. If you want to use a different software version, go to the latest documentation version with matching MAJOR.MINOR and follow instructions there. Else you may download the software version. We will refer to its version number as `M.m.P` (please replace accordingly):

   > $ wget https://repo1.maven.org/maven2/org/ow2/authzforce/authzforce-ce-server-dist/M.m.P/authzforce-ce-server-dist-M.m.P.deb

   > You should get a file called `authzforce-ce-server-dist-M.m.P.deb`.

4. Copy this file to the host where you want to install the software.

5. On the host, from the directory where you copied this file, run the following commands:

       $ sudo apt install curl
       $ sudo apt install ./authzforce-ce-server-dist-M.m.P.deb

6. At the end, you will see a message giving optional instructions to go through. Please follow them as necessary.

Note that Tomcat default configuration may specify a very low value for the Java `Xmx` flag, causing the AuthzForce webapp startup to fail. In that case, make sure Tomcat with `Xmx` at 1 Go or more (2 Go recommended). You can fix it as follows:

    $ sudo sed -i "s/-Xmx128m/-Xmx1024m/" /etc/default/tomcat
    $ sudo systemctl restart tomcat10

Known issue: lack of entropy may cause delays in Tomcat start up on virtual machines in particular: more info on Entropy Source issue. So beware.

##### Upgrade

If you are still using an older version of AuthzForce and wish to migrate your setup to the new version, assuming you made a backup in a separate location, as told previously, please follow these steps:

1. Download AuthzForce server upgrader distribution (.tar.gz extension) from Maven Central Repository in the same version as the Server version you want to upgrade to. You get a file called `authzforce-ce-server-upgrader-M.m.P.tar.gz` (replace `M.m.P` with the corresponding version).

2. Copy this file to the host where the old AuthzForce Server is installed, and unzip it and change directory:

       $ tar xvzf authzforce-ce-server-upgrader-M.m.P.tar.gz
       $ cd authzforce-ce-server-upgrader-M.m.P

3. Follow the instructions in file `README.html`.

##### Advanced setup

The Minimal setup gave you minimal installation steps to get started testing the features of the GE API. This may be enough for testing purposes, but barely for production. If you are targeting a production environment, you have to carry out extra installation and configuration steps to address non-functional aspects: security (including availability), performance, etc. The Appendix also gives some recommendations on what you should do.

### Administration

#### Tomcat

For configuring and managing Tomcat, please refer to the official user guide.

#### AuthzForce webapp

The AuthzForce webapp configuration directory is located here: `/opt/authzforce-ce-server/conf`.

In particular, the file `logback.xml` configures the logging for the webapp (independently from Tomcat). By default, AuthzForce-specific logs go to `/var/log/tomcat10/authzforce-ce/error.log`.

Restart Tomcat to apply any configuration change:

    $ sudo systemctl restart tomcat10

#### Fast Infoset mode

Fast Infoset is an ITU-T/ISO standard for representing XML (XML Information Set to be accurate) using binary encodings, designed for use cases to provide smaller encoding sizes and faster processing than a W3C XML representation as text. The open source Fast Infoset project provide some performance results and more information about the standardisation status. There are several use cases at the origin of Fast Infoset. A major one comes from the Web3D consortium that is responsible for open standards in real-time 3D communication, and that adopted Fast Infoset for the serialization and compression of X3D documents. X3D is a standard for representing 3D scenes and objects using XML.

AuthzForce Server offers experimental support for Fast Infoset (use with caution). This feature is disabled by default. To enable Fast Infoset support, change the value of the parameter `spring.profiles.active` to `+fastinfoset` in the webapp context configuration file `/etc/tomcat10/Catalina/localhost/authzforce-ce.xml`; then restart Tomcat as shown in the previous section in order to apply changes.

#### Policy Domain Administration

##### The Concept of Policy Domain

The application is multi-tenant, i.e. it allows users or organizations to work on authorization policies in complete isolation from each other. In this document, we use the term domain instead of tenant. In this context, a policy domain consists of:

- Various metadata about the domain: ID assigned by the AuthzForce API, external ID (assigned by the provisioning client), description;

- A policy repository;

- Attribute Providers configuration: attribute providers provide attributes that the PEP does NOT directly provide in the XACML <Request>. For example, an attribute provider may get attribute values from an external database.

The reasons for creating different domains:

- Users or organizations do not want others to access their data, or even be impacted by others working on the same application.

- The same user or organization may want to work on different domains for different use cases; e.g. work with one policy for production environment, another for testing, another for a specific use case project, etc.

##### Default Domain Settings

Administrators can set default settings for all domains to make sure domains are created in a proper configuration according to an administrative policy, or, in more simple terms, the administrator’s preferences. The administrator may change these settings in the various XML files inside the folder `/opt/authzforce-ce-server/conf/domain.tmpl`:

- `pdp.xml`:

  - `maxVariableRefDepth`: optional, positive integer that indicates the maximum depth of Variable reference chaining allowed in policies: `VariableDefinition` 1 -> `VariableDefinition` 2 -> …, where -> represents a XACML VariableReference. No limit if undefined. This property applies only to policies loaded by the PDP, i.e. the root policy and policies referenced from it directly or indirectly via XACML PolicySetIdReference.

  - `maxPolicyRefDepth`: optional, positive integer that indicates the maximum depth of Policy(Set) reference chaining: `PolicySet` 1 -> `PolicySet` 2 -> … -> `PolicySet` N; where -> represents a XACML PolicySetIdReference. No limit if undefined. This property applies only to policies loaded by the PDP, i.e. the root policy and policies referenced from it directly or indirectly via XACML PolicySetIdReference.

  - `clientRequestErrorVerbosityLevel`: optional, positive integer (default: 0) that sets the level of detail in the XACML StatusDetail element returned in the Indeterminate Decision Result in case of bad Request (XACML syntax/content is invalid). Increasing this value usually helps better pinpoint the reason why a particular Request was rejected by the XACML parser. This only applies to the content of the HTTP request body (XACML), it does not apply to HTTP-level errors (e.g. bad HTTP headers), in which case you get a HTTP status code 400 without any XACML response since the request is rejected before the body is passed to the XACML parser.

- `policies/cm9vdA/0.1.0.xml`: the default root XACML PolicySet enforced by the PDP on the domain. As an administrator, you may change the content of this policy on two conditions:

  1. You must not change the `PolicySetId`.

  2. If you change the `Version` (e.g. to `1.2.3`), you must change the filename prefix (before `.xsd` extension) to the same value (e.g. `1.2.3.xsd`).

- `properties.xml`: other domain properties, more specifically:

  - `maxPolicyCount`: optional, stricly positive integer that indicates the maximum number of policies on a domain, no limit if undefined.

  - `maxVersionCountPerPolicy`: optional, stricly positive integer that indicates the maximum number of versions per policy, no limit if undefined.

  - `versionRollingEnabled`: boolean, true if and only if policy versions should be rolled over, i.e. when `maxVersionCountPerPolicy` has been reached, oldest versions are automatically removed to make place.

##### Domain Creation

You create a domain by doing a HTTP POST request with XML payload to URL: `http://${SERVER_NAME}:${PORT}/authzforce-ce/domains`. Replace `${SERVER_NAME}` and `${PORT}` with your server hostname and port for HTTP. You can do it with `curl` tool with the the following content in a XML file (`domainProperties.xml` in this example) as the HTTP request body:

    $ cat domainProperties.xml
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <domainProperties
     xmlns="http://authzforce.github.io/rest-api-model/xmlns/authz/5"
     externalId="external0">
     <description>This is my domain</description>
    </domainProperties>

    $ curl --verbose --request "POST" \
    --header "Content-Type: application/xml;charset=UTF-8" \
    --data @domainProperties.xml \
    --header "Accept: application/xml" \
      http://${SERVER_NAME}:${PORT}/authzforce-ce/domains

    ...
    > POST /authzforce-ce/domains HTTP/1.1
    > Content-Type: application/xml;charset=UTF-8
    > Accept: application/xml
    > Content-Length: 227
    >
    ...
    < HTTP/1.1 200 OK
    < Server: Authorization System
    < Date: Mon, 04 Aug 2016 13:00:12 GMT
    < Content-Type: application/xml
    < Transfer-Encoding: chunked
    <
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <link xmlns="http://www.w3.org/2005/Atom"
      rel="item" href="h_D23LsDEeWFwqVFFMDLTQ"
      title="h_D23LsDEeWFwqVFFMDLTQ"/>

WARNING: Mind the leading and trailing single quotes for the `--data` argument. Do not use double quotes instead of these single quotes, otherwise curl will remove the double quotes in the XML payload itself, and send invalid XML which will be rejected by the server. You may use the `--trace-ascii -` argument (the last dash here means stdout) instead of `--verbose`, in order to check the actual request body sent by `curl`. So use it only if you need to dump the outgoing (and incoming) data, in particular the request body, on stdout.

The `href` value in the response above gives you the domain ID (in the form of a Base64-encoded UUID) assigned by the API. You need this ID for any further operation on the domain.

##### Domain Removal

You remove a domain by doing a HTTP DELETE request with XML payload to URL: `http://${SERVER_NAME}:${PORT}/authzforce-ce/domains/{domain_ID}`. For example with `curl` tool:

    $ curl --verbose --request DELETE \
     --header "Content-Type: application/xml;charset=UTF-8" \
     --header "Accept: application/xml" \
     http://${SERVER_NAME}:${PORT}/authzforce-ce/domains/h_D23LsDEeWFwqVFFMDLTQ

Policy administration is part of the Authorization Server API, addressed more extensively in the User and Programmers Guide.

### High Availability

In order to achieve high availability with multiple AuthzForce Server instances (AuthzForce Server cluster), you need to make sure that the following directories are synchronized on all instances:

- Configuration directory: `/opt/authzforce-ce-server/conf`. This directory is not modified by the API but only by administrators having access to the directory, and any change to it requires restarting Tomcat to apply. Therefore, this directory requires synchronization only after a manual change by a server admin, which should not occur very often. When it occurs, the server administrators may reproduce the changes on each instance manually; or, if there are too many instances for this to be practical, they may use automatic file synchronization solutions, or a distributed filesystems (e.g. NFS) combined with file monitoring solutions. Both kinds of solutions must be capable of executing a specific command, to restart Tomcat in this case, whenever a filesystem change in the directory is detected on a instance node. For example, csync2 is a solution of the first kind that is free and open source.

- Data directory: `/opt/authzforce-ce-server/data`. This is where the Server API persists and retrieves domain data such as policies. Therefore, it is critical to keep this directory synchronized across all the nodes in the high availability cluster, using either file synchronization solutions such as csync2, or distributed file systems such as NFS. Besides, for usability and performance reasons, the AuthzForce server caches certain objects in memory such as domains’ PDPs and ID-externalId mappings (more info in the User and Programmers Guide). Therefore, it is also critical to re-sync the AuthzForce Server cache after certain changes done directly by aforementioned solutions to the local data directory. There are two ways to do that:

  - REST API: you can keep the server in sync with the data directory by calling the following API operations, dependending on the type of change (`encoded_domainId` is the result of encoding the `domainId` using the “URL and Filename safe Base64 Alphabet” specified in Table 2 of RFC 4648):

    - HEAD `/domains`: to be used after any global change to the data directory. Inappropriate and largely suboptimal if there are many domains but changes concern only one or a few of them, in which case the next operations should be preferred.

    - HEAD `/domains/{domainId}`: to be used after a specific domain directory `/opt/authzforce-ce-server/data/domains/{encoded_domainId}` is created.

    - DELETE `/domains/{domainId}`: to be used after a specific domain directory `/opt/authzforce-ce-server/data/domains/{encoded_domainId}` is deleted.

    - HEAD `/domains/{domainId}/properties`: to be used after a specific domain’s properties file `/opt/authzforce-ce-server/data/domains/{encoded_domainId}/properties.xml` is modified (especially the `externalId` property).

    - HEAD `/domains/{domainId}/pap/pdp.properties`: to be used after a specific domain’s PDP configuration file `/opt/authzforce-ce-server/data/domains/{encoded_domainId}/pdp.xml` or policies directory `/opt/authzforce-ce-server/data/domains/{encoded_domainId}/policies` is modified.

    In these operations, you may use `GET` method instead of `HEAD` as well. However, `HEAD` is recommended for better performances as it does not return any content (response body), on the contrary to `GET`. Beware that the `Content-Length` returned by a `HEAD` is still the same as would be returned by the `GET` equivalent. In any case, if you opt for the file synchronization solution as mentioned earlier, you would have to make it call one of these operations depending on the type of change detected. If you opt for the distributed file system, you would need a file monitoring solution to detect changes and make such calls.

  - Embedded file monitoring threads: it is possible to enable file monitoring threads embedded in AuthzForce Server. These threads check for changes to the local data directory periodically, and synchronize the cache automatically. This feature is disabled by default. To enable it, change the value of the parameter `org.ow2.authzforce.domains.sync.interval` to a strictly positive integer in the webapp context configuration file `/etc/tomcat10/Catalina/localhost/authzforce-ce.xml`. The parameter value indicates the period between two checks for changes, in seconds. Beware that this feature creates one extra thread per domain. Therefore, the impact on memory and CPU usage increases with the number of domains. Last but not least, use this feature only on filesystems that support millisecond or higher resolution of file timestamps, such as `ext4` (supports nanosecond resolution). Indeed, Authzforce file monitoring threads use file timestamps to detect changes. As a result, if the resolution of the filesystem is coarser than the millisecond, and a file change occurred in less than a second after the last check, it will go undetected (the file’s mtime timestamp is not updated), and synchronization will not work as expected.

### Sanity check procedures

The Sanity Check Procedures are the steps that a System Administrator will take to verify that the installation is ready to be tested. This is therefore a preliminary set of tests to ensure that obvious or basic malfunctioning is fixed before proceeding to unit tests, integration tests and user validation.

#### End-to-End testing

To check the proper deployment and operation of the AuthzForce Server, perform the following steps:

1. Get the list of policy administration domains by doing the following HTTP request, replacing `${host}` with the server hostname, and `${port}` with the HTTP port of the server, for example with `curl` tool:

       $ curl --verbose --show-error --write-out '\n' \
         --request GET http://${host}:${port}/authzforce-ce/domains

2. Check the response which should have the following headers and body (there may be more headers which do not require checking here):

       Status Code: 200 OK
       Content-Type: application/xml

       <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
       <resources
         xmlns="http://authzforce.github.io/rest-api-model/xmlns/authz/5"
         xmlns:atom="http://www.w3.org/2005/Atom">
         <atom:link rel="item" href="1XepFknrEea2mQAdYFsFBQ" title="1XepFknrEea2mQAdYFsFBQ"/>
         ... list of links to other policy domains omitted here...
       </resources>

You can check the exact body format in the representation element of response code 200 for method `getDomains`, and all other API resources and operations in general, in the WADL (Web Application Description Language) document available at the following URL:

    http://${host}:${port}/authzforce-ce/?_wadl

#### List of Running Processes

- One or more `java` processes for Tomcat.

#### Network interfaces Up & Open

- TCP 22;

- TCP 8080.

The port 8080 can be replaced by any other port Tomcat is listening to for HTTP connections to the webapp.

#### Databases

None.

### Diagnosis Procedures

1. Perform the test described in End-to-End testing.

2. If you get a Connection Refused/Error, check whether Tomcat is started:

       $ sudo systemctl status tomcat10

3. If status stopped, start Tomcat:

       $ sudo systemctl start tomcat10

4. If Tomcat fails to start, check for any Tomcat high-level error in Tomcat log directory: `/var/log/tomcat10`

5. If Tomcat is successfully started (no error in server logs), perform the test described in End-to-End testing again.

6. If you still get a Connection Refused/error, check whether Tomcat is not listening on a different port:

       $ sudo netstat -lataupen|grep java

7. If you still get a connection refused/error, especially if you are connecting remotely, check whether you are able to connect locally, then check the network link, i.e. whether any network filtering is in place on the host or on the access network, or other network issue: network interface status, DNS/IP adress resolution, routing, etc.

8. If you get an error `404 Not Found`, make sure the webapp is deployed and enabled in Tomcat. Check for any webapp deployment error in file: `/var/log/tomcat10/authzforce-ce/error.log`.

### Resource availability

To have a healthy enabler, the resource requirements listed in System Requirements must be satisfied, in particular:

- Minimum RAM: 4GB;

- Minimum CPU: 2.6 GHz;

- Minimum Disk space: 10 GB.

#### Remote Service Access

None.

#### Resource consumption

The resource consumption strongly depends on the number of concurrent clients and requests per client, the number of policy domains (a.k.a. tenants in this context) managed by the Authorization Server, and the complexity of the policies defined by administrators of each domain.

The memory consumption shall remain under 80% of allocated RAM. See System Requirements for the minimum required RAM.

The CPU usage shall remain under 80% of allocated CPU. See System Requirements for the minimum required CPU.

As for disk usage, at any time, there should be 1GB free space left on the disk.

#### I/O flows

- HTTPS flows with possibly large XML payloads to port 8443 or whatever port Tomcat is listening to for HTTPS connections to the webapp;

- HTTP flows with possibly large XML payloads to port 8080 or whatever port Tomcat is listening to for HTTP connections to the webapp.

### Appendix

#### Security setup for production

You have to secure the environment of the application server and the server itself. Securing the environment of a server in general will not be addressed here, because it is a large subject for which you can find a lot of public documentation. You will learn about perimeter security, network and transport-level security (firewall, IDS/IPS…), OS security, application-level security (Web Application Firewall), etc. For instance, the NIST Guide to General Server Security (SP 800-123) is a good start.

##### Server Security Setup

For more Tomcat-specific security guidelines, please read Tomcat 9 Security considerations.

For security of communications (confidentiality, integrity, client/server authentication), it is also recommended to enable SSL/TLS with PKI certificates. The first step to set up this is to have your Certification Authority (PKI) issue a server certificate for your AuthzForce instance. You can also issue certificates for clients if you want to require client certificate authentication to access the AuthzForce server/API. If you don’t have such a CA at hand, you can create your own (a basic one) with instructions given in the next section.

##### Certificate Authority Setup

If you have a CA already, you can skip this section. So this section is about creating a basic local Certificate Authority (CA) for internal use. This CA will be in charge of issuing certificates to the Authorization Server and clients, for authentication, integrity and confidentiality purposes. This procedure requires JDK 1.7 or later. (For the sake of simplicity, we do not use a subordinate CA, although you should for production, see keytool command example, use the `pathlen` parameter to restrict number of subordinate CA, `pathlen=0` means no subordinate.)

1. Generate the CA keypair and certificate on the platform where the Authorization Server is to be deployed (change the validity argument to your security requirements, example here is 365 days):

       $ keytool -genkeypair -keystore taz-ca-keystore.jks -alias taz-ca \
         -dname "CN=My Organization CA, O=FIWARE" -keyalg RSA -keysize 2048 \
         -validity 365 -ext bc:c="ca:true,pathlen:0"

2. Export the CA certificate to PEM format for easier distribution to clients:

       $ keytool -keystore taz-ca-keystore.jks -alias taz-ca \
         -exportcert -rfc > taz-ca-cert.pem

##### Server SSL Certificate Setup

For Tomcat 9, refer to the Tomcat 9 SSL/TLS Configuration HOW-TO.

##### Web Application Secutity

###### XML and JSON Security

The AuthzForce web application exposes a XML-based API. Therefore it is vulnerable to XML denial-of-service attacks. To mitigate these attacks, there are two solutions:

- AuthzForce native protection: you can add the following Environment entries in AuthzForce webapp context file `/etc/tomcat10/Catalina/localhost/authzforce-ce.xml` (if an entry is absent or its value is negative, the default value is used):

       <Environment
        name="org.apache.cxf.stax.maxChildElements"
        description="Maximum number of child elements (resp. properties) in an input XML element (resp. JSON)."
        type="java.lang.Integer"
        value="1000"
        override="false" />

       <Environment
        name="org.apache.cxf.stax.maxElementDepth"
        description="Maximum depth of an element (resp. JSON object) in input XML (resp. JSON)."
        type="java.lang.Integer"
        value="100"
        override="false" />

       <!--Following entries are not supported in Fast Infoset mode
       (more info: https://issues.apache.org/jira/browse/CXF-6848) -->
       <Environment
        name="org.apache.cxf.stax.maxAttributeCount"
        description="Maximum number of attributes per element in input XML."
        type="java.lang.Integer"
        value="100"
        override="false" />

       <Environment
        name="org.apache.cxf.stax.maxAttributeSize"
        description="Maximum size of a single attribute in input XML."
        type="java.lang.Integer"
        value="1000"
        override="false" />

       <Environment
        name="org.apache.cxf.stax.maxTextLength"
        description="Maximum size of XML text node (resp. JSON string)  in input XML (resp. JSON)."
        type="java.lang.Integer"
        value="1000"
        override="false" />

      <Environment
        name="org.ow2.authzforce.domains.xacmlJsonSchemaRelativePath"
                   description="Path to JSON schema file for XACML JSON Profile's Request validation, relative to ${org.ow2.authzforce.config.dir} (if undefined/empty value, the Request.schema.json file from authzforce-ce-xacml-json-model project is used by default). This property applies if and only if 'org.ow2.authzforce.domains.enableXacmlJsonProfile' is true."
       type="java.lang.String"
       value=""
       override="false" />

  Restart Tomcat to apply changes.

- Dedicated WAF: for better mitigation, we recommend using a WAF (Web Application Firewall) with XML attack mitigation features in front of the Authzforce server.

There are commercial as well as open source WAFs available on the market. However, beware that this solution is not compatible with Fast Infoset, unless the WAF itself supports Fast Infoset. Similarly, if you want to use TLS, then the WAF or some proxy in front of it must support TLS to be the TLS server endpoint.

###### Disabling unused features

You can disable all PAP features, i.e. make the REST API read-only by setting the `enablePdpOnly` environment entry

  to `true` in AuthzForce webapp context file `/etc/tomcat10/Catalina/localhost/authzforce-ce.xml` (if an entry is absent or its value is negative, the default value is used):

  >     <Environment name="org.ow2.authzforce.domains.enablePdpOnly" value="true" type="java.lang.Boolean" override="false"
  >     description="Enable PDP only, i.e. disable all PAP (or other administration) features iff true" />

###### User and Role Management Setup

In production, access to the API must be restricted and explicitly authorized. To control which clients can do what on which resources, we need to have access to user identity and attributes and assign proper roles to them. These user and role management features are no longer supported by the AuthzForce server itself, but should be delegated to the Identity Management GE.

#### Performance Tuning

For Tomcat and JVM tuning, we strongly recommend reading and applying - when relevant - the guidelines from the following links:

- Performance tuning best practices for VMware Apache Tomcat;

- Tuning Tomcat Performance For Optimum Speed;

- How to optimize tomcat performance in production;

- Apache Tomcat Tuning Guide for REST/HTTP APIs.

Last but not least, consider tuning the OS, hardware (CPU, RAM…), network, using load-balancing, high-availability solutions, and so on.

## User and Programmers Guide

This guide explains how to use the API to manage XACML-based access control policies and provide authorization decisions based on such policies and the context of a given access request.

If you have been using a previous version of AuthzForce, check the release notes to know what is changed and what is new.

### Background and Detail

This User and Programmers Guide applies to the reference implementation of the Authorization PDP GE which is part of FIWARE Security Architecture. Please find more information about this Generic Enabler in the following Open Specification.

### User Guide

Since the Authorization PDP is a Generic Enabler which provides backend functionality to other applications (e.g. Generic Enablers or end user facing applications) and security administrators, we do not distinguish between the User and Programmers Guide. Please refer to the Programmers Guide section for more information.

### Programmer Guide

AuthzForce provides the following APIs:

- PDP API (PDP = Policy Decision Point in the XACML terminology): provides an API for getting authorization decisions computed by a XACML-compliant access control engine;

- PAP API (PAP = Policy Administration Point in XACML terminology): provides API for managing XACML policies to be handled by the Authorization Service PDP.

The full API (RESTful) is described by a document written in the Web Application Description Language format (WADL) and associated XML schema files available in Authzforce rest-api-model project files.

XACML is the main international OASIS standard for access control language and request-response formats, that addresses most use cases of access control. AuthzForce supports the full core XACML 3.0 language; therefore it allows to enforce generic and complex access control policies.

#### General recommendations for developers

In all the sample XML outputs shown in the next sections, the XML namespace prefix of any API response element, such as the XACML `Response` element, might vary from an AuthzForce run time to another, but it is always the same XML element as the prefix is always mapped to the same namespace, such as `urn:oasis:names:tc:xacml:3.0:core:schema:wd-17` (XACML 3.0 namespace) for the XACML `Response`. Therefore, any valid (namespace-aware) XML parser will handle it equally, no matter the namespace prefix. Beware of that XML namespace-prefix mapping issue if you are parsing XML manually.

We strongly recommend developers to use XML-schema-aware software with XML schema validation enabled for all XML processing. This will make troubleshooting easier, and save you a lot of trouble. You can find the XML schemas and an example of Java client code with schema validation in the Authzforce rest-api-model project files.

#### Attribute-Based Access Control

AuthzForce provides Attribute-Based Access Control. To understand what is meant by attribute in the context of access control, below is the list of standard categories of attributes identified by the XACML standard:

- Subject attributes: the subject is an actor (human, program, device, etc.) requesting access to a resource; attributes may be user ID, Organization, Role, Clearance, etc. In fact, XACML enables you to be more specific about the type of subject, e.g. intermediary subject, requesting machine, etc.

- Resource attributes: the resource is a passive entity (from the access control perspective) on which subject requests to act upon (e.g. data but also human, device, application, etc.); resource attributes may be resource ID, URL, classification, etc.

- Action attributes: the action is the action that the subject requests to perform on the resource (e.g. create, read, delete); attributes may be action ID, parameter A, parameter B, etc.

- Environment attributes: anything else, e.g. current time, CPU load of the PEP/PDP, global threat level, etc.

If this is not enough, XACML enables you to make your own attribute categories as well.

#### Product info API

You can get product information (name, version…) with following HTTP request:

- Method: GET

- Path: `/version`

- Headers:

  > - Accept: `application/xml; charset=UTF-8`

#### Domain Management API

The API allows AuthzForce application administrators or administration interfaces to create domains for the users, and remove domains once they are no longer used. This part of the API is described in the section Policy Domain Administration.

The API is provided over HTTP in order to comply with the test assertions `urn:oasis:names:tc:xacml:3.0:profile:rest:assertion:http:client` and `urn:oasis:names:tc:xacml:3.0:profile:rest:assertion:http:server` of REST Profile of XACML v3.0 Version 1.0.

Each AuthzForce domain represents an independent RESTful XACML system, in the context of the REST Profile of XACML v3.0 Version 1.0.

End-users may retrieve the domain’s resource content as follows:

- Method: GET

- Path: `/domains/{domainId}`

- Headers:

  > - Accept: `application/xml; charset=UTF-8`

For example, this request gets the resource for domain `iMnxv7sDEeWFwqVFFMDLTQ`

    GET /domains/iMnxv7sDEeWFwqVFFMDLTQ
    HTTP/1.1
    Accept: application/xml; charset=UTF-8

If the domain exists, the response goes:

     1HTTP/1.1 200 OK
     2Content-Type: application/xml; charset=UTF-8
     3
     4<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
     5<domain
     6 xmlns="http://authzforce.github.io/rest-api-model/xmlns/authz/5"
     7 xmlns:atom="http://www.w3.org/2005/Atom">
     8 <properties externalId="test-domain1">
     9  <description>Test domain</description>
    10 </properties>
    11 <childResources>
    12  <atom:link rel="item" href="/properties" title="Domain properties"/>
    13  <atom:link rel="item" href="/pap" title="Policy Administration Point"/>
    14  <atom:link
    15   rel="http://docs.oasis-open.org/ns/xacml/relation/pdp"
    16   href="/pdp" title="Policy Decision Point"/>
    17 </childResources>
    18</domain>

If a domain with such ID does not exist, an error 404 is returned.

Therefore, in the context of the REST Profile of XACML v3.0 Version 1.0, the location of the single entry point of a domain-specific RESTful XACML system is `/domains/{domainId}`, and you may get the link to the PDP from the response for the `GET` request to this entry point location, looking for the link relation `http://docs.oasis-open.org/ns/xacml/relation/pdp`. In this respect, we comply with test assertions `urn:oasis:names:tc:xacml:3.0:profile:rest:assertion:home:documentation`, `urn:oasis:names:tc:xacml:3.0:profile:rest:assertion:home:status` and `urn:oasis:names:tc:xacml:3.0:profile:rest:assertion:home:pdp` of the REST Profile of XACML v3.0 Version 1.0.

The API also allows users to update certain properties of the domain allocated to them:

- An externalId (optional) for the domain, which users/clients can modify and more easily use as reference, as opposed to the unique and read-only domain ID assigned by the API - once and for all - when the domain is created;

- A description of the domain (optional).

You may retrieve the current domain properties as follows:

- Method: GET

- Path: `/domains/{domainId}/properties`

- Headers:

  > - Accept: `application/xml; charset=UTF-8`

For example, this request gets the properties of domain `iMnxv7sDEeWFwqVFFMDLTQ`. In this case, there is no specific property, which is the case by default:

    GET /domains/iMnxv7sDEeWFwqVFFMDLTQ/properties
    HTTP/1.1
    Accept: application/xml; charset=UTF-8

The response goes:

    1<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    2<domainProperties
    3   xmlns="http://authzforce.github.io/rest-api-model/xmlns/authz/5"
    4   externalId="test-domain1">
    5   <description>Test domain</description>
    6</domainProperties>

You may update the domain properties as follows:

- Method: PUT

- Path: `/domains/{domainId}/properties`

- Headers:

  > - Content-Type: `application/xml; charset=UTF-8`

  > - Accept: `application/xml; charset=UTF-8`

- Body: new properties.

For example, this request sets the `externalId` property to `my-domain-123`:

    1PUT /domains/iMnxv7sDEeWFwqVFFMDLTQ/properties
    2HTTP/1.1
    3Accept: application/xml; charset=UTF-8
    4Content-Type: application/xml; charset=UTF-8
    5
    6<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    7<domainProperties
    8 xmlns="http://authzforce.github.io/rest-api-model/xmlns/authz/5"
    9 externalId="my-domain-123" />

The response is the new properties.

As a result, the domain’s external ID `my-domain-123` points to the domain `iMnxv7sDEeWFwqVFFMDLTQ`. Clients may only rely on the externalId under their control to recover the API-defined domain ID, before they begin to use other API operations that require the API-defined domain ID. Indeed, clients may look up the API-defined ID corresponding to a given `externalId` as follows:

    GET /domains?externalId=my-domain-123
    HTTP/1.1
    Accept: application/xml; charset=UTF-8

The response gives the corresponding domain ID in a link `href` attribute:

    1<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    2<resources
    3  xmlns="http://authzforce.github.io/rest-api-model/xmlns/authz/5"
    4  xmlns:atom="http://www.w3.org/2005/Atom">
    5  <atom:link rel="item" href="iMnxv7sDEeWFwqVFFMDLTQ" title="iMnxv7sDEeWFwqVFFMDLTQ"/>
    6</resources>

#### Policy Administration API

The PAP is used by policy administrators to manage the policy repository from which the PDP loads the enforced policies. The PAP supports multi-tenancy in the form of generic administration domains that are separate from each other. Each policy administrator (except the Superadmin) is in fact a domain administrator, insofar as he is allowed to manage the policy for one or more specific domains. Domains are typically used to support isolation of tenants (one domain per tenant).

##### Adding and updating Policies

The PAP provides a RESTful API for adding and updating policies to a specific domain. HTTP requests to this API must be formatted as follows:

- Method: POST

- Path: `/domains/{domainId}/pap/policies`

- Headers:

  > - Content-Type: `application/xml; charset=UTF-8`

  > - Accept: `application/xml; charset=UTF-8`

- Body: XACML PolicySet as defined in the XACML 3.0 schema.

Example of request given below:

     1POST /domains/iMnxv7sDEeWFwqVFFMDLTQ/pap/policies
     2HTTP/1.1
     3Accept: application/xml; charset=UTF-8
     4Content-Type: application/xml; charset=UTF-8
     5
     6<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
     7<PolicySet
     8 xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"
     9 PolicySetId="P1"
    10 Version="1.0"
    11 PolicyCombiningAlgId="urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-unless-permit">
    12 <Description>Sample PolicySet</Description>
    13 <Target />
    14 <Policy
    15  PolicyId="MissionManagementApp"
    16  Version="1.0"
    17  RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-unless-permit">
    18  <Description>Policy for MissionManagementApp</Description>
    19  <Target>
    20   <AnyOf>
    21    <AllOf>
    22     <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
    23      <AttributeValue
    24       DataType="http://www.w3.org/2001/XMLSchema#string">MissionManagementApp</AttributeValue>
    25      <AttributeDesignator
    26       Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
    27       AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"
    28       DataType="http://www.w3.org/2001/XMLSchema#string"
    29       MustBePresent="true" />
    30     </Match>
    31    </AllOf>
    32   </AnyOf>
    33  </Target>
    34  <Rule RuleId="MissionManager_role_can_manage_team" Effect="Permit">
    35   <Description>Only MissionManager role authorized to manage the mission team</Description>
    36   <Target>
    37    <AnyOf>
    38     <AllOf>
    39      <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
    40       <AttributeValue
    41        DataType="http://www.w3.org/2001/XMLSchema#string">Team</AttributeValue>
    42       <AttributeDesignator
    43        Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
    44        AttributeId="urn:thales:xacml:2.0:resource:sub-resource-id"
    45        DataType="http://www.w3.org/2001/XMLSchema#string"
    46        MustBePresent="true" />
    47      </Match>
    48     </AllOf>
    49    </AnyOf>
    50    <AnyOf>
    51     <AllOf>
    52      <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
    53       <AttributeValue
    54        DataType="http://www.w3.org/2001/XMLSchema#string">manage</AttributeValue>
    55       <AttributeDesignator
    56        Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
    57        AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
    58        DataType="http://www.w3.org/2001/XMLSchema#string"
    59        MustBePresent="true" />
    60      </Match>
    61     </AllOf>
    62    </AnyOf>
    63   </Target>
    64   <Condition>
    65    <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:any-of">
    66     <Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal" />
    67      <AttributeValue
    68       DataType="http://www.w3.org/2001/XMLSchema#string">MissionManager</AttributeValue>
    69      <AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:2.0:subject:role"
    70       DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"
    71       Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" />
    72    </Apply>
    73   </Condition>
    74  </Rule>
    75 </Policy>
    76</PolicySet>

The HTTP response status is 200 with a link to manage the new policy, if the request was successful. The link is made of the policy ID and version separated by ‘/’.

Response:

    1HTTP/1.1 200 OK
    2Content-Type: application/xml; charset=UTF-8
    3
    4<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    5<atom:link xmlns:atom="http://www.w3.org/2005/Atom"
    6  rel="item" href="P1/1.0" title="Policy 'P1' v1.0"/>

To update a policy, you add a new version of the policy, i.e. you send the same request as above, but with a higher `Version` value.

WARNING: after you add/update a policy, it is not necessarily used, i.e.evaluated, by the PDP. The PDP starts the evaluation with the root policy specified in the Policy Decision (PDP) Properties. Therefore, only this root policy and any other one referenced (directly or indirectly) by this root policy is applicable. See the section Policy Decision (PDP) Properties to learn how to verify applicable policies and change the root policy.

WARNING: Although AuthzForce Server supports `application/json` media type as well for sending/getting policies in JSON format, it is still experimental for various reasons. One of which is a strong limitation that you should be much aware before using it for complex XACML policies: XML schema type definitions using a repeated``choice`` (between different element types) or a polymorphic sequence with `maxOccurs > 1` are not handled properly in JSON, at least not in any standard way or without significant customization of JSON processing. For example of such polymorphic sequence, an XACML Apply element may contain multiple Expression elements in a sequence, and an Expression may be an Apply again, or an AttributeValue, or an AttributeDesignator, or a VariableReference, etc. For example of repeated `choice`, a XACML PolicySet may contain P1, then PS1, then P2, then PS2, where `P` stands for XACML Policy and `PS` for XACML PolicySet. With the well-known simple conventions like the one used by AuthzForce Server for XML-to-JSON mapping, this is mapped to two separate JSON arrays, one for Policy element(s) (`[P1, P2]`) and one for PolicySet element(s) (`[PS1, PS2]`). Therefore, the originally intended evaluation order is lost! It gets even worse if you use PolicySetIdReference element(s) as well (PolicyIdReference is out of the question since not supported by the API). Of course, there are solutions such as adding a wrapping JSON object with a key called `PolicyOrPolicySetOrPolicySetIdReference` with an array as value where each item must have a type information to inform the consumer whether it is a Policy, PolicySet or PolicySetIdReference. This kind of solution is used in JAXB for instance to map XML to Java model (except the array is replaced by a Java collection). Like in JAXB to Java, this introduces some extra complexity to JSON processing that makes the JSON alternative lose much of its appeal compared to XML. In short, you should not use JSON for policies either mixing XACML Policy, PolicySet or PolicySetIdReference elements within the same PolicySet; or Expressions within the same Apply.

##### Getting Policies and Policy Versions

Once added to the domain as shown previously, you can get the policy by its ID as follows:

- Method: GET

- Path: `/domains/{domainId}/pap/policies/{policyId}`

- Headers:

  > - Accept: `application/xml; charset=UTF-8`

For example:

    GET /domains/iMnxv7sDEeWFwqVFFMDLTQ/pap/policies/P1 HTTP/1.1 Accept: application/xml; charset=UTF-8

The response is the list of links to the versions of the policy `P1` available in the domain `iMnxv7sDEeWFwqVFFMDLTQ`:

     1HTTP/1.1 200 OK
     2Content-Type: application/xml; charset=UTF-8
     3
     4<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
     5<resources
     6  xmlns="http://authzforce.github.io/rest-api-model/xmlns/authz/5"
     7  xmlns:atom="http://www.w3.org/2005/Atom">
     8    <atom:link rel="item" href="1.0"/>
     9    <atom:link rel="item" href="1.1"/>
    10    <atom:link rel="item" href="2.0"/>
    11    <atom:link rel="item" href="2.1"/>
    12    <atom:link rel="item" href="2.2"/>
    13    ...
    14</resources>

As the `href` values are telling you, you may get a specific version of the policy as follows:

- Method: GET

- Path: `/domains/{domainId}/pap/policies/{policyId}/{version}`

- Headers:

  > - Accept: `application/xml; charset=UTF-8`

For example:

    GET /domains/iMnxv7sDEeWFwqVFFMDLTQ/pap/policies/P1/1.0 HTTP/1.1 Accept: application/xml; charset=UTF-8

The response is the policy document (XACML PolicySet) in this version.

You may use the special keyword `latest` as version here to get the latest version of a given policy; e.g. URL path `/domains/iMnxv7sDEeWFwqVFFMDLTQ/pap/policies/P1/latest` points to the latest version of the policy `P1` in domain `iMnxv7sDEeWFwqVFFMDLTQ`.

Last but not least, you may get all policies in the domain as follows:

- Method: GET

- Path: `/domains/{domainId}/pap/policies`

- Headers:

  > - Accept: `application/xml; charset=UTF-8`

For example:

     1GET /domains/iMnxv7sDEeWFwqVFFMDLTQ/pap/policies
     2HTTP/1.1
     3Accept: application/xml; charset=UTF-8
     4
     5<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
     6<resources
     7  xmlns="http://authzforce.github.io/rest-api-model/xmlns/authz/5"
     8  xmlns:atom="http://www.w3.org/2005/Atom">
     9    <atom:link rel="item" href="root"/>
    10    <atom:link rel="item" href="P1"/>
    11    <atom:link rel="item" href="P2"/>
    12</resources>

##### Removing Policies and Policy Versions

You may remove a policy version from the domain as follows:

- Method: DELETE

- Path: `/domains/{domainId}/pap/policies/{policyId}/{version}`

- Headers:

  > - Accept: `application/xml; charset=UTF-8`

For example:

    DELETE /domains/iMnxv7sDEeWFwqVFFMDLTQ/pap/policies/P1/1.0 HTTP/1.1 Accept: application/xml; charset=UTF-8

The response is the removed policy document (XACML PolicySet) in this version.

You may remove a policy, i.e. all versions of a policy from the domain as follows:

- Method: DELETE

- Path: `/domains/{domainId}/pap/policies/{policyId}`

- Headers:

  > - Accept: `application/xml; charset=UTF-8`

For example:

    DELETE /domains/iMnxv7sDEeWFwqVFFMDLTQ/pap/policies/P1 HTTP/1.1 Accept: application/xml; charset=UTF-8

The response is the list of links to all the removed versions of the policy, similar to the the GET request on the same URL.

##### Re-usable Policies (e.g. for Hierarchical RBAC)

The PAP API supports policies that have references to other policies existing in the domain. This allows to include/reuse a given policy from multiple policies, or multiple parts of the same policy, by means of XACML `<PolicySetIdReference>` elements. One major application of this is Hierarchical RBAC. You can refer to the XACML v3.0 Core and Hierarchical Role Based Access Control (RBAC) Profile specification for how to achieve hierarchical RBAC with `<PolicySetIdReference>` elements.

For example, I want to define a role Employee and a role Manager derived from Employee. In other words, permissions of an Employee are included in the permissions of a Manager. In order to create this role hierarchy, we first add the Employee’s Permission PolicySet:

     1POST /domains/iMnxv7sDEeWFwqVFFMDLTQ/pap/policies
     2HTTP/1.1
     3Accept: application/xml; charset=UTF-8
     4Content-Type: application/xml; charset=UTF-8
     5
     6<?xml version="1.0" encoding="UTF-8"?>
     7<PolicySet
     8 xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"
     9 PolicySetId="PPS:Employee"
    10 Version="1.0"
    11 PolicyCombiningAlgId="urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-unless-permit">
    12 <Description>Permissions specific to the Employee role</Description>
    13 <Target />
    14 <Policy
    15  PolicyId="PP:Employee"
    16  Version="1.0"
    17  RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-unless-permit">
    18  <Target />
    19  <Rule RuleId="Permission_to_create_issue_ticket" Effect="Permit">
    20   <Target>
    21    <AnyOf>
    22     <AllOf>
    23      <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
    24       <AttributeValue
    25        DataType="http://www.w3.org/2001/XMLSchema#string">https://acme.com/tickets</AttributeValue>
    26       <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
    27        AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"
    28        DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true" />
    29      </Match>
    30     </AllOf>
    31    </AnyOf>
    32    <AnyOf>
    33     <AllOf>
    34      <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
    35       <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">POST</AttributeValue>
    36       <AttributeDesignator
    37        Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
    38        AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
    39        DataType="http://www.w3.org/2001/XMLSchema#string"
    40        MustBePresent="true" />
    41      </Match>
    42     </AllOf>
    43    </AnyOf>
    44   </Target>
    45  </Rule>
    46 </Policy>
    47</PolicySet>

Then we add the role-based hierarchical policy defining the Employee role and the Manager role, both with a reference (`<PolicySetIdReference>`) to the Employee’s Permission PolicySet added previously. The Manager role has one policy more, so more permissions:

     1POST /domains/iMnxv7sDEeWFwqVFFMDLTQ/pap/policies
     2HTTP/1.1
     3Accept: application/xml; charset=UTF-8
     4Content-Type: application/xml; charset=UTF-8
     5
     6<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
     7<PolicySet xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"
     8 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     9 PolicySetId="rbac:policyset"
    10 Version="1.0"
    11 PolicyCombiningAlgId="urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-unless-permit">
    12 <Description>Root PolicySet</Description>
    13 <Target />
    14 <PolicySet PolicySetId="RPS:Employee" Version="1.0"
    15  PolicyCombiningAlgId="urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-unless-permit">
    16  <Description>Employee Role PolicySet</Description>
    17  <Target>
    18   <AnyOf>
    19    <AllOf>
    20     <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
    21      <AttributeValue
    22       DataType="http://www.w3.org/2001/XMLSchema#string">Employee</AttributeValue>
    23      <AttributeDesignator
    24       Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
    25       AttributeId="urn:oasis:names:tc:xacml:2.0:subject:role"
    26       DataType="http://www.w3.org/2001/XMLSchema#string"
    27       MustBePresent="true" />
    28     </Match>
    29    </AllOf>
    30   </AnyOf>
    31  </Target>
    32  <PolicySetIdReference>PPS:Employee</PolicySetIdReference>
    33 </PolicySet>
    34 <PolicySet PolicySetId="RPS:Manager" Version="1.0"
    35  PolicyCombiningAlgId="urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:deny-unless-permit">
    36  <Description>Manager Role PolicySet</Description>
    37  <Target>
    38   <AnyOf>
    39    <AllOf>
    40     <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
    41      <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Manager</AttributeValue>
    42      <AttributeDesignator
    43       Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
    44       AttributeId="urn:oasis:names:tc:xacml:2.0:subject:role"
    45       DataType="http://www.w3.org/2001/XMLSchema#string"
    46       MustBePresent="true" />
    47     </Match>
    48    </AllOf>
    49   </AnyOf>
    50  </Target>
    51  <Policy PolicyId="PP1:Manager" Version="1.0"
    52   RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-unless-permit">
    53   <Description>Permissions specific to Manager Role</Description>
    54   <Target />
    55   <Rule
    56    RuleId="Permission_to_create_new_project" Effect="Permit">
    57    <Target>
    58     <AnyOf>
    59      <AllOf>
    60       <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
    61        <AttributeValue
    62         DataType="http://www.w3.org/2001/XMLSchema#string">https://acme.com/projects</AttributeValue>
    63        <AttributeDesignator
    64         Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
    65         AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"
    66         DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true" />
    67       </Match>
    68      </AllOf>
    69     </AnyOf>
    70     <AnyOf>
    71      <AllOf>
    72       <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
    73        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">POST</AttributeValue>
    74        <AttributeDesignator
    75         Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
    76         AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
    77         DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
    78       </Match>
    79      </AllOf>
    80     </AnyOf>
    81    </Target>
    82   </Rule>
    83  </Policy>
    84  <!-- This role is senior to the Employee role, therefore includes the Employee role Permission
    85   PolicySet -->
    86  <PolicySetIdReference>PPS:Employee</PolicySetIdReference>
    87 </PolicySet>
    88</PolicySet>

You may add more policies for more roles as you wish. Once you are satisfied with your role hierarchy, you may apply your new RBAC policy by updating the domain’s root policy reference (this may not be necessary if you reused the same root policy ID as before, in which case your policy is already active by now):

    1PUT /domains/iMnxv7sDEeWFwqVFFMDLTQ/pap/pdp.properties
    2HTTP/1.1
    3Accept: application/xml; charset=UTF-8
    4Content-Type: application/xml; charset=UTF-8
    5
    6<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    7<pdpPropertiesUpdate xmlns="http://authzforce.github.io/rest-api-model/xmlns/authz/5">
    8 <rootPolicyRefExpression>rbac:policyset</rootPolicyRefExpression>
    9</pdpPropertiesUpdate>

The policy is now enforced by the PDP as described in the next section.

##### Policy Repository (PRP) Properties

Administrators (global or domain-specific) may configure the policy repository with the following properties:

> - `maxPolicyCount`: optional, stricly positive integer that indicates the maximum number of policies on a domain, no limit if undefined.

> - `maxVersionCountPerPolicy`: optional, stricly positive integer that indicates the maximum number of versions per policy, no limit if undefined.

> - `versionRollingEnabled`: boolean, true if and only if policy versions should be rolled over, i.e. when `maxVersionCountPerPolicy` has been reached, oldest versions are automatically removed to make place.

For example, below is a HTTP GET request and response for the policy repository properties of domain `iMnxv7sDEeWFwqVFFMDLTQ`:

     1GET /domains/iMnxv7sDEeWFwqVFFMDLTQ/pap/prp.properties
     2Accept: application/xml
     3
     4-
     5
     6HTTP/1.1 200 OK
     7Content-Type: application/xml
     8
     9<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    10<prpProperties xmlns="http://authzforce.github.io/rest-api-model/xmlns/authz/5">
    11   <maxPolicyCount>10</maxPolicyCount>
    12   <maxVersionCountPerPolicy>10</maxVersionCountPerPolicy>
    13   <versionRollingEnabled>true</versionRollingEnabled>
    14</prpProperties>

The HTTP PUT request to update the properties has a body that is similar to the GET response:

    1PUT /domains/iMnxv7sDEeWFwqVFFMDLTQ/pap/prp.properties
    2Content-Type: application/xml
    3
    4<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    5<prpProperties xmlns="http://authzforce.github.io/rest-api-model/xmlns/authz/5">
    6   <maxPolicyCount>4</maxPolicyCount>
    7   <maxVersionCountPerPolicy>2</maxVersionCountPerPolicy>
    8   <versionRollingEnabled>true</versionRollingEnabled>
    9</prpProperties>

The response format is the same as for the GET request.

##### Policy Decision (PDP) Properties

Administrators (global or domain-specific) may configure the PDP engine with the following properties:

- `rootPolicyRefExpression`: reference - in the form of a XACML PolicySetIdReference - to the root policy. The root policy is the policy from which the PDP starts the evaluation. A policy matching this reference must exist on the domain, therefore it must have been added in the way described in Adding and updating Policies. If there is no specific `Version` in the reference, the latest matching policy version is selected.

- `feature` elements: enable particular PDP features. Each `feature` has an ID, `type` and `enabled` flag saying whether the feature is enabled or not.

Supported PDP features (IDs) by `type`:

- Type `urn:ow2:authzforce:feature-type:pdp:core`: PDP core engine features (as opposed to other types related to PDP extensions ).

  > - `urn:ow2:authzforce:feature:pdp:core:strict-attribute-issuer-match`: strict matching of attribute `Issuer` values in XACML Requests against corresponding attribute designators’ `Issuer` values in policies. This means that an `<AttributeDesignator>` without `Issuer` only matches request Attributes without `Issuer` (and same AttributeId, Category…). This mode is not fully compliant with XACML 3.0 Core specifcation of AttributeDesignator (§5.29), in the case that the Issuer is indeed not present on a AttributeDesignator, but it may perform better and is recommended when all AttributeDesignators have an Issuer. Reminder: XACML 3.0 Core specifcation of AttributeDesignator (§5.29) says: If the Issuer is not present in the attribute designator, then the matching of the attribute to the named attribute SHALL be governed by AttributeId and DataType attributes alone.

  > - `urn:ow2:authzforce:feature:pdp:core:xpath-eval`: enables support for XACML AttributeSelectors and datatype `urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression`. If this feature is disabled, only standard XACML 3.0 Core datatypes marked M, i.e. mandatory, are supported. Since `xpathExpression` is optional in the standard, it is therefore not supported unless this feature is enabled. This feature is experimental and may have a negative impact on performance. Use with caution.

- Type `urn:ow2:authzforce:feature-type:pdp:request-preproc`: XACML (Individual) Request preprocessor (Individual means that even if the XACML Multiple Decision Profile is active, the request preprocessor applies to each Individual Decision Request as defined in the Profile). As a convention, request preprocessor IDs with suffix `-lax` allow multivalued attributes in form of duplicate Attribute elements (with same meta-data) in the same Attributes element of a Request, in order to accept multivalued attributes in conformance with XACML 3.0 Core specification of Multivalued attributes (§7.3.3). Request preprocessor IDs with suffix `-strict` do not allow this behavior, i.e. multivalued attributes must be formed by grouping all AttributeValue elements in the same Attribute element (instead of duplicate Attribute elements), therefore they do not fully comply with XACML 3.0 Core specification of Multivalued attributes (§7.3.3). However, they perform usually better than their `-lax` counterparts since it simplifies the Request and allows parsing optimizations by the PDP. Below is an example of Request that would not be accepted by a `-strict` request preprocessor because of duplicate Attribute:

       1<Request
       2 xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" ReturnPolicyIdList="false" CombinedDecision="false"> <Attributes Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject">
       3    <Attribute AttributeId="urn:oasis:names:tc:xacml:2.0:subject:role" IncludeInResult="false">
       4       <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">CSO</AttributeValue>
       5    </Attribute>
       6    <Attribute AttributeId="urn:oasis:names:tc:xacml:2.0:subject:role" IncludeInResult="false">
       7       <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">CTO</AttributeValue>
       8    </Attribute> ...
       9 </Attributes> ...
      10</Request>

  Below is the equivalent of the previous Request in a form that is accepted by a `-strict` request preprocessor (no duplicate Attribute):

      1<Request
      2 xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" ReturnPolicyIdList="false" CombinedDecision="false"> <Attributes Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject">
      3    <Attribute AttributeId="urn:oasis:names:tc:xacml:2.0:subject:role" IncludeInResult="false">
      4       <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">CSO</AttributeValue> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">CTO</AttributeValue>
      5    </Attribute> ...
      6 </Attributes> ...
      7</Request>

  Built-in request preprocessor IDs:

  > - urn:ow2:authzforce:feature:pdp:request-preproc:xacml-xml:default-lax (resp. urn:ow2:authzforce:feature:pdp:request-preproc:xacml-json:default-lax) and urn:ow2:authzforce:feature:pdp:request-preproc:xacml-xml:default-strict (resp. urn:ow2:authzforce:feature:pdp:request-preproc:xacml-json:default-strict): supports only XACML/XML (resp. XACML/JSON) Request elements marked as mandatory in XACML 3.0 Core specification (§10.2.1) (in particular, no support for Multiple Decision Profile);

  > - urn:ow2:authzforce:feature:pdp:request-preproc:xacml-xml:multiple:repeated-attribute-categories-lax (resp. urn:ow2:authzforce:feature:pdp:request-preproc:xacml-json:multiple:repeated-attribute-categories-lax) and urn:ow2:authzforce:feature:pdp:request-preproc:xacml-xml:multiple:repeated-attribute-categories-lax (resp. urn:ow2:authzforce:feature:pdp:request-preproc:xacml-json:multiple:repeated-attribute-categories-lax): Provides the functionality identified by urn:oasis:names:tc:xacml:3.0:profile:multiple:repeated-attribute-categories in XACML v3.0 Multiple Decision Profile Version 1.0 (§3.3) for XACML/XML (resp. XACML/JSON) requests.

  Only one request preprocessor may be enabled for XML (resp. JSON) input at at time, i.e. input Java type for the RequestPreprocessor class is *oasis.names.tc.xacml._3_0.core.schema.wd_17.Request* (resp. *org.json.JSONObject*).

- Types `urn:ow2:authzforce:feature-type:pdp:data-type` and `urn:ow2:authzforce:feature-type:pdp:function`: PDP extensions providing non-core XACML data types and functions respectively, i.e. not specified in XACML 3.0 Core standard §10.2.7 and §10.2.8 respectively. More information in next section PDP Extensions.

Follow the example of request/response below to get the current PDP properties in domain `iMnxv7sDEeWFwqVFFMDLTQ`:

     1GET /domains/iMnxv7sDEeWFwqVFFMDLTQ/pap/pdp.properties
     2Accept: application/xml
     3
     4-
     5
     6HTTP/1.1 200 OK
     7Content-Type: application/xml
     8
     9<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    10<pdpProperties
    11 xmlns="http://authzforce.github.io/rest-api-model/xmlns/authz/5"
    12 lastModifiedTime="2016-05-28T14:21:35.730Z">
    13 <feature
    14  type="urn:ow2:authzforce:feature-type:pdp:core"
    15  enabled="false">urn:ow2:authzforce:feature:pdp:core:strict-attribute-issuer-match</feature>
    16 <feature
    17  type="urn:ow2:authzforce:feature-type:pdp:request-preproc"
    18  enabled="true">urn:ow2:authzforce:feature:pdp:request-preproc:default-lax</feature>
    19 <feature
    20  type="urn:ow2:authzforce:feature-type:pdp:request-preproc"
    21  enabled="false">urn:ow2:authzforce:feature:pdp:request-preproc:default-strict</feature>
    22 <feature
    23  type="urn:ow2:authzforce:feature-type:pdp:request-preproc"
    24  enabled="false">urn:ow2:authzforce:feature:pdp:request-preproc:multiple:repeated-attribute-categories-strict</feature>
    25 <feature
    26  type="urn:ow2:authzforce:feature-type:pdp:request-preproc"
    27  enabled="false">urn:ow2:authzforce:feature:pdp:request-preproc:multiple:repeated-attribute-categories-lax</feature>
    28 ...(content omitted)...
    29 <rootPolicyRefExpression>root</rootPolicyRefExpression>
    30 <applicablePolicies>
    31  <rootPolicyRef Version="0.1.0">root</rootPolicyRef>
    32  <refPolicyRef Version="1.0">PPS:Employee</refPolicyRef>
    33  <refPolicyRef Version="1.0">PPS:Manager</refPolicyRef>
    34  ...(content omitted)...
    35 </applicablePolicies>
    36</pdpProperties>

As you can see, the GET response provides extra information such as:

- `lastModifiedTime`: the last time the PDP was reloaded (due to a change of root policy for instance);

- `applicablePolicies`: the actual root policy (`rootPolicyRef` element) version selected for evaluation according to the `rootPolicyRefExpression`, and any policy referenced from it (`refPolicyRef` elements) directly or indirectly via `PolicySetIdReference`.

The HTTP PUT request to update the PDP properties goes as follows:

     1PUT /domains/iMnxv7sDEeWFwqVFFMDLTQ/pap/pdp.properties
     2Content-Type: application/xml
     3
     4<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
     5<pdpPropertiesUpdate xmlns="http://authzforce.github.io/rest-api-model/xmlns/authz/5">
     6 <feature
     7  type="urn:ow2:authzforce:feature-type:pdp:request-preproc"
     8  enabled="true">urn:ow2:authzforce:feature:pdp:request-preproc:multiple:repeated-attribute-categories-lax</feature>
     9 <rootPolicyRefExpression>root</rootPolicyRefExpression>
    10</pdpPropertiesUpdate>

This example sets the root policy reference to the latest version of the policy with `PolicySetId = 'root'` that must exist in the domain (see Adding and updating Policies), and enables support for the XACML Multiple Decision profile with repeated attribute categories (urn:oasis:names:tc:xacml:3.0:profile:multiple:repeated-attribute-categories). Notice that only one feature element in the request although it is not the only one PDP feature. In this case, the API assumes that all features missing from the request must be disabled. Therefore, it is only necessary to send the enabled features in the request.

##### PDP Extensions

Non-core (not defined in XACML 3.0 Core standard) PDP behavior and features may be implemented by various types of extensions, particularly to support specific XACML Profiles:

- Attribute Datatypes: to support extra XACML datatypes, e.g. from DLP/NAC Profile;

- Functions: to support extra XACML functions, e.g. from DLP/NAC Profile;

- Attribute Providers: to customize the way attribute value are retrieved outside the PEP’s Request.

- Request Preprocessors: to customize the processing of individual decision requests;

- Result Postprocessors: to customize the processing of XACML Results in Response;

- Combining algorithms: to add custom policy or rule combining algorithms.

###### Attribute Datatype extensions

The XACML 3.0 Core standard allows to use extra attribute data types not defined in the standard. Before you can use such datatypes in Authzforce API, you must implement and provide it as an Attribute Datatype extension, or get it from a third party as such; and then you deploy it on Authzforce server and enable it on a specific domain. The AuthzForce project also provides a separate Datatype extension example for documentation and testing purposes. If you wish to make your own Attribute Datatype extension, read on the next section. If you wish to test the example provided by AuthzForce or if you have another one ready for use, you may jump to the section Integrating an Attribute Datatype extension into AuthzForce Server.

###### Making an Attribute Datatype extension

The steps to make your own Attribute Datatype extension for AuthzForce go as follows:

1. Create a Maven project with `jar` packaging type and following Maven dependency:

       1 <dependency>
       2  <groupId>org.ow2.authzforce</groupId>
       3  <artifactId>authzforce-ce-core-pdp-api</artifactId>
       4  <version>22.0.0</version>
       5  <scope>provided<scope>
       6 </dependency>

2. Create your attribute datatype factory and value instance class (as in the Factory design pattern). The factory class must be public, and implement interface `org.ow2.authzforce.core.pdp.api.value.DatatypeFactory<AV>`, where `AV` stands for your AttributeValue Implementation Class, i.e. the concrete attribute value implementation class; and the factory class must have a public no-argument constructor or no constructor.

   To facilitate the implementation process, instead of implementing this `DatatypeFactory` interface directly, you should extend one of the following `DatatypeFactory` sub-classes when it applies:

   - `org.ow2.authzforce.core.pdp.api.value.SimpleValue.StringContentOnlyFactory<AV>`: to be extended for implementing text-only primitive datatypes (equivalent to simple XML types). You may use AuthzForce TestDNSNameWithPortValue class (used for AuthzForce unit tests) as an example. This example provides a test implementation of datatype `dnsName-value` defined in XACML Data Loss Prevention / Network Access Control (DLP/NAC) Profile Version 1.0. In this example, the static nested class `Factory` is the one extending `org.ow2.authzforce.core.pdp.api.value.SimpleValue.StringContentOnlyFactory<TestDNSNameWithPortValue>`. Such a class has a factory method (`TestDNSNameWithPortValue getInstance(String val)`) that takes a string argument corresponding to the text in the XACML AttributeValue (which must not contain any XML element or attribute).

   - `org.ow2.authzforce.core.pdp.api.value.SimpleValue.Factory<AV>`: to be extended for implementing primitive XACML datatypes with XML attributes (equivalent to complex XML types with simple content). An example of such datatype is `xpathExpression` which requires an XML attribute named `XPathCategory`. Note that the datatype `xpathExpression` is natively supported but enabled only if feature `urn:ow2:authzforce:feature:pdp:core:xpath-eval` is enabled in the PDP configuration.

   - `org.ow2.authzforce.core.pdp.api.value.BaseDatatypeFactory<AV>`: to be extended for implementing structured attributes (XACML 3.0 Core, §8.2) (equivalent to complex XML types with complex content). You may use AuthzForce TestXACMLPolicyAttributeValue class (used for AuthzForce unit tests) as an example. In this example, the static nested class `Factory` is the one extending `org.ow2.authzforce.core.pdp.api.value.BaseDatatypeFactory<TestXACMLPolicyAttributeValue>`. Such a class has a factory method `TestXACMLPolicyAttributeValue getInstance(List<Serializable> content, Map<QName, String> otherAttributes, ...)` that creates an instance of your AttributeValue Implementation Class, i.e. `TestXACMLPolicyAttributeValue` in this case. where the argument `otherAttributes` represents the XML attributes and argument `content` the mixed content of a XACML AttributeValue parsed by JAXB.

3. When your implementation class is ready, create a text file `org.ow2.authzforce.core.pdp.api.PdpExtension` in folder `src/main/resources/META-INF/services` (you have to create the folder first) and put the fully qualified name of your implementation class on the first line of this file, like in the example from AuthzForce source code.

4. Run Maven `package` to produce a JAR from the Maven project.

Now you have an Attribute Datatype extension ready for integration into AuthzForce Server, as explained in the next section.

###### Integrating an Attribute Datatype extension into AuthzForce Server

This section assumes you have an Attribute Datatype extension in form of a JAR, typically produced by the process described in the previous section. You may use AuthzForce PDP Core Tests JAR if you only wish to test the examples in this documentation. This JAR is available on Maven Central: groupId= `org.ow2.authzforce`, artifactId= `authzforce-ce-core-pdp-testutils`, version= `21.0.1`.

The steps to integrate the extension into the AuthzForce Server go as follows:

1. Make the JAR - and any extra dependency - visible from the AuthzForce webapp in Tomcat. One way to do it consists to copy the JAR (e.g. `authzforce-ce-core-pdp-testutils-16.0.0.jar` in our example) into `/opt/authzforce-ce-server/webapp/WEB-INF/lib`. For other ways, please refer to Tomcat HowTo.

2. Finally, restart Tomcat to apply changes.

###### Enabling an Attribute Datatype extension on a domain

Once you have deployed the extension on Authzforce, following previous instructions, you are ready to enable it on a specific domain’s PDP by updating the PDP properties with an enabled `feature` of type `urn:ow2:authzforce:feature-type:pdp:data-type` and value equal to the ID returned by the method `getId()` of the extension’s factory implementation class. The following example enables the datatype `dnsName-value` (defined in DLP/NAC profile) on the PDP, provided that the AuthzForce PDP Core Tests JAR has been deployed (see previous section):

     1PUT /domains/iMnxv7sDEeWFwqVFFMDLTQ/pap/pdp.properties
     2Content-Type: application/xml
     3
     4<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
     5<pdpPropertiesUpdate xmlns="http://authzforce.github.io/rest-api-model/xmlns/authz/5">
     6 <feature
     7  type="urn:ow2:authzforce:feature-type:pdp:data-type"
     8  enabled="true">urn:oasis:names:tc:xacml:3.0:data-type:dnsName-value</feature>
     9 <rootPolicyRefExpression>root</rootPolicyRefExpression>
    10</pdpPropertiesUpdate>

###### Function Extensions

The XACML 3.0 Core standard allows to use extra functions not defined in the standard. Before you can use such functions in Authzforce API, you must implement and provide it as an Function extension, or get it from a third party as such; and then you deploy it on Authzforce server and enable it on a specific domain. The AuthzForce project also provides a separate Function extension example for documentation and testing purposes. If you wish to make your own Function extension, read on the next section. If you wish to test the example provided by AuthzForce or if you have another one ready for use, you may jump to the section Integrating a Function extension into AuthzForce Server.

###### Making a Function extension

The steps to make your own Function extension go as follows:

1. Create a Maven project with `jar` packaging type and following Maven dependency:

       1 <dependency>
       2  <groupId>org.ow2.authzforce</groupId>
       3  <artifactId>authzforce-ce-core-pdp-api</artifactId>
       4  <version>22.0.0</version>
       5  <scope>provided<scope>
       6 </dependency>

2. A Function extension class must implement interface `org.ow2.authzforce.core.pdp.api.func.Function`; and have a public no-argument constructor or no constructor. Instead of implementing this `Function` interface directly, you should extend one of the following `Function` sub-classes whenever possible, depending on your needs:

   - `org.ow2.authzforce.core.pdp.api.func.ComparisonFunction`: to be extended for implementing comparison functions `type-greater-than`, `type-greater-than-or-equal`, `type-less-than` and `type-less-than-or-equal`. Examples from XACML 3.0 Core standard: see §A.3.6 and §A.3.8.

   - `org.ow2.authzforce.core.pdp.api.func.EqualTypeMatchFunction`: to be extended for implementing match functions with two parameters of same type`. Examples from XACML 3.0 Core standard: equality functions in §A.3.1, `x500name-match`, `string-starts-with`. You may use AuthzForce TestDNSNameValueEqualFunction class (used for AuthzForce unit tests) as an example. This example provides a test implementation of function `dnsName-value-equal` defined in XACML Data Loss Prevention / Network Access Control (DLP/NAC) Profile Version 1.0.

   - `org.ow2.authzforce.core.pdp.api.func.NonEqualTypeMatchFunction`: to be extended for implementing match functions with two parameters of different type. Examples from XACML 3.0 Core standard: `rfc822Name-match`, `anyURI-starts-with`, `dnsName-regexp-match`.

   - `org.ow2.authzforce.core.pdp.api.func.HigherOrderBagFunction`: to be extended for implementing higher-order bag functions. Examples from XACML 3.0 Core standard are functions in §A.3.12.

   - `org.ow2.authzforce.core.pdp.api.func.SingleParameterTypedFirstOrderFunction`: to be extended for implementing first-order functions having all parameters of the same type, when previous cases do not apply. Examples from XACML 3.0 Core standard are logical `and`, `or` or `not` in §A.3.5.

   - `org.ow2.authzforce.core.pdp.api.func.MultiParameterTypedFirstOrderFunction`: to be extended for implementing first-order functions having at least two different types of parameters, when previous cases do not apply. Examples from XACML 3.0 Core standard are logical `n-of` and `*-substring` functions.

   - `org.ow2.authzforce.core.pdp.api.func.BaseFunction`: to be extended for implementing functions when none of the previous cases apply.

3. When your implementation class is ready, create a text file `org.ow2.authzforce.core.pdp.api.PdpExtension` in folder `src/main/resources/META-INF/services` (you have to create the folder first) and put the fully qualified name of your implementation class on the first line of this file, like in the example from Authzforce source code.

4. Run Maven `package` to produce a JAR from the Maven project.

Now you have a Function extension ready for integration into AuthzForce Server, as explained in the next section.

###### Integrating a Function extension into AuthzForce Server

This section assumes you have a Function extension in form of a JAR, typically produced by the process described in the previous section. You may use AuthzForce PDP Core Tests JAR if you only wish to test the examples in this documentation. This JAR is available on Maven Central: groupId= `org.ow2.authzforce`, artifactId= `authzforce-ce-core-pdp-testutils`, version= `21.0.1`.

The steps to integrate the extension into the AuthzForce Server go as follows:

1. Make the JAR - and any extra dependency - visible from the AuthzForce webapp in Tomcat. One way to do it consists to copy the JAR (e.g. `authzforce-ce-core-pdp-testutils-16.0.0.jar` in our example) into `/opt/authzforce-ce-server/webapp/WEB-INF/lib`. For other ways, please refer to Tomcat HowTo.

2. Finally, restart Tomcat to apply changes.

###### Enabling a Function extension on a domain

Once you have deployed the extension on Authzforce, following previous instructions, you are ready to enable it on a specific domain’s PDP by updating the PDP properties with an enabled `feature` of type `urn:ow2:authzforce:feature-type:pdp:function-set` if the extension extends `BaseFunctionSet` class or implements directly its superinterface `FunctionSet`; else use the feature type `urn:ow2:authzforce:feature-type:pdp:function`, and value equal to the ID returned by the method `getId()` of the extension implementation class. The following example enables the function `dnsName-value-equal` and required datatype `dnsName-value` (defined in DLP/NAC profile) on the PDP, provided that the AuthzForce PDP Core Tests JAR has been deployed (see previous section):

     1PUT /domains/iMnxv7sDEeWFwqVFFMDLTQ/pap/pdp.properties
     2Content-Type: application/xml
     3
     4<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
     5<pdpPropertiesUpdate xmlns="http://authzforce.github.io/rest-api-model/xmlns/authz/5">
     6 <feature
     7  type="urn:ow2:authzforce:feature-type:pdp:data-type"
     8  enabled="true">urn:oasis:names:tc:xacml:3.0:data-type:dnsName-value</feature>
     9 <feature
    10  type="urn:ow2:authzforce:feature-type:pdp:data-type"
    11  enabled="true">urn:oasis:names:tc:xacml:3.0:data-type:dnsName-value-equal</feature>
    12 <rootPolicyRefExpression>root</rootPolicyRefExpression>
    13</pdpPropertiesUpdate>

###### Combining Algorithm Extensions

The XACML 3.0 Core standard allows to use extra policy/rule combining algorithms not defined in the standard. Before you can use such algorithms in Authzforce API, you must implement and provide it as an Combining Algorithm extension, or get it from a third party as such; and then you deploy it on Authzforce server and enable it on a specific domain. The AuthzForce project also provides a separate Combining Algorithm extension example for documentation and testing purposes. If you wish to make your own Combining Algorithm extension, read on the next section. If you wish to test the example provided by AuthzForce or if you have another one ready for use, you may jump to the section Integrating a Combining Algorithm extension into AuthzForce Server.

###### Making a Combining Algorithm extension

The steps to make your own Combining Algorithm extension go as follows:

1. Create a Maven project with `jar` packaging type and following Maven dependency:

       1 <dependency>
       2  <groupId>org.ow2.authzforce</groupId>
       3  <artifactId>authzforce-ce-core-pdp-api</artifactId>
       4  <version>22.0.0</version>
       5 </dependency>

2. Create the Java implementation class, either extending class org.ow2.authzforce.core.pdp.api.combining.BaseCombiningAlg<D> or, as second resort, implementing interface org.ow2.authzforce.core.pdp.api.combining.CombiningAlg<D>, where the type parameter `D` represents the type of elements combined by the algorithm implementation (policy or rule), more precisely `D` must be one of the following:

   - `org.ow2.authzforce.core.pdp.api.Decidable` (recommended option) for a policy/rule combining algorithm implementation, i.e. combining policies and rules equally. For example, although the XACML standard specifies two distinct identifiers for the policy combining version and rule combining version of the deny-unless-permit algorithm, the normative algorithm specification in pseudo-code is the same, and is actually implemented by one single Java class in AuthzForce. We strongly recommend this type parameter for your implementation as it makes it more generic and maximizes its reuse.

   - `org.ow2.authzforce.core.pdp.api.policy.PolicyEvaluator` for a policy-only combining algorithm, e.g. the XACML Core standard only-one-applicable algorithm, or the on-permit-apply-second policy combining algorithm from XACML 3.0 Additional Combining Algorithms Profile Version 1.0. You may use AuthzForce TestOnPermitApplySecondCombiningAlg class (used for AuthzForce unit tests) as an example of implementation for this algorithm.

   This class must have a public no-argument constructor or no constructor.

3. When your implementation class is ready, create a text file `org.ow2.authzforce.core.pdp.api.PdpExtension` in folder `src/main/resources/META-INF/services` (you have to create the folder first) and put the fully qualified name of your implementation class on the first line of this file, like in the example from Authzforce source code.

4. Run Maven `package` to produce a JAR from the Maven project.

Now you have a Combining Algorithm extension ready for integration into AuthzForce Server, as explained in the next section.

###### Integrating a Combining Algorithm extension into AuthzForce Server

This section assumes you have a Combining Algorithm extension in form of a JAR, typically produced by the process described in the previous section. You may use AuthzForce PDP Core Tests JAR if you only wish to test the examples in this documentation. This JAR is available on Maven Central: groupId= `org.ow2.authzforce`, artifactId= `authzforce-ce-core-pdp-testutils`, version= `21.0.1`.

The steps to integrate the extension into the AuthzForce Server go as follows:

1. Make the JAR - and any extra dependency - visible from the AuthzForce webapp in Tomcat. One way to do it consists to copy the JAR (e.g. `authzforce-ce-core-pdp-testutils-21.0.1.jar` in our example) into `/opt/authzforce-ce-server/webapp/WEB-INF/lib`. For other ways, please refer to Tomcat HowTo.

2. Finally, restart Tomcat to apply changes.

###### Enabling a Combining Algorithm extension on a domain

Once you have deployed the extension on Authzforce, following previous instructions, you are ready to enable it on a specific domain’s PDP by updating the PDP properties with an enabled `feature` of type `urn:ow2:authzforce:feature-type:pdp:combining-algorithm`. The following example enables the combining algorithm `on-permit-apply-second` on the PDP, provided that the AuthzForce PDP Core Tests JAR has been deployed (see previous section):

     1PUT /domains/iMnxv7sDEeWFwqVFFMDLTQ/pap/pdp.properties
     2Content-Type: application/xml
     3
     4<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
     5<pdpPropertiesUpdate xmlns="http://authzforce.github.io/rest-api-model/xmlns/authz/5">
     6 <feature
     7  type="urn:ow2:authzforce:feature-type:pdp:combining-algorithm"
     8  enabled="true">urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:on-permit-apply-second</feature>
     9 <rootPolicyRefExpression>root</rootPolicyRefExpression>
    10</pdpPropertiesUpdate>

###### Request Preprocessor Extensions

With AuthzForce Request Preprocessor extensions, you can support new ways of processing XACML Requests before evaluation by the PDP engine (e.g. used for implementing XACML v3.0 Multiple Decision Profile Version 1.0 - Repeated attribute categories (§3.3) ), for example support alternative request formats/syntax that can be translated to XACML.

Before you can use such extensions in AuthzForce API, you must implement one or get it from a third party as such; and then you deploy it on AuthzForce Server and enable it on a specific domain. Beware that AuthzForce already provides a Request Preprocessor implementing the functionality identified by urn:oasis:names:tc:xacml:3.0:profile:multiple:repeated-attribute-categories in XACML v3.0 Multiple Decision Profile Version 1.0 - Repeated attribute categories (§3.3).

If you wish to make your own Request Preprocessor extension, read on the next section. If you wish to test the example provided by AuthzForce or if you have another one ready for use, you may jump to the section Enabling a Request Preprocessor extension on a domain.

###### Making a Request Preprocessor extension

The steps to make your own Request Preprocessor extension for AuthzForce go as follows:

1. Create a Maven project with `jar` packaging type and following Maven dependency:

       <dependency>
        <groupId>org.ow2.authzforce</groupId>
        <artifactId>authzforce-ce-core-pdp-api</artifactId>
        <version>22.0.0</version>
       </dependency>

2. Create a Java class implementing interface `org.ow2.authzforce.core.pdp.api.DecisionRequestPreprocessor.Factory`. This class must have a public no-argument constructor or no constructor. This factory class’s main goal is to create instances of `org.ow2.authzforce.core.pdp.api.DecisionRequestPreprocessor`. As the latter is an interface, you need a concrete subclass for your implementation. Instead of implementing the interface `DecisionRequestPreprocessor` directly to do so, you should extend class `org.ow2.authzforce.core.pdp.api.io.BaseXacmlJaxbRequestPreprocessor` to facilitate the process whenever possible. You may use AuthzForce SingleDecisionXacmlJaxbRequestPreprocessor.LaxVariantFactory (resp. SingleDecisionXacmlJaxbRequestPreprocessor.StrictVariantFactory) class as an example for -lax (resp. -strict) request preprocessor. This class implements the minimal XACML 3.0 Core-compliant request preprocessor identified by `urn:ow2:authzforce:feature:pdp:request-preproc:xacml-xml:default-lax` (resp. `urn:ow2:authzforce:feature:pdp:request-preproc:xacml-xml:default-strict`).

3. When your implementation class is ready, create a text file `org.ow2.authzforce.core.pdp.api.PdpExtension` in folder `src/main/resources/META-INF/services` (you have to create the folder first) and put the fully qualified name of your implementation class on the first line of this file, like in the example from AuthzForce source code.

4. Run Maven `package` to produce a JAR from the Maven project.

Now you have a Request Preprocessor extension ready for integration into AuthzForce Server, as explained in the next section.

###### Integrating a Request Preprocessor extension into AuthzForce Server

This section assumes you have a Request Preprocessor extension in form of a JAR, typically produced by the process described in the previous section. The steps to integrate the extension into the AuthzForce Server go as follows:

1. Make the JAR - and any extra dependency - visible from the AuthzForce webapp in Tomcat. One way to do it consists to copy the JAR (e.g. `authzforce-ce-core-pdp-testutils-21.0.1.jar` in our example) into `/opt/authzforce-ce-server/webapp/WEB-INF/lib`. For other ways, please refer to Tomcat HowTo.

2. Finally, restart Tomcat to apply changes.

###### Enabling a Request Preprocessor extension on a domain

Once you have deployed the extension on Authzforce, following previous instructions, you are ready to enable it on a specific domain’s PDP by updating the PDP properties with an enabled `feature` of type `urn:ow2:authzforce:feature-type:pdp:request-preproc` and value equal to the ID returned by the method `getId()` of the extension’s factory implementation class. Please refer to Policy Decision (PDP) Properties for examples.

###### Result Postprocessor Extensions

With AuthzForce Result Postprocessors extensions, you can support new ways of processing XACML Results after evaluation by the PDP engine (e.g. used for implementing XACML v3.0 Multiple Decision Profile Version 1.0 - Requests for a combined decision ).

Before you can use such extensions in AuthzForce API, you must implement one or get it from a third party as such. The AuthzForce project also provides a separate Result Postprocessor extension example for documentation and testing purposes. If you wish to make your own Result Postprocessor extension, read on the next section. If you wish to test the example provided by AuthzForce or if you have another one ready for use, you may jump to the section Enabling a Result Postprocessor extension on a domain.

###### Making a Result Postprocessors extension

The steps to make your own Result Postprocessors extension go as follows:

1. Create a Maven project with `jar` packaging type and following Maven dependency:

       <dependency>
        <groupId>org.ow2.authzforce</groupId>
        <artifactId>authzforce-ce-core-pdp-api</artifactId>
        <version>22.0.0</version>
       </dependency>

2. Create your ResultPostprocessor factory and concrete implementation class (as in the Factory design pattern). The factory class must be public, and implement interface org.ow2.authzforce.core.pdp.api.DecisionResultPostprocessor.Factory. This class must have a public no-argument constructor or no constructor. You may use AuthzForce TestCombinedDecisionXacmlJaxbResultPostprocessor class (used for AuthzForce unit tests) as an example. This example provides a test implementation of feature `urn:oasis:names:tc:xacml:3.0:profile:multiple:combined-decision` from XACML v3.0 Multiple Decision Profile Version 1.0. If you are processing XACML/XML Response, you may extend the more convenient class org.ow2.authzforce.core.pdp.api.io.BaseXacmlJaxbResultPostprocessor.Factory.

3. When your implementation class is ready, create a text file `org.ow2.authzforce.core.pdp.api.PdpExtension` in folder `src/main/resources/META-INF/services` (you have to create the folder first) and put the fully qualified name of your implementation class on the first line of this file, like in the example from AuthzForce source code.

4. Run Maven `package` to produce a JAR from the Maven project.

Now you have a Result Postprocessor extension ready for integration into AuthzForce Server, as explained in the next section.

###### Integrating a Result Postprocessor extension into AuthzForce Server

This section assumes you have a Combining Algorithm extension in form of a JAR, typically produced by the process described in the previous section. You may use AuthzForce PDP Core Tests JAR if you only wish to test the examples in this documentation. This JAR is available on Maven Central: groupId= `org.ow2.authzforce`, artifactId= `authzforce-ce-core-pdp-testutils`, version= `21.0.1`.

The steps to integrate the extension into the AuthzForce Server go as follows:

1. Make the JAR - and any extra dependency - visible from the AuthzForce webapp in Tomcat. One way to do it consists to copy the JAR (e.g. `authzforce-ce-core-pdp-testutils-21.0.1.jar` in our example) into `/opt/authzforce-ce-server/webapp/WEB-INF/lib`. For other ways, please refer to Tomcat HowTo.

2. Finally, restart Tomcat to apply changes.

###### Enabling a Result Postprocessor extension on a domain

Once you have deployed the extension on Authzforce, following previous instructions, you are ready to enable it on a specific domain’s PDP by updating the PDP properties with an enabled `feature` of type `urn:ow2:authzforce:feature-type:pdp:result-postproc`. The following example enables Authzforce combined decision result postprocessor (implementing the feature `urn:oasis:names:tc:xacml:3.0:profile:multiple:combined-decision` from XACML v3.0 Multiple Decision Profile Version 1.0 for testing) on the PDP, provided that the AuthzForce PDP Core Tests JAR has been deployed (see previous section):

     1PUT /domains/iMnxv7sDEeWFwqVFFMDLTQ/pap/pdp.properties
     2Content-Type: application/xml
     3
     4<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
     5<pdpPropertiesUpdate xmlns="http://authzforce.github.io/rest-api-model/xmlns/authz/5">
     6 <feature
     7  type="urn:ow2:authzforce:feature-type:pdp:result-postproc"
     8  enabled="true">urn:ow2:authzforce:feature:pdp:result-postproc:multiple:test-combined-decision</feature>
     9 <rootPolicyRefExpression>root</rootPolicyRefExpression>
    10</pdpPropertiesUpdate>

###### Attribute Providers

The API allows to manage PDP attribute providers. These are PDP extensions that enable the PDP to get attributes from other sources than PEPs’ requests. Such sources may be remote services, databases, etc. The AuthzForce Server distribution does not provide attribute providers out of the box, but allows you to plug in custom-made one(s) from your own invention or from third parties. The AuthzForce project also provides a separate Attribute Provider example, for testing and documentation purposes only. If you wish to make your own attribute provider, read on the next section. If you wish to test the example provided by AuthzForce or have another one ready for use, you may jump to the section Integrating an Attribute Provider into AuthzForce Server.

###### Making an Attribute Provider

The steps to make your own PDP Attribute Provider extension for AuthzForce go as follows:

1. Create a Maven project with `jar` packaging type.

2. Create an XML schema file with `.xsd` extension in the `src/main/resources` folder of your Maven project. Make sure this filename is potentially unique on a Java classpath, like your usual Java class names. One way to make sure is to use a filename prefix following the same conventions as the Java package naming conventions. In this schema file, define an XML type for your attribute provider configuration format. This type must extend `AbstractAttributeProvider` from namespace `http://authzforce.github.io/xmlns/pdp/ext/3`. You may use the schema of AuthzForce TestAttributeProvider (used for AuthzForce unit tests only) as an example. In this example, the XSD filename is `org.ow2.authzforce.core.pdp.testutil.ext.xsd` and the defined XML type extending `AbstractAttributeProvider` is `TestAttributeProviderDescriptor`.

3. Copy the files `bindings.xjb` and `catalog.xml` from AuthzForce source code into the `src/main/jaxb` folder (you have to create this folder first) of your Maven project.

4. Add the following Maven dependency and build plugin configuration to your Maven POM:

        1<dependency>
        2 <groupId>org.ow2.authzforce</groupId>
        3 <artifactId>authzforce-ce-core-pdp-api</artifactId>
        4 <version>22.0.0</version>
        5 <scope>provided</scope>
        6</dependency>
        7...
        8<build>
        9 ...
       10 <plugins>
       11  <plugin>
       12   <groupId>org.jvnet.jaxb</groupId>
       13   <artifactId>jaxb-maven-plugin</artifactId>
       14   <version>4.0.0</version>
       15   <configuration>
       16    <!-- debug=true will generate JAXBDebug class. More info: https://github.com/highsource/maven-jaxb2-plugin/wiki/Miscellaneous -->
       17    <debug>false</debug>
       18    <strict>false</strict>
       19    <verbose>true</verbose>
       20    <removeOldOutput>true</removeOldOutput>
       21    <extension>true</extension>
       22    <useDependenciesAsEpisodes>true</useDependenciesAsEpisodes>
       23    <catalog>src/main/jaxb/catalog.xml</catalog>
       24    <bindingDirectory>src/main/jaxb</bindingDirectory>
       25    <schemaDirectory>src/main/resources</schemaDirectory>
       26    <!-- If you wish to use extensions, for exemple Value Constructor -->
       27    <!--
       28    <args>
       29         <arg>-Xvalue-constructor</arg>
       30      </args>
       31      <plugins>
       32         <plugin>
       33               <groupId>org.jvnet.jaxb</groupId>
       34               <artifactId>jaxb-plugins</artifactId>
       35               <version>4.0.0</version>
       36         </plugin>
       37      </plugins>
       38      -->
       39   </configuration>
       40   <executions>
       41    <execution>
       42     <id>jaxb-generate-compile-sources</id>
       43     <phase>generate-sources</phase>
       44     <goals>
       45      <goal>generate</goal>
       46     </goals>
       47    </execution>
       48   </executions>
       49  </plugin>
       50  ...
       51 </plugins>
       52</build>
       53...

5. Run Maven `generate-sources`. This will generate the JAXB-annotated class(es) from the XML schema into the folder `target/generated-sources/xjc`, one of which corresponds to your attribute provider XML type defined in the second step, therefore has the same name and also extends `org.ow2.authzforce.xmlns.pdp.ext.AbstractAttributeProvider` class corresponding to `AbstractAttributeProvider` type in the XML schema. For example, in the case of the AuthzForce Test AttributeProvider aforementioned, the corresponding generated class is `org.ow2.authzforce.core.pdp.testutil.ext.xmlns.TestAttributeProviderDescriptor`. In your case and in general, we will refer to it as your Attribute Provider Model class.

6. Create your Attribute Provider factory and concrete implementation class (as in the Factory design pattern). The factory class must be public, and extend CloseableNamedAttributeProvider.FactoryBuilder`<APM>`, where `APM` stands for your Attribute Provider Model Class; and the factory class must have a public no-argument constructor or no constructor. You may use the AuthzForce TestAttributeProvider implementation class (used for AuthzForce unit tests only) as an example. In this example, the static nested class `Factory` is the one extending `CloseableNamedAttributeProvider.FactoryBuilder<TestAttributeProviderDescriptor>`. Such a class has a factory method `getInstance(APM config, ...)` (`getInstance(TestAttributeProviderDescriptor conf, ...)` in the example) that, from an instance of your `APM` representing the XML input (`TestAttributeProviderDescriptor` in the example), creates an instance of your Attribute Provider implementation class (`TestAttributeProvider` in the example). Indeed, your Attribute Provider implementation class must implement the interface CloseableNamedAttributeProvider. To facilitate the implementation process, instead of implementing this interface directly, you should extend BaseNamedAttributeProvider in your implementation class, whenever possible. This class already implements the required interface. There are cases where it is not possible; for instance, since BaseNamedAttributeProvider is an abstract class, if your implementation needs to extend another abstract class, you have no choice but to implement the interface directly, because a Java class cannot extend multiple abstract classes. In any case, as mandated by the interface, your implementation class must implement the method `get(attributeFQN, datatype, context)` in charge of actually retrieving the extra attributes (`TestAttributeProvider#get(...)` in the example). The `attributeFQN` identifies an XACML attribute’s fully qualified name, i.e. category, ID and optional Issuer that the PDP is requesting from your attribute provider; the `datatype` is the expected attribute datatype; and `context` is the request context, including the content from the current XACML Request and possibly extra attributes retrieved so far by other Attribute Providers.

7. When your Attribute Provider implementation class is ready, you create a configuration file to enable AuthzForce extension manager to discover this new extension dynamically at runtime. AuthzForce extension mechanism is based on Java native extension mechanism. In this regard, the PdpExtension interface is the SPI, and your AttributeProvider implementation must be registered as one of the Service Provider for this SPI. In short, all you have to do is create a configuration file `org.ow2.authzforce.core.pdp.api.PdpExtension` in folder `src/main/resources/META-INF/services` (you may have to create the folder first) and put the fully qualified name of your implementation class on the first line of this file (or a new line if there are others already there), like in the example from AuthzForce source code. More info.

8. Run Maven `package` to produce a JAR from the Maven project.

Now you have an Attribute Provider extension ready for integration into AuthzForce Server, as explained in the next section.

###### Integrating an Attribute Provider into AuthzForce Server

This section assumes you have an Attribute Provider extension in form of a JAR, typically produced by the process in the previous section. You may use AuthzForce PDP Core Tests JAR if you only wish to test the examples in this documentation. This JAR is available on Maven Central: groupId= `org.ow2.authzforce`, artifactId= `authzforce-ce-core-pdp-testutils`, version= `21.0.1`.

The steps to integrate the extension into the AuthzForce Server go as follows:

1. Make the JAR - and any extra dependency - visible from the AuthzForce webapp in Tomcat. One way to do it consists to copy the JAR (e.g. `authzforce-ce-core-pdp-testutils-13.3.1.jar` in our example) into `/opt/authzforce-ce-server/webapp/WEB-INF/lib`. For other ways, please refer to Tomcat HowTo.

2. Import your attribute provider XML schema in the XML schema file `/opt/authzforce-ce-server/conf/authzforce-ext.xsd`, using `namespace` only (no `schemaLocation`), like in the example from Authzforce code with this schema import for AuthzForce `TestAttributeProvider`:

       1<xs:import namespace="http://authzforce.github.io/core/xmlns/test/3" />

3. Add a `uri` element to XML catalog file `/opt/authzforce-ce-server/conf/catalog.xml`, with your attribute Provider XML namespace as `name` attribute value, and, the location of your XML schema file within the JAR, as `uri` attribute value, prefixed by `classpath:`. For example, in the sample XML catalog from Authzforce source code, we add the following line for AuthzForce `TestAttributeProvider`:

       1<uri name="http://authzforce.github.io/core/xmlns/test/3" uri="classpath:org.ow2.authzforce.core.pdp.testutil.ext.xsd"/>

4. Finally, restart Tomcat to apply changes.

###### Managing attribute providers configuration

Once you have deployed a new attribute provider extension on Authzforce, following previous instructions, you are ready to use it on a domain:

- Method: PUT

- Path: `/domains/{domainId}/pap/attribute.providers`

- Headers:

  > - Content-Type: `application/xml; charset=UTF-8`

  > - Accept: `application/xml; charset=UTF-8`

- Body: new attribute providers.

For example, this request instantiates a specific `TestAttributeProvider` configuration on domain `iMnxv7sDEeWFwqVFFMDLTQ` (as mentioned in the previous section, `TestAttributeProvider` is merely an example for testing and documentation purposes, it is not available in a default installation of Authzforce):

     1PUT /domains/iMnxv7sDEeWFwqVFFMDLTQ/pap/attribute.providers
     2HTTP/1.1
     3Accept: application/xml; charset=UTF-8
     4Content-Type: application/xml; charset=UTF-8
     5
     6<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
     7<attributeProviders
     8 xmlns="http://authzforce.github.io/rest-api-model/xmlns/authz/5"
     9 xmlns:xacml="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17">
    10 <attributeProvider
    11  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    12  xmlns:test="http://authzforce.github.io/core/xmlns/test/3"
    13  xsi:type="test:TestAttributeProviderDescriptor" id="test">
    14  <xacml:Attributes
    15   Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject">
    16   <xacml:Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:example:attribute:role"
    17    IncludeInResult="false">
    18    <xacml:AttributeValue
    19     DataType="http://www.w3.org/2001/XMLSchema#string">Physician</xacml:AttributeValue>
    20   </xacml:Attribute>
    21  </xacml:Attributes>
    22 </attributeProvider>
    23</attributeProviders>

The response is the new attribute provider configuration from the request.

In this second example, we disable all PDP attribute providers of domain `iMnxv7sDEeWFwqVFFMDLTQ` by sending an empty element:

    1PUT /domains/iMnxv7sDEeWFwqVFFMDLTQ/pap/attribute.providers
    2HTTP/1.1
    3Accept: application/xml; charset=UTF-8
    4Content-Type: application/xml; charset=UTF-8
    5
    6<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    7<attributeProviders xmlns="http://authzforce.github.io/rest-api-model/xmlns/authz/5" />

Finally, you may get the current attribute providers anytime as follows:

- Method: GET

- Path: `/domains/{domainId}/pap/attribute.providers`

- Headers:

  > - Accept: `application/xml; charset=UTF-8`

For example, this request gets the PDP attribute providers of domain `iMnxv7sDEeWFwqVFFMDLTQ`:

    1GET /domains/iMnxv7sDEeWFwqVFFMDLTQ/pap/attribute.providers
    2HTTP/1.1
    3Accept: application/xml; charset=UTF-8
    4
    5<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    6<attributeProviders xmlns="http://authzforce.github.io/rest-api-model/xmlns/authz/5">
    7  ...
    8</attributeProviders>

#### Policy Decision API

The PDP API returns an authorization decision based on the currently enforced policy, access control attributes provided in the request and possibly other attributes resolved by the PDP itself. The Authorization decision is typically `Permit` or `Deny`. The PDP is able to resolve extra attributes not provided directly in the request, such as the current date/time (environment attribute).

The PDP provides an HTTP RESTful API for requesting authorization decisions, that complies with test assertions `urn:oasis:names:tc:xacml:3.0:profile:rest:assertion:pdp:xacml:status`, `urn:oasis:names:tc:xacml:3.0:profile:rest:assertion:pdp:xacml:body` and `urn:oasis:names:tc:xacml:3.0:profile:rest:assertion:pdp:xacml:invalid` of REST Profile of XACML v3.0 Version 1.0.

The HTTP request must be formatted as follows:

- Method: POST

- Path: `/domains/{domainId}/pdp`

- Headers:

  > - Content-Type: `application/xml; charset=UTF-8`

  > - Accept: `application/xml; charset=UTF-8`

- Body: XACML Request as defined in the XACML 3.0 schema.

The HTTP response body is a XACML Response as defined in the XACML 3.0 schema.

Example of request given below:

     1POST /domains/iMnxv7sDEeWFwqVFFMDLTQ/pdp
     2HTTP/1.1
     3Accept: application/xml; charset=UTF-8
     4Content-Type: application/xml; charset=UTF-8
     5
     6<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
     7<Request xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"
     8 CombinedDecision="false" ReturnPolicyIdList="false">
     9 <Attributes
    10  Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject">
    11  <Attribute
    12   AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
    13   IncludeInResult="false">
    14   <AttributeValue
    15   DataType="http://www.w3.org/2001/XMLSchema#string">joe</AttributeValue>
    16  </Attribute>
    17  <Attribute AttributeId="urn:oasis:names:tc:xacml:2.0:subject:role"
    18   IncludeInResult="false"> <AttributeValue
    19   DataType="http://www.w3.org/2001/XMLSchema#string">Manager</AttributeValue>
    20  </Attribute>
    21 </Attributes>
    22 <Attributes
    23  Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource">
    24  <Attribute
    25   AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"
    26   IncludeInResult="false">
    27   <AttributeValue
    28    DataType="http://www.w3.org/2001/XMLSchema#string">MissionManagementApp</AttributeValue>
    29  </Attribute>
    30  <Attribute
    31   AttributeId="urn:thales:xacml:2.0:resource:sub-resource-id" IncludeInResult="false">
    32   <AttributeValue
    33    DataType="http://www.w3.org/2001/XMLSchema#string">Team</AttributeValue>
    34  </Attribute>
    35 </Attributes>
    36 <Attributes
    37  Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action">
    38  <Attribute
    39   AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
    40   IncludeInResult="false">
    41   <AttributeValue
    42    DataType="http://www.w3.org/2001/XMLSchema#string">manage</AttributeValue>
    43  </Attribute>
    44 </Attributes>
    45 <Attributes
    46  Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" />
    47</Request>

Response:

    1HTTP/1.1 200 OK
    2Content-Type: application/xml; charset=UTF-8
    3
    4<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    5<Response xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17">
    6 <Result>
    7     <Decision>Permit</Decision>
    8 </Result>
    9</Response>

If the XACML request was invalid (invalid format), an error 400 is returned.

#### Fast Infoset

Fast Infoset is an ITU-T/ISO standard for representing XML (XML Information Set to be accurate) using binary encodings, designed for use cases to provide smaller encoding sizes and faster processing than a W3C XML representation as text. The open source Fast Infoset project provide some performance results and more information about the standardisation status. There are several use cases at the origin of Fast Infoset. A major one comes from the Web3D consortium that is responsible for open standards in real-time 3D communication, and that adopted Fast Infoset for the serialization and compression of X3D documents. X3D is a standard for representing 3D scenes and objects using XML.

AuthzForce Server API offers experimental support for Fast Infoset (use with caution). This feature is disabled by default and needs to be enabled explicitly by the administrator as told in the Fast Infoset mode. When it is enabled, provided that your API client supports Fast Infoset as well, you may use Fast Infoset on the server API by replacing the media type `application/xml` with `application/fastinfoset` in your API request headers (Accept/Content-Type).

#### Integration with the IdM and PEP Proxy GEs (e.g. for OAuth)

AuthzForce integrates with the Identity Management (KeyRock) and PEP Proxy GE (Wilma) reference implementations. For an overview of the main interactions, please refer to the Basic and Advanced sections of Wilma programmer guide.

After you installed and configured KeyRock, to connect it to Authzforce, you modify the properties with names prefixed by `ACCESS_CONTROL_` in the configuration file `fiware-idm/horizon/openstack_dashboard/local/local_settings.py` (example on KeyRock Github repository) according to your AuthzForce instance properties. For example:

    1// ACCESS CONTROL GE
    2// URL to Authzforce server (http(s)://HOST:PORT)
    3ACCESS_CONTROL_URL = 'http://127.0.0.1:8080'
    4// Magic key, required only if securing the AZF with a PEP Proxy
    5ACCESS_CONTROL_MAGIC_KEY = 'undefined'

WARNING: If you are using KeyRock v5.3.0 or older, you also have to change the content of IDM’s template file `openstack_dashboard/templates/access_control/policy_properties.xacml` to this (basically the only change consists to remove the `ns2` namespace prefix):

    1<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    2<pdpPropertiesUpdate xmlns="http://authzforce.github.io/rest-api-model/xmlns/authz/5">
    3 <rootPolicyRefExpression>{{ policy_id }}</rootPolicyRefExpression>
    4</pdpPropertiesUpdate>

Then restart the IdM to apply changes, and go to IdM web interface, and check that the permissions and roles are well configured for your application. You may have to ‘trigger’ the policy generation in IdM by going to your application > Manage roles and click Save to trigger the XACML generation. More information in KeyRock installation and administration guide.

Then, after you installed and configured Wilma, to connect it to Authzforce, you modify the settings in `config.azf` object of configuration file `config.js` (example) according to your AuthzForce instance properties. More information in Wilma installation and administration guide.

#### Software Libraries for clients of AuthzForce or other Authorization PDP GEis

The full API (RESTful) is described by a document written in the Web Application Description Language format (WADL) and associated XML schema files available in Authzforce rest-api-model project files. Therefore, you can use any WADL-supporting REST framework for clients; for instance in Java: Jersey, Apache CXF. From that, you can use WADL-to-code generators to generate your client code. For example in Java, ‘wadl2java’ tools allow to generate code for JAX-RS compatible frameworks such as Apache CXF and Jersey. Actually, we can provide a CXF-based Java library created with this tool to facilitate the development of clients.

Read the Docs v: 12.0.1-1

Versions
  latest
  12.0.1-1
  4.2.0
  user-guide-only
  release-9.0.1
  release-8.1.0.1
  release-8.0.1
  release-5.4.1e
  release-5.3.0a
  release-5.2.0
  release-5.1.2
  release-4.4.1d
  release-4.3.0
  release-12.0.1
  release-11.0.0
  release-10.1.1
  install-guide-only

Downloads

On Read the Docs
  Project Home
  Builds