{"info":{"_postman_id":"6554748b-8871-4e83-8c4d-7ab315f9894a","name":"FIWARE XACML Rules","description":"<html><head></head><body><p><a href=\"https://www.fiware.org/developers/catalogue/\"><img src=\"https://nexus.lab.fiware.org/repository/raw/public/badges/chapters/security.svg\" alt=\"FIWARE Security\"></a></p>\n<p>This tutorial introduces an additional security generic enabler - <strong>Authzforce</strong>\nand adds fine grained control to the security rules generated by <strong>Keyrock</strong>.\nAccess to the entities created in the\n<a href=\"https://github.com/Fiware/tutorials.PEP-Proxy\">previous tutorial</a> is now\nconfigured and controlled using an XACML access control policy - this creates a\nflexible ruleset which can be uploaded and reinterpreted on the fly so complex\nbusiness rules can be created and changed according to current circumstances.</p>\n<p>The tutorial discusses code showing how to integrate <strong>Authzforce</strong> within a web\napplication and demonstrates examples of <strong>Authzforce</strong> XACML Server-PDP\ninteractions. <a href=\"https://ec.haxx.se/\">cUrl</a> commands are used to show the\ninteractions between generic enablers.</p>\n<p>The <code>docker-compose</code> files for this tutorial can be found on GitHub: </p>\n<p><img src=\"https://fiware.github.io/tutorials.XACML-Access-Rules/icon/GitHub-Mark-32px.png\" alt=\"GitHub\"> <a href=\"https://github.com/Fiware/tutorials.XACML-Access-Rules\">FIWARE 405: Ruleset Based Permissions</a></p>\n<h1 id=\"ruleset-based-permissions\">Ruleset Based Permissions</h1>\n<blockquote>\n<p>\"Say: Come, I will rehearse what <em>Allah</em> hath prohibited you from:</p>\n<ul>\n<li>Join not anything as equal with <em>Him</em></li>\n<li>Be good to your parents</li>\n<li>Kill not your children on a plea of want - <em>We</em> provide sustenance for you\nand for them</li>\n<li>Come not nigh to shameful deeds. Whether open or secret</li>\n<li>Take not life, which <em>Allah</em> hath made sacred, except by way of justice\nand law</li>\n</ul>\n<p>thus doth <em>He</em> command you, that ye may learn wisdom.\"</p>\n<p>— Quran 6.151, Sūrat al-Anʻām</p>\n</blockquote>\n<p><a href=\"https://github.com/Fiware/tutorials.Securing-Access\">Previous tutorials</a> have\nintroduced a simple access control system based on authentication (level 1) or\nbasic authorization access to resources based on a role (level 2). These\npolicies are easy to create, but the rules within them are very black and white,\nrules cannot rely on one another, have exception clauses or offer access based\non time limits or attribute values. There is also no mechanism to resolve\ndifferent rules in the case of conflict.</p>\n<p>To satisfy a complex access control scenario, an additional arbitration\nmicroservice is required, which is able to come to a judgement on each\nPermit/Deny policy decision by reading and interpreting the full set of access\ncontrol rules, and based their judgement on the evidence provided by the\nrequesting service.</p>\n<p>FIWARE <a href=\"https://authzforce-ce-fiware.readthedocs.io/\">Authzforce</a> is a service\nwhich is able to provide such an interpretive Policy Decision Point (PDP). It is\nan advanced access control Generic Enabler which is able to interpret rules\nsupplied using the\n<a href=\"https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=xacml\">XACML standard</a>.\nRulesets can be amended and uploaded at any time providing a flexible method to\nmaintain security policies which can change according to business need.\nFurthermore the language used to describe the access policy is designed to be\nhighly extensible and cover any access control scenario.</p>\n<h2 id=\"what-is-xacml\">What is XACML</h2>\n<p>eXtensible Access Control Markup Language (XACML) is a vendor neutral\ndeclarative access control policy language. It was created to promote common\naccess control terminology and interoperability. The architectural naming\nconventions for elements such as Policy Execution Point (PEP) and Policy\nDecision Point (PDP) come from the XACML specifications.</p>\n<p>XACML policies are split into a hierarchy of three levels - <code>&lt;PolicySet&gt;</code>,\n<code>&lt;Policy&gt;</code> and <code>&lt;Rule&gt;</code>, the <code>&lt;PolicySet&gt;</code> is a collection of <code>&lt;Policy&gt;</code>\nelements each of which contain one or more <code>&lt;Rule&gt;</code> elements.</p>\n<p>Each <code>&lt;Rule&gt;</code> within a <code>&lt;Policy&gt;</code> is evaluated as to whether it should grant\naccess to a resource - the overall <code>&lt;Policy&gt;</code> result is defined by the overall\nresult of all <code>&lt;Rule&gt;</code> elements processed in turn. Separate <code>&lt;Policy&gt;</code> results\nare then evaluated against each other using combining alogorthms define which\n<code>&lt;Policy&gt;</code> wins in case of conflict.</p>\n<p>A <code>&lt;Rule&gt;</code> element consists of a <code>&lt;Target&gt;</code> and a <code>&lt;Condition&gt;</code>. This is an\nexample <code>&lt;Rule&gt;</code>, it states access will be granted (<code>Effect=\"Permit\"</code>) when a\nPOST request is sent to the <code>/bell/ring</code> endpoint, provided that the\n<code>subject:role</code> has been provided and that the\n<code>role=security-role-0000-0000-000000000000</code> :</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-xml\">&lt;Rule RuleId=\"alrmbell-ring-0000-0000-000000000000\" Effect=\"Permit\"&gt;\n  &lt;Description&gt;Ring Alarm Bell&lt;/Description&gt;\n  &lt;Target&gt;\n    &lt;AnyOf&gt;\n      &lt;AllOf&gt;\n        &lt;Match MatchId=\"urn:oasis:names:tc:xacml:1.0:function:string-equal\"&gt;\n          &lt;AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\"&gt;/bell/ring&lt;/AttributeValue&gt;\n          &lt;AttributeDesignator Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\" AttributeId=\"urn:thales:xacml:2.0:resource:sub-resource-id\" DataType=\"http://www.w3.org/2001/XMLSchema#string\" MustBePresent=\"true\" /&gt;\n        &lt;/Match&gt;\n      &lt;/AllOf&gt;\n    &lt;/AnyOf&gt;\n    &lt;AnyOf&gt;\n      &lt;AllOf&gt;\n        &lt;Match MatchId=\"urn:oasis:names:tc:xacml:1.0:function:string-equal\"&gt;\n          &lt;AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\"&gt;POST&lt;/AttributeValue&gt;\n          &lt;AttributeDesignator Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:action\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:action:action-id\" DataType=\"http://www.w3.org/2001/XMLSchema#string\" MustBePresent=\"true\" /&gt;\n        &lt;/Match&gt;\n      &lt;/AllOf&gt;\n    &lt;/AnyOf&gt;\n  &lt;/Target&gt;\n  &lt;Condition&gt;\n    &lt;Apply FunctionId=\"urn:oasis:names:tc:xacml:3.0:function:any-of\"&gt;\n      &lt;Function FunctionId=\"urn:oasis:names:tc:xacml:1.0:function:string-equal\" /&gt;\n      &lt;AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\"&gt;security-role-0000-0000-000000000000&lt;/AttributeValue&gt;\n      &lt;AttributeDesignator Category=\"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\" AttributeId=\"urn:oasis:names:tc:xacml:2.0:subject:role\" DataType=\"http://www.w3.org/2001/XMLSchema#string\" MustBePresent=\"false\" /&gt;\n    &lt;/Apply&gt;\n  &lt;/Condition&gt;\n&lt;/Rule&gt;\n</code></pre>\n<p>This is a very verbose method for creating a simple Verb-Resource access rule,\nbut unlike simple Verb-Resource rules, with XACML, other more complex\ncomparisons can be made, for example checking that time is before a certain hour\nof day, or checking that a URL starts with or contains a certain string.\nConditions can be specified down to the attribute level or combined to make\ncomplex calculations, for example - an XACML <code>&lt;Rule&gt;</code> could be created to apply\nthe following policy:</p>\n<blockquote>\n<p><em>A store manager is able to amend Product prices only the first of the month,\nand can only alter prices of products she or her immediate superior has\ncreated in the first place</em></p>\n</blockquote>\n<p>Such a <code>&lt;Rule&gt;</code> would require that the <code>&lt;Condition&gt;</code> includes separate\nclauses/clarifications for the following:</p>\n<ul>\n<li>What is the User's role? (e.g. <code>manager</code>)</li>\n<li>What action is being invoked? (e.g PATCH or PUT)</li>\n<li>Which resource is being protected URL string? (e.g. <code>/v2/entities</code>)</li>\n<li>What other information must be present in the body of the request? (e.g.\nEntity <code>type</code> must equal <code>Product</code>)</li>\n<li>When is the resource being requested? (e.g. the current date)</li>\n<li>What other additional information must be retrieved from elsewhere prior to\nmaking the request<ul>\n<li>Who created the entity? Is it me or my manager?</li>\n</ul>\n</li>\n</ul>\n<p>As you can see these rules can quickly become very complex. For this initial\nintroduction to XACML, the basic rule set used will be kept as simple as\npossible to avoid unnecessary confusion, suffice it to say that an access policy\nbased on XACML can be expanded to fit the security needs of any complex system.</p>\n<h1 id=\"prerequisites\">Prerequisites</h1>\n<h2 id=\"docker\">Docker</h2>\n<p>To keep things simple all components will be run using\n<a href=\"https://www.docker.com\">Docker</a>. <strong>Docker</strong> is a container technology which\nallows to different components isolated into their respective environments.</p>\n<ul>\n<li>To install Docker on Windows follow the instructions\n<a href=\"https://docs.docker.com/docker-for-windows/\">here</a></li>\n<li>To install Docker on Mac follow the instructions\n<a href=\"https://docs.docker.com/docker-for-mac/\">here</a></li>\n<li>To install Docker on Linux follow the instructions\n<a href=\"https://docs.docker.com/install/\">here</a></li>\n</ul>\n<p><strong>Docker Compose</strong> is a tool for defining and running multi-container Docker\napplications. A\n<a href=\"https://raw.githubusercontent.com/Fiware/tutorials.Identity-Management/master/docker-compose.yml\">YAML file</a>\nis used configure the required services for the application. This means all\ncontainer services can be brought up in a single command. Docker Compose is\ninstalled by default as part of Docker for Windows and Docker for Mac, however\nLinux users will need to follow the instructions found\n<a href=\"https://docs.docker.com/compose/install/\">here</a></p>\n<h2 id=\"cygwin\">Cygwin</h2>\n<p>We will start up our services using a simple bash script. Windows users should\ndownload <a href=\"http://www.cygwin.com/\">cygwin</a> to provide a command-line\nfunctionality similar to a Linux distribution on Windows.</p>\n<h1 id=\"architecture\">Architecture</h1>\n<p>This application adds level 3 Advanced Authorization security into the existing\nStock Management and Sensors-based application created in\n<a href=\"https://github.com/Fiware/tutorials.Securing-Access/\">previous tutorials</a> and\nsecures access to the context broker behind a\n<a href=\"https://github.com/Fiware/tutorials.PEP-Proxy/\">PEP Proxy</a>. It will make use of\nfive FIWARE components - the\n<a href=\"https://fiware-orion.readthedocs.io/en/latest/\">Orion Context Broker</a>,the\n<a href=\"https://fiware-iotagent-ul.readthedocs.io/en/latest/\">IoT Agent for UltraLight 2.0</a>,\nthe <a href=\"https://fiware-idm.readthedocs.io/en/latest/\">Keyrock</a> Identity Manager,\nthe <a href=\"\">Wilma</a> PEP Proxy and the\n<a href=\"https://authzforce-ce-fiware.readthedocs.io\">Authzforce</a> XACML Server. All\naccess control decisions will be delegated to <strong>Authzforce</strong> which will read the\nruleset from a previously uploaded policy domain.</p>\n<p>Both the Orion Context Broker and the IoT Agent rely on open source\n<a href=\"https://www.mongodb.com/\">MongoDB</a> technology to keep persistence of the\ninformation they hold. We will also be using the dummy IoT devices created in\nthe <a href=\"https://github.com/Fiware/tutorials.IoT-Sensors/\">previous tutorial</a>.\n<strong>Keyrock</strong> uses its own <a href=\"https://www.mysql.com/\">MySQL</a> database.</p>\n<p>Therefore the overall architecture will consist of the following elements:</p>\n<ul>\n<li>The FIWARE\n<a href=\"https://fiware-orion.readthedocs.io/en/latest/\">Orion Context Broker</a> which\nwill receive requests using\n<a href=\"https://fiware.github.io/specifications/OpenAPI/ngsiv2\">NGSI</a></li>\n<li>The FIWARE\n<a href=\"https://fiware-iotagent-ul.readthedocs.io/en/latest/\">IoT Agent for UltraLight 2.0</a>\nwhich will receive southbound requests using\n<a href=\"https://fiware.github.io/specifications/OpenAPI/ngsiv2\">NGSI</a> and convert\nthem to\n<a href=\"https://fiware-iotagent-ul.readthedocs.io/en/latest/usermanual/index.html#user-programmers-manual\">UltraLight 2.0</a>\ncommands for the devices</li>\n<li>FIWARE <a href=\"https://fiware-idm.readthedocs.io/en/latest/\">Keyrock</a> offer a\ncomplement Identity Management System including:<ul>\n<li>An OAuth2 authentication system for Applications and Users</li>\n<li>A site graphical frontend for Identity Management Administration</li>\n<li>An equivalent REST API for Identity Management via HTTP requests</li>\n</ul>\n</li>\n<li>FIWARE <a href=\"https://authzforce-ce-fiware.readthedocs.io/\">Authzforce</a> is a XACML\nServer providing an interpretive Policy Decision Point (PDP) access to the\n<strong>Orion</strong> and/or <strong>IoT Agent</strong> microservices</li>\n<li>FIWARE <a href=\"https://fiware-pep-proxy.rtfd.io/\">Wilma</a> is a PEP Proxy securing\naccess to the <strong>Orion</strong> microservices, it delegates the passing of\nauthorisation decisions to <strong>Authzforce</strong> PDP</li>\n<li>The underlying <a href=\"https://www.mongodb.com/\">MongoDB</a> database :<ul>\n<li>Used by the <strong>Orion Context Broker</strong> to hold context data information\nsuch as data entities, subscriptions and registrations</li>\n<li>Used by the <strong>IoT Agent</strong> to hold device information such as device URLs\nand Keys</li>\n</ul>\n</li>\n<li>A <a href=\"https://www.mysql.com/\">MySQL</a> database :<ul>\n<li>Used to persist user identities, applications, roles and permissions</li>\n</ul>\n</li>\n<li>The <strong>Stock Management Frontend</strong> does the following:<ul>\n<li>Displays store information</li>\n<li>Shows which products can be bought at each store</li>\n<li>Allows users to \"buy\" products and reduce the stock count.</li>\n<li>Allows authorized users into restricted areas, it also delegates\nauthoriation decisions to the <strong>Authzforce</strong> PDP</li>\n</ul>\n</li>\n<li>A webserver acting as set of\n<a href=\"https://github.com/Fiware/tutorials.IoT-Sensors\">dummy IoT devices</a> using\nthe\n<a href=\"https://fiware-iotagent-ul.readthedocs.io/en/latest/usermanual/index.html#user-programmers-manual\">UltraLight 2.0</a>\nprotocol running over HTTP - access to certain resources is restricted.</li>\n</ul>\n<p>Since all interactions between the elements are initiated by HTTP requests, the\nentities can be containerized and run from exposed ports.</p>\n<p><img src=\"https://fiware.github.io/tutorials.XACML-Access-Rules/img/architecture.png\" alt=\"\"></p>\n<p>The specific architecture of each section of the tutorial is discussed below.</p>\n<h2 id=\"keyrock-configuration\">Keyrock Configuration</h2>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-yaml\">keyrock:\n    image: fiware/idm\n    container_name: fiware-keyrock\n    hostname: keyrock\n    networks:\n        default:\n            ipv4_address: 172.18.1.5\n    depends_on:\n        - mysql-db\n        - authzforce\n    ports:\n        - \"3005:3005\"\n    environment:\n        - DEBUG=idm:*\n        - DATABASE_HOST=mysql-db\n        - IDM_DB_PASS_FILE=/run/secrets/my_secret_data\n        - IDM_DB_USER=root\n        - IDM_HOST=http://localhost:3005\n        - IDM_PORT=3005\n        - IDM_ADMIN_USER=alice\n        - IDM_ADMIN_EMAIL=alice-the-admin@test.com\n        - IDM_ADMIN_PASS=test\n        - IDM_PDP_LEVEL=advanced\n        - IDM_AUTHZFORCE_ENABLED=true\n        - IDM_AUTHZFORCE_HOST=authzforce\n        - IDM_AUTHZFORCE_PORT=8080\n    secrets:\n        - my_secret_data\n</code></pre>\n<p>The <code>keyrock</code> container is a web application server listening on a single port:</p>\n<ul>\n<li>Port <code>3005</code> has been exposed for HTTP traffic so we can display the web page\nand interact with the REST API.</li>\n</ul>\n<p>The <code>keyrock</code> container is connecting to <strong>Authzforce</strong> and is driven by\nenvironment variables as shown:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Key</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>IDM_PDP_LEVEL</td>\n<td><code>advanced</code></td>\n<td>Flag indicating that <strong>Keyrock</strong> should delegate PDP decisions to Authzforce</td>\n</tr>\n<tr>\n<td>IDM_AUTHZFORCE_ENABLED</td>\n<td><code>true</code></td>\n<td>Flag indicating that <strong>Authzforce</strong> is available</td>\n</tr>\n<tr>\n<td>IDM_AUTHZFORCE_HOST</td>\n<td><code>authzforce</code></td>\n<td>This is URL where the <strong>Authzforce</strong> is found</td>\n</tr>\n<tr>\n<td>IDM_AUTHZFORCE_PORT</td>\n<td><code>8080</code></td>\n<td>Port that <strong>Authzforce</strong> is listening on</td>\n</tr>\n</tbody>\n</table>\n</div><p>The other <code>keyrock</code> container configuration values described in the YAML file\nhave been described in previous tutorials</p>\n<h2 id=\"pep-proxy-configuration\">PEP Proxy Configuration</h2>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-yaml\">orion-proxy:\n    image: fiware/pep-proxy\n    container_name: fiware-orion-proxy\n    hostname: orion-proxy\n    networks:\n        default:\n            ipv4_address: 172.18.1.10\n    depends_on:\n        - keyrock\n        - authzforce\n    ports:\n        - \"1027:1027\"\n    expose:\n        - \"1027\"\n    environment:\n        - PEP_PROXY_APP_HOST=orion\n        - PEP_PROXY_APP_PORT=1026\n        - PEP_PROXY_PORT=1027\n        - PEP_PROXY_IDM_HOST=keyrock\n        - PEP_PROXY_HTTPS_ENABLED=false\n        - PEP_PROXY_IDM_SSL_ENABLED=false\n        - PEP_PROXY_IDM_PORT=3005\n        - PEP_PROXY_APP_ID=tutorial-dckr-site-0000-xpresswebapp\n        - PEP_PROXY_USERNAME=pep_proxy_00000000-0000-0000-0000-000000000000\n        - PEP_PASSWORD=test\n        - PEP_PROXY_PDP=authzforce\n        - PEP_PROXY_AUTH_ENABLED=true\n        - PEP_PROXY_MAGIC_KEY=1234\n        - PEP_PROXY_AZF_PROTOCOL=http\n        - PEP_PROXY_AZF_HOST=authzforce\n        - PEP_PROXY_AZF_PORT=8080\n</code></pre>\n<p>The <code>orion-proxy</code> container is an instance of FIWARE <strong>Wilma</strong> listening on port\n<code>1027</code>, it is configured to forward traffic to <code>orion</code> on port <code>1026</code>, which is\nthe default port that the Orion Context Broker is listening to for NGSI\nRequests.</p>\n<p>The <code>orion-proxy</code> container is delegating PDP decisions to <strong>Authzforce</strong> and is\ndriven by environment variables as shown:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Key</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>PEP_PROXY_PDP</td>\n<td><code>authzforce</code></td>\n<td>Flag ensuring that the PEP Proxy uses Authzforce as a PDP</td>\n</tr>\n<tr>\n<td>PEP_PROXY_AZF_PROTOCOL</td>\n<td><code>http</code></td>\n<td>Flag to enable use of the XACML PDP</td>\n</tr>\n<tr>\n<td>PEP_PROXY_AZF_HOST</td>\n<td><code>authzforce</code></td>\n<td>This is URL where the <strong>Authzforce</strong> is found users</td>\n</tr>\n<tr>\n<td>PEP_PROXY_AZF_PORT</td>\n<td><code>8080</code></td>\n<td>Port that <strong>Authzforce</strong> is listening on</td>\n</tr>\n</tbody>\n</table>\n</div><p>The other <code>orion-proxy</code> container configuration values described in the YAML\nfile have been described in previous tutorials</p>\n<h2 id=\"authzforce-configuration\">Authzforce Configuration</h2>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-yaml\">authzforce:\n    image: fiware/authzforce-ce-server\n    hostname: authzforce\n    container_name: fiware-authzforce\n    networks:\n        default:\n            ipv4_address: 172.18.1.12\n    ports:\n        - \"8080:8080\"\n    volumes:\n        - ./authzforce/domains:/opt/authzforce-ce-server/data/domains\n</code></pre>\n<p>The <code>authzforce</code> container is listening on port <code>8080</code>, where it receives\nrequests to make PDP decisions. A volume has been exposed to upload a\npre-configured domain so that a set of XACML access control policies has already\nbeen supplied.</p>\n<h2 id=\"tutorial-security-configuration\">Tutorial Security Configuration</h2>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-yaml\">tutorial:\n    image: fiware/tutorials.context-provider\n    hostname: tutorial\n    container_name: fiware-tutorial\n    networks:\n        default:\n            ipv4_address: 172.18.1.7\n    expose:\n        - \"3000\"\n        - \"3001\"\n    ports:\n        - \"3000:3000\"\n        - \"3001:3001\"\n    environment:\n        - \"DEBUG=tutorial:*\"\n        - \"WEB_APP_PORT=3000\"\n        - \"KEYROCK_URL=http://localhost\"\n        - \"KEYROCK_IP_ADDRESS=http://172.18.1.5\"\n        - \"KEYROCK_PORT=3005\"\n        - \"KEYROCK_CLIENT_ID=tutorial-dckr-site-0000-xpresswebapp\"\n        - \"KEYROCK_CLIENT_SECRET=tutorial-dckr-site-0000-clientsecret\"\n        - \"CALLBACK_URL=http://localhost:3000/login\"\n        - \"AUTHZFORCE_ENABLED=true\"\n        - \"AUTHZFORCE_URL=http://authzforce\"\n        - \"AUTHZFORCE_PORT=8080\"\n</code></pre>\n<p>The <code>tutorial</code> container is listening on two ports:</p>\n<ul>\n<li>Port <code>3000</code> is exposed so we can see the web page displaying the Dummy IoT\ndevices.</li>\n<li>Port <code>3001</code> is exposed purely for tutorial access - so that cUrl or Postman\ncan make UltraLight commands without being part of the same network.</li>\n</ul>\n<p>The <code>tutorial</code> container is now secured by <strong>Authforce</strong>, and is driven by\nenvironment variables as shown:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Key</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>AUTHZFORCE_ENABLED</td>\n<td><code>true</code></td>\n<td>Flag to enable use of the XACML PDP</td>\n</tr>\n<tr>\n<td>AUTHZFORCE_URL</td>\n<td><code>http://authzforce</code></td>\n<td>This is URL where the <strong>Authzforce</strong> is found users</td>\n</tr>\n<tr>\n<td>AUTHZFORCE_PORT</td>\n<td><code>8080</code></td>\n<td>Port that <strong>Authzforce</strong> is listening on</td>\n</tr>\n</tbody>\n</table>\n</div><p>The other <code>tutorial</code> container configuration values described in the YAML file\nhave been described in previous tutorials</p>\n<h1 id=\"start-up\">Start Up</h1>\n<p>To start the installation, do the following:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-console\">git clone git@github.com:Fiware/tutorials.XACML-Access-Rules.git\ncd tutorials.XACML-Access-Rules\n\n./services create\n</code></pre>\n<blockquote>\n<p><strong>Note</strong> The initial creation of Docker images can take up to three minutes</p>\n</blockquote>\n<p>Thereafter, all services can be initialized from the command-line by running the\n<a href=\"https://github.com/Fiware/tutorials.XACML-Access-Rules/blob/master/services\">services</a>\nBash script provided within the repository:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-console\">./services start\n</code></pre>\n<blockquote>\n<p>:information_source: <strong>Note:</strong> If you want to clean up and start over again\nyou can do so with the following command:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-console\">./services stop\n</code></pre>\n</blockquote>\n<h3 id=\"dramatis-personae\">Dramatis Personae</h3>\n<p>The following people at <code>test.com</code> legitimately have accounts within the\nApplication</p>\n<ul>\n<li>Alice, she will be the Administrator of the <strong>Keyrock</strong> Application</li>\n<li>Bob, the Regional Manager of the supermarket chain - he has several store\nmanagers under him:<ul>\n<li>Manager1</li>\n<li>Manager2</li>\n</ul>\n</li>\n<li>Charlie, the Head of Security of the supermarket chain - he has several\nstore detectives under him:<ul>\n<li>Detective1</li>\n<li>Detective2</li>\n</ul>\n</li>\n</ul>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Name</th>\n<th>eMail</th>\n<th>Password</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>alice</td>\n<td><a href=\"mailto:alice-the-admin@test.com\">alice-the-admin@test.com</a></td>\n<td><code>test</code></td>\n</tr>\n<tr>\n<td>bob</td>\n<td><a href=\"mailto:bob-the-manager@test.com\">bob-the-manager@test.com</a></td>\n<td><code>test</code></td>\n</tr>\n<tr>\n<td>charlie</td>\n<td><a href=\"mailto:charlie-security@test.com\">charlie-security@test.com</a></td>\n<td><code>test</code></td>\n</tr>\n<tr>\n<td>manager1</td>\n<td><a href=\"mailto:manager1@test.com\">manager1@test.com</a></td>\n<td><code>test</code></td>\n</tr>\n<tr>\n<td>manager2</td>\n<td><a href=\"mailto:manager2@test.com\">manager2@test.com</a></td>\n<td><code>test</code></td>\n</tr>\n<tr>\n<td>detective1</td>\n<td><a href=\"mailto:detective1@test.com\">detective1@test.com</a></td>\n<td><code>test</code></td>\n</tr>\n<tr>\n<td>detective2</td>\n<td><a href=\"mailto:detective2@test.com\">detective2@test.com</a></td>\n<td><code>test</code></td>\n</tr>\n</tbody>\n</table>\n</div><p>The following people at <code>example.com</code> have signed up for accounts, but have no\nreason to be granted access</p>\n<ul>\n<li>Eve - Eve the Eavesdropper</li>\n<li>Mallory - Mallory the malicious attacker</li>\n<li>Rob - Rob the Robber</li>\n</ul>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Name</th>\n<th>eMail</th>\n<th>Password</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>eve</td>\n<td><a href=\"mailto:eve@example.com\">eve@example.com</a></td>\n<td><code>test</code></td>\n</tr>\n<tr>\n<td>mallory</td>\n<td><a href=\"mailto:mallory@example.com\">mallory@example.com</a></td>\n<td><code>test</code></td>\n</tr>\n<tr>\n<td>rob</td>\n<td><a href=\"mailto:rob@example.com\">rob@example.com</a></td>\n<td><code>test</code></td>\n</tr>\n</tbody>\n</table>\n</div></body></html>","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","toc":[{"content":"Ruleset Based Permissions","slug":"ruleset-based-permissions"},{"content":"Prerequisites","slug":"prerequisites"},{"content":"Architecture","slug":"architecture"},{"content":"Start Up","slug":"start-up"}],"owner":"513743","collectionId":"6554748b-8871-4e83-8c4d-7ab315f9894a","publishedId":"RznBPLzn","public":true,"customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"FF7059"},"publishDate":"2020-01-02T11:11:33.000Z"},"item":[{"name":"Reading XACML Access Rules","item":[{"name":"Authzforce - Obtain Version Information","id":"6b8adac5-0ff6-45aa-9818-22db2d27f438","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Accept","value":"application/xml","type":"text"}],"url":"http://localhost:8080/authzforce-ce/version","description":"<p>Once <strong>Authzforce</strong> is running, you can check the status by making an HTTP\nrequest to the exposed administration port (usually <code>8080</code>. If the response is\nblank, this is usually because <strong>Authzforce</strong> is not running or is listening on\nanother port.</p>\n<p>The response returns information about the version of Authzforce.</p>\n","urlObject":{"protocol":"http","path":["authzforce-ce","version"],"host":["localhost:8080"],"query":[],"variable":[]}},"response":[],"_postman_id":"6b8adac5-0ff6-45aa-9818-22db2d27f438"},{"name":"List all domains","id":"6f24ebcf-eaa2-4a7f-815c-f419d9ab97a7","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"http://localhost:8080/authzforce-ce/domains","description":"<p>To request domain information from <strong>Authzforce</strong>, make a request to the\n<code>/authzforce-ce/domains</code> endpoint.</p>\n<p>The response lists the domains which are available in <strong>Authzforce</strong>. This\ncorresponds to the directory structure uploaded to <strong>Authzforce</strong> on start-up.</p>\n","urlObject":{"protocol":"http","path":["authzforce-ce","domains"],"host":["localhost:8080"],"query":[],"variable":[]}},"response":[],"_postman_id":"6f24ebcf-eaa2-4a7f-815c-f419d9ab97a7"},{"name":"Read a single domain","id":"8eba82d9-91bf-4e79-ac0f-66c04f03c229","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"http://localhost:8080/authzforce-ce/domains/gQqnLOnIEeiBFQJCrBIBDA","description":"<p>To read information about a domain, and to explore further, make a request to\nthe <code>authzforce-ce/domains/gQqnLOnIEeiBFQJCrBIBDA</code> endpoint. The following request\nobtains information about the <code>gQqnLOnIEeiBFQJCrBIBDA</code> domain, which has been\ngenerated using using a random key by an external Policy Adminstration Point in\nthis case <strong>Keyrock</strong> has been used as the PAP, and pre-generated the rule sets.</p>\n<p>The response lists more information about the domain, including the id used\nwithin <strong>Keyrock</strong> (<code>tutorial-dckr-site-0000-xpresswebapp</code>)</p>\n","urlObject":{"protocol":"http","path":["authzforce-ce","domains","gQqnLOnIEeiBFQJCrBIBDA"],"host":["localhost:8080"],"query":[],"variable":[]}},"response":[],"_postman_id":"8eba82d9-91bf-4e79-ac0f-66c04f03c229"},{"name":"List all PolicySets available within a Domain","id":"051f9200-52bb-4fa5-ac8a-da515dfc6889","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"http://localhost:8080/authzforce-ce/domains/gQqnLOnIEeiBFQJCrBIBDA/pap/policies","description":"<p>To list the generated ids for all of the PolicySets found within a domain make a\nrequest to the <code>authzforce-ce/domains/gQqnLOnIEeiBFQJCrBIBDA/pap/policies</code> endpoint. The\nfollowing request obtains a list of a given policy ids found within the\n<code>gQqnLOnIEeiBFQJCrBIBDA</code> domain.</p>\n<p>The response returns a list of available revisions of the given policy which are\navailable within. the <strong>Authzforce</strong> container. This corresponds the named XML\nfiles <code>1.xml</code>, <code>2.xml</code> etc.</p>\n","urlObject":{"protocol":"http","path":["authzforce-ce","domains","gQqnLOnIEeiBFQJCrBIBDA","pap","policies"],"host":["localhost:8080"],"query":[],"variable":[]}},"response":[],"_postman_id":"051f9200-52bb-4fa5-ac8a-da515dfc6889"},{"name":"List the available revisions of a PolicySet","id":"9e04e292-b976-4dc5-8f07-37ae25f31f3e","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"http://localhost:8080/authzforce-ce/domains/gQqnLOnIEeiBFQJCrBIBDA/pap/policies/f8194af5-8a07-486a-9581-c1f05d05483c","description":"<p>To list the available revisions of a policy, make a request to the\n<code>authzforce-ce/domains/gQqnLOnIEeiBFQJCrBIBDA/pap/policies/f8194af5-8a07-486a-9581-c1f05d05483c</code> endpoint.\nAvailable policy id are randomly generated, and can be obtained by drilling down\nusing the previous request. The following request obtains a list revision of a\ngiven policy found within the <code>gQqnLOnIEeiBFQJCrBIBDA</code> domain.</p>\n<p>The response returns a list of available revisions of the given policy which are\navailable within the <strong>Authzforce</strong> container. This corresponds the named XML\nfiles <code>1.xml</code>, <code>2.xml</code> etc.</p>\n","urlObject":{"protocol":"http","path":["authzforce-ce","domains","gQqnLOnIEeiBFQJCrBIBDA","pap","policies","f8194af5-8a07-486a-9581-c1f05d05483c"],"host":["localhost:8080"],"query":[],"variable":[]}},"response":[],"_postman_id":"9e04e292-b976-4dc5-8f07-37ae25f31f3e"},{"name":"Read a single version of a PolicySet","id":"042b20b8-93e7-4f01-9e04-246f3719819e","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"http://localhost:8080/authzforce-ce/domains/gQqnLOnIEeiBFQJCrBIBDA/pap/policies/f8194af5-8a07-486a-9581-c1f05d05483c/2","description":"<p>To obtain a single revison of a <code>&lt;PolicySet&gt;</code>, make a request to the\n<code>authzforce-ce/domains/gQqnLOnIEeiBFQJCrBIBDA/pap/policies/f8194af5-8a07-486a-9581-c1f05d05483c/{{revision-number}}</code>\nendpoint. The following request obtains the second revision of the given policy\nfound within the <code>gQqnLOnIEeiBFQJCrBIBDA</code> domain.</p>\n<p>The response contains the full <code>&lt;PolicySet&gt;</code> for the given revision. This is a\ncopy of\n<a href=\"https://github.com/Fiware/tutorials.XACML-Access-Rules/blob/master/authzforce/domains/gQqnLOnIEeiBFQJCrBIBDA/policies/ZjgxOTRhZjUtOGEwNy00ODZhLTk1ODEtYzFmMDVkMDU0ODNj/2.xml\">the file</a>\nheld within <strong>Authzforce</strong>.</p>\n","urlObject":{"protocol":"http","path":["authzforce-ce","domains","gQqnLOnIEeiBFQJCrBIBDA","pap","policies","f8194af5-8a07-486a-9581-c1f05d05483c","2"],"host":["localhost:8080"],"query":[],"variable":[]}},"response":[],"_postman_id":"042b20b8-93e7-4f01-9e04-246f3719819e"}],"id":"34a57f1e-4fbd-4d2f-9c56-c559e278d8bb","description":"<p>A single XACML server can be used to administrate access control policies for\nmultiple applications. <strong>Authzforce</strong> is implicitly multi-tenant, in that it\nallows separate organizations to work on their policies in isolation from one\nanother. This is done by separating the security policies for each application\ninto a separate <strong>domain</strong> where they can access their own <code>&lt;PolicySets&gt;</code>. A\ndomain holds meta data about the secured application along with versions of the\npolicies themselves (effectively a series of files which can be accessed by a\nfile server). The domain management API can be used to query <strong>Authzforce</strong>\nabout the domains served and policies held.</p>\n","event":[{"listen":"prerequest","script":{"id":"a4c41e34-093d-4739-b5e1-13736c5a803c","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"62d13514-54db-4270-a2c2-beed012e7404","type":"text/javascript","exec":[""]}}],"_postman_id":"34a57f1e-4fbd-4d2f-9c56-c559e278d8bb"},{"name":"Requesting Policy Decisions","item":[{"name":"Permit Access to a Resource","id":"b4cbbdc9-18c9-4db9-bf68-602e5c7715da","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/xml","type":"text"}],"body":{"mode":"raw","raw":"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Request xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" CombinedDecision=\"false\" ReturnPolicyIdList=\"false\">\n   <Attributes Category=\"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\">\n      <Attribute AttributeId=\"urn:oasis:names:tc:xacml:2.0:subject:role\" IncludeInResult=\"false\">\n         <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">managers-role-0000-0000-000000000000</AttributeValue>\n      </Attribute>\n   </Attributes>\n   <Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\">\n      <Attribute AttributeId=\"urn:oasis:names:tc:xacml:1.0:resource:resource-id\" IncludeInResult=\"false\">\n         <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">tutorial-dckr-site-0000-xpresswebapp</AttributeValue>\n      </Attribute>\n      <Attribute AttributeId=\"urn:thales:xacml:2.0:resource:sub-resource-id\" IncludeInResult=\"false\">\n         <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">/app/price-change</AttributeValue>\n      </Attribute>\n   </Attributes>\n   <Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:action\">\n      <Attribute AttributeId=\"urn:oasis:names:tc:xacml:1.0:action:action-id\" IncludeInResult=\"false\">\n         <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">GET</AttributeValue>\n      </Attribute>\n   </Attributes>\n   <Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\" />\n</Request>"},"url":"http://localhost:8080/authzforce-ce/domains/gQqnLOnIEeiBFQJCrBIBDA/pdp","description":"<p>To request a decision from Authzforce, make a POST requets to the\n<code>domains/{domain-id}/pdp</code> endpoint. In this case the user has the\n<code>managers-role-0000-0000-000000000000</code> and is requesting access the the\n<code>/app/price-change</code> resource.</p>\n<p>The <code>managers-role-0000-0000-000000000000</code> permits access to the\n<code>/app/price-change</code> endpoint. The response for a successful request includes a\n<code>&lt;Decision&gt;</code> element to <code>Permit</code> access to the resource.</p>\n","urlObject":{"protocol":"http","path":["authzforce-ce","domains","gQqnLOnIEeiBFQJCrBIBDA","pdp"],"host":["localhost:8080"],"query":[],"variable":[]}},"response":[],"_postman_id":"b4cbbdc9-18c9-4db9-bf68-602e5c7715da"},{"name":"Deny Access to a Resource","id":"71a148b9-d998-48f6-ae9b-4a7a0c58552f","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/xml","type":"text"}],"body":{"mode":"raw","raw":"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Request xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" CombinedDecision=\"false\" ReturnPolicyIdList=\"false\">\n   <Attributes Category=\"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\">\n      <Attribute AttributeId=\"urn:oasis:names:tc:xacml:2.0:subject:role\" IncludeInResult=\"false\">\n         <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">security-role-0000-0000-000000000000</AttributeValue>\n      </Attribute>\n   </Attributes>\n   <Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\">\n      <Attribute AttributeId=\"urn:oasis:names:tc:xacml:1.0:resource:resource-id\" IncludeInResult=\"false\">\n         <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">tutorial-dckr-site-0000-xpresswebapp</AttributeValue>\n      </Attribute>\n      <Attribute AttributeId=\"urn:thales:xacml:2.0:resource:sub-resource-id\" IncludeInResult=\"false\">\n         <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">/app/price-change</AttributeValue>\n      </Attribute>\n   </Attributes>\n   <Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:action\">\n      <Attribute AttributeId=\"urn:oasis:names:tc:xacml:1.0:action:action-id\" IncludeInResult=\"false\">\n         <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">GET</AttributeValue>\n      </Attribute>\n   </Attributes>\n   <Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\" />\n</Request>"},"url":"http://localhost:8080/authzforce-ce/domains/gQqnLOnIEeiBFQJCrBIBDA/pdp","description":"<p>To request a decision from Authzforce, make a POST requets to the\n<code>domains/{domain-id}/pdp</code> endpoint. In this case the user has the\n<code>security-role-0000-0000-000000000000</code> and is requesting access the the\n<code>/app/price-change</code> resource.</p>\n<p>The <code>security-role-0000-0000-000000000000</code> does not permit access to the\n<code>/app/price-change</code> endpoint. The response for an unsuccessful request includes\na <code>&lt;Decision&gt;</code> element which will <code>Deny</code> access to the resource.</p>\n","urlObject":{"protocol":"http","path":["authzforce-ce","domains","gQqnLOnIEeiBFQJCrBIBDA","pdp"],"host":["localhost:8080"],"query":[],"variable":[]}},"response":[],"_postman_id":"71a148b9-d998-48f6-ae9b-4a7a0c58552f"}],"id":"08d23e31-e200-47e9-907d-137a1940d550","description":"<p>For the purpose of this tutorial, <strong>Authzforce</strong> has been just been supplied\nwith a simple set of basic role-based rules in a similar fashion to the level 2\nauthorization example found in the previous Securing Access tutorial:</p>\n<ul>\n<li>The unlock door command can only be sent by <strong>Security</strong> staff.</li>\n<li>Access to the price-change and order-stock areas are only available to\n<strong>Managers</strong></li>\n<li>People with either the <strong>Manager</strong> or <strong>Security</strong> role can ring the bell</li>\n<li>Both <strong>Manager</strong> or <strong>Security</strong> can access and interact with the store data</li>\n</ul>\n<p>The only difference is that access to all store entities is now restricted to\nusers with an assigned role rather than being based on level 1 authentication\naccess.</p>\n<p>To request a decision from Authzforce, a structured request containing all\nrelevant information must be sent to the <code>domains/{domain-id}/pdp</code> endpoint. In\nthis case, the Body of the request includes information such as the roles that\nthe User has, the application id that is being requested\n(<code>tutorial-dckr-site-0000-xpresswebapp</code>) and the HTTP verb and resource that are\nbeing requested ( a GET request on the <code>/app/price-change</code> URL). Obviously the\ninformation passed in the Body can be expanded as the rules become more complex.</p>\n","event":[{"listen":"prerequest","script":{"id":"7b40d496-0a0f-424d-a300-d7a4c7946cf7","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"121f1a38-45b2-4245-9fdc-97dfd34c1f5b","type":"text/javascript","exec":[""]}}],"_postman_id":"08d23e31-e200-47e9-907d-137a1940d550"},{"name":"PDP - Advanced Authorization","item":[{"name":"Keyrock - User Obtains an Access Token","id":"bcf98c37-9e73-4ec6-8bbb-2e5e54686af6","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Authorization","value":"Basic dHV0b3JpYWwtZGNrci1zaXRlLTAwMDAteHByZXNzd2ViYXBwOnR1dG9yaWFsLWRja3Itc2l0ZS0wMDAwLWNsaWVudHNlY3JldA==","description":"<p>base64 concatenation of Client Id and Client Secret</p>\n"},{"key":"Content-Type","value":"application/x-www-form-urlencoded"},{"key":"Accept","value":"application/json"}],"body":{"mode":"raw","raw":"username=bob-the-manager@test.com&password=test&grant_type=password"},"url":"http://localhost:3005/oauth2/token","description":"<p>In order to identify themselves, every user must obtain an access token, in\norder to do so, they must use one of the OAuth2 access grants described in a\n<a href=\"https://github.com/Fiware/tutorials.Securing-Access\">previous tutorial</a>.</p>\n<p>To log in using the user-credentials flow send a POST request to the\n<code>oauth2/token</code> endpoint of <strong>Keyrock</strong> with the <code>grant_type=password</code></p>\n<p>The response returns an <code>access_token</code> to identify the user (in this case Bob\nthe Manager)</p>\n","urlObject":{"protocol":"http","path":["oauth2","token"],"host":["localhost:3005"],"query":[],"variable":[]}},"response":[],"_postman_id":"bcf98c37-9e73-4ec6-8bbb-2e5e54686af6"},{"name":"Keyrock - Obtain Roles and Domain","id":"59184bac-1fa0-4fa4-985e-62a707d0c726","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"http://localhost:3005/user?access_token=1b88827586409b3b4dc67378e6b945c99b94c6cf&app_id=tutorial-dckr-site-0000-xpresswebapp&authzforce=true","description":"<p>If a user has logged in, the <code>access_token</code> can be used in combiniation with the <code>/user</code> endpoint\nto obtain access permissions to a resouce. This example retrieves Bobs's permissions to a given\nresource.</p>\n<p>Where :</p>\n<ul>\n<li><code>{{access-token}}</code> is the current access token of a logged in user (e.g.\n<code>08fef363c429cb34cfff3f56dfe751a8d1890690</code>)</li>\n<li><code>tutorial-dckr-site-0000-xpresswebapp</code> holds the application to request\n<code>tutorial-dckr-site-0000-xpresswebapp</code> and <code>authzforce=true</code> indicates that\nwe want to obtain an <strong>Authzforce</strong> Domain from <strong>Keyrock</strong></li>\n</ul>\n<p>The response include an <code>authorization_decision</code> attribute which denies direct\naccess for the request, but includes additional information so that an\nadditional request a decision from <strong>Authzforce</strong></p>\n<p>In the example below the access token used belonged to Bob the manager, and his\nroles and the <code>app_azf_domain</code> associated to the <code>app-id</code> are returned.</p>\n","urlObject":{"protocol":"http","path":["user"],"host":["localhost:3005"],"query":[{"key":"access_token","value":"1b88827586409b3b4dc67378e6b945c99b94c6cf"},{"key":"app_id","value":"tutorial-dckr-site-0000-xpresswebapp"},{"key":"authzforce","value":"true"}],"variable":[]}},"response":[],"_postman_id":"59184bac-1fa0-4fa4-985e-62a707d0c726"},{"name":"Authzforce - Apply a Policy to a Request","id":"d260afa1-4c85-4306-af9a-cf37541dc96b","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/xml","type":"text"}],"body":{"mode":"raw","raw":"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Request xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" CombinedDecision=\"false\" ReturnPolicyIdList=\"false\">\n   <Attributes Category=\"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\">\n      <Attribute AttributeId=\"urn:oasis:names:tc:xacml:2.0:subject:role\" IncludeInResult=\"false\">\n         <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">managers-role-0000-0000-000000000000</AttributeValue>\n      </Attribute>\n   </Attributes>\n   <Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\">\n      <Attribute AttributeId=\"urn:oasis:names:tc:xacml:1.0:resource:resource-id\" IncludeInResult=\"false\">\n         <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">tutorial-dckr-site-0000-xpresswebapp</AttributeValue>\n      </Attribute>\n      <Attribute AttributeId=\"urn:thales:xacml:2.0:resource:sub-resource-id\" IncludeInResult=\"false\">\n         <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">/v2/entities</AttributeValue>\n      </Attribute>\n   </Attributes>\n   <Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:action\">\n      <Attribute AttributeId=\"urn:oasis:names:tc:xacml:1.0:action:action-id\" IncludeInResult=\"false\">\n         <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">POST</AttributeValue>\n      </Attribute>\n   </Attributes>\n   <Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\" />\n</Request>"},"url":"http://localhost:8080/authzforce-ce/domains/gQqnLOnIEeiBFQJCrBIBDA/pdp","description":"<p>To request a decision from Authzforce, a structured request containing all\nrelevant information must be sent to the <code>domains/{domain-id}/pdp</code> endpoint. In\nthis case, the Body of the request includes information such as the roles that\nthe User has (<code>managers-role-0000-0000-000000000000</code>), the application id that\nis being requested (<code>tutorial-dckr-site-0000-xpresswebapp</code>) and the HTTP verb\nand resource that are being requested ( a POST request on the <code>/v2/entities</code>\nURL)</p>\n<p>The response includes a <code>&lt;Decision&gt;</code> element which will either <code>Permit</code> or\n<code>Deny</code> the request.</p>\n","urlObject":{"protocol":"http","path":["authzforce-ce","domains","gQqnLOnIEeiBFQJCrBIBDA","pdp"],"host":["localhost:8080"],"query":[],"variable":[]}},"response":[],"_postman_id":"d260afa1-4c85-4306-af9a-cf37541dc96b"}],"id":"2a70896b-9f08-4b9a-8c83-e4864ccf797b","description":"<p>As a reminder, there are three Levels of PDP Access Control:</p>\n<ul>\n<li>Level 1: Authentication Access - Allow all actions to every signed in user\nand no actions to an anonymous user.</li>\n<li>Level 2: Basic Authorization - Check which resources and verbs the currently\nlogged in user should have access to</li>\n<li>Level 3: Advanced Authorization - Fine grained control through\n<a href=\"https://en.wikipedia.org/wiki/XACML\">XACML</a></li>\n</ul>\n<p>Within FIWARE, Level 3 access control can be provided by adding <strong>Authzforce</strong>\nto the existing security microservices (IDM and PEP Proxy) within the Smart\nApplication infrastructure. Access control levels 1 and 2 have been covered in\n<a href=\"https://github.com/Fiware/tutorials.Securing-Access\">previous tutorials</a> and\ncan be fulfilled using <strong>Keyrock</strong> alone or with or without an associated PEP\nProxy.</p>\n<p>Advanced Authorization is able to deal with complex rulesets. Permissions are no\nlonger merely based on a fixed role, resource and an action, but can be extended\nas necessary.</p>\n<p>For example users in role <code>XXX</code> can access URL <strong>starting with</strong> <code>YYY</code> provided\nthat the HTTP verb <strong>is either</strong> <code>GET</code>, <code>PUT</code> or <code>POST</code>. Such users may also\n<code>DELETE</code> <strong>provided that</strong> they were the creator in the first place.</p>\n<p>Within the tutorial programatic example we are using our own trusted instance of\n<strong>Keyrock</strong> - once a user has signed in and obtained an <code>access_token</code>, the\n<code>access_token</code> can be stored in session and used to retrieve user details on\ndemand. All access to the Orion context broker is hidden behind a PEP Proxy.\nWhenever a request is made to Orion, the <code>access_token</code> is passed in the header\nof the request, and the PEP proxy handles the decision to whether to execute the\nrequest.</p>\n","event":[{"listen":"prerequest","script":{"id":"d0b2c33c-4bd4-4144-b0c4-6ff68f7c4b51","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"1c0f1529-fe24-44cf-a947-6cc4d9132580","type":"text/javascript","exec":[""]}}],"_postman_id":"2a70896b-9f08-4b9a-8c83-e4864ccf797b"},{"name":"Advanced Authorization - Sample Code","item":[],"id":"5c0fb346-ffee-4564-aea1-c77e217ff41f","description":"<p>Programmatically, any Policy Execution Point consists of two parts, an oAuth\nrequest to Keyrock retrieves information about the user (such as the assigned\nroles) as well as the policy domain to be queried.</p>\n<p>A second request is sent to the relevant domain endpoint within Authzforce,\nproviding all of the information necessary for Authzforce to provide a\njudgement. Authzforce responds with a <strong>permit</strong> or <strong>deny</strong> response, and the\ndecision whether to continue can be made thereafter.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-javascript\">function authorizeAdvancedXACML(req, res, next, resource = req.url) {\n    const keyrockUserUrl =\n        \"http://keyrock/user?access_token=\" +\n        req.session.access_token +\n        \"&amp;app_id=\" +\n        clientId +\n        \"&amp;authzforce=true\";\n\n    return oa\n        .get(keyrockUserUrl)\n        .then(response =&gt; {\n            const user = JSON.parse(response);\n            return azf.policyDomainRequest(\n                user.app_azf_domain,\n                user.roles,\n                resource,\n                req.method\n            );\n        })\n        .then(authzforceResponse =&gt; {\n            res.locals.authorized = authzforceResponse === \"Permit\";\n            return next();\n        })\n        .catch(error =&gt; {\n            debug(error);\n            res.locals.authorized = false;\n            return next();\n        });\n}\n</code></pre>\n<p>The full code to supply each request to Authzforce can be found within the\ntutorials'\n<a href=\"https://github.com/Fiware/tutorials.Step-by-Step/blob/master/context-provider/lib/azf.js\">Git Repository</a> -\nthe actual information to supply will depend on business use case - it could be\nexpanded to include temporal information, relationships between records and so\non, but in this very simple example only roles are necessary.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-javascript\">const xml2js = require(\"xml2js\");\nconst request = require(\"request\");\n\nfunction policyDomainRequest(domain, roles, resource, action) {\n    let body =\n        '&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\\n' +\n        '&lt;Request xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\" CombinedDecision=\"false\" ReturnPolicyIdList=\"false\"&gt;\\n';\n    // Code to create the XML body for the request is omitted\n    body = body + \"&lt;/Request&gt;\";\n\n    const options = {\n        method: \"POST\",\n        url: \"http://authzforceUrl/authzforce-ce/domains/\" + domain + \"/pdp\",\n        headers: { \"Content-Type\": \"application/xml\" },\n        body\n    };\n\n    return new Promise((resolve, reject) =&gt; {\n        request(options, function(error, response, body) {\n            let decision;\n            xml2js.parseString(\n                body,\n                { tagNameProcessors: [xml2js.processors.stripPrefix] },\n                function(err, jsonRes) {\n                    // The decision is found within the /Response/Result[0]/Decision[0] XPath\n                    decision = jsonRes.Response.Result[0].Decision[0];\n                }\n            );\n            decision = String(decision);\n            return error ? reject(error) : resolve(decision);\n        });\n    });\n}\n</code></pre>\n<h3 id=\"advanced-authorization---pep-proxy\">Advanced Authorization - PEP Proxy</h3>\n<p>Applying advanced authorization within a PEP proxy requires very similar code to\nthe programmatic example described above. The <strong>Wilma</strong> generic enabler extracts\na token from the header supplied by the request and makes a request to\n<strong>Keyrock</strong> to obtain further information about the user. A PDP request is then\nmade to <strong>Authzforce</strong> to decide whether to procede.</p>\n<p>Obviously any scalable solution should also cache information about the PDP\nrequests made and the responses to avoid making unnecessary requests.</p>\n<h2 id=\"pdp---advanced-authorization---running-the-example\">PDP - Advanced Authorization - Running the Example</h2>\n<blockquote>\n<p><strong>Note</strong> Five resources have been secured at level 3:</p>\n<ul>\n<li>sending the unlock door command</li>\n<li>sending the ring bell command</li>\n<li>access to the price-change area</li>\n<li>access to the order-stock area</li>\n<li>access to Orion (behind a PEP Proxy)</li>\n</ul>\n</blockquote>\n<h4 id=\"eve-the-eavesdropper\">Eve the Eavesdropper</h4>\n<p>Eve has an account, but no roles in the application.</p>\n<blockquote>\n<p><strong>Note</strong> As Eve has a recognized account, she gains full authentication\naccess. This means she is able to <em>view</em> the Store page, even though her\naccount has no roles attached.</p>\n</blockquote>\n<ul>\n<li>From <code>http://localhost:3000</code>, log in as <code>eve@example.com</code> with the password\n<code>test</code></li>\n</ul>\n<h5 id=\"level-3--advanced-authorization-access\">Level 3 : Advanced Authorization Access</h5>\n<ul>\n<li><p>Click on any store page - access to view the page is <strong>permitted</strong> for any\nlogged in users, however access to retrieve Orion data is now <strong>denied</strong>\nsince Eve has no role which permits access.</p>\n</li>\n<li><p>Click on the restricted access links at <code>http://localhost:3000</code> - access is\n<strong>denied</strong></p>\n</li>\n<li><p>Open the Device Monitor on <code>http://localhost:3000/device/monitor</code></p>\n<ul>\n<li>Unlock a door - access is <strong>denied</strong></li>\n<li>Ring a bell - access is <strong>denied</strong></li>\n</ul>\n</li>\n</ul>\n<h4 id=\"bob-the-regional-manager\">Bob The Regional Manager</h4>\n<p>Bob has the <strong>management</strong> role</p>\n<ul>\n<li>From <code>http://localhost:3000</code>, log in as <code>bob-the-manager@test.com</code> with the\npassword <code>test</code></li>\n</ul>\n<h5 id=\"level-3--advanced-authorization-access-1\">Level 3 : Advanced Authorization Access</h5>\n<ul>\n<li>Click on the restricted access links at <code>http://localhost:3000</code> - access is\n<strong>permitted</strong> - This is a management only permission</li>\n<li>Open the Device Monitor on <code>http://localhost:3000/device/monitor</code><ul>\n<li>Unlock a door - access is <strong>denied</strong>. - This is a security only\npermission</li>\n<li>Ring a bell - access is <strong>permitted</strong> - This is permitted to management\nusers</li>\n</ul>\n</li>\n</ul>\n<h4 id=\"charlie-the-security-manager\">Charlie the Security Manager</h4>\n<p>Charlie has the <strong>security</strong> role</p>\n<ul>\n<li>From <code>http://localhost:3000</code>, log in as <code>charlie-security@test.com</code> with the\npassword <code>test</code></li>\n</ul>\n<h5 id=\"level-3-advanced-authorization-access\">Level 3: Advanced Authorization Access</h5>\n<ul>\n<li>Click on the restricted access links at <code>http://localhost:3000</code> - access is\n<strong>denied</strong> - This is a management only permission</li>\n<li>Open the Device Monitor on <code>http://localhost:3000/device/monitor</code><ul>\n<li>Unlock a door - access is <strong>permitted</strong> - This is a security only\npermission</li>\n<li>Ring a bell - access is <strong>permitted</strong> - This is permitted to security\nusers</li>\n</ul>\n</li>\n</ul>\n","_postman_id":"5c0fb346-ffee-4564-aea1-c77e217ff41f"}],"event":[{"listen":"prerequest","script":{"id":"bf821021-7bc2-471e-9ab7-a55ecb9e663f","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"1269e342-1093-4844-83cb-f8fed192c512","type":"text/javascript","exec":[""]}}],"variable":[{"key":"authzforce","value":"localhost:8080"},{"key":"keyrock","value":"localhost:3005"},{"key":"domain-id","value":"gQqnLOnIEeiBFQJCrBIBDA"},{"key":"policy-id","value":"f8194af5-8a07-486a-9581-c1f05d05483c"},{"key":"Authorization","value":"dHV0b3JpYWwtZGNrci1zaXRlLTAwMDAteHByZXNzd2ViYXBwOnR1dG9yaWFsLWRja3Itc2l0ZS0wMDAwLWNsaWVudHNlY3JldA=="},{"key":"access-token-bob","value":"1b88827586409b3b4dc67378e6b945c99b94c6cf"},{"key":"app-id","value":"tutorial-dckr-site-0000-xpresswebapp"}]}