diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000..8eb1db97e3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,51 @@
+# Intellij
+###################
+.idea
+*.iml
+
+# Eclipse #
+###########
+.project
+.settings
+.classpath
+
+# NetBeans #
+############
+nbactions.xml
+nb-configuration.xml
+catalog.xml
+
+# Compiled source #
+###################
+*.com
+*.class
+*.dll
+*.exe
+*.o
+*.so
+
+# Packages #
+############
+# it's better to unpack these files and commit the raw source
+# git has its own built in compression methods
+*.7z
+*.dmg
+*.gz
+*.iso
+*.jar
+*.rar
+*.tar
+*.zip
+
+# Logs and databases #
+######################
+*.log
+
+# Maven #
+#########
+target
+
+# Git Book #
+############
+_book/
+node_modules/
\ No newline at end of file
diff --git a/README.adoc b/README.adoc
index 46693e172d..03484e99f5 100755
--- a/README.adoc
+++ b/README.adoc
@@ -1,4 +1,3 @@
-
Keycloak Authorization Services Guide
======================
diff --git a/SUMMARY.adoc b/SUMMARY.adoc
index 199115c391..4d143a7fcc 100755
--- a/SUMMARY.adoc
+++ b/SUMMARY.adoc
@@ -1,3 +1,34 @@
= {{book.title}}
- . link:topics/preface.adoc[Preface]
+ . link:topics/overview/overview.adoc[Overview]
+ .. link:topics/overview/architecture.adoc[Architecture]
+ .. link:topics/overview/terminology.adoc[Terminology]
+ . link:topics/resource-server/overview.adoc[Managing Resource Servers]
+ .. link:topics/resource-server/view.adoc[Viewing Resource Servers]
+ .. link:topics/resource-server/create.adoc[Creating Resource Servers]
+ ... link:topics/resource-server/uma-protection-scope.adoc[Defining uma_protection scope]
+ ... link:topics/resource-server/uma-authz-entitlement-scope.adoc[Defining uma_authorization and kc_entitlement scopes]
+ .. link:topics/resource-server/policy-enforcement-mode.adoc[Policy Enforcement Modes]
+ .. link:topics/resource-server/configuring-entitlements.adoc[Configuring Entitlements]
+ .. link:topics/resource-server/import-export-configuration.adoc[Import/Export Authorization Configuration]
+ . link:topics/resource/overview.adoc[Managing Resources and Scopes]
+ . link:topics/permission/overview.adoc[Managing Permissions]
+ .. link:topics/permission/view.adoc[Viewing Permissions]
+ .. link:topics/permission/create-resource.adoc[Creating Resource-based Permissions]
+ .. link:topics/permission/create-scope.adoc[Creating Scope-based Permissions]
+ .. link:topics/permission/policy-decision-strategy.adoc[Policy Decision Strategies]
+ . link:topics/policy/overview.adoc[Managing Policies]
+ .. link:topics/policy/view.adoc[Viewing Policies]
+ .. link:topics/policy/aggregated-policy.adoc[Aggregated Policy]
+ .. link:topics/policy/logic.adoc[Positive and Negative Logic]
+ .. link:topics/policy/evaluation-api.adoc[Policy Evaluation API]
+ . link:topics/policy-evaluation-tool/overview.adoc[Evaluating and Testing Policies]
+ . link:topics/service/overview.adoc[Authorization Services]
+ .. link:topics/service/protection-api.adoc[The Protection API]
+ .. link:topics/service/authorization-api.adoc[The Authorization API]
+ .. link:topics/service/entitlement-api.adoc[The Entitlement API]
+ . link:topics/enforcer/overview.adoc[Policy Enforcers]
+ .. link:topics/enforcer/jaxrs-enforcer.adoc[JAX-RS Policy Enforcer]
+ .. link:topics/enforcer/servlet-enforcer.adoc[Servlet Policy Enforcer]
+ .. link:topics/enforcer/client-api.adoc[Using the Authorization Client API]
+ . link:topics/example/overview.adoc[Examples]
\ No newline at end of file
diff --git a/book.json b/book.json
index 9fa460ddae..46e39298d6 100755
--- a/book.json
+++ b/book.json
@@ -15,7 +15,8 @@
"images": "keycloak-images",
"project": {
"name": "Keycloak",
- "version": "1.9.3.Final-SNAPSHOT"
+ "version": "1.9.3.Final-SNAPSHOT",
+ "module": "Authorization Services"
}
}
}
diff --git a/images/authz-arch-overview.png b/images/authz-arch-overview.png
new file mode 100644
index 0000000000..0a29424860
Binary files /dev/null and b/images/authz-arch-overview.png differ
diff --git a/topics/enforcer/client-api.adoc b/topics/enforcer/client-api.adoc
new file mode 100755
index 0000000000..84cff32f74
--- /dev/null
+++ b/topics/enforcer/client-api.adoc
@@ -0,0 +1 @@
+== Authorization Client API
\ No newline at end of file
diff --git a/topics/enforcer/jaxrs-enforcer.adoc b/topics/enforcer/jaxrs-enforcer.adoc
new file mode 100755
index 0000000000..503f2ba8f9
--- /dev/null
+++ b/topics/enforcer/jaxrs-enforcer.adoc
@@ -0,0 +1 @@
+== JAX-RS Policy Enforcer
\ No newline at end of file
diff --git a/topics/enforcer/overview.adoc b/topics/enforcer/overview.adoc
new file mode 100755
index 0000000000..68f4036058
--- /dev/null
+++ b/topics/enforcer/overview.adoc
@@ -0,0 +1 @@
+== Policy Enforcers
\ No newline at end of file
diff --git a/topics/enforcer/servlet-enforcer.adoc b/topics/enforcer/servlet-enforcer.adoc
new file mode 100755
index 0000000000..fab0b5bba2
--- /dev/null
+++ b/topics/enforcer/servlet-enforcer.adoc
@@ -0,0 +1 @@
+== Servlet Policy Enforcer
\ No newline at end of file
diff --git a/topics/example/overview.adoc b/topics/example/overview.adoc
new file mode 100755
index 0000000000..4488a0c1b4
--- /dev/null
+++ b/topics/example/overview.adoc
@@ -0,0 +1,5 @@
+== Examples
+
+We provide a few examples about how to use the {{book.project.name}} {{book.project.module}}. These examples are very useful to understand the concepts here introduced.
+
+The examples are located at *examples/authz*. They contain a README.md file with more details about how to build and deploy them.
\ No newline at end of file
diff --git a/topics/overview/architecture.adoc b/topics/overview/architecture.adoc
new file mode 100755
index 0000000000..1028581ff3
--- /dev/null
+++ b/topics/overview/architecture.adoc
@@ -0,0 +1,31 @@
+== Architecture
+
+image:../../images/authz-arch-overview.png[alt="Keycloak AuthZ Architecture Overview"]
+
+From a design perspective, the {{book.project.module}} are based on a well defined set of authorization patterns providing a:
+
+* **Policy Administration Point (PAP)**
++
+Provides a set of UIs based on the Keycloak Administration Console to manage resource servers, resources, scopes, permissions and policies.
+Part of this also accomplished remotely through the use of the link:../service/protection-api.html[Protection API].
++
+
+* **Policy Decision Point (PDP)**
++
+Provides a distributable policy decision point, where authorization requests are sent to and policies are evaluated accordingly with the permissions being requested. Part of this also accomplished remotely through the use of the
+link:../service/authorization-api.html[Authorization] and link:../service/entitlement-api.html[Entitlement] APIs.
++
+
+* **Policy Enforcement Point (PEP)**
++
+Provides implementations for different environments to actually enforce authorization decisions on the resource server side.
+Keycloak provides some built-in link:../enforcer/overview.html[Policy Enforcers].
++
+
+* **Policy Information Point (PIP)**
++
+Being based on {{book.project.name}} Authentication Server, you can obtain attributes from identities and from the runtime environment.
+
+Instead of doing authorization by your own, {{book.project.name}} provides a centralized but still distributable server
+to govern protected resources and their respective policies within an application or organization using some well-known authorization patterns and standards such as
+_OAuth2_ and https://docs.kantarainitiative.org/uma/rec-uma-core.html[User-Managed Access (UMA)].
\ No newline at end of file
diff --git a/topics/overview/overview.adoc b/topics/overview/overview.adoc
new file mode 100755
index 0000000000..af86f51de5
--- /dev/null
+++ b/topics/overview/overview.adoc
@@ -0,0 +1,28 @@
+== Overview
+
+{{book.project.name}} supports fine-grained permissions and policies with a mix and match of different access control
+mechanisms such as:
+
+* **Attribute-based Access Control**
+* **Role-based Access Control**
+* **User-based Access Control**
+* **Context-based Access Control**
+* **Rule-based Access Control**
+ ** Using Javascript
+ ** Using JBoss Drools
+* **Support for custom ACMs through a Policy Provider SPI**
+
+Being based on a set of administrative UIs and a RESTful API, {{book.project.name}} provides the necessary means to create permissions
+for your protected resources and scopes, associate these permissions with authorization policies and enforce authorization
+decisions in your application and services.
+
+Considering that today we need to consider a very heterogeneous environment, where users are distributed across different regions, with different local policies,
+using different devices and with a high demand for information sharing, Keycloak Authorization Services can be used as great tool to:
+
+* Control your protected resources and the actions that can be performed on them
+* Centralized Policy Management
+* Resource Management
+* Auditing
+* Authorization Workflows and User-Managed Access
+* Avoid code replication across projects
+* Avoid redeploys of your applications when your security requirements need to change thus the permissions and policies associated with your protected resources
\ No newline at end of file
diff --git a/topics/overview/terminology.adoc b/topics/overview/terminology.adoc
new file mode 100755
index 0000000000..c92ff2eb3c
--- /dev/null
+++ b/topics/overview/terminology.adoc
@@ -0,0 +1,106 @@
+== Terminology
+
+Before going further, it is important to understand some terms and concepts introduced with {{book.project.name}} {{book.project.module}}.
+
+==== Resource Server
+
+If you are familiar with OAuth2, a Resource Server is the server hosting the protected resources, capable of accepting
+and responding to protected resource requests.
+
+Resource servers usually rely on some kind of information to decide whether access to a protected resource should be granted or not. For RESTful-based resource servers,
+that information is usually obtained from a security token, usually sent as a bearer token on every single request to the server. For web applications that rely on a session to
+authenticate their users, that information is usually stored into user's session and retrieved from there on every single request.
+
+In Keycloak, any *confidential* client application may act as a resource server. Whose resources and their respective scopes are
+protected and ruled by a set of authorization policies.
+
+==== Resource Server
+
+A resource is part of the assets of an application and the organization. It may be a single API
+endpoint, a set of API endpoints, a classic web resource such as an HTML page, and so on.
+In authorization policy terminology, a resource is the _object_ being protected.
+
+Every single resource has a unique identifier, where a resource may also be used to represent a single
+or a set of resources. For instance, you may want to manage a _Banking Account Resource_ that represents and defines a set of authorization policies for all banking accounts.
+But you may also have a _Alice Banking Account_, which represents a single resource owned by a single customer, which may have its own set of authorization policies.
+
+In {{book.project.name}}, a resource defines a small set of information that is common to different types of resources, such as:
+
+* *Name*
++
+A human-readable and unique string describing a set of one or more resources.
++
+* *Type*
++
+A string uniquely identifying the type of a set of one or more resources. Usually, the type is a URN that can be used to
+group different resource instances.
++
+* *URI*
++
+A URI that provides the location/address for the resource. For HTTP resources, the URI
+is usually the relative path used to serve these resources.
++
+* *Scopes*
++
+A bounded extent of access that is possible to perform on a resource. In authorization
+policy terminology, a scope is one of the potentially many verbs that can logically
+apply to a resource.
++
+* *Owner*
++
+An entity that owns the resource. It can be the resource server itself or even a
+specific user.
+
+==== Scope
+
+A bounded extent of access that is possible to perform on a resource. In authorization policy
+terminology, a scope is one of the potentially many _verbs_ that can logically apply to a resource.
+
+Usually, a scope is defined as a URN that indicates what can be done with a given resource. Example of scopes are _urn:domain:resource:scope:view_,
+_urn:domain:scopes:admin:manage_, etc.
+
+Scopes have a small set of information as follows:
+
+* *Name*
++
+A human-readable and unique string describing the scope.
+
+A single scope may be associated with zero or more resources.
+
+==== Permission
+
+A permission associates the object being protected and the policies that must be evaluated in order to decide whether access should be granted or not.
+
+In {{book.project.name}}, a permission can be defined for a:
+
+* *Resource*
++
+In this case, the permission is associated with a set of one or more resources. Here you can define that only a specific
+resource with a specific _name_ or _identifier_ is protected or even use a _type_ to protect any resource with a given type.
+
+
+* *Scope*
++
+In this case, the permission is associated with a set of one or more scopes. Where you may want to protect scopes associated with a
+specific resource or any scope regardless the resources they are associated.
+
+When associating policies to permissions, you can also define the _decision strategy_ that will be used during the evaluation of these
+policies in order to decide whether a permission is granted or not depending on the outcome of each associated policy.
+
+==== Policy
+
+A policy defines the conditions that must be satisfied to grant access to an object. Different than permissions, you don't really specify the object being protected
+but the conditions that must be satisfied to get access to a given object (eg.: resource, scope or both).
+Policies are strongly related with the different _access control mechanism_ that you can use to actually protect your resources.
+Within a policy you can use ABAC, RBAC, Context-based Access Control or any combination of these.
+
+Keycloak leverages the concept of policies and how you define them by providing the concept of *Aggregated Policies*, where you can build a "policy of policies" and still control the behavior of the evaluation.
+Instead of writing a single and huge policy with all conditions that must be satisfied to get access to a given resource, policies in Keycloak follows the *divide-and-conquer* technique,
+so you can create individual policies, reuse them on different permissions and build more complex policies by combining them into a single one.
+
+==== Policy Provider
+
+Policy providers are responsible to support a specific policy type. Although {{book.project.name}} provides some built-in policies, backed by their corresponding
+policy providers, nothing stops you to create your own policy types in order to better support your requirements or a specific use case.
+
+{{book.project.name}} provides a *SPI* (Service Provider Interface) that you can use to plug your own policy providers.
\ No newline at end of file
diff --git a/topics/permission/create-resource.adoc b/topics/permission/create-resource.adoc
new file mode 100755
index 0000000000..8b5ce2fe54
--- /dev/null
+++ b/topics/permission/create-resource.adoc
@@ -0,0 +1,3 @@
+== Creating Resource-based Permissions
+
+You can create permissions by selecting which type of permission you want to create: resource or scope.
\ No newline at end of file
diff --git a/topics/permission/create-scope.adoc b/topics/permission/create-scope.adoc
new file mode 100755
index 0000000000..9bb832de3a
--- /dev/null
+++ b/topics/permission/create-scope.adoc
@@ -0,0 +1,3 @@
+== Creating Scope-based Permissions
+
+You can create permissions by selecting which type of permission you want to create: resource or scope.
\ No newline at end of file
diff --git a/topics/permission/overview.adoc b/topics/permission/overview.adoc
new file mode 100755
index 0000000000..0e7497c934
--- /dev/null
+++ b/topics/permission/overview.adoc
@@ -0,0 +1,19 @@
+== Managing Permissions
+
+As mentioned before, permissions define the object being protected, which can be a resource or scope, and the authorization policies
+that must be evaluated in order to grant or deny the permission. Before creating a permission you must have the resources or scopes you want to protected, as well the policies you want to apply to the permission.
+
+Permissions can be created to protect two main types of objects: *resource* and *scope*.
+
+* *Resource*
++
+In this case, the permission is associated with a set of one or more resources. Here you can define that only a specific
+resource with a specific _name_ or _identifier_ is protected or even use a _type_ to protect any resource with a given type.
++
+* *Scope*
++
+In this case, the permission is associated with a set of one or more scopes. Where you may want to protect scopes associated with a specific resource or any scope regardless the resources they are associated.
+
+*Resource-based* permissions are suitable for resource protection. There you you can define one or more resources to protect or even protect all resources with a given type.
+
+*Scope-based* permissions are suitable for scope protection. There you you can define one or more scopes associated with a given resource or even protect scopes without specify a resource.
\ No newline at end of file
diff --git a/topics/permission/policy-decision-strategy.adoc b/topics/permission/policy-decision-strategy.adoc
new file mode 100755
index 0000000000..5931fac430
--- /dev/null
+++ b/topics/permission/policy-decision-strategy.adoc
@@ -0,0 +1,15 @@
+== Policy Decision Strategies
+
+When associating policies to a permission, you may also define a decision strategy to decide how the outcome from the associated policies should be interpreted to build a final decision.
+
+* *Unanimous*
++
+This is the default strategy if none is provided. In this case, _all_ policies must evaluate to a positive decision in order to the final decision be also positive.
++
+* *Affirmative*
++
+In this case, _at least one_ policy must evaluate to a positive decision in order to the final decision be also positive.
++
+* *Consensus*
++
+In this case, the number of positive decisions must be greater than the number of negative decisions. If the number of positive and negative decisions is the same, the final decision will be negative.
\ No newline at end of file
diff --git a/topics/permission/view.adoc b/topics/permission/view.adoc
new file mode 100755
index 0000000000..c25ac471ac
--- /dev/null
+++ b/topics/permission/view.adoc
@@ -0,0 +1,4 @@
+== Viewing Permissions
+
+You can view all permissions associated with a resource server by clicking on the *Permission* tab when editing a resource server. On this tab, you'll find the list of permissions
+and options to create and edit a permission.
\ No newline at end of file
diff --git a/topics/policy-evaluation-tool/overview.adoc b/topics/policy-evaluation-tool/overview.adoc
new file mode 100755
index 0000000000..25b6b3cf61
--- /dev/null
+++ b/topics/policy-evaluation-tool/overview.adoc
@@ -0,0 +1,5 @@
+== Policy Evaluation Tool
+
+When designing your policies, you can use a UI to simulate authorization requests and check how your policies are being evaluated.
+
+The Policy Evaluation Tool can be accessed by clicking the *Evaluate* tab when editing a resource server. There you may provide different inputs to simulate real authorization requests and check the effect of your policies.
\ No newline at end of file
diff --git a/topics/policy/aggregated-policy.adoc b/topics/policy/aggregated-policy.adoc
new file mode 100755
index 0000000000..438a2b63de
--- /dev/null
+++ b/topics/policy/aggregated-policy.adoc
@@ -0,0 +1,30 @@
+== Aggregated Policies
+
+As mentioned before, Keycloak allows you to build a policy of policies, a concept that we call *Aggregated Policies*. Policy aggregation allows you to reuse existing policies to build more complex ones and keep your permissions even more decoupled from the
+policies that are actually evaluated during the processing of authorization requests.
+
+Let's suppose you have a resource called _Confidential Resource_ that can be accessed only by users with a _confidential_ role and from
+a well known network. You may want to create a single policy, let's say using Javascript or Drools, with both conditions. However, you may want to reuse the _confidential_ role
+part of this policy to apply to other permissions despite the network.
+
+In this case, Keycloak allows you to create separate policies for both _confidential_ role and network conditions and create another one based on
+them. You can easily achieve that by using a *Aggregate Policy* that combines other policies and then apply this aggregate policy to any permission you want.
+
+[NOTE]
+When creating aggregated policies, make sure you don't introduce a circular reference/dependency between policies. If you do so, Keycloak will not let you create or update the policy.
+
+=== Decision Strategy for Aggregated Policies
+
+When creating aggregated policies, you can also define the decision strategy that will be used during to calculate the final decision based on the outcome from each policy.
+
+* *Unanimous*
++
+This is the default strategy if none is provided. In this case, _all_ policies must evaluate to a positive decision in order to the final decision be also positive.
++
+* *Affirmative*
++
+In this case, _at least one_ policy must evaluate to a positive decision in order to the final decision be also positive.
++
+* *Consensus*
++
+In this case, the number of positive decisions must be greater than the number of negative decisions. If the number of positive and negative decisions is the same, the final decision will be negative.
\ No newline at end of file
diff --git a/topics/policy/evaluation-api.adoc b/topics/policy/evaluation-api.adoc
new file mode 100755
index 0000000000..349ed946ac
--- /dev/null
+++ b/topics/policy/evaluation-api.adoc
@@ -0,0 +1,42 @@
+== Evaluation API
+
+When writing rule-based policies such as when you are using Javascript or JBoss Drools, Keycloak provides an *Evaluation API* from where you
+can obtain useful information.
+
+This API consists of a few interfaces that provides you access to information such as:
+
+* Information about the identity asking for a permission. Here you can obtain the identity identifier (eg.: username) or any other claim/attribute about it.
+* Information about the runtime environment and any other attribute associated with the execution context.
+
+The main interface is *org.keycloak.authorization.policy.evaluation.Evaluation*, which defines the following contract:
+
+```java
+public interface Evaluation {
+
+ /**
+ * Returns the {@link ResourcePermission} to be evaluated.
+ *
+ * @return the permission to be evaluated
+ */
+ ResourcePermission getPermission();
+
+ /**
+ * Returns the {@link EvaluationContext}. Which provides access to the whole evaluation runtime context.
+ *
+ * @return the evaluation context
+ */
+ EvaluationContext getContext();
+
+ /**
+ * Grants the requested permission to the caller.
+ */
+ void grant();
+
+ /**
+ * Denies the requested permission.
+ */
+ void deny();
+}
+```
+
+For full instructions on using the Evaluation API refer to JavaDocs.
\ No newline at end of file
diff --git a/topics/policy/logic.adoc b/topics/policy/logic.adoc
new file mode 100644
index 0000000000..158de20ff3
--- /dev/null
+++ b/topics/policy/logic.adoc
@@ -0,0 +1,7 @@
+== Positive and Negative Logic
+
+Policies may be configured with a *Positive* or *Negative* logic. In a nutshell, this option allows you to define whether the policy result should be kept as it is or be negated.
+
+For instance, suppose you want to create a policy where only users *not* granted with a specific role should be allowed to do something. In this case,
+you may create a _Role-based Policy_ using that role and set its *Logic* field to *Negative*. If you keep *Positive*, which
+is the default behavior, the policy result will be kept as it is.
\ No newline at end of file
diff --git a/topics/policy/overview.adoc b/topics/policy/overview.adoc
new file mode 100755
index 0000000000..2fa8b684b5
--- /dev/null
+++ b/topics/policy/overview.adoc
@@ -0,0 +1,31 @@
+== Managing Policies
+
+As mentioned before, policies define the conditions that must satisfied before granting access to a set of one or more resources.
+
+Keycloak provides some built-in implementations that you can use to create from the most simple to the more complex policy using different access control mechanisms.
+
+* *User-Based Policy*
++
+Defines that only a set of one or more users are allowed to access a protected resource.
++
+* *Role-Based Policy*
++
+Defines that only a set of one or more roles are allowed to access a protected resource.
++
+* *Time-Based Policy*
+Defines that access to a protected resource is granted depending on time conditions.
++
+* *Javascript-Based Policy*
++
+A type of rule-based access control where you can use Javascript to write the policy conditions. With this policy
+you have great flexibility to define from the more simple to most complex conditions.
++
+* *Drools-Based Policy*
++
+A type of rule-based access control where you can use JBoss Drools to define your policies. Here you can package policies as Maven artifacts
+and get all the benefits of the rule engine provided by JBoss Drools.
++
+* *Aggregated Policy*
++
+Allows you to combine different policies into a single one. With this policy you can reuse existing policies and derive policies from them
+accordingly with your requirements.
\ No newline at end of file
diff --git a/topics/policy/view.adoc b/topics/policy/view.adoc
new file mode 100755
index 0000000000..6accb51b3f
--- /dev/null
+++ b/topics/policy/view.adoc
@@ -0,0 +1,4 @@
+== Viewing Policies
+
+You can view all policies associated with a resource server by clicking on the *Policy* tab when editing a resource server. On this tab, you'll find the list of policies
+and options to create and edit a policy.
\ No newline at end of file
diff --git a/topics/preface.adoc b/topics/preface.adoc
deleted file mode 100755
index 860e9fd39f..0000000000
--- a/topics/preface.adoc
+++ /dev/null
@@ -1,20 +0,0 @@
-== Preface
-
-In some of the example listings, what is meant to be displayed on one line does not fit inside the available page width.These lines have been broken up. A '\' at the end of a line means that a break has been introduced to fit in the page, with the following lines indented.
-So:
-
-[source]
-----
-Let's pretend to have an extremely \
-long line that \
-does not fit
-This one is short
-----
-Is really:
-
-[source]
-----
-Let's pretend to have an extremely long line that does not fit
-This one is short
-----
-
diff --git a/topics/resource-server/configuring-entitlements.adoc b/topics/resource-server/configuring-entitlements.adoc
new file mode 100755
index 0000000000..f78904f2ee
--- /dev/null
+++ b/topics/resource-server/configuring-entitlements.adoc
@@ -0,0 +1,6 @@
+== Configuring Entitlements
+
+Entitlements are very useful when you want to obtain all permissions for a specific user based on the resources managed by a resource server.
+More on link:../service/entitlement-api.html[Entitlements] and link:../service/authorization-api.html[Incremental Authorization] later.
+
+When configuring a resource server you may enable/disable entitlements by clicking the *Entitlements* switch.
\ No newline at end of file
diff --git a/topics/resource-server/create.adoc b/topics/resource-server/create.adoc
new file mode 100755
index 0000000000..409331bc84
--- /dev/null
+++ b/topics/resource-server/create.adoc
@@ -0,0 +1,18 @@
+== Creating Resource Servers
+
+As mentioned before, everything is based on the existence of a resource server. And a resource server is basically a
+*confidential* client application in {{book.project.name}}.
+
+To enable a client application as a resource server you need to make sure:
+
+* Your client application is configured as a *confidential* client.
+* Your client application is configured with *Service Accounts*.
+
+The reason why you need to use a confidential client and enable client credentials is that resource servers must be able to access the
+_Protection API_ to manage their resources and issue _Permission Tickets_ for their clients. More about permission tickets later.
+
+In {{book.project.name}} Administration Console, resource servers can be managed by clicking the _Authorization_ menu item on the left side menu. There you have a
+list of any existing resource server and options to create a new one.
+
+When creating a new resource server, you just need to select a client application from the _Client_ combobox. There are a few other configuration
+options that you can provide, but the defaults should be enough to get started.
\ No newline at end of file
diff --git a/topics/resource-server/import-export-configuration.adoc b/topics/resource-server/import-export-configuration.adoc
new file mode 100755
index 0000000000..5639a59f77
--- /dev/null
+++ b/topics/resource-server/import-export-configuration.adoc
@@ -0,0 +1,7 @@
+== Import/Export Authorization Configuration
+
+Keycloak also allows you to import a JSON file with all the configuration for a resource server, as well export and download a JSON file with all the configuration
+of an existing resource server.
+
+When you import or export the configuration for a given resource server, you are doing it for all authorization configuration associated with it: resources, scopes, permissions,
+policies, etc.
\ No newline at end of file
diff --git a/topics/resource-server/overview.adoc b/topics/resource-server/overview.adoc
new file mode 100755
index 0000000000..6bb146e1ad
--- /dev/null
+++ b/topics/resource-server/overview.adoc
@@ -0,0 +1,3 @@
+== Managing Resource Servers
+
+This section describes the administration functions for managing resource servers.
\ No newline at end of file
diff --git a/topics/resource-server/policy-enforcement-mode.adoc b/topics/resource-server/policy-enforcement-mode.adoc
new file mode 100755
index 0000000000..7cdfbcd37f
--- /dev/null
+++ b/topics/resource-server/policy-enforcement-mode.adoc
@@ -0,0 +1,14 @@
+== Policy Enforcement Modes
+
+Resource servers provide a *Policy Enforcement Mode* configuration option that dictates how policies are enforced when processing authorization requests sent to the server.
+
+* *Enforcing*
++
+This is the default mode. Requests are denied by default even when there is no policy associated with a given resource.
++
+* *Permissive*
++
+Requests are allowed even when there is no policy associated with a given resource.
+* *Disabled*
++
+Completely disables the evaluation of policies and allow access to any resource.
\ No newline at end of file
diff --git a/topics/resource-server/uma-authz-entitlement-scope.adoc b/topics/resource-server/uma-authz-entitlement-scope.adoc
new file mode 100755
index 0000000000..091dd9d9d2
--- /dev/null
+++ b/topics/resource-server/uma-authz-entitlement-scope.adoc
@@ -0,0 +1,14 @@
+== Defining uma_authorization and kc_entitlement scopes
+
+In order to allow client applications to obtain authorization tokens from the server, you need to create two roles:
+
+* *uma_authorization*
++
+This role grants access to client application to ask the server for authorization tokens.
+
+* *kc_entitlement*
++
+This role grants access to client application to ask the server for entitlements.
+
+Once they are created for a client application, you must associate these roles with your users. These steps are necessary to tell Keycloak
+that the client application is allowed to obtain authorization data on behalf of your users.
\ No newline at end of file
diff --git a/topics/resource-server/uma-protection-scope.adoc b/topics/resource-server/uma-protection-scope.adoc
new file mode 100755
index 0000000000..fb09af81a8
--- /dev/null
+++ b/topics/resource-server/uma-protection-scope.adoc
@@ -0,0 +1,5 @@
+== Defining uma_protection scope
+
+As mentioned before, resource servers must have access to the *Protection API* to manage their resources and issue *Permission Tickets*.
+
+For that, you must create a _realm role_ with name *uma_protection* and map this role to the client application that you want to configure as a resource server.
\ No newline at end of file
diff --git a/topics/resource-server/view.adoc b/topics/resource-server/view.adoc
new file mode 100755
index 0000000000..de66d79f4f
--- /dev/null
+++ b/topics/resource-server/view.adoc
@@ -0,0 +1,2 @@
+== Viewing Resource Servers
+
diff --git a/topics/resource/overview.adoc b/topics/resource/overview.adoc
new file mode 100755
index 0000000000..9b09751019
--- /dev/null
+++ b/topics/resource/overview.adoc
@@ -0,0 +1,14 @@
+== Managing Resources and Scopes
+
+After creating a resource server, you can start creating resources - and their respective scopes - that you want to protect. Resources and scopes can be managed
+by clicking on the *Resource* and *Scope* tabs, respectively.
+
+Resource management is pretty straight forward and generic. The main thing you should care about is the granularity of the resources you create. In other words, resources can
+be created to represent a set of one or more resources and the way you define them is crucial to start managing permissions.
+
+Resources also have an owner. By default, resources created from the adminstration console are owned by the resource server itself. However, resources can also be associated with your users, so you can
+create permissions based on the resource owner. For instance, only the resource owner is allowed to delete or update a given resource.
+
+Resource management is also exposed through the *Protection API* to allow resource servers to remotely manage their resources. This is a very important
+feature that allows resource servers to obtain the list of protected resources in order to actually enforce the authorization decisions. We'll see more on that
+later when we talk about _Policy Enforcers_.
\ No newline at end of file
diff --git a/topics/service/authorization-api.adoc b/topics/service/authorization-api.adoc
new file mode 100755
index 0000000000..9e745b19e3
--- /dev/null
+++ b/topics/service/authorization-api.adoc
@@ -0,0 +1,57 @@
+== Authorization API
+
+The Authorization API consists of a single endpoint responsible to issue a special type of token with all the requested permissions given
+a permission ticket and a OAuth2 access_token.
+
+```bash
+curl -X POST -H "Authorization: Bearer ${access_token}" -H "Content-Type: application/json" -d '{
+ "ticket": "${permission_ticket}"
+}' "http://localhost:8080/auth/realms/photoz/authz/authorize"
+```
+
+As mentioned before, the permission ticket contains the resources and scopes the client is requesting access. Based on it, the authorization endpoint is going
+to evaluate all the policies associated with these resources and scopes and return back a final token with all the granted permissions.
+
+```json
+{
+ "permissions": [
+ {
+ "resource_set_id": "87852cb2-700f-45d1-a9ab-786564aa123a",
+ "scopes": [
+ "urn:photoz.com:scopes:album:view",
+ "urn:photoz.com:scopes:album:create"
+ ]
+ },
+ {
+ "resource_set_id": "fe372a25-65ef-4140-926c-96d9523ee40b",
+ "scopes": [
+ "urn:photoz.com:scopes:profile:view"
+ ]
+ }
+ ],
+ "accessToken": "eyJhbGciOiJSUzI1NiJ9.eyJqdGkiOiJmOTNlMjhjOC1kMDIzLTRhMTQtYjViZS03NGY0ZjljMjI2NmYiLCJleHAiOjE0NjA0ODg1MDcsIm5iZiI6MCwiaWF0IjoxNDYwNDg4NDQ3LCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvcGhvdG96IiwiYXVkIjoicGhvdG96LWh0bWw1LWNsaWVudCIsInN1YiI6ImJkMzBlNDA5LTM4YjItNDM5Yy1iOTdlLTFhYzk0MzE2YWRmMCIsInR5cCI6IkJlYXJlciIsImF6cCI6InBob3Rvei1odG1sNS1jbGllbnQiLCJub25jZSI6IjkzY2JlMjA2LTg4Y2UtNGMxNi04NGEzLWE0NWMzNzNkY2FjNSIsInNlc3Npb25fc3RhdGUiOiI3NmQwYTdlMi03YWY0LTQ3NmYtOTZlZS1kMjE1NjQ0ZTIxOTIiLCJjbGllbnRfc2Vzc2lvbiI6IjRjMDZkZTZjLTkyZGUtNGIzYi04MGZhLWIzMjZiNjYyMWIwNyIsImFsbG93ZWQtb3JpZ2lucyI6WyIiXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbInVzZXIiXX0sInJlc291cmNlX2FjY2VzcyI6eyJwaG90b3otaHRtbDUtY2xpZW50Ijp7InJvbGVzIjpbImtjX2VudGl0bGVtZW50IiwidW1hX2F1dGhvcml6YXRpb24iXX19LCJuYW1lIjoiQWxpY2UgSW4gQ2hhaW5zIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiYWxpY2UiLCJnaXZlbl9uYW1lIjoiQWxpY2UiLCJmYW1pbHlfbmFtZSI6IkluIENoYWlucyIsImVtYWlsIjoiYWxpY2VAa2V5Y2xvYWsub3JnIn0.Bllirh-Lr9Q1hgMIZGzT1gR0uVPGhby5L92B6zSu4Zj22UMMV_JlxR-2l7lI5qHYdMgUhm2vdLKZ0axhSKT63OUsWV1cN6exkNAUcjfS3sCJIEljUAmDDh-2pw3f6oE5l7llHzatNH8VNqbZs-Z6TXj2fyrta-fUyu6IDgCaKoQ",
+ "jti": "0975d59a-4550-45a4-a535-6d520b1ffa77-1460488455577",
+ "exp": 1460488507,
+ "nbf": 0,
+ "iat": 1460488447,
+ "sub": "bd30e409-38b2-439c-b97e-1ac94316adf0",
+ "typ": "kc_ett",
+ "azp": "photoz-html5-client"
+}
+```
+
+Following the UMA specification, this token is called Requesting Party Token or just RPT. With a RPT, a client
+can send this token as a bearer token to a resource server, which in turn will introspect the RPT sent by the client and check if the resource the client
+is trying to access can be mapped to the any permission within the RPT.
+
+When asking for RPTs using the Authorization API, the corresponding access_token must contain a uma_authorization scope. In other words, the client asking for
+RPTs on behalf of an user must be granted with this scope.
+
+=== Incremental Authorization
+
+As mentioned before, when asking for a RPT you must send a permission ticket and a OAuth2 access_token. However, accordingly
+with UMA specification, you may also send some previous (and still valid) RPT. In this case, the resulting RPT will consist of all permissions being requested within the
+permission ticket plus those that are present on a previous RPT.
+
+That process is what we call incremental authorization, given that the final RPT consists of permissions previously granted (based on the previous RPT) and the new permissions
+from a permission ticket.
\ No newline at end of file
diff --git a/topics/service/entitlement-api.adoc b/topics/service/entitlement-api.adoc
new file mode 100755
index 0000000000..faf372bd2e
--- /dev/null
+++ b/topics/service/entitlement-api.adoc
@@ -0,0 +1,20 @@
+== Entitlements API
+
+An entitlement in the context of an access control decision is a privilege for an user or a process to
+perform or have rights to an action on a resource. The concept is pretty much similar to what we were calling a permission.
+
+However, the Entitlements API allows you to obtain all the entitlements or permissions given an OAuth2 _access_token_. Different
+than the Authorization API, which is strongly based on UMA, this API provides a more simple way to obtain the permissions for a given user
+or entity in possession of a OAuth2 _access_token.
+
+In this case, {{book.project.name}} will evaluate policies associated with any resource within a resource server and return the permissions that were granted during this process.
+
+```bash
+curl -X GET -H "Authorization: Bearer ${access_token}" "http://localhost:8080/auth/realms/photoz/authz/entitlement?resourceServerId=photoz-restful-api"
+```
+
+The resulting token from a "entitlements request" is the same when you are using the Authorization API. At end you will get a RPT with all the permissions
+or entitlements for a given user.
+
+When asking for entitlements, the corresponding _access_token_ must contain a *kc_entitlement* scope. In other words, the client asking for
+entitlements on behalf of an user must be granted with this scope.
\ No newline at end of file
diff --git a/topics/service/overview.adoc b/topics/service/overview.adoc
new file mode 100755
index 0000000000..84a826728b
--- /dev/null
+++ b/topics/service/overview.adoc
@@ -0,0 +1,11 @@
+== Authorization Services
+
+Keycloak Authorization Services are based on OAuth2 and User-Managed Access (UMA). Where the latter is basically a OAuth2 profile
+that defines new terms, tokens and flows in order to define how resource owners can control protected-resource access by clients operated
+by arbitrary requesting parties, where the resources reside on any number of resource servers, and where a centralized authorization server governs access based on resource owner policies.
+
+However, our implementation of UMA is limited to provide a protocol to enable clients and resource servers to obtain and exchange permissions for their users. In the future,
+we are planning to also support other functionalities and flows provided with UMA such as authorization flows and resource owner's resource sharing. In other words, for now our focus
+is API security and for that UMA provides a very simple and easy-to-use extension to OAuth2 to support fine-grained authorization.
+
+That said, we strongly recommend you to take a look at https://docs.kantarainitiative.org/uma/rec-uma-core.html[UMA specification].
\ No newline at end of file
diff --git a/topics/service/protection-api.adoc b/topics/service/protection-api.adoc
new file mode 100755
index 0000000000..0707028b00
--- /dev/null
+++ b/topics/service/protection-api.adoc
@@ -0,0 +1,40 @@
+== Protection API
+
+The Protection API consists of set of endpoints responsible to:
+
+* *Resource Registration*
++
+From this endpoint resource servers can manage their resources and perform operations such as create, update, remove and searches.
+
+* *Permission Registation*
++
+From this endpoint, resource servers may ask the server for a permission ticket that in turn will be sent to a client in order to obtain a final token with all the permissions for a given user.
+
+When accessing the Protection API the client application acting as a resource server must be able to obtain an access token from the Keycloak Server.
+With this token, the resource server is allowed to invoke the protection endpoints and perform any operation. Beside that, they need to be granted with a
+*uma_protection* role. If none of these conditions are met, access to the Protection API is denied.
+
+=== Permission Ticket
+
+As mentioned before, one of the main services provided by the Protection API is related with issuing _permission tickets_.
+
+A permission ticket is a special type of the token introduced with UMA that provides a "correlation handle that is conveyed from an authorization server to a resource server,
+from a resource server to a client, and ultimately from a client back to an authorization server, to enable the authorization server to assess the correct policies to apply to a request for authorization data".
+
+It completely hides from clients the permissions required to access a set of one or more resources at the resource server and allows the authorization server to introduce another security layer that manages
+permissions requests to a resource server and its resources. For instance, in the future we are planning to support authorization workflows where an user can control his resources and approve permission requests
+from others to access his resources (resource sharing).
+
+Permission tickets can be obtained by a resource server as follows:
+
+```bash
+curl -X POST -H "Authorization: Bearer ${access_token}" -d '{
+"resource_set_id": "53fe1824-9d8b-4c8d-a03d-c9547318cdf2",
+"scopes": [
+"urn:photoz.com:scopes:album:view"
+]
+}' "http://localhost:8080/auth/realms/photoz/authz/protection/permission"
+```
+
+As mentioned before, the _access_token_ sent with the request above was issued to the resource server using client credentials. Where the access_token
+also include a *uma_protection* scope.
\ No newline at end of file