[[_policy_js]] = JavaScript-Based Policy You can use this type of policy to define conditions for your permissions using JavaScript. It is one of the rule-based policy types supported by {project_name}, and provides flexibility to write any policy based on the <<_policy_evaluation_api, Evaluation API>>. To create a new JavaScript-based policy, select *JavaScript* in the dropdown list in the upper right corner of the policy listing. NOTE: By default, JavaScript Policies can not be uploaded to the server. You should prefer deploying your JS Policies directly to the server as described in link:{developerguide_jsproviders_link}[{developerguide_jsproviders_name}]. If you still want to use the {project_name} Administration Console to manage your JS policies you should enable the `Upload Scripts` feature. .Add JavaScript Policy image:{project_images}/policy/create-js.png[alt="Add JavaScript Policy"] == Configuration * *Name* + A human-readable and unique string describing the policy. A best practice is to use names that are closely related to your business and security requirements, so you can identify them more easily. + * *Description* + A string containing details about this policy. + * *Code* + The JavaScript code providing the conditions for this policy. + * *Logic* + The <<_policy_logic, Logic>> of this policy to apply after the other conditions have been evaluated. == Creating a JS Policy from a Deployed JAR File {project_name} allows you to deploy a JAR file in order to deploy scripts to the server. Please, take a look at link:{developerguide_jsproviders_link}[{developerguide_jsproviders_name}] for more details. Once you have your scripts deployed, you should be able to select the scripts you deployed from the list of available policy providers. == Examples === Checking for attributes from the evaluation context Here is a simple example of a JavaScript-based policy that uses attribute-based access control (ABAC) to define a condition based on an attribute obtained from the execution context: ```javascript var context = $evaluation.getContext(); var contextAttributes = context.getAttributes(); if (contextAttributes.containsValue('kc.client.network.ip_address', '127.0.0.1')) { $evaluation.grant(); } ``` === Checking for attributes from the current identity Here is a simple example of a JavaScript-based policy that uses attribute-based access control (ABAC) to define a condition based on an attribute obtained associated with the current identity: ```javascript var context = $evaluation.getContext(); var identity = context.getIdentity(); var attributes = identity.getAttributes(); var email = attributes.getValue('email').asString(0); if (email.endsWith('@keycloak.org')) { $evaluation.grant(); } ``` Where these attributes are mapped from whatever claim is defined in the token that was used in the authorization request. === Checking for roles granted to the current identity You can also use Role-Based Access Control (RBAC) in your policies. In the example below, we check if a user is granted with a `keycloak_user` *realm* role: ```javascript var context = $evaluation.getContext(); var identity = context.getIdentity(); if (identity.hasRealmRole('keycloak_user')) { $evaluation.grant(); } ``` Or you can check if a user is granted with a `my-client-role` *client* role, where `my-client` is the client id of the client application: ```javascript var context = $evaluation.getContext(); var identity = context.getIdentity(); if (identity.hasClientRole('my-client', 'my-client-role')) { $evaluation.grant(); } ``` === Checking for roles granted to an user To check for realm roles granted to an user: ```javascript var realm = $evaluation.getRealm(); if (realm.isUserInRealmRole('marta', 'role-a')) { $evaluation.grant(); } ``` Or for client roles granted to an user: ```javascript var realm = $evaluation.getRealm(); if (realm.isUserInClientRole('marta', 'my-client', 'some-client-role')) { $evaluation.grant(); } ``` === Checking for roles granted to a group To check for realm roles granted to a group: ```javascript var realm = $evaluation.getRealm(); if (realm.isGroupInRole('/Group A/Group D', 'role-a')) { $evaluation.grant(); } ``` === Pushing arbitrary claims to the resource server To push arbitrary claims to the resource server in order to provide additional information on how permissions should be enforced: ```javascript var permission = $evaluation.getPermission(); // decide if permission should be granted if (granted) { permission.addClaim('claim-a', 'claim-a'); permission.addClaim('claim-a', 'claim-a1'); permission.addClaim('claim-b', 'claim-b'); } ``` === Checking for group membership ```javascript var realm = $evaluation.getRealm(); if (realm.isUserInGroup('marta', '/Group A/Group B')) { $evaluation.grant(); } ``` === Mixing different access control mechanisms You can also use a combination of several access control mechanisms. The example below shows how roles(RBAC) and claims/attributes(ABAC) checks can be used within the same policy. In this case we check if user is granted with `admin` role or has an e-mail from `keycloak.org` domain: ```javascript var context = $evaluation.getContext(); var identity = context.getIdentity(); var attributes = identity.getAttributes(); var email = attributes.getValue('email').asString(0); if (identity.hasRealmRole('admin') || email.endsWith('@keycloak.org')) { $evaluation.grant(); } ``` NOTE: When writing your own rules, keep in mind that the *$evaluation* object is an object implementing *org.keycloak.authorization.policy.evaluation.Evaluation*. For more information about what you can access from this interface, see the <<_policy_evaluation_api, Evaluation API>>.