Repository: mrparkers/terraform-provider-keycloak
Pull request #242 (2020-03-03 06:12:05)

WIP: Add client scope mapping of roles between clients
Hey @mrparkers, thanks for creating and maintaining this provider. It's great to see such activity and collaboration.

I am planning a Keycloak deploy and am trying to provision it using terraform and this provider. A use case I have is [mapping roles between clients](https://www.keycloak.org/docs-api/5.0/rest-api/index.html#_scope_mappings_resource).

This is my first time with keycloak and golang so I'm submitting a WIP just to be sure I am on the right track. Please let me know if you would prefer the implementation another way.

- [x] Implement `create`, `read`, `delete` resources (`update` is not needed)
- [x] Test coverage
- [X] ~Update docs with new resource~ Add example

I went with the following structure for the resource. I didn't use an array of roles as I thought that might add complexity for roles from different parent clients:

```
resource "keycloak_generic_client_role_mapper" "role_mapping" {
  realm_id  = "${keycloak_realm.realm.id}"
  client_id = "${keycloak_openid_client.client.id}"
  role_id   = "${keycloak_role.role.id}"
}
```

Any direction before I wrap up the docs and tests would be great

mrparkers: The code looks good so far.  My only thought for you is that the provider already supports the [`keycloak_openid_hardcoded_role_protocol_mapper`](https://mrparkers.github.io/terraform-provider-keycloak/resources/keycloak_openid_hardcoded_role_protocol_mapper/) resource that allows you to map roles to clients using a protocol mapper.

I am not really sure if this solves the same problem as the resource you're suggesting, which appears to use the same API as the "Scopes" tab on the client interface.

In any case, I don't have a problem with merging this PR, I'd just like you to add some tests and some example HCL within the `example/main.tf` file.  Adding docs would also be super helpful but I don't typically require that from new contributors.

Thanks for the PR!
mukuru-shaun: Awesome, glad it's on the right track. The difference with the hardcoded mapper is that the role then **will** come back in the token for your client.
If you use the scope mapping like this proposal the user also needs to have the role assigned to them in order to get the role. So if you get the role back in the token you can be sure the user can access that role and not just that the client can access the role.

I will get the tests and docs sorted asap. Thanks again for being so active and welcoming to contributions 🙇 

Patch:
diff --git a/.circleci/config.yml b/.circleci/config.yml
index db8e072..fa9f6b5 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -27,6 +27,7 @@ defaults:
     - image: circleci/golang:1.13.5
 
   keycloak_env: &keycloak_env
+    command: ["-b", "0.0.0.0", "-Dkeycloak.profile.feature.upload_scripts=enabled"]
     environment:
       DB_VENDOR: H2
       KEYCLOAK_LOGLEVEL: DEBUG
@@ -67,6 +68,7 @@ jobs:
         <<: *keycloak_env
     <<: *testacc_job
 
+
   test-8.0.1:
     docker:
       - <<: *go_image
@@ -74,6 +76,7 @@ jobs:
         <<: *keycloak_env
     <<: *testacc_job
 
+
   build-and-release:
     docker:
       - <<: *go_image
diff --git a/docker-compose.yml b/docker-compose.yml
index afe716b..ea5ced0 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -17,7 +17,8 @@ services:
     ports:
     - 8389:389
   keycloak:
-    image: jboss/keycloak:8.0.1
+    image:  jboss/keycloak:8.0.1
+    command: -b 0.0.0.0 -Dkeycloak.profile.feature.upload_scripts=enabled
     depends_on:
     - postgres
     - openldap
@@ -35,3 +36,4 @@ services:
     - 8080:8080
     volumes:
     - ./custom-user-federation-example/build/libs:/opt/jboss/keycloak/providers/
+
diff --git a/docs/resources/keycloak_authentication_execution_config.md b/docs/resources/keycloak_authentication_execution_config.md
new file mode 100644
index 0000000..ce47731
--- /dev/null
+++ b/docs/resources/keycloak_authentication_execution_config.md
@@ -0,0 +1,53 @@
+# keycloak_authentication_execution_config
+
+Allows for managing an authentication execution configuration.
+
+### Example Usage
+
+```hcl
+resource "keycloak_realm" "realm" {
+	realm   = "my-realm"
+	enabled = true
+}
+
+resource "keycloak_authentication_flow" "flow" {
+	realm_id = "${keycloak_realm.realm.id}"
+	alias    = "my-flow-alias"
+}
+
+resource "keycloak_authentication_execution" "execution" {
+	realm_id          = "${keycloak_realm.realm.id}"
+	parent_flow_alias = "${keycloak_authentication_flow.flow.alias}"
+	authenticator     = "identity-provider-redirector"
+}
+
+resource "keycloak_authentication_execution_config" "config" {
+	realm_id     = "${keycloak_realm.realm.id}"
+	execution_id = "${keycloak_authentication_execution.execution.id}"
+	alias        = "my-config-alias"
+	config = {
+		defaultProvider = "my-config-default-idp"
+	}
+}
+```
+
+### Argument Reference
+
+The following arguments are supported:
+
+- `realm_id` - (Required) The realm the authentication execution exists in.
+- `execution_id` - (Required) The authentication execution this configuration is attached to.
+- `alias` - (Required) The name of the configuration.
+- `config` - (Optional) The configuration. Keys are specific to each configurable authentication execution and not checked when applying.
+
+### Import
+
+Configurations can be imported using the format `{{realm}}/{{authenticationExecutionId}}/{{authenticationExecutionConfigId}}`.
+If the `authenticationExecutionId` is incorrect, the import will still be successful.
+A subsequent apply will change the `authenticationExecutionId` to the correct one, which causes the configuration to be replaced.
+
+Example:
+
+```bash
+$ terraform import keycloak_authentication_execution_config.config my-realm/be081463-ddbf-4b42-9eff-9c97886f24ff/30559fcf-6fb8-45ea-8c46-2b86f46ebc17
+```
diff --git a/example/client_authorization_policys.tf b/example/client_authorization_policys.tf
new file mode 100644
index 0000000..b269fc2
--- /dev/null
+++ b/example/client_authorization_policys.tf
@@ -0,0 +1,174 @@
+resource keycloak_realm_authorization test {
+  realm                = "%s"
+  enabled              = true
+  display_name         = "foo"
+  account_theme        = "base"
+  access_code_lifespan = "30m"
+}
+
+resource keycloak_openid_client_authorization_authorization test {
+  client_id                = "test-openid-client"
+  name                     = "test-openid-client"
+  realm_id                 = "${keycloak_realm_authorization.test.id}"
+  description              = "a test openid client"
+  standard_flow_enabled    = true
+  service_accounts_enabled = true
+  access_type              = "CONFIDENTIAL"
+  client_secret            = "secret"
+  valid_redirect_uris = [
+    "http://localhost:5555/callback",
+  ]
+  authorization {
+    policy_enforcement_mode = "ENFORCING"
+  }
+}
+
+# 
+# create aggregate_policy
+# 
+
+resource keycloak_role_aggregate test {
+  realm_id = "${keycloak_realm_authorization.test.id}"
+  name     = "aggregate_policy_role"
+}
+
+resource keycloak_openid_client_authorization_role_policy test {
+  resource_server_id = "${keycloak_openid_client_authorization.test.resource_server_id}"
+  realm_id           = "${keycloak_realm_authorization.test.id}"
+  name               = "keycloak_openid_client_authorization_role_policy"
+  decision_strategy  = "UNANIMOUS"
+  logic              = "POSITIVE"
+  type               = "role"
+  role {
+    id       = "${keycloak_role_aggregate.test.id}"
+    required = false
+  }
+}
+
+resource keycloak_openid_client_authorization_aggregate_policy test {
+  resource_server_id = "${keycloak_openid_client_authorization.test.resource_server_id}"
+  realm_id           = "${keycloak_realm_authorization.test.id}"
+  name               = "keycloak_openid_client_authorization_aggregate_policy"
+  decision_strategy  = "UNANIMOUS"
+  logic              = "POSITIVE"
+  policies           = ["${keycloak_openid_client_authorization_role_policy.test.id}"]
+}
+
+# 
+# create client policy 
+# 
+
+resource keycloak_openid_client_authorization_client_policy test {
+  resource_server_id = "${keycloak_openid_client_authorization.test.resource_server_id}"
+  realm_id           = "${keycloak_realm_authorization.test.id}"
+  name               = "keycloak_openid_client_authorization_client_policy"
+  decision_strategy  = "AFFIRMATIVE"
+  logic              = "POSITIVE"
+  clients            = ["${keycloak_openid_client_authorization.test.resource_server_id}"]
+}
+
+# 
+# create group policy
+# 
+
+resource keycloak_group test {
+  realm_id = "${keycloak_realm_authorization.test.id}"
+  name     = "foo"
+}
+
+resource keycloak_openid_client_authorization_group_policy test {
+  resource_server_id = "${keycloak_openid_client_authorization.test.resource_server_id}"
+  realm_id           = "${keycloak_realm_authorization.test.id}"
+  name               = "client_group_policy_test"
+  groups {
+    id              = "${keycloak_group.test.id}"
+    path            = "${keycloak_group.test.path}"
+    extend_children = false
+  }
+  logic             = "POSITIVE"
+  decision_strategy = "UNANIMOUS"
+}
+
+
+# 
+# create JS policy
+# 
+
+resource keycloak_openid_client_authorization_js_policy test {
+  resource_server_id = "${keycloak_openid_client_authorization.test.resource_server_id}"
+  realm_id           = "${keycloak_realm_authorization.test.id}"
+  name               = "client_js_policy_test"
+  logic              = "POSITIVE"
+  decision_strategy  = "UNANIMOUS"
+  code               = "test"
+  description        = "description"
+}
+
+
+# 
+#  create role policy
+# 
+
+resource keycloak_role test {
+  realm_id = "${keycloak_realm_authorization.test.id}"
+  name     = "new_role"
+}
+
+resource keycloak_openid_client_authorization_role_policy test {
+  resource_server_id = "${keycloak_openid_client_authorization.test.resource_server_id}"
+  realm_id           = "${keycloak_realm_authorization.test.id}"
+  name               = "keycloak_openid_client_authorization_role_policy"
+  decision_strategy  = "AFFIRMATIVE"
+  logic              = "POSITIVE"
+  type               = "role"
+  role {
+    id       = "${keycloak_role.test.id}"
+    required = false
+  }
+}
+
+# 
+# create time policy
+# 
+
+resource keycloak_openid_client_authorization_time_policy test {
+  resource_server_id = "${keycloak_openid_client_authorization.test.resource_server_id}"
+  realm_id           = "${keycloak_realm_authorization.test.id}"
+  name               = "%s"
+  not_on_or_after    = "2500-12-12 01:01:11"
+  not_before         = "2400-12-12 01:01:11"
+  day_month          = "1"
+  day_month_end      = "2"
+  year               = "2500"
+  year_end           = "2501"
+  month              = "1"
+  month_end          = "5"
+  hour               = "1"
+  hour_end           = "5"
+  minute             = "10"
+  minute_end         = "30"
+  logic              = "POSITIVE"
+  decision_strategy  = "UNANIMOUS"
+}
+
+# 
+# create user policy
+# 
+
+resource keycloak_user test {
+  realm_id = "${keycloak_realm_authorization.test.id}"
+  username = "test-user"
+
+  email      = "test-user@fakedomain.com"
+  first_name = "Testy"
+  last_name  = "Tester"
+}
+
+resource keycloak_openid_client_authorization_user_policy test {
+  resource_server_id = "${keycloak_openid_client_authorization.test.resource_server_id}"
+  realm_id           = "${keycloak_realm_authorization.test.id}"
+  name               = "client_user_policy_test"
+  users              = ["${keycloak_user.test.id}"]
+  logic              = "POSITIVE"
+  decision_strategy  = "UNANIMOUS"
+}
diff --git a/example/main.tf b/example/main.tf
index 5b1cefd..40a4981 100644
--- a/example/main.tf
+++ b/example/main.tf
@@ -714,3 +714,12 @@ resource "keycloak_authentication_execution" "browser-copy-otp" {
   requirement = "REQUIRED"
   depends_on = ["keycloak_authentication_execution.browser-copy-auth-username-password-form"]
 }
+
+resource "keycloak_authentication_execution_config" "config" {
+  realm_id     = "${keycloak_realm.test.id}"
+  execution_id = "${keycloak_authentication_execution.browser-copy-idp-redirect.id}"
+  alias        = "idp-XXX-config"
+  config = {
+    defaultProvider = "idp-XXX"
+  }
+}
diff --git a/example/roles.tf b/example/roles.tf
index da847d6..1056194 100644
--- a/example/roles.tf
+++ b/example/roles.tf
@@ -96,6 +96,13 @@ resource "keycloak_openid_hardcoded_role_protocol_mapper" "pet_app_pet_api_read_
   role_id = "${keycloak_role.pet_api_read_pet.id}"
 }
 
+// Map a role from the "pet_api" api client to the "pet_app" consumer client
+resource "keycloak_generic_client_role_mapper" "pet_app_pet_api_read_role_mapping" {
+  realm_id  = "${keycloak_realm.roles_example.id}"
+  client_id = "${keycloak_openid_client.pet_app.id}"
+  role_id   = "${keycloak_role.pet_api_read_pet.id}"
+}
+
 // Users and groups
 
 resource "keycloak_group" "pet_api_base" {
diff --git a/keycloak/authentication_execution_config.go b/keycloak/authentication_execution_config.go
new file mode 100644
index 0000000..8966c1b
--- /dev/null
+++ b/keycloak/authentication_execution_config.go
@@ -0,0 +1,38 @@
+package keycloak
+
+import (
+	"fmt"
+)
+
+// https://www.keycloak.org/docs-api/8.0/rest-api/index.html#_authenticatorconfigrepresentation
+type AuthenticationExecutionConfig struct {
+	RealmId     string            `json:"-"`
+	ExecutionId string            `json:"-"`
+	Id          string            `json:"id"`
+	Alias       string            `json:"alias"`
+	Config      map[string]string `json:"config"`
+}
+
+// https://www.keycloak.org/docs-api/8.0/rest-api/index.html#_newexecutionconfig
+func (keycloakClient *KeycloakClient) NewAuthenticationExecutionConfig(config *AuthenticationExecutionConfig) (string, error) {
+	_, location, err := keycloakClient.post(fmt.Sprintf("/realms/%s/authentication/executions/%s/config", config.RealmId, config.ExecutionId), config)
+	if err != nil {
+		return "", err
+	}
+	return getIdFromLocationHeader(location), nil
+}
+
+// https://www.keycloak.org/docs-api/8.0/rest-api/index.html#_getauthenticatorconfig
+func (keycloakClient *KeycloakClient) GetAuthenticationExecutionConfig(config *AuthenticationExecutionConfig) error {
+	return keycloakClient.get(fmt.Sprintf("/realms/%s/authentication/config/%s", config.RealmId, config.Id), config, nil)
+}
+
+// https://www.keycloak.org/docs-api/8.0/rest-api/index.html#_updateauthenticatorconfig
+func (keycloakClient *KeycloakClient) UpdateAuthenticationExecutionConfig(config *AuthenticationExecutionConfig) error {
+	return keycloakClient.put(fmt.Sprintf("/realms/%s/authentication/config/%s", config.RealmId, config.Id), config)
+}
+
+// https://www.keycloak.org/docs-api/8.0/rest-api/index.html#_removeauthenticatorconfig
+func (keycloakClient *KeycloakClient) DeleteAuthenticationExecutionConfig(config *AuthenticationExecutionConfig) error {
+	return keycloakClient.delete(fmt.Sprintf("/realms/%s/authentication/config/%s", config.RealmId, config.Id), nil)
+}
diff --git a/keycloak/generic_client.go b/keycloak/generic_client.go
index 6e63028..1694253 100644
--- a/keycloak/generic_client.go
+++ b/keycloak/generic_client.go
@@ -28,6 +28,19 @@ func (keycloakClient *KeycloakClient) listGenericClients(realmId string) ([]*Gen
 	return clients, nil
 }
 
+func (keycloakClient *KeycloakClient) GetGenericClient(realmId, id string) (*GenericClient, error) {
+	var client GenericClient
+
+	err := keycloakClient.get(fmt.Sprintf("/realms/%s/clients/%s", realmId, id), &client, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	client.RealmId = realmId
+
+	return &client, nil
+}
+
 func (keycloakClient *KeycloakClient) GetGenericClientByClientId(realmId, clientId string) (*GenericClient, error) {
 	var clients []GenericClient
 
diff --git a/keycloak/keycloak_client.go b/keycloak/keycloak_client.go
index a1013c2..fce3701 100644
--- a/keycloak/keycloak_client.go
+++ b/keycloak/keycloak_client.go
@@ -6,7 +6,6 @@ import (
 	"crypto/x509"
 	"encoding/json"
 	"fmt"
-	"golang.org/x/net/publicsuffix"
 	"io"
 	"io/ioutil"
 	"log"
@@ -16,6 +15,8 @@ import (
 	"net/url"
 	"strings"
 	"time"
+
+	"golang.org/x/net/publicsuffix"
 )
 
 type KeycloakClient struct {
diff --git a/keycloak/openid_client_authorization_aggregate_policy.go b/keycloak/openid_client_authorization_aggregate_policy.go
new file mode 100644
index 0000000..e2acc7b
--- /dev/null
+++ b/keycloak/openid_client_authorization_aggregate_policy.go
@@ -0,0 +1,68 @@
+package keycloak
+
+import (
+	"encoding/json"
+	"fmt"
+)
+
+type OpenidClientAuthorizationAggregatePolicy struct {
+	Id               string   `json:"id,omitempty"`
+	RealmId          string   `json:"-"`
+	ResourceServerId string   `json:"-"`
+	Name             string   `json:"name"`
+	DecisionStrategy string   `json:"decisionStrategy"`
+	Logic            string   `json:"logic"`
+	Policies         []string `json:"policies"`
+	Type             string   `json:"type"`
+	Description      string   `json:"description"`
+}
+
+func (keycloakClient *KeycloakClient) NewOpenidClientAuthorizationAggregatePolicy(policy *OpenidClientAuthorizationAggregatePolicy) error {
+	body, _, err := keycloakClient.post(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/aggregate", policy.RealmId, policy.ResourceServerId), policy)
+	if err != nil {
+		return err
+	}
+	err = json.Unmarshal(body, &policy)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (keycloakClient *KeycloakClient) UpdateOpenidClientAuthorizationAggregatePolicy(policy *OpenidClientAuthorizationAggregatePolicy) error {
+	err := keycloakClient.put(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/aggregate/%s", policy.RealmId, policy.ResourceServerId, policy.Id), policy)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (keycloakClient *KeycloakClient) DeleteOpenidClientAuthorizationAggregatePolicy(realmId, resourceServerId, policyId string) error {
+	return keycloakClient.delete(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/aggregate/%s", realmId, resourceServerId, policyId), nil)
+}
+
+func (keycloakClient *KeycloakClient) GetOpenidClientAuthorizationAggregatePolicy(realmId, resourceServerId, policyId string) (*OpenidClientAuthorizationAggregatePolicy, error) {
+
+	policy := OpenidClientAuthorizationAggregatePolicy{
+		Id:               policyId,
+		ResourceServerId: resourceServerId,
+		RealmId:          realmId,
+	}
+
+	err := keycloakClient.get(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/aggregate/%s", realmId, resourceServerId, policyId), &policy, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var keycloakPolicies []map[string]interface{}
+	errTwo := keycloakClient.get(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/%s/associatedPolicies", realmId, resourceServerId, policyId), &keycloakPolicies, nil)
+	if errTwo != nil {
+		return nil, err
+	}
+
+	for i := 0; i < len(keycloakPolicies); i++ {
+		policy.Policies = append(policy.Policies, keycloakPolicies[i]["id"].(string))
+	}
+
+	return &policy, nil
+}
diff --git a/keycloak/openid_client_authorization_client_policy.go b/keycloak/openid_client_authorization_client_policy.go
new file mode 100644
index 0000000..09b2c98
--- /dev/null
+++ b/keycloak/openid_client_authorization_client_policy.go
@@ -0,0 +1,57 @@
+package keycloak
+
+import (
+	"encoding/json"
+	"fmt"
+)
+
+type OpenidClientAuthorizationClientPolicy struct {
+	Id               string   `json:"id,omitempty"`
+	RealmId          string   `json:"-"`
+	ResourceServerId string   `json:"-"`
+	Name             string   `json:"name"`
+	DecisionStrategy string   `json:"decisionStrategy"`
+	Logic            string   `json:"logic"`
+	Type             string   `json:"type"`
+	Clients          []string `json:"clients"`
+	Description      string   `json:"description"`
+}
+
+func (keycloakClient *KeycloakClient) NewOpenidClientAuthorizationClientPolicy(policy *OpenidClientAuthorizationClientPolicy) error {
+	body, _, err := keycloakClient.post(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/client", policy.RealmId, policy.ResourceServerId), policy)
+	if err != nil {
+		return err
+	}
+	err = json.Unmarshal(body, &policy)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (keycloakClient *KeycloakClient) UpdateOpenidClientAuthorizationClientPolicy(policy *OpenidClientAuthorizationClientPolicy) error {
+	err := keycloakClient.put(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/client/%s", policy.RealmId, policy.ResourceServerId, policy.Id), policy)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (keycloakClient *KeycloakClient) DeleteOpenidClientAuthorizationClientPolicy(realmId, resourceServerId, policyId string) error {
+	return keycloakClient.delete(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/client/%s", realmId, resourceServerId, policyId), nil)
+}
+
+func (keycloakClient *KeycloakClient) GetOpenidClientAuthorizationClientPolicy(realmId, resourceServerId, policyId string) (*OpenidClientAuthorizationClientPolicy, error) {
+
+	policy := OpenidClientAuthorizationClientPolicy{
+		Id:               policyId,
+		ResourceServerId: resourceServerId,
+		RealmId:          realmId,
+	}
+	err := keycloakClient.get(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/client/%s", realmId, resourceServerId, policyId), &policy, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return &policy, nil
+}
diff --git a/keycloak/openid_client_authorization_group_policy.go b/keycloak/openid_client_authorization_group_policy.go
new file mode 100644
index 0000000..a21d860
--- /dev/null
+++ b/keycloak/openid_client_authorization_group_policy.go
@@ -0,0 +1,64 @@
+package keycloak
+
+import (
+	"encoding/json"
+	"fmt"
+)
+
+type OpenidClientAuthorizationGroupPolicy struct {
+	Id               string                           `json:"id,omitempty"`
+	RealmId          string                           `json:"-"`
+	ResourceServerId string                           `json:"-"`
+	Name             string                           `json:"name"`
+	DecisionStrategy string                           `json:"decisionStrategy"`
+	Logic            string                           `json:"logic"`
+	Type             string                           `json:"type"`
+	GroupsClaim      string                           `json:"groupsClaim"`
+	Groups           []OpenidClientAuthorizationGroup `json:"groups,omitempty"`
+	Description      string                           `json:"description"`
+}
+
+type OpenidClientAuthorizationGroup struct {
+	Id             string `json:"id,omitempty"`
+	Path           string `json:"path,omitempty"`
+	ExtendChildren bool   `json:"extendChildren,omitempty"`
+}
+
+func (keycloakClient *KeycloakClient) NewOpenidClientAuthorizationGroupPolicy(policy *OpenidClientAuthorizationGroupPolicy) error {
+	body, _, err := keycloakClient.post(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/group", policy.RealmId, policy.ResourceServerId), policy)
+	if err != nil {
+		return err
+	}
+	err = json.Unmarshal(body, &policy)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (keycloakClient *KeycloakClient) UpdateOpenidClientAuthorizationGroupPolicy(policy *OpenidClientAuthorizationGroupPolicy) error {
+	err := keycloakClient.put(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/group/%s", policy.RealmId, policy.ResourceServerId, policy.Id), policy)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (keycloakClient *KeycloakClient) DeleteOpenidClientAuthorizationGroupPolicy(realmId, resourceServerId, policyId string) error {
+	return keycloakClient.delete(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/role/%s", realmId, resourceServerId, policyId), nil)
+}
+
+func (keycloakClient *KeycloakClient) GetOpenidClientAuthorizationGroupPolicy(realmId, resourceServerId, policyId string) (*OpenidClientAuthorizationGroupPolicy, error) {
+
+	policy := OpenidClientAuthorizationGroupPolicy{
+		Id:               policyId,
+		ResourceServerId: resourceServerId,
+		RealmId:          realmId,
+	}
+	err := keycloakClient.get(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/group/%s", realmId, resourceServerId, policyId), &policy, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return &policy, nil
+}
diff --git a/keycloak/openid_client_authorization_js_policy.go b/keycloak/openid_client_authorization_js_policy.go
new file mode 100644
index 0000000..fe0ae65
--- /dev/null
+++ b/keycloak/openid_client_authorization_js_policy.go
@@ -0,0 +1,57 @@
+package keycloak
+
+import (
+	"encoding/json"
+	"fmt"
+)
+
+type OpenidClientAuthorizationJSPolicy struct {
+	Id               string `json:"id,omitempty"`
+	RealmId          string `json:"-"`
+	ResourceServerId string `json:"-"`
+	Name             string `json:"name"`
+	DecisionStrategy string `json:"decisionStrategy"`
+	Logic            string `json:"logic"`
+	Type             string `json:"type"`
+	Code             string `json:"code"`
+	Description      string `json:"description"`
+}
+
+func (keycloakClient *KeycloakClient) NewOpenidClientAuthorizationJSPolicy(policy *OpenidClientAuthorizationJSPolicy) error {
+	body, _, err := keycloakClient.post(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/js", policy.RealmId, policy.ResourceServerId), policy)
+	if err != nil {
+		return err
+	}
+	err = json.Unmarshal(body, &policy)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (keycloakClient *KeycloakClient) UpdateOpenidClientAuthorizationJSPolicy(policy *OpenidClientAuthorizationJSPolicy) error {
+	err := keycloakClient.put(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/js/%s", policy.RealmId, policy.ResourceServerId, policy.Id), policy)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (keycloakClient *KeycloakClient) DeleteOpenidClientAuthorizationJSPolicy(realmId, resourceServerId, policyId string) error {
+	return keycloakClient.delete(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/js/%s", realmId, resourceServerId, policyId), nil)
+}
+
+func (keycloakClient *KeycloakClient) GetOpenidClientAuthorizationJSPolicy(realmId, resourceServerId, policyId string) (*OpenidClientAuthorizationJSPolicy, error) {
+
+	policy := OpenidClientAuthorizationJSPolicy{
+		Id:               policyId,
+		ResourceServerId: resourceServerId,
+		RealmId:          realmId,
+	}
+	err := keycloakClient.get(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/js/%s", realmId, resourceServerId, policyId), &policy, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return &policy, nil
+}
diff --git a/keycloak/openid_client_authorization_role_policy.go b/keycloak/openid_client_authorization_role_policy.go
new file mode 100644
index 0000000..de04d5a
--- /dev/null
+++ b/keycloak/openid_client_authorization_role_policy.go
@@ -0,0 +1,62 @@
+package keycloak
+
+import (
+	"encoding/json"
+	"fmt"
+)
+
+type OpenidClientAuthorizationRolePolicy struct {
+	Id               string                          `json:"id,omitempty"`
+	RealmId          string                          `json:"-"`
+	ResourceServerId string                          `json:"-"`
+	Name             string                          `json:"name"`
+	DecisionStrategy string                          `json:"decisionStrategy"`
+	Logic            string                          `json:"logic"`
+	Type             string                          `json:"type"`
+	Roles            []OpenidClientAuthorizationRole `json:"roles,omitempty"`
+	Description      string                          `json:"description"`
+}
+
+type OpenidClientAuthorizationRole struct {
+	Id       string `json:"id,omitempty"`
+	Required bool   `json:"required"`
+}
+
+func (keycloakClient *KeycloakClient) NewOpenidClientAuthorizationRolePolicy(policy *OpenidClientAuthorizationRolePolicy) error {
+	body, _, err := keycloakClient.post(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/role", policy.RealmId, policy.ResourceServerId), policy)
+	if err != nil {
+		return err
+	}
+	err = json.Unmarshal(body, &policy)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (keycloakClient *KeycloakClient) UpdateOpenidClientAuthorizationRolePolicy(policy *OpenidClientAuthorizationRolePolicy) error {
+	err := keycloakClient.put(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/role/%s", policy.RealmId, policy.ResourceServerId, policy.Id), policy)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (keycloakClient *KeycloakClient) DeleteOpenidClientAuthorizationRolePolicy(realmId, resourceServerId, policyId string) error {
+	return keycloakClient.delete(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/role/%s", realmId, resourceServerId, policyId), nil)
+}
+
+func (keycloakClient *KeycloakClient) GetOpenidClientAuthorizationRolePolicy(realmId, resourceServerId, policyId string) (*OpenidClientAuthorizationRolePolicy, error) {
+
+	policy := OpenidClientAuthorizationRolePolicy{
+		Id:               policyId,
+		ResourceServerId: resourceServerId,
+		RealmId:          realmId,
+	}
+	err := keycloakClient.get(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/role/%s", realmId, resourceServerId, policyId), &policy, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return &policy, nil
+}
diff --git a/keycloak/openid_client_authorization_time_policy.go b/keycloak/openid_client_authorization_time_policy.go
new file mode 100644
index 0000000..965dd55
--- /dev/null
+++ b/keycloak/openid_client_authorization_time_policy.go
@@ -0,0 +1,68 @@
+package keycloak
+
+import (
+	"encoding/json"
+	"fmt"
+)
+
+type OpenidClientAuthorizationTimePolicy struct {
+	Id               string `json:"id,omitempty"`
+	RealmId          string `json:"-"`
+	ResourceServerId string `json:"-"`
+	Name             string `json:"name"`
+	DecisionStrategy string `json:"decisionStrategy"`
+	Logic            string `json:"logic"`
+	Type             string `json:"type"`
+	NotBefore        string `json:"notBefore"`
+	NotOnOrAfter     string `json:"notOnOrAfter"`
+	DayMonth         string `json:"dayMonth"`
+	DayMonthEnd      string `json:"dayMonthEnd"`
+	Month            string `json:"month"`
+	MonthEnd         string `json:"monthEnd"`
+	Year             string `json:"year"`
+	YearEnd          string `json:"yearEnd"`
+	Hour             string `json:"hour"`
+	HourEnd          string `json:"hourEnd"`
+	Minute           string `json:"minute"`
+	MinuteEnd        string `json:"minuteEnd"`
+	Description      string `json:"description"`
+}
+
+func (keycloakClient *KeycloakClient) NewOpenidClientAuthorizationTimePolicy(policy *OpenidClientAuthorizationTimePolicy) error {
+	body, _, err := keycloakClient.post(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/time", policy.RealmId, policy.ResourceServerId), policy)
+	if err != nil {
+		return err
+	}
+	err = json.Unmarshal(body, &policy)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (keycloakClient *KeycloakClient) UpdateOpenidClientAuthorizationTimePolicy(policy *OpenidClientAuthorizationTimePolicy) error {
+	err := keycloakClient.put(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/time/%s", policy.RealmId, policy.ResourceServerId, policy.Id), policy)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (keycloakClient *KeycloakClient) DeleteOpenidClientAuthorizationTimePolicy(realmId, resourceServerId, policyId string) error {
+	return keycloakClient.delete(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/time/%s", realmId, resourceServerId, policyId), nil)
+}
+
+func (keycloakClient *KeycloakClient) GetOpenidClientAuthorizationTimePolicy(realmId, resourceServerId, policyId string) (*OpenidClientAuthorizationTimePolicy, error) {
+
+	policy := OpenidClientAuthorizationTimePolicy{
+		Id:               policyId,
+		ResourceServerId: resourceServerId,
+		RealmId:          realmId,
+	}
+	err := keycloakClient.get(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/time/%s", realmId, resourceServerId, policyId), &policy, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return &policy, nil
+}
diff --git a/keycloak/openid_client_authorization_user_policy.go b/keycloak/openid_client_authorization_user_policy.go
new file mode 100644
index 0000000..7fe44d8
--- /dev/null
+++ b/keycloak/openid_client_authorization_user_policy.go
@@ -0,0 +1,57 @@
+package keycloak
+
+import (
+	"encoding/json"
+	"fmt"
+)
+
+type OpenidClientAuthorizationUserPolicy struct {
+	Id               string   `json:"id,omitempty"`
+	RealmId          string   `json:"-"`
+	ResourceServerId string   `json:"-"`
+	Name             string   `json:"name"`
+	DecisionStrategy string   `json:"decisionStrategy"`
+	Logic            string   `json:"logic"`
+	Type             string   `json:"type"`
+	Users            []string `json:"users"`
+	Description      string   `json:"description"`
+}
+
+func (keycloakClient *KeycloakClient) NewOpenidClientAuthorizationUserPolicy(policy *OpenidClientAuthorizationUserPolicy) error {
+	body, _, err := keycloakClient.post(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/user", policy.RealmId, policy.ResourceServerId), policy)
+	if err != nil {
+		return err
+	}
+	err = json.Unmarshal(body, &policy)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (keycloakClient *KeycloakClient) UpdateOpenidClientAuthorizationUserPolicy(policy *OpenidClientAuthorizationUserPolicy) error {
+	err := keycloakClient.put(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/user/%s", policy.RealmId, policy.ResourceServerId, policy.Id), policy)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (keycloakClient *KeycloakClient) DeleteOpenidClientAuthorizationUserPolicy(realmId, resourceServerId, policyId string) error {
+	return keycloakClient.delete(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/user/%s", realmId, resourceServerId, policyId), nil)
+}
+
+func (keycloakClient *KeycloakClient) GetOpenidClientAuthorizationUserPolicy(realmId, resourceServerId, policyId string) (*OpenidClientAuthorizationUserPolicy, error) {
+
+	policy := OpenidClientAuthorizationUserPolicy{
+		Id:               policyId,
+		ResourceServerId: resourceServerId,
+		RealmId:          realmId,
+	}
+	err := keycloakClient.get(fmt.Sprintf("/realms/%s/clients/%s/authz/resource-server/policy/user/%s", realmId, resourceServerId, policyId), &policy, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return &policy, nil
+}
diff --git a/keycloak/role_scope_mapping.go b/keycloak/role_scope_mapping.go
new file mode 100644
index 0000000..5cfdffa
--- /dev/null
+++ b/keycloak/role_scope_mapping.go
@@ -0,0 +1,43 @@
+package keycloak
+
+import (
+	"fmt"
+)
+
+func roleScopeMappingUrl(realmId, clientId string, role *Role) string {
+	return fmt.Sprintf("/realms/%s/clients/%s/scope-mappings/clients/%s", realmId, clientId, role.ClientId)
+}
+
+func (keycloakClient *KeycloakClient) CreateRoleScopeMapping(realmId string, clientId string, role *Role) error {
+	roleUrl := roleScopeMappingUrl(realmId, clientId, role)
+
+	_, _, err := keycloakClient.post(roleUrl, []Role{*role})
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (keycloakClient *KeycloakClient) GetRoleScopeMapping(realmId string, clientId string, role *Role) (*Role, error) {
+	roleUrl := roleScopeMappingUrl(realmId, clientId, role)
+	var roles []Role
+
+	err := keycloakClient.get(roleUrl, &roles, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	for _, mappedRole := range roles {
+		if mappedRole.Id == role.Id {
+			return role, nil
+		}
+	}
+
+	return nil, nil
+}
+
+func (keycloakClient *KeycloakClient) DeleteRoleScopeMapping(realmId string, clientId string, role *Role) error {
+	roleUrl := roleScopeMappingUrl(realmId, clientId, role)
+	return keycloakClient.delete(roleUrl, nil)
+}
diff --git a/provider/data_source_keycloak_openid_client_authorization_policy.go b/provider/data_source_keycloak_openid_client_authorization_policy.go
index 12b1405..4dc9568 100644
--- a/provider/data_source_keycloak_openid_client_authorization_policy.go
+++ b/provider/data_source_keycloak_openid_client_authorization_policy.go
@@ -2,6 +2,7 @@ package provider
 
 import (
 	"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
+	"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
 	"github.com/mrparkers/terraform-provider-keycloak/keycloak"
 )
 
@@ -31,8 +32,9 @@ func dataSourceKeycloakOpenidClientAuthorizationPolicy() *schema.Resource {
 				Computed: true,
 			},
 			"logic": {
-				Type:     schema.TypeString,
-				Computed: true,
+				Type:         schema.TypeString,
+				Optional:     true,
+				ValidateFunc: validation.StringInSlice(keycloakPolicyLogicTypes, false),
 			},
 			"policies": {
 				Type:     schema.TypeSet,
diff --git a/provider/generic_resource_policy_import.go b/provider/generic_resource_policy_import.go
new file mode 100644
index 0000000..ca4d2b8
--- /dev/null
+++ b/provider/generic_resource_policy_import.go
@@ -0,0 +1,20 @@
+package provider
+
+import (
+	"fmt"
+	"strings"
+
+	"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
+)
+
+func genericResourcePolicyImport(d *schema.ResourceData, _ interface{}) ([]*schema.ResourceData, error) {
+	parts := strings.Split(d.Id(), "/")
+	if len(parts) != 3 {
+		return nil, fmt.Errorf("Invalid import. Supported import formats: {{realmId}}/{{resourceServerId}}/{{authorizationResourceId}}")
+	}
+	d.Set("realm_id", parts[0])
+	d.Set("resource_server_id", parts[1])
+	d.SetId(parts[3])
+
+	return []*schema.ResourceData{d}, nil
+}
diff --git a/provider/keycloak_policy_helpers.go b/provider/keycloak_policy_helpers.go
new file mode 100644
index 0000000..033662d
--- /dev/null
+++ b/provider/keycloak_policy_helpers.go
@@ -0,0 +1,5 @@
+package provider
+
+var (
+	keycloakPolicyLogicTypes = []string{"POSITIVE", "NEGATIVE"}
+)
diff --git a/provider/provider.go b/provider/provider.go
index 6ecc053..5bd2811 100644
--- a/provider/provider.go
+++ b/provider/provider.go
@@ -47,6 +47,7 @@ func KeycloakProvider() *schema.Provider {
 			"keycloak_openid_client_optional_scopes":                   resourceKeycloakOpenidClientOptionalScopes(),
 			"keycloak_saml_client":                                     resourceKeycloakSamlClient(),
 			"keycloak_generic_client_protocol_mapper":                  resourceKeycloakGenericClientProtocolMapper(),
+			"keycloak_generic_client_role_mapper":                      resourceKeycloakGenericClientRoleMapper(),
 			"keycloak_saml_user_attribute_protocol_mapper":             resourceKeycloakSamlUserAttributeProtocolMapper(),
 			"keycloak_saml_user_property_protocol_mapper":              resourceKeycloakSamlUserPropertyProtocolMapper(),
 			"keycloak_hardcoded_attribute_identity_provider_mapper":    resourceKeycloakHardcodedAttributeIdentityProviderMapper(),
@@ -58,6 +59,13 @@ func KeycloakProvider() *schema.Provider {
 			"keycloak_oidc_google_identity_provider":                   resourceKeycloakOidcGoogleIdentityProvider(),
 			"keycloak_oidc_identity_provider":                          resourceKeycloakOidcIdentityProvider(),
 			"keycloak_openid_client_authorization_resource":            resourceKeycloakOpenidClientAuthorizationResource(),
+			"keycloak_openid_client_group_policy":                      resourceKeycloakOpenidClientAuthorizationGroupPolicy(),
+			"keycloak_openid_client_role_policy":                       resourceKeycloakOpenidClientAuthorizationRolePolicy(),
+			"keycloak_openid_client_aggregate_policy":                  resourceKeycloakOpenidClientAuthorizationAggregatePolicy(),
+			"keycloak_openid_client_js_policy":                         resourceKeycloakOpenidClientAuthorizationJSPolicy(),
+			"keycloak_openid_client_time_policy":                       resourceKeycloakOpenidClientAuthorizationTimePolicy(),
+			"keycloak_openid_client_user_policy":                       resourceKeycloakOpenidClientAuthorizationUserPolicy(),
+			"keycloak_openid_client_client_policy":                     resourceKeycloakOpenidClientAuthorizationClientPolicy(),
 			"keycloak_openid_client_authorization_scope":               resourceKeycloakOpenidClientAuthorizationScope(),
 			"keycloak_openid_client_authorization_permission":          resourceKeycloakOpenidClientAuthorizationPermission(),
 			"keycloak_openid_client_service_account_role":              resourceKeycloakOpenidClientServiceAccountRole(),
@@ -66,6 +74,7 @@ func KeycloakProvider() *schema.Provider {
 			"keycloak_authentication_flow":                             resourceKeycloakAuthenticationFlow(),
 			"keycloak_authentication_subflow":                          resourceKeycloakAuthenticationSubFlow(),
 			"keycloak_authentication_execution":                        resourceKeycloakAuthenticationExecution(),
+			"keycloak_authentication_execution_config":                 resourceKeycloakAuthenticationExecutionConfig(),
 		},
 		Schema: map[string]*schema.Schema{
 			"client_id": {
diff --git a/provider/resource_keycloak_authentication_execution_config.go b/provider/resource_keycloak_authentication_execution_config.go
new file mode 100644
index 0000000..76d0bfe
--- /dev/null
+++ b/provider/resource_keycloak_authentication_execution_config.go
@@ -0,0 +1,137 @@
+package provider
+
+import (
+	"fmt"
+	"strings"
+
+	"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
+	"github.com/mrparkers/terraform-provider-keycloak/keycloak"
+)
+
+func resourceKeycloakAuthenticationExecutionConfig() *schema.Resource {
+	return &schema.Resource{
+		Create: resourceKeycloakAuthenticationExecutionConfigCreate,
+		Read:   resourceKeycloakAuthenticationExecutionConfigRead,
+		Delete: resourceKeycloakAuthenticationExecutionConfigDelete,
+		Update: resourceKeycloakAuthenticationExecutionConfigUpdate,
+		Importer: &schema.ResourceImporter{
+			State: resourceKeycloakAuthenticationExecutionConfigImport,
+		},
+		Schema: map[string]*schema.Schema{
+			"realm_id": {
+				Type:     schema.TypeString,
+				Required: true,
+				ForceNew: true,
+			},
+			"execution_id": {
+				Type:     schema.TypeString,
+				Required: true,
+				ForceNew: true,
+			},
+			"alias": {
+				Type:     schema.TypeString,
+				Required: true,
+				ForceNew: true,
+			},
+			"config": {
+				Type:     schema.TypeMap,
+				Elem:     &schema.Schema{Type: schema.TypeString},
+				Required: true,
+			},
+		},
+	}
+}
+
+func getAuthenticationExecutionConfigFromData(data *schema.ResourceData) *keycloak.AuthenticationExecutionConfig {
+	config := make(map[string]string)
+	for key, value := range data.Get("config").(map[string]interface{}) {
+		config[key] = value.(string)
+	}
+	return &keycloak.AuthenticationExecutionConfig{
+		Id:          data.Id(),
+		RealmId:     data.Get("realm_id").(string),
+		ExecutionId: data.Get("execution_id").(string),
+		Alias:       data.Get("alias").(string),
+		Config:      config,
+	}
+}
+
+func setAuthenticationExecutionConfigData(data *schema.ResourceData, config *keycloak.AuthenticationExecutionConfig) {
+	data.SetId(config.Id)
+	data.Set("realm_id", config.RealmId)
+	data.Set("execution_id", config.ExecutionId)
+	data.Set("alias", config.Alias)
+	data.Set("config", config.Config)
+}
+
+func resourceKeycloakAuthenticationExecutionConfigCreate(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	config := getAuthenticationExecutionConfigFromData(data)
+
+	id, err := keycloakClient.NewAuthenticationExecutionConfig(config)
+	if err != nil {
+		return err
+	}
+
+	data.SetId(id)
+
+	return resourceKeycloakAuthenticationExecutionConfigRead(data, meta)
+}
+
+func resourceKeycloakAuthenticationExecutionConfigRead(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	config := &keycloak.AuthenticationExecutionConfig{
+		RealmId:     data.Get("realm_id").(string),
+		ExecutionId: data.Get("execution_id").(string),
+		Id:          data.Id(),
+	}
+
+	err := keycloakClient.GetAuthenticationExecutionConfig(config)
+	if err != nil {
+		return handleNotFoundError(err, data)
+	}
+
+	setAuthenticationExecutionConfigData(data, config)
+
+	return nil
+}
+
+func resourceKeycloakAuthenticationExecutionConfigUpdate(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	config := getAuthenticationExecutionConfigFromData(data)
+
+	err := keycloakClient.UpdateAuthenticationExecutionConfig(config)
+	if err != nil {
+		return err
+	}
+
+	return resourceKeycloakAuthenticationExecutionConfigRead(data, meta)
+}
+
+func resourceKeycloakAuthenticationExecutionConfigDelete(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	config := &keycloak.AuthenticationExecutionConfig{
+		RealmId: data.Get("realm_id").(string),
+		Id:      data.Id(),
+	}
+
+	return keycloakClient.DeleteAuthenticationExecutionConfig(config)
+}
+
+func resourceKeycloakAuthenticationExecutionConfigImport(data *schema.ResourceData, _ interface{}) ([]*schema.ResourceData, error) {
+	parts := strings.Split(data.Id(), "/")
+
+	if len(parts) != 3 || parts[0] == "" || parts[1] == "" || parts[2] == "" {
+		return nil, fmt.Errorf("invalid import. Supported import formats: {{realm}}/{{authenticationExecutionId}}/{{authenticationExecutionConfigId}}")
+	}
+
+	data.Set("realm_id", parts[0])
+	data.Set("execution_id", parts[1])
+	data.SetId(parts[2])
+
+	return []*schema.ResourceData{data}, nil
+}
diff --git a/provider/resource_keycloak_generic_client_role_mapper.go b/provider/resource_keycloak_generic_client_role_mapper.go
new file mode 100644
index 0000000..f2e1043
--- /dev/null
+++ b/provider/resource_keycloak_generic_client_role_mapper.go
@@ -0,0 +1,92 @@
+package provider
+
+import (
+	"fmt"
+
+	"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
+	"github.com/mrparkers/terraform-provider-keycloak/keycloak"
+)
+
+func resourceKeycloakGenericClientRoleMapper() *schema.Resource {
+	return &schema.Resource{
+		Create: resourceKeycloakGenericClientRoleMapperCreate,
+		Read:   resourceKeycloakGenericClientRoleMapperRead,
+		Delete: resourceKeycloakGenericClientRoleMapperDelete,
+
+		Schema: map[string]*schema.Schema{
+			"realm_id": {
+				Type:     schema.TypeString,
+				Required: true,
+				ForceNew: true,
+			},
+			"client_id": {
+				Type:     schema.TypeString,
+				Required: true,
+				ForceNew: true,
+			},
+			"role_id": {
+				Type:     schema.TypeString,
+				Required: true,
+				ForceNew: true,
+			},
+		},
+	}
+}
+
+func resourceKeycloakGenericClientRoleMapperCreate(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	realmId := data.Get("realm_id").(string)
+	clientId := data.Get("client_id").(string)
+	roleId := data.Get("role_id").(string)
+
+	role, err := keycloakClient.GetRole(realmId, roleId)
+	if err != nil {
+		return err
+	}
+
+	err = keycloakClient.CreateRoleScopeMapping(realmId, clientId, role)
+	if err != nil {
+		return err
+	}
+
+	data.SetId(fmt.Sprintf("%s/client/%s/scope-mappings/%s/%s", realmId, clientId, role.ClientId, role.Id))
+
+	return resourceKeycloakGenericClientRoleMapperRead(data, meta)
+}
+
+func resourceKeycloakGenericClientRoleMapperRead(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	realmId := data.Get("realm_id").(string)
+	clientId := data.Get("client_id").(string)
+	roleId := data.Get("role_id").(string)
+
+	role, err := keycloakClient.GetRole(realmId, roleId)
+	if err != nil {
+		return err
+	}
+
+	mappedRole, err := keycloakClient.GetRoleScopeMapping(realmId, clientId, role)
+
+	if mappedRole == nil {
+		data.SetId("")
+	}
+
+	return nil
+}
+
+func resourceKeycloakGenericClientRoleMapperDelete(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	realmId := data.Get("realm_id").(string)
+	clientId := data.Get("client_id").(string)
+	roleId := data.Get("role_id").(string)
+
+	role, err := keycloakClient.GetRole(realmId, roleId)
+	if err != nil {
+		return err
+	}
+
+	return keycloakClient.DeleteRoleScopeMapping(realmId, clientId, role)
+}
diff --git a/provider/resource_keycloak_openid_client_authorization_aggregate_policy.go b/provider/resource_keycloak_openid_client_authorization_aggregate_policy.go
new file mode 100644
index 0000000..9aa659b
--- /dev/null
+++ b/provider/resource_keycloak_openid_client_authorization_aggregate_policy.go
@@ -0,0 +1,141 @@
+package provider
+
+import (
+	"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
+	"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
+	"github.com/mrparkers/terraform-provider-keycloak/keycloak"
+)
+
+func resourceKeycloakOpenidClientAuthorizationAggregatePolicy() *schema.Resource {
+	return &schema.Resource{
+		Create: resourceKeycloakOpenidClientAuthorizationAggregatePolicyCreate,
+		Read:   resourceKeycloakOpenidClientAuthorizationAggregatePolicyRead,
+		Delete: resourceKeycloakOpenidClientAuthorizationAggregatePolicyDelete,
+		Update: resourceKeycloakOpenidClientAuthorizationAggregatePolicyUpdate,
+		Importer: &schema.ResourceImporter{
+			State: genericResourcePolicyImport,
+		},
+		Schema: map[string]*schema.Schema{
+			"resource_server_id": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"realm_id": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"name": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"decision_strategy": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"logic": {
+				Type:         schema.TypeString,
+				Optional:     true,
+				ValidateFunc: validation.StringInSlice(keycloakPolicyLogicTypes, false),
+			},
+			"policies": {
+				Type:     schema.TypeSet,
+				Elem:     &schema.Schema{Type: schema.TypeString},
+				Required: true,
+			},
+			"description": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+		},
+	}
+}
+
+func getOpenidClientAuthorizationAggregatePolicyResourceFromData(data *schema.ResourceData) *keycloak.OpenidClientAuthorizationAggregatePolicy {
+	var policies []string
+
+	if v, ok := data.GetOk("policies"); ok {
+		for _, policy := range v.(*schema.Set).List() {
+			policies = append(policies, policy.(string))
+		}
+	}
+
+	resource := keycloak.OpenidClientAuthorizationAggregatePolicy{
+		Id:               data.Id(),
+		ResourceServerId: data.Get("resource_server_id").(string),
+		RealmId:          data.Get("realm_id").(string),
+		DecisionStrategy: data.Get("decision_strategy").(string),
+		Logic:            data.Get("logic").(string),
+		Name:             data.Get("name").(string),
+		Type:             "aggregate",
+		Policies:         policies,
+		Description:      data.Get("description").(string),
+	}
+	return &resource
+}
+
+func setOpenidClientAuthorizationAggregatePolicyResourceData(data *schema.ResourceData, policy *keycloak.OpenidClientAuthorizationAggregatePolicy) {
+	data.SetId(policy.Id)
+
+	data.Set("resource_server_id", policy.ResourceServerId)
+	data.Set("realm_id", policy.RealmId)
+	data.Set("name", policy.Name)
+	data.Set("decision_strategy", policy.DecisionStrategy)
+	data.Set("logic", policy.Logic)
+	data.Set("policies", policy.Policies)
+	data.Set("description", policy.Description)
+}
+
+func resourceKeycloakOpenidClientAuthorizationAggregatePolicyCreate(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	resource := getOpenidClientAuthorizationAggregatePolicyResourceFromData(data)
+	err := keycloakClient.NewOpenidClientAuthorizationAggregatePolicy(resource)
+	if err != nil {
+		return err
+	}
+
+	setOpenidClientAuthorizationAggregatePolicyResourceData(data, resource)
+
+	return resourceKeycloakOpenidClientAuthorizationAggregatePolicyRead(data, meta)
+}
+
+func resourceKeycloakOpenidClientAuthorizationAggregatePolicyRead(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	realmId := data.Get("realm_id").(string)
+	resourceServerId := data.Get("resource_server_id").(string)
+	id := data.Id()
+
+	resource, err := keycloakClient.GetOpenidClientAuthorizationAggregatePolicy(realmId, resourceServerId, id)
+	if err != nil {
+		return handleNotFoundError(err, data)
+	}
+
+	setOpenidClientAuthorizationAggregatePolicyResourceData(data, resource)
+
+	return nil
+}
+
+func resourceKeycloakOpenidClientAuthorizationAggregatePolicyUpdate(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+	resource := getOpenidClientAuthorizationAggregatePolicyResourceFromData(data)
+
+	err := keycloakClient.UpdateOpenidClientAuthorizationAggregatePolicy(resource)
+	if err != nil {
+		return err
+	}
+
+	setOpenidClientAuthorizationAggregatePolicyResourceData(data, resource)
+
+	return nil
+}
+
+func resourceKeycloakOpenidClientAuthorizationAggregatePolicyDelete(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	realmId := data.Get("realm_id").(string)
+	resourceServerId := data.Get("resource_server_id").(string)
+	id := data.Id()
+
+	return keycloakClient.DeleteOpenidClientAuthorizationAggregatePolicy(realmId, resourceServerId, id)
+}
diff --git a/provider/resource_keycloak_openid_client_authorization_client_policy.go b/provider/resource_keycloak_openid_client_authorization_client_policy.go
new file mode 100644
index 0000000..1e2bb7c
--- /dev/null
+++ b/provider/resource_keycloak_openid_client_authorization_client_policy.go
@@ -0,0 +1,143 @@
+package provider
+
+import (
+	"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
+	"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
+	"github.com/mrparkers/terraform-provider-keycloak/keycloak"
+)
+
+func resourceKeycloakOpenidClientAuthorizationClientPolicy() *schema.Resource {
+	return &schema.Resource{
+		Create: resourceKeycloakOpenidClientAuthorizationClientPolicyCreate,
+		Read:   resourceKeycloakOpenidClientAuthorizationClientPolicyRead,
+		Delete: resourceKeycloakOpenidClientAuthorizationClientPolicyDelete,
+		Update: resourceKeycloakOpenidClientAuthorizationClientPolicyUpdate,
+		Importer: &schema.ResourceImporter{
+			State: genericResourcePolicyImport,
+		},
+		Schema: map[string]*schema.Schema{
+			"resource_server_id": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"realm_id": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"name": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"decision_strategy": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"logic": {
+				Type:         schema.TypeString,
+				Optional:     true,
+				ValidateFunc: validation.StringInSlice(keycloakPolicyLogicTypes, false),
+			},
+			"description": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"clients": {
+				Type:     schema.TypeSet,
+				Elem:     &schema.Schema{Type: schema.TypeString},
+				Required: true,
+			},
+		},
+	}
+}
+
+func getOpenidClientAuthorizationClientAuthorizationClientPolicyResourceFromData(data *schema.ResourceData) *keycloak.OpenidClientAuthorizationClientPolicy {
+	var clients []string
+
+	if v, ok := data.GetOk("clients"); ok {
+		for _, client := range v.(*schema.Set).List() {
+			clients = append(clients, client.(string))
+		}
+	}
+
+	resource := keycloak.OpenidClientAuthorizationClientPolicy{
+		Id:               data.Id(),
+		ResourceServerId: data.Get("resource_server_id").(string),
+		RealmId:          data.Get("realm_id").(string),
+		DecisionStrategy: data.Get("decision_strategy").(string),
+		Logic:            data.Get("logic").(string),
+		Name:             data.Get("name").(string),
+		Type:             "client",
+		Clients:          clients,
+		Description:      data.Get("description").(string),
+	}
+	return &resource
+}
+
+func setOpenidClientAuthorizationClientAuthorizationClientPolicyResourceData(data *schema.ResourceData, policy *keycloak.OpenidClientAuthorizationClientPolicy) {
+	data.SetId(policy.Id)
+
+	data.Set("resource_server_id", policy.ResourceServerId)
+	data.Set("realm_id", policy.RealmId)
+	data.Set("name", policy.Name)
+	data.Set("decision_strategy", policy.DecisionStrategy)
+	data.Set("logic", policy.Logic)
+	data.Set("description", policy.Description)
+	data.Set("clients", policy.Clients)
+}
+
+func resourceKeycloakOpenidClientAuthorizationClientPolicyCreate(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	resource := getOpenidClientAuthorizationClientAuthorizationClientPolicyResourceFromData(data)
+
+	err := keycloakClient.NewOpenidClientAuthorizationClientPolicy(resource)
+	if err != nil {
+		return err
+	}
+
+	setOpenidClientAuthorizationClientAuthorizationClientPolicyResourceData(data, resource)
+
+	return resourceKeycloakOpenidClientAuthorizationClientPolicyRead(data, meta)
+}
+
+func resourceKeycloakOpenidClientAuthorizationClientPolicyRead(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	realmId := data.Get("realm_id").(string)
+	resourceServerId := data.Get("resource_server_id").(string)
+	id := data.Id()
+
+	resource, err := keycloakClient.GetOpenidClientAuthorizationClientPolicy(realmId, resourceServerId, id)
+	if err != nil {
+		return handleNotFoundError(err, data)
+	}
+
+	setOpenidClientAuthorizationClientAuthorizationClientPolicyResourceData(data, resource)
+
+	return nil
+}
+
+func resourceKeycloakOpenidClientAuthorizationClientPolicyUpdate(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	resource := getOpenidClientAuthorizationClientAuthorizationClientPolicyResourceFromData(data)
+
+	err := keycloakClient.UpdateOpenidClientAuthorizationClientPolicy(resource)
+	if err != nil {
+		return err
+	}
+
+	setOpenidClientAuthorizationClientAuthorizationClientPolicyResourceData(data, resource)
+
+	return nil
+}
+
+func resourceKeycloakOpenidClientAuthorizationClientPolicyDelete(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	realmId := data.Get("realm_id").(string)
+	resourceServerId := data.Get("resource_server_id").(string)
+	id := data.Id()
+
+	return keycloakClient.DeleteOpenidClientAuthorizationClientPolicy(realmId, resourceServerId, id)
+}
diff --git a/provider/resource_keycloak_openid_client_authorization_group_policy.go b/provider/resource_keycloak_openid_client_authorization_group_policy.go
new file mode 100644
index 0000000..e2dd202
--- /dev/null
+++ b/provider/resource_keycloak_openid_client_authorization_group_policy.go
@@ -0,0 +1,171 @@
+package provider
+
+import (
+	"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
+	"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
+	"github.com/mrparkers/terraform-provider-keycloak/keycloak"
+)
+
+func resourceKeycloakOpenidClientAuthorizationGroupPolicy() *schema.Resource {
+	return &schema.Resource{
+		Create: resourceKeycloakOpenidClientAuthorizationGroupPolicyCreate,
+		Read:   resourceKeycloakOpenidClientAuthorizationGroupPolicyRead,
+		Delete: resourceKeycloakOpenidClientAuthorizationGroupPolicyDelete,
+		Update: resourceKeycloakOpenidClientAuthorizationGroupPolicyUpdate,
+		Importer: &schema.ResourceImporter{
+			State: genericResourcePolicyImport,
+		},
+		Schema: map[string]*schema.Schema{
+			"resource_server_id": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"realm_id": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"name": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"decision_strategy": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"logic": {
+				Type:         schema.TypeString,
+				Optional:     true,
+				ValidateFunc: validation.StringInSlice(keycloakPolicyLogicTypes, false),
+			},
+			"description": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"groups_claim": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"groups": {
+				Type:     schema.TypeList,
+				Required: true,
+				MinItems: 1,
+				Elem: &schema.Resource{
+					Schema: map[string]*schema.Schema{
+						"id": {
+							Type:     schema.TypeString,
+							Required: true,
+						},
+						"path": {
+							Type:     schema.TypeString,
+							Required: true,
+						},
+						"extend_children": {
+							Type:     schema.TypeBool,
+							Required: true,
+						},
+					},
+				},
+			},
+		},
+	}
+}
+
+func getOpenidClientAuthorizationGroupPolicyResourceFromData(data *schema.ResourceData) *keycloak.OpenidClientAuthorizationGroupPolicy {
+	var groups []keycloak.OpenidClientAuthorizationGroup
+	if v, ok := data.Get("groups").([]interface{}); ok {
+		for _, group := range v {
+			groupMap := group.(map[string]interface{})
+			tempGroup := keycloak.OpenidClientAuthorizationGroup{
+				Id:             groupMap["id"].(string),
+				Path:           groupMap["path"].(string),
+				ExtendChildren: groupMap["extend_children"].(bool),
+			}
+			groups = append(groups, tempGroup)
+		}
+	}
+
+	resource := keycloak.OpenidClientAuthorizationGroupPolicy{
+		Id:               data.Id(),
+		ResourceServerId: data.Get("resource_server_id").(string),
+		RealmId:          data.Get("realm_id").(string),
+		DecisionStrategy: data.Get("decision_strategy").(string),
+		Logic:            data.Get("logic").(string),
+		Name:             data.Get("name").(string),
+		Type:             "group",
+		GroupsClaim:      data.Get("groups_claim").(string),
+		Groups:           groups,
+		Description:      data.Get("description").(string),
+	}
+
+	return &resource
+}
+
+func setOpenidClientAuthorizationGroupPolicyResourceData(data *schema.ResourceData, policy *keycloak.OpenidClientAuthorizationGroupPolicy) {
+	data.SetId(policy.Id)
+
+	data.Set("resource_server_id", policy.ResourceServerId)
+	data.Set("realm_id", policy.RealmId)
+	data.Set("name", policy.Name)
+	data.Set("decision_strategy", policy.DecisionStrategy)
+	data.Set("logic", policy.Logic)
+	data.Set("description", policy.Description)
+	data.Set("groups_claim", policy.GroupsClaim)
+	data.Set("groups", policy.Groups)
+}
+
+func resourceKeycloakOpenidClientAuthorizationGroupPolicyCreate(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	resource := getOpenidClientAuthorizationGroupPolicyResourceFromData(data)
+
+	err := keycloakClient.NewOpenidClientAuthorizationGroupPolicy(resource)
+	if err != nil {
+		return err
+	}
+
+	setOpenidClientAuthorizationGroupPolicyResourceData(data, resource)
+
+	return resourceKeycloakOpenidClientAuthorizationGroupPolicyRead(data, meta)
+}
+
+func resourceKeycloakOpenidClientAuthorizationGroupPolicyRead(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	realmId := data.Get("realm_id").(string)
+	resourceServerId := data.Get("resource_server_id").(string)
+	id := data.Id()
+
+	resource, err := keycloakClient.GetOpenidClientAuthorizationGroupPolicy(realmId, resourceServerId, id)
+	if err != nil {
+		return handleNotFoundError(err, data)
+	}
+
+	setOpenidClientAuthorizationGroupPolicyResourceData(data, resource)
+
+	return nil
+}
+
+func resourceKeycloakOpenidClientAuthorizationGroupPolicyUpdate(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	resource := getOpenidClientAuthorizationGroupPolicyResourceFromData(data)
+
+	err := keycloakClient.UpdateOpenidClientAuthorizationGroupPolicy(resource)
+	if err != nil {
+		return err
+	}
+
+	setOpenidClientAuthorizationGroupPolicyResourceData(data, resource)
+
+	return nil
+}
+
+func resourceKeycloakOpenidClientAuthorizationGroupPolicyDelete(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	realmId := data.Get("realm_id").(string)
+	resourceServerId := data.Get("resource_server_id").(string)
+	id := data.Id()
+
+	return keycloakClient.DeleteOpenidClientAuthorizationGroupPolicy(realmId, resourceServerId, id)
+}
diff --git a/provider/resource_keycloak_openid_client_authorization_js_policy.go b/provider/resource_keycloak_openid_client_authorization_js_policy.go
new file mode 100644
index 0000000..f052e65
--- /dev/null
+++ b/provider/resource_keycloak_openid_client_authorization_js_policy.go
@@ -0,0 +1,139 @@
+package provider
+
+import (
+	"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
+	"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
+	"github.com/mrparkers/terraform-provider-keycloak/keycloak"
+)
+
+func resourceKeycloakOpenidClientAuthorizationJSPolicy() *schema.Resource {
+	return &schema.Resource{
+		Create: resourceKeycloakOpenidClientAuthorizationJSPolicyCreate,
+		Read:   resourceKeycloakOpenidClientAuthorizationJSPolicyRead,
+		Delete: resourceKeycloakOpenidClientAuthorizationJSPolicyDelete,
+		Update: resourceKeycloakOpenidClientAuthorizationJSPolicyUpdate,
+		Importer: &schema.ResourceImporter{
+			State: genericResourcePolicyImport,
+		},
+		Schema: map[string]*schema.Schema{
+			"resource_server_id": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"realm_id": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"name": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"decision_strategy": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"logic": {
+				Type:         schema.TypeString,
+				Optional:     true,
+				ValidateFunc: validation.StringInSlice(keycloakPolicyLogicTypes, false),
+			},
+			"type": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"description": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"code": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+		},
+	}
+}
+
+func getOpenidClientAuthorizationJSPolicyResourceFromData(data *schema.ResourceData) *keycloak.OpenidClientAuthorizationJSPolicy {
+
+	resource := keycloak.OpenidClientAuthorizationJSPolicy{
+		Id:               data.Id(),
+		ResourceServerId: data.Get("resource_server_id").(string),
+		RealmId:          data.Get("realm_id").(string),
+		DecisionStrategy: data.Get("decision_strategy").(string),
+		Logic:            data.Get("logic").(string),
+		Name:             data.Get("name").(string),
+		Type:             "js",
+		Code:             data.Get("code").(string),
+		Description:      data.Get("description").(string),
+	}
+	return &resource
+}
+
+func setOpenidClientAuthorizationJSPolicyResourceData(data *schema.ResourceData, policy *keycloak.OpenidClientAuthorizationJSPolicy) {
+	data.SetId(policy.Id)
+
+	data.Set("resource_server_id", policy.ResourceServerId)
+	data.Set("realm_id", policy.RealmId)
+	data.Set("name", policy.Name)
+	data.Set("decision_strategy", policy.DecisionStrategy)
+	data.Set("logic", policy.Logic)
+	data.Set("description", policy.Description)
+	data.Set("code", policy.Code)
+}
+
+func resourceKeycloakOpenidClientAuthorizationJSPolicyCreate(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	resource := getOpenidClientAuthorizationJSPolicyResourceFromData(data)
+
+	err := keycloakClient.NewOpenidClientAuthorizationJSPolicy(resource)
+	if err != nil {
+		return err
+	}
+
+	setOpenidClientAuthorizationJSPolicyResourceData(data, resource)
+
+	return resourceKeycloakOpenidClientAuthorizationJSPolicyRead(data, meta)
+}
+
+func resourceKeycloakOpenidClientAuthorizationJSPolicyRead(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	realmId := data.Get("realm_id").(string)
+	resourceServerId := data.Get("resource_server_id").(string)
+	id := data.Id()
+
+	resource, err := keycloakClient.GetOpenidClientAuthorizationJSPolicy(realmId, resourceServerId, id)
+	if err != nil {
+		return handleNotFoundError(err, data)
+	}
+
+	setOpenidClientAuthorizationJSPolicyResourceData(data, resource)
+
+	return nil
+}
+
+func resourceKeycloakOpenidClientAuthorizationJSPolicyUpdate(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	resource := getOpenidClientAuthorizationJSPolicyResourceFromData(data)
+
+	err := keycloakClient.UpdateOpenidClientAuthorizationJSPolicy(resource)
+	if err != nil {
+		return err
+	}
+
+	setOpenidClientAuthorizationJSPolicyResourceData(data, resource)
+
+	return nil
+}
+
+func resourceKeycloakOpenidClientAuthorizationJSPolicyDelete(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	realmId := data.Get("realm_id").(string)
+	resourceServerId := data.Get("resource_server_id").(string)
+	id := data.Id()
+
+	return keycloakClient.DeleteOpenidClientAuthorizationJSPolicy(realmId, resourceServerId, id)
+}
diff --git a/provider/resource_keycloak_openid_client_authorization_role_policy.go b/provider/resource_keycloak_openid_client_authorization_role_policy.go
new file mode 100644
index 0000000..09b9b23
--- /dev/null
+++ b/provider/resource_keycloak_openid_client_authorization_role_policy.go
@@ -0,0 +1,165 @@
+package provider
+
+import (
+	"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
+	"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
+	"github.com/mrparkers/terraform-provider-keycloak/keycloak"
+)
+
+func resourceKeycloakOpenidClientAuthorizationRolePolicy() *schema.Resource {
+	return &schema.Resource{
+		Create: resourceKeycloakOpenidClientAuthorizationRolePolicyCreate,
+		Read:   resourceKeycloakOpenidClientAuthorizationRolePolicyRead,
+		Delete: resourceKeycloakOpenidClientAuthorizationRolePolicyDelete,
+		Update: resourceKeycloakOpenidClientAuthorizationRolePolicyUpdate,
+		Importer: &schema.ResourceImporter{
+			State: genericResourcePolicyImport,
+		},
+		Schema: map[string]*schema.Schema{
+			"resource_server_id": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"realm_id": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"name": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"decision_strategy": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"logic": {
+				Type:         schema.TypeString,
+				Optional:     true,
+				ValidateFunc: validation.StringInSlice(keycloakPolicyLogicTypes, false),
+			},
+			"type": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"description": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"role": {
+				Type:     schema.TypeList,
+				Required: true,
+				MinItems: 1,
+				Elem: &schema.Resource{
+					Schema: map[string]*schema.Schema{
+						"id": {
+							Type:     schema.TypeString,
+							Required: true,
+						},
+						"required": {
+							Type:     schema.TypeBool,
+							Required: true,
+						},
+					},
+				},
+			},
+		},
+	}
+}
+
+func getOpenidClientAuthorizationRolePolicyResourceFromData(data *schema.ResourceData) *keycloak.OpenidClientAuthorizationRolePolicy {
+	var rolesList []keycloak.OpenidClientAuthorizationRole
+	if v, ok := data.Get("role").([]interface{}); ok {
+		for _, role := range v {
+			roleMap := role.(map[string]interface{})
+			tempRole := keycloak.OpenidClientAuthorizationRole{
+				Id:       roleMap["id"].(string),
+				Required: roleMap["required"].(bool),
+			}
+			rolesList = append(rolesList, tempRole)
+		}
+	}
+
+	resource := keycloak.OpenidClientAuthorizationRolePolicy{
+		Id:               data.Id(),
+		ResourceServerId: data.Get("resource_server_id").(string),
+		RealmId:          data.Get("realm_id").(string),
+		DecisionStrategy: data.Get("decision_strategy").(string),
+		Logic:            data.Get("logic").(string),
+		Name:             data.Get("name").(string),
+		Type:             "role",
+		Roles:            rolesList,
+		Description:      data.Get("description").(string),
+	}
+
+	return &resource
+}
+
+func setOpenidClientAuthorizationRolePolicyResourceData(data *schema.ResourceData, policy *keycloak.OpenidClientAuthorizationRolePolicy) {
+	data.SetId(policy.Id)
+
+	data.Set("resource_server_id", policy.ResourceServerId)
+	data.Set("realm_id", policy.RealmId)
+	data.Set("name", policy.Name)
+	data.Set("decision_strategy", policy.DecisionStrategy)
+	data.Set("logic", policy.Logic)
+	data.Set("type", policy.Type)
+	data.Set("description", policy.Description)
+	data.Set("roles", policy.Roles)
+}
+
+func resourceKeycloakOpenidClientAuthorizationRolePolicyCreate(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	resource := getOpenidClientAuthorizationRolePolicyResourceFromData(data)
+
+	err := keycloakClient.NewOpenidClientAuthorizationRolePolicy(resource)
+	if err != nil {
+		return err
+	}
+
+	setOpenidClientAuthorizationRolePolicyResourceData(data, resource)
+
+	return resourceKeycloakOpenidClientAuthorizationRolePolicyRead(data, meta)
+}
+
+func resourceKeycloakOpenidClientAuthorizationRolePolicyRead(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	realmId := data.Get("realm_id").(string)
+	resourceServerId := data.Get("resource_server_id").(string)
+	id := data.Id()
+
+	resource, err := keycloakClient.GetOpenidClientAuthorizationRolePolicy(realmId, resourceServerId, id)
+	if err != nil {
+		return handleNotFoundError(err, data)
+	}
+
+	setOpenidClientAuthorizationRolePolicyResourceData(data, resource)
+
+	return nil
+}
+
+func resourceKeycloakOpenidClientAuthorizationRolePolicyUpdate(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	resource := getOpenidClientAuthorizationRolePolicyResourceFromData(data)
+
+	err := keycloakClient.UpdateOpenidClientAuthorizationRolePolicy(resource)
+	if err != nil {
+		return err
+	}
+
+	setOpenidClientAuthorizationRolePolicyResourceData(data, resource)
+
+	return nil
+}
+
+func resourceKeycloakOpenidClientAuthorizationRolePolicyDelete(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	realmId := data.Get("realm_id").(string)
+	resourceServerId := data.Get("resource_server_id").(string)
+	id := data.Id()
+
+	return keycloakClient.DeleteOpenidClientAuthorizationRolePolicy(realmId, resourceServerId, id)
+}
diff --git a/provider/resource_keycloak_openid_client_authorization_time_policy.go b/provider/resource_keycloak_openid_client_authorization_time_policy.go
new file mode 100644
index 0000000..6f8e0d1
--- /dev/null
+++ b/provider/resource_keycloak_openid_client_authorization_time_policy.go
@@ -0,0 +1,202 @@
+package provider
+
+import (
+	"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
+	"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
+	"github.com/mrparkers/terraform-provider-keycloak/keycloak"
+)
+
+func resourceKeycloakOpenidClientAuthorizationTimePolicy() *schema.Resource {
+	return &schema.Resource{
+		Create: resourceKeycloakOpenidClientAuthorizationTimePolicyCreate,
+		Read:   resourceKeycloakOpenidClientAuthorizationTimePolicyRead,
+		Delete: resourceKeycloakOpenidClientAuthorizationTimePolicyDelete,
+		Update: resourceKeycloakOpenidClientAuthorizationTimePolicyUpdate,
+		Importer: &schema.ResourceImporter{
+			State: genericResourcePolicyImport,
+		},
+		Schema: map[string]*schema.Schema{
+			"resource_server_id": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"realm_id": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"name": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"decision_strategy": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"logic": {
+				Type:         schema.TypeString,
+				Optional:     true,
+				ValidateFunc: validation.StringInSlice(keycloakPolicyLogicTypes, false),
+			},
+			"description": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"not_before": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"not_on_or_after": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"day_month": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"day_month_end": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"month": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"month_end": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"year": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"year_end": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"hour": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"hour_end": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"minute": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"minute_end": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+		},
+	}
+}
+
+func getOpenidClientAuthorizationTimePolicyResourceFromData(data *schema.ResourceData) *keycloak.OpenidClientAuthorizationTimePolicy {
+
+	resource := keycloak.OpenidClientAuthorizationTimePolicy{
+		Id:               data.Id(),
+		ResourceServerId: data.Get("resource_server_id").(string),
+		RealmId:          data.Get("realm_id").(string),
+		DecisionStrategy: data.Get("decision_strategy").(string),
+		Logic:            data.Get("logic").(string),
+		Name:             data.Get("name").(string),
+		Type:             "time",
+		NotBefore:        data.Get("not_before").(string),
+		NotOnOrAfter:     data.Get("not_on_or_after").(string),
+		DayMonth:         data.Get("day_month").(string),
+		DayMonthEnd:      data.Get("day_month_end").(string),
+		Month:            data.Get("month").(string),
+		MonthEnd:         data.Get("month_end").(string),
+		Year:             data.Get("year").(string),
+		YearEnd:          data.Get("year_end").(string),
+		Hour:             data.Get("hour").(string),
+		HourEnd:          data.Get("hour_end").(string),
+		Minute:           data.Get("minute").(string),
+		MinuteEnd:        data.Get("minute_end").(string),
+		Description:      data.Get("description").(string),
+	}
+	return &resource
+}
+
+func setOpenidClientAuthorizationTimePolicyResourceData(data *schema.ResourceData, policy *keycloak.OpenidClientAuthorizationTimePolicy) {
+	data.SetId(policy.Id)
+
+	data.Set("resource_server_id", policy.ResourceServerId)
+	data.Set("realm_id", policy.RealmId)
+	data.Set("name", policy.Name)
+	data.Set("decision_strategy", policy.DecisionStrategy)
+	data.Set("logic", policy.Logic)
+	data.Set("type", policy.Type)
+	data.Set("description", policy.Description)
+	data.Set("not_on_or_after", policy.NotOnOrAfter)
+	data.Set("not_before", policy.NotBefore)
+	data.Set("day_month", policy.DayMonth)
+	data.Set("day_month_end", policy.DayMonthEnd)
+	data.Set("month", policy.Month)
+	data.Set("month_end", policy.MonthEnd)
+	data.Set("year", policy.Year)
+	data.Set("year_end", policy.YearEnd)
+	data.Set("hour", policy.Hour)
+	data.Set("hour_end", policy.HourEnd)
+	data.Set("minute", policy.Minute)
+	data.Set("minute_end", policy.MinuteEnd)
+}
+
+func resourceKeycloakOpenidClientAuthorizationTimePolicyCreate(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	resource := getOpenidClientAuthorizationTimePolicyResourceFromData(data)
+
+	err := keycloakClient.NewOpenidClientAuthorizationTimePolicy(resource)
+	if err != nil {
+		return err
+	}
+
+	setOpenidClientAuthorizationTimePolicyResourceData(data, resource)
+
+	return resourceKeycloakOpenidClientAuthorizationTimePolicyRead(data, meta)
+}
+
+func resourceKeycloakOpenidClientAuthorizationTimePolicyRead(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	realmId := data.Get("realm_id").(string)
+	resourceServerId := data.Get("resource_server_id").(string)
+	id := data.Id()
+
+	resource, err := keycloakClient.GetOpenidClientAuthorizationTimePolicy(realmId, resourceServerId, id)
+	if err != nil {
+		return handleNotFoundError(err, data)
+	}
+
+	setOpenidClientAuthorizationTimePolicyResourceData(data, resource)
+
+	return nil
+}
+
+func resourceKeycloakOpenidClientAuthorizationTimePolicyUpdate(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	resource := getOpenidClientAuthorizationTimePolicyResourceFromData(data)
+
+	err := keycloakClient.UpdateOpenidClientAuthorizationTimePolicy(resource)
+	if err != nil {
+		return err
+	}
+
+	setOpenidClientAuthorizationTimePolicyResourceData(data, resource)
+
+	return nil
+}
+
+func resourceKeycloakOpenidClientAuthorizationTimePolicyDelete(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	realmId := data.Get("realm_id").(string)
+	resourceServerId := data.Get("resource_server_id").(string)
+	id := data.Id()
+
+	return keycloakClient.DeleteOpenidClientAuthorizationTimePolicy(realmId, resourceServerId, id)
+}
diff --git a/provider/resource_keycloak_openid_client_authorization_user_policy.go b/provider/resource_keycloak_openid_client_authorization_user_policy.go
new file mode 100644
index 0000000..1d25f17
--- /dev/null
+++ b/provider/resource_keycloak_openid_client_authorization_user_policy.go
@@ -0,0 +1,142 @@
+package provider
+
+import (
+	"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
+	"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
+	"github.com/mrparkers/terraform-provider-keycloak/keycloak"
+)
+
+func resourceKeycloakOpenidClientAuthorizationUserPolicy() *schema.Resource {
+	return &schema.Resource{
+		Create: resourceKeycloakOpenidClientAuthorizationUserPolicyCreate,
+		Read:   resourceKeycloakOpenidClientAuthorizationUserPolicyRead,
+		Delete: resourceKeycloakOpenidClientAuthorizationUserPolicyDelete,
+		Update: resourceKeycloakOpenidClientAuthorizationUserPolicyUpdate,
+		Importer: &schema.ResourceImporter{
+			State: genericResourcePolicyImport,
+		},
+		Schema: map[string]*schema.Schema{
+			"resource_server_id": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"realm_id": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"name": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"decision_strategy": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"logic": {
+				Type:         schema.TypeString,
+				Optional:     true,
+				ValidateFunc: validation.StringInSlice(keycloakPolicyLogicTypes, false),
+			},
+			"description": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"users": {
+				Type:     schema.TypeSet,
+				Elem:     &schema.Schema{Type: schema.TypeString},
+				Required: true,
+			},
+		},
+	}
+}
+
+func getOpenidClientAuthorizationUserPolicyResourceFromData(data *schema.ResourceData) *keycloak.OpenidClientAuthorizationUserPolicy {
+	var users []string
+	if v, ok := data.GetOk("users"); ok {
+		for _, user := range v.(*schema.Set).List() {
+			users = append(users, user.(string))
+		}
+	}
+
+	resource := keycloak.OpenidClientAuthorizationUserPolicy{
+		Id:               data.Id(),
+		ResourceServerId: data.Get("resource_server_id").(string),
+		RealmId:          data.Get("realm_id").(string),
+		DecisionStrategy: data.Get("decision_strategy").(string),
+		Logic:            data.Get("logic").(string),
+		Name:             data.Get("name").(string),
+		Type:             "user",
+		Users:            users,
+		Description:      data.Get("description").(string),
+	}
+	return &resource
+}
+
+func setOpenidClientAuthorizationUserPolicyResourceData(data *schema.ResourceData, policy *keycloak.OpenidClientAuthorizationUserPolicy) {
+	data.SetId(policy.Id)
+
+	data.Set("resource_server_id", policy.ResourceServerId)
+	data.Set("realm_id", policy.RealmId)
+	data.Set("name", policy.Name)
+	data.Set("decision_strategy", policy.DecisionStrategy)
+	data.Set("logic", policy.Logic)
+	data.Set("description", policy.Description)
+	data.Set("users", policy.Users)
+}
+
+func resourceKeycloakOpenidClientAuthorizationUserPolicyCreate(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	resource := getOpenidClientAuthorizationUserPolicyResourceFromData(data)
+
+	err := keycloakClient.NewOpenidClientAuthorizationUserPolicy(resource)
+	if err != nil {
+		return err
+	}
+
+	setOpenidClientAuthorizationUserPolicyResourceData(data, resource)
+
+	return resourceKeycloakOpenidClientAuthorizationUserPolicyRead(data, meta)
+}
+
+func resourceKeycloakOpenidClientAuthorizationUserPolicyRead(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	realmId := data.Get("realm_id").(string)
+	resourceServerId := data.Get("resource_server_id").(string)
+	id := data.Id()
+
+	resource, err := keycloakClient.GetOpenidClientAuthorizationUserPolicy(realmId, resourceServerId, id)
+	if err != nil {
+		return handleNotFoundError(err, data)
+	}
+
+	setOpenidClientAuthorizationUserPolicyResourceData(data, resource)
+
+	return nil
+}
+
+func resourceKeycloakOpenidClientAuthorizationUserPolicyUpdate(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	resource := getOpenidClientAuthorizationUserPolicyResourceFromData(data)
+
+	err := keycloakClient.UpdateOpenidClientAuthorizationUserPolicy(resource)
+	if err != nil {
+		return err
+	}
+
+	setOpenidClientAuthorizationUserPolicyResourceData(data, resource)
+
+	return nil
+}
+
+func resourceKeycloakOpenidClientAuthorizationUserPolicyDelete(data *schema.ResourceData, meta interface{}) error {
+	keycloakClient := meta.(*keycloak.KeycloakClient)
+
+	realmId := data.Get("realm_id").(string)
+	resourceServerId := data.Get("resource_server_id").(string)
+	id := data.Id()
+
+	return keycloakClient.DeleteOpenidClientAuthorizationUserPolicy(realmId, resourceServerId, id)
+}


Test patch:
diff --git a/provider/resource_keycloak_authentication_execution_config_test.go b/provider/resource_keycloak_authentication_execution_config_test.go
new file mode 100644
index 0000000..b0e19dc
--- /dev/null
+++ b/provider/resource_keycloak_authentication_execution_config_test.go
@@ -0,0 +1,253 @@
+package provider
+
+import (
+	"fmt"
+	"testing"
+
+	"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
+	"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
+	"github.com/hashicorp/terraform-plugin-sdk/terraform"
+	"github.com/mrparkers/terraform-provider-keycloak/keycloak"
+)
+
+func TestAccKeycloakAuthenticationExecutionConfig_basic(t *testing.T) {
+	realmName := "terraform-r-" + acctest.RandString(10)
+	var config1, config2 keycloak.AuthenticationExecutionConfig
+
+	resource.Test(t, resource.TestCase{
+		Providers:    testAccProviders,
+		PreCheck:     func() { testAccPreCheck(t) },
+		CheckDestroy: testAccCheckKeycloakAuthenticationExecutionConfigDestroy,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKeycloakAuthenticationExecutionConfig(realmName),
+				Check: resource.ComposeTestCheckFunc(
+					testAccCheckKeycloakAuthenticationExecutionConfigExists("keycloak_authentication_execution_config.config", &config1),
+					resource.TestCheckResourceAttr("keycloak_authentication_execution_config.config", "realm_id", realmName),
+					resource.TestCheckResourceAttr("keycloak_authentication_execution_config.config", "alias", "some-config-alias"),
+					resource.TestCheckResourceAttr("keycloak_authentication_execution_config.config", "config.%", "1"),
+					resource.TestCheckResourceAttr("keycloak_authentication_execution_config.config", "config.defaultProvider", "some-config-default-idp"),
+				),
+			},
+			{
+				Config: testAccKeycloakAuthenticationExecutionConfigUpdatedConfig(realmName),
+				Check: resource.ComposeTestCheckFunc(
+					testAccCheckKeycloakAuthenticationExecutionConfigExists("keycloak_authentication_execution_config.config", &config2),
+					resource.TestCheckResourceAttr("keycloak_authentication_execution_config.config", "realm_id", realmName),
+					resource.TestCheckResourceAttr("keycloak_authentication_execution_config.config", "alias", "some-config-alias"),
+					resource.TestCheckResourceAttr("keycloak_authentication_execution_config.config", "config.%", "1"),
+					resource.TestCheckResourceAttr("keycloak_authentication_execution_config.config", "config.defaultProvider", "some-updated-config-default-idp"),
+					testAccCheckKeycloakAuthenticationExecutionConfigForceNew(&config1, &config2, false),
+				),
+			},
+		},
+	})
+}
+
+func TestAccKeycloakAuthenticationExecutionConfig_updateForcesNew(t *testing.T) {
+	realmName := "terraform-r-" + acctest.RandString(10)
+	var config1, config2 keycloak.AuthenticationExecutionConfig
+
+	resource.Test(t, resource.TestCase{
+		Providers:    testAccProviders,
+		PreCheck:     func() { testAccPreCheck(t) },
+		CheckDestroy: testAccCheckKeycloakAuthenticationExecutionConfigDestroy,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKeycloakAuthenticationExecutionConfig(realmName),
+				Check: resource.ComposeTestCheckFunc(
+					testAccCheckKeycloakAuthenticationExecutionConfigExists("keycloak_authentication_execution_config.config", &config1),
+					resource.TestCheckResourceAttr("keycloak_authentication_execution_config.config", "realm_id", realmName),
+					resource.TestCheckResourceAttr("keycloak_authentication_execution_config.config", "alias", "some-config-alias"),
+					resource.TestCheckResourceAttr("keycloak_authentication_execution_config.config", "config.%", "1"),
+					resource.TestCheckResourceAttr("keycloak_authentication_execution_config.config", "config.defaultProvider", "some-config-default-idp"),
+				),
+			},
+			{
+				Config: testAccKeycloakAuthenticationExecutionConfigUpdatedAlias(realmName),
+				Check: resource.ComposeTestCheckFunc(
+					testAccCheckKeycloakAuthenticationExecutionConfigExists("keycloak_authentication_execution_config.config", &config2),
+					resource.TestCheckResourceAttr("keycloak_authentication_execution_config.config", "realm_id", realmName),
+					resource.TestCheckResourceAttr("keycloak_authentication_execution_config.config", "alias", "some-updated-config-alias"),
+					resource.TestCheckResourceAttr("keycloak_authentication_execution_config.config", "config.%", "1"),
+					resource.TestCheckResourceAttr("keycloak_authentication_execution_config.config", "config.defaultProvider", "some-config-default-idp"),
+					testAccCheckKeycloakAuthenticationExecutionConfigForceNew(&config1, &config2, true),
+				),
+			},
+		},
+	})
+}
+
+func TestAccKeycloakAuthenticationExecutionConfig_import(t *testing.T) {
+	realmName := "terraform-r-" + acctest.RandString(10)
+
+	resource.Test(t, resource.TestCase{
+		Providers:    testAccProviders,
+		PreCheck:     func() { testAccPreCheck(t) },
+		CheckDestroy: testAccCheckKeycloakAuthenticationExecutionConfigDestroy,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccKeycloakAuthenticationExecutionConfig(realmName),
+			},
+			{
+				ResourceName:      "keycloak_authentication_execution_config.config",
+				ImportState:       true,
+				ImportStateVerify: true,
+				ImportStateIdFunc: getExecutionConfigImportId("keycloak_authentication_execution_config.config"),
+			},
+		},
+	})
+}
+
+func getExecutionConfigImportId(resourceName string) resource.ImportStateIdFunc {
+	return func(s *terraform.State) (string, error) {
+		rs, ok := s.RootModule().Resources[resourceName]
+		if !ok {
+			return "", fmt.Errorf("resource %s not found", resourceName)
+		}
+
+		realmId := rs.Primary.Attributes["realm_id"]
+		executionId := rs.Primary.Attributes["execution_id"]
+		id := rs.Primary.ID
+
+		return fmt.Sprintf("%s/%s/%s", realmId, executionId, id), nil
+	}
+}
+
+func testAccCheckKeycloakAuthenticationExecutionConfigExists(resourceName string, config *keycloak.AuthenticationExecutionConfig) resource.TestCheckFunc {
+	return func(s *terraform.State) error {
+		rs, ok := s.RootModule().Resources[resourceName]
+		if !ok {
+			return fmt.Errorf("resource %s not found in state", resourceName)
+		}
+
+		config.RealmId = rs.Primary.Attributes["realm_id"]
+		config.ExecutionId = rs.Primary.Attributes["execution_id"]
+		config.Id = rs.Primary.ID
+
+		keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient)
+		if err := keycloakClient.GetAuthenticationExecutionConfig(config); err != nil {
+			return fmt.Errorf("error fetching authentication execution config: %v", err)
+		}
+
+		return nil
+	}
+}
+
+func testAccCheckKeycloakAuthenticationExecutionConfigDestroy(s *terraform.State) error {
+	keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient)
+
+	for _, rs := range s.RootModule().Resources {
+		if rs.Type != "keycloak_authentication_execution_config" {
+			continue
+		}
+
+		config := &keycloak.AuthenticationExecutionConfig{
+			RealmId: rs.Primary.Attributes["realm_id"],
+			Id:      rs.Primary.ID,
+		}
+		if err := keycloakClient.GetAuthenticationExecutionConfig(config); err == nil {
+			return fmt.Errorf("authentication execution config still exists")
+		} else if !keycloak.ErrorIs404(err) {
+			return fmt.Errorf("could not fetch authentication execution config: %v", err)
+		}
+	}
+
+	return nil
+}
+
+func testAccCheckKeycloakAuthenticationExecutionConfigForceNew(old, new *keycloak.AuthenticationExecutionConfig, wantNew bool) resource.TestCheckFunc {
+	return func(s *terraform.State) error {
+		if wantNew {
+			if old.Id == new.Id {
+				return fmt.Errorf("expecting authentication execution config ID to differ, got %+v and %+v", old, new)
+			}
+		} else {
+			if old.Id != new.Id {
+				return fmt.Errorf("expecting authentication execution config ID to be equal, got %+v and %+v", old, new)
+			}
+		}
+		return nil
+	}
+}
+
+func testAccKeycloakAuthenticationExecutionConfig(realm string) string {
+	return fmt.Sprintf(`
+resource "keycloak_realm" "realm" {
+	realm = "%s"
+}
+
+resource "keycloak_authentication_flow" "flow" {
+	realm_id = "${keycloak_realm.realm.id}"
+	alias    = "some-flow-alias"
+}
+
+resource "keycloak_authentication_execution" "execution" {
+	realm_id          = "${keycloak_realm.realm.id}"
+	parent_flow_alias = "${keycloak_authentication_flow.flow.alias}"
+	authenticator     = "identity-provider-redirector"
+}
+
+resource "keycloak_authentication_execution_config" "config" {
+	realm_id     = "${keycloak_realm.realm.id}"
+	execution_id = "${keycloak_authentication_execution.execution.id}"
+	alias        = "some-config-alias"
+	config = {
+		defaultProvider = "some-config-default-idp"
+	}
+}`, realm)
+}
+
+func testAccKeycloakAuthenticationExecutionConfigUpdatedConfig(realm string) string {
+	return fmt.Sprintf(`
+resource "keycloak_realm" "realm" {
+	realm = "%s"
+}
+
+resource "keycloak_authentication_flow" "flow" {
+	realm_id = "${keycloak_realm.realm.id}"
+	alias    = "some-flow-alias"
+}
+
+resource "keycloak_authentication_execution" "execution" {
+	realm_id          = "${keycloak_realm.realm.id}"
+	parent_flow_alias = "${keycloak_authentication_flow.flow.alias}"
+	authenticator     = "identity-provider-redirector"
+}
+
+resource "keycloak_authentication_execution_config" "config" {
+	realm_id     = "${keycloak_realm.realm.id}"
+	execution_id = "${keycloak_authentication_execution.execution.id}"
+	alias        = "some-config-alias"
+	config = {
+		defaultProvider = "some-updated-config-default-idp"
+	}
+}`, realm)
+}
+
+func testAccKeycloakAuthenticationExecutionConfigUpdatedAlias(realm string) string {
+	return fmt.Sprintf(`
+resource "keycloak_realm" "realm" {
+	realm = "%s"
+}
+
+resource "keycloak_authentication_flow" "flow" {
+	realm_id = "${keycloak_realm.realm.id}"
+	alias    = "some-flow-alias"
+}
+
+resource "keycloak_authentication_execution" "execution" {
+	realm_id          = "${keycloak_realm.realm.id}"
+	parent_flow_alias = "${keycloak_authentication_flow.flow.alias}"
+	authenticator     = "identity-provider-redirector"
+}
+
+resource "keycloak_authentication_execution_config" "config" {
+	realm_id     = "${keycloak_realm.realm.id}"
+	execution_id = "${keycloak_authentication_execution.execution.id}"
+	alias        = "some-updated-config-alias"
+	config = {
+		defaultProvider = "some-config-default-idp"
+	}
+}`, realm)
+}
diff --git a/provider/resource_keycloak_generic_client_role_mapper_test.go b/provider/resource_keycloak_generic_client_role_mapper_test.go
new file mode 100644
index 0000000..5260f3a
--- /dev/null
+++ b/provider/resource_keycloak_generic_client_role_mapper_test.go
@@ -0,0 +1,142 @@
+package provider
+
+import (
+	"fmt"
+	"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
+	"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
+	"github.com/hashicorp/terraform-plugin-sdk/terraform"
+	"github.com/mrparkers/terraform-provider-keycloak/keycloak"
+	"testing"
+)
+
+func TestGenericRoleMapper_basic(t *testing.T) {
+	realmName := "terraform-" + acctest.RandString(10)
+	parentClientName := "client1-" + acctest.RandString(10)
+	parentRoleName := "role-" + acctest.RandString(10)
+	childClientName := "client2-" + acctest.RandString(10)
+
+	resource.Test(t, resource.TestCase{
+		Providers: testAccProviders,
+		PreCheck:  func() { testAccPreCheck(t) },
+		Steps: []resource.TestStep{
+			{
+				Config: testKeycloakGenericRoleMapping_basic(realmName, parentClientName, parentRoleName, childClientName),
+				Check:  testAccCheckKeycloakScopeMappingExists("keycloak_generic_client_role_mapper.child-client-with-parent-client-role"),
+			},
+		},
+	})
+}
+
+func TestGenericRoleMapper_createAfterManualDestroy(t *testing.T) {
+	var role = &keycloak.Role{}
+	var childClient = &keycloak.GenericClient{}
+
+	realmName := "terraform-" + acctest.RandString(10)
+	parentClientName := "client1-" + acctest.RandString(10)
+	parentRoleName := "role-" + acctest.RandString(10)
+	childClientName := "client2-" + acctest.RandString(10)
+
+	resource.Test(t, resource.TestCase{
+		Providers: testAccProviders,
+		PreCheck:  func() { testAccPreCheck(t) },
+		Steps: []resource.TestStep{
+			{
+				Config: testKeycloakGenericRoleMapping_basic(realmName, parentClientName, parentRoleName, childClientName),
+				Check: resource.ComposeTestCheckFunc(
+					testAccCheckKeycloakScopeMappingExists("keycloak_generic_client_role_mapper.child-client-with-parent-client-role"),
+					testAccCheckKeycloakRoleFetch("keycloak_role.parent-role", role),
+					testAccCheckKeycloakGenericClientFetch("keycloak_openid_client.child-client", childClient),
+				),
+			},
+			{
+				PreConfig: func() {
+					keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient)
+
+					err := keycloakClient.DeleteRoleScopeMapping(childClient.RealmId, childClient.Id, role)
+					if err != nil {
+						t.Fatal(err)
+					}
+				},
+				Config: testKeycloakGenericRoleMapping_basic(realmName, parentClientName, parentRoleName, childClientName),
+				Check:  testAccCheckKeycloakScopeMappingExists("keycloak_generic_client_role_mapper.child-client-with-parent-client-role"),
+			},
+		},
+	})
+}
+
+func testKeycloakGenericRoleMapping_basic(realmName, parentClientName, parentRoleName, childClientName string) string {
+	return fmt.Sprintf(`
+resource "keycloak_realm" "realm" {
+	realm = "%s"
+}
+
+resource "keycloak_openid_client" "parent-client" {
+	realm_id    = "${keycloak_realm.realm.id}"
+	client_id   = "%s"
+	access_type = "PUBLIC"
+}
+
+resource "keycloak_role" "parent-role" {
+  realm_id  = "${keycloak_realm.realm.id}"
+  client_id = "${keycloak_openid_client.parent-client.id}"
+  name      = "%s"
+}
+
+resource "keycloak_openid_client" "child-client" {
+	realm_id    = "${keycloak_realm.realm.id}"
+	client_id   = "%s"
+	access_type = "PUBLIC"
+}
+
+resource "keycloak_generic_client_role_mapper" "child-client-with-parent-client-role" {
+  realm_id  = "${keycloak_realm.realm.id}"
+  client_id = "${keycloak_openid_client.child-client.id}"
+  role_id   = "${keycloak_role.parent-role.id}"
+}
+	`, realmName, parentClientName, parentRoleName, childClientName)
+}
+
+func testAccCheckKeycloakScopeMappingExists(resourceName string) resource.TestCheckFunc {
+	return func(s *terraform.State) error {
+		_, ok := s.RootModule().Resources[resourceName]
+		if !ok {
+			return fmt.Errorf("resource not found: %s", resourceName)
+		}
+
+		return nil
+	}
+}
+
+func testAccCheckKeycloakGenericClientFetch(resourceName string, client *keycloak.GenericClient) resource.TestCheckFunc {
+	return func(s *terraform.State) error {
+		fetchedClient, err := getGenericClientFromState(s, resourceName)
+		if err != nil {
+			return err
+		}
+
+		client.Id = fetchedClient.Id
+		client.ClientId = fetchedClient.ClientId
+		client.RealmId = fetchedClient.RealmId
+
+		return nil
+	}
+}
+
+func getGenericClientFromState(s *terraform.State, resourceName string) (*keycloak.GenericClient, error) {
+	keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient)
+
+	rs, ok := s.RootModule().Resources[resourceName]
+	if !ok {
+		return nil, fmt.Errorf("resource not found: %s", resourceName)
+	}
+
+	id := rs.Primary.ID
+	realm := rs.Primary.Attributes["realm_id"]
+
+	client, err := keycloakClient.GetGenericClient(realm, id)
+	if err != nil {
+		return nil, fmt.Errorf("error getting generic client %s: %s", id, err)
+	}
+
+	return client, nil
+}
diff --git a/provider/resource_keycloak_openid_client_authorization_aggregate_policy_test.go b/provider/resource_keycloak_openid_client_authorization_aggregate_policy_test.go
new file mode 100644
index 0000000..9e26331
--- /dev/null
+++ b/provider/resource_keycloak_openid_client_authorization_aggregate_policy_test.go
@@ -0,0 +1,127 @@
+package provider
+
+import (
+	"fmt"
+	"testing"
+
+	"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
+	"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
+	"github.com/hashicorp/terraform-plugin-sdk/terraform"
+	"github.com/mrparkers/terraform-provider-keycloak/keycloak"
+)
+
+func TestResourceKeycloakOpenidClientAuthorizationAggregatePolicy(t *testing.T) {
+	realmName := "terraform-" + acctest.RandString(10)
+	clientId := "terraform-" + acctest.RandString(10)
+
+	resource.Test(t, resource.TestCase{
+		Providers:    testAccProviders,
+		PreCheck:     func() { testAccPreCheck(t) },
+		CheckDestroy: testResourceKeycloakOpenidClientAuthorizationAggregatePolicyDestroy(),
+		Steps: []resource.TestStep{
+			{
+				Config: testResourceKeycloakOpenidClientAuthorizationAggregatePolicy_basic(realmName, clientId),
+				Check:  testResourceKeycloakOpenidClientAuthorizationAggregatePolicyExists("keycloak_openid_client_aggregate_policy.test"),
+			},
+		},
+	})
+}
+
+func getResourceKeycloakOpenidClientAuthorizationAggregatePolicyFromState(s *terraform.State, resourceName string) (*keycloak.OpenidClientAuthorizationAggregatePolicy, error) {
+	keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient)
+
+	rs, ok := s.RootModule().Resources[resourceName]
+	if !ok {
+		return nil, fmt.Errorf("resource not found: %s", resourceName)
+	}
+
+	realm := rs.Primary.Attributes["realm_id"]
+	resourceServerId := rs.Primary.Attributes["resource_server_id"]
+	policyId := rs.Primary.ID
+
+	policy, err := keycloakClient.GetOpenidClientAuthorizationAggregatePolicy(realm, resourceServerId, policyId)
+	if err != nil {
+		return nil, fmt.Errorf("error getting openid client auth aggregate policy config with alias %s: %s", resourceServerId, err)
+	}
+
+	return policy, nil
+}
+
+func testResourceKeycloakOpenidClientAuthorizationAggregatePolicyDestroy() resource.TestCheckFunc {
+	return func(s *terraform.State) error {
+		for _, rs := range s.RootModule().Resources {
+			if rs.Type != "keycloak_openid_client_aggregate_policy" {
+				continue
+			}
+
+			realm := rs.Primary.Attributes["realm"]
+			resourceServerId := rs.Primary.Attributes["resource_server_id"]
+			policyId := rs.Primary.ID
+
+			keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient)
+
+			policy, _ := keycloakClient.GetOpenidClientAuthorizationAggregatePolicy(realm, resourceServerId, policyId)
+			if policy != nil {
+				return fmt.Errorf("policy config with id %s still exists", policyId)
+			}
+		}
+
+		return nil
+	}
+}
+
+func testResourceKeycloakOpenidClientAuthorizationAggregatePolicyExists(resourceName string) resource.TestCheckFunc {
+	return func(s *terraform.State) error {
+		_, err := getResourceKeycloakOpenidClientAuthorizationAggregatePolicyFromState(s, resourceName)
+		if err != nil {
+			return err
+		}
+
+		return nil
+	}
+}
+
+func testResourceKeycloakOpenidClientAuthorizationAggregatePolicy_basic(realm, clientId string) string {
+	return fmt.Sprintf(`
+	resource keycloak_realm test {
+		realm = "%s"
+	}
+	
+	resource keycloak_openid_client test {
+		client_id                = "%s"
+		realm_id                 = "${keycloak_realm.test.id}"
+		access_type              = "CONFIDENTIAL"
+		service_accounts_enabled = true
+		authorization {
+			policy_enforcement_mode = "ENFORCING"
+		}
+	}
+
+	resource "keycloak_role" "test" {
+    realm_id    = "${keycloak_realm.test.id}"
+    name        = "aggregate_policy_role"
+	}
+
+	resource keycloak_openid_client_role_policy test {
+		resource_server_id = "${keycloak_openid_client.test.resource_server_id}"
+		realm_id = "${keycloak_realm.test.id}"
+		name = "keycloak_openid_client_role_policy"
+		decision_strategy = "UNANIMOUS"
+		logic = "POSITIVE"
+		type = "role"
+		role  {
+			id = "${keycloak_role.test.id}" 
+			required = false
+		}
+	}
+	
+	resource keycloak_openid_client_aggregate_policy test {
+		resource_server_id = "${keycloak_openid_client.test.resource_server_id}"
+		realm_id = "${keycloak_realm.test.id}"
+		name = "keycloak_openid_client_aggregate_policy"
+		decision_strategy = "UNANIMOUS"
+		logic = "POSITIVE"
+		policies = ["${keycloak_openid_client_role_policy.test.id}"]
+	}
+	`, realm, clientId)
+}
diff --git a/provider/resource_keycloak_openid_client_authorization_client_policy_test.go b/provider/resource_keycloak_openid_client_authorization_client_policy_test.go
new file mode 100644
index 0000000..c7cb31c
--- /dev/null
+++ b/provider/resource_keycloak_openid_client_authorization_client_policy_test.go
@@ -0,0 +1,112 @@
+package provider
+
+import (
+	"fmt"
+	"testing"
+
+	"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
+	"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
+	"github.com/hashicorp/terraform-plugin-sdk/terraform"
+	"github.com/mrparkers/terraform-provider-keycloak/keycloak"
+)
+
+func TestResourceKeycloakOpenidClientAuthorizationClientPolicy(t *testing.T) {
+	realmName := "terraform-" + acctest.RandString(10)
+	clientId := "terraform-" + acctest.RandString(10)
+	roleName := "terraform-" + acctest.RandString(10)
+
+	resource.Test(t, resource.TestCase{
+		Providers:    testAccProviders,
+		PreCheck:     func() { testAccPreCheck(t) },
+		CheckDestroy: testResourceKeycloakOpenidClientAuthorizationClientPolicyDestroy(),
+		Steps: []resource.TestStep{
+			{
+				Config: testResourceKeycloakOpenidClientAuthorizationClientPolicy_basic(realmName, roleName, clientId),
+				Check:  testResourceKeycloakOpenidClientAuthorizationClientPolicyExists("keycloak_openid_client_client_policy.test"),
+			},
+		},
+	})
+}
+
+func getResourceKeycloakOpenidClientAuthorizationClientPolicyFromState(s *terraform.State, resourceName string) (*keycloak.OpenidClientAuthorizationClientPolicy, error) {
+	keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient)
+
+	rs, ok := s.RootModule().Resources[resourceName]
+	if !ok {
+		return nil, fmt.Errorf("resource not found: %s", resourceName)
+	}
+
+	realm := rs.Primary.Attributes["realm_id"]
+	resourceServerId := rs.Primary.Attributes["resource_server_id"]
+	policyId := rs.Primary.ID
+
+	policy, err := keycloakClient.GetOpenidClientAuthorizationClientPolicy(realm, resourceServerId, policyId)
+	if err != nil {
+		return nil, fmt.Errorf("error getting openid client auth role policy config with alias %s: %s", resourceServerId, err)
+	}
+
+	return policy, nil
+}
+
+func testResourceKeycloakOpenidClientAuthorizationClientPolicyDestroy() resource.TestCheckFunc {
+	return func(s *terraform.State) error {
+		for _, rs := range s.RootModule().Resources {
+			if rs.Type != "keycloak_openid_client_client_policy" {
+				continue
+			}
+
+			realm := rs.Primary.Attributes["realm_id"]
+			resourceServerId := rs.Primary.Attributes["resource_server_id"]
+			policyId := rs.Primary.ID
+
+			keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient)
+
+			policy, _ := keycloakClient.GetOpenidClientAuthorizationClientPolicy(realm, resourceServerId, policyId)
+			if policy != nil {
+				return fmt.Errorf("policy config with id %s still exists", policyId)
+			}
+		}
+
+		return nil
+	}
+}
+
+func testResourceKeycloakOpenidClientAuthorizationClientPolicyExists(resourceName string) resource.TestCheckFunc {
+	return func(s *terraform.State) error {
+		_, err := getResourceKeycloakOpenidClientAuthorizationClientPolicyFromState(s, resourceName)
+
+		if err != nil {
+			return err
+		}
+
+		return nil
+	}
+}
+
+func testResourceKeycloakOpenidClientAuthorizationClientPolicy_basic(realm, roleName, clientId string) string {
+
+	return fmt.Sprintf(`
+	resource keycloak_realm test {
+		realm = "%s"
+	}
+	
+	resource keycloak_openid_client test {
+		client_id                = "%s"
+		realm_id                 = "${keycloak_realm.test.id}"
+		access_type              = "CONFIDENTIAL"
+		service_accounts_enabled = true
+		authorization {
+			policy_enforcement_mode = "ENFORCING"
+		}
+	}
+	
+	resource keycloak_openid_client_client_policy test {
+		resource_server_id = "${keycloak_openid_client.test.resource_server_id}"
+		realm_id = "${keycloak_realm.test.id}"
+		name = "keycloak_openid_client_client_policy"
+		decision_strategy = "AFFIRMATIVE"
+		logic = "POSITIVE"
+		clients = ["${keycloak_openid_client.test.resource_server_id}"]
+	}
+	`, realm, clientId)
+}
diff --git a/provider/resource_keycloak_openid_client_authorization_group_policy_test.go b/provider/resource_keycloak_openid_client_authorization_group_policy_test.go
new file mode 100644
index 0000000..05ac43b
--- /dev/null
+++ b/provider/resource_keycloak_openid_client_authorization_group_policy_test.go
@@ -0,0 +1,119 @@
+package provider
+
+import (
+	"fmt"
+	"testing"
+
+	"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
+	"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
+	"github.com/hashicorp/terraform-plugin-sdk/terraform"
+	"github.com/mrparkers/terraform-provider-keycloak/keycloak"
+)
+
+func TestResourceKeycloakOpenidClientAuthorizationGroupPolicy(t *testing.T) {
+	realmName := "terraform-" + acctest.RandString(10)
+	clientId := "terraform-" + acctest.RandString(10)
+
+	resource.Test(t, resource.TestCase{
+		Providers:    testAccProviders,
+		PreCheck:     func() { testAccPreCheck(t) },
+		CheckDestroy: testResourceKeycloakOpenidClientAuthorizationGroupPolicyDestroy(),
+		Steps: []resource.TestStep{
+			{
+				Config: testResourceKeycloakOpenidClientAuthorizationGroupPolicy_basic(realmName, clientId),
+				Check:  testResourceKeycloakOpenidClientAuthorizationGroupPolicyExists("keycloak_openid_client_group_policy.test"),
+			},
+		},
+	})
+}
+
+func getResourceKeycloakOpenidClientAuthorizationGroupPolicyFromState(s *terraform.State, resourceName string) (*keycloak.OpenidClientAuthorizationGroupPolicy, error) {
+	keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient)
+
+	rs, ok := s.RootModule().Resources[resourceName]
+	if !ok {
+		return nil, fmt.Errorf("resource not found: %s", resourceName)
+	}
+
+	realm := rs.Primary.Attributes["realm_id"]
+	resourceServerId := rs.Primary.Attributes["resource_server_id"]
+	policyId := rs.Primary.ID
+
+	policy, err := keycloakClient.GetOpenidClientAuthorizationGroupPolicy(realm, resourceServerId, policyId)
+	if err != nil {
+		return nil, fmt.Errorf("error getting openid client auth role policy config with alias %s: %s", resourceServerId, err)
+	}
+
+	return policy, nil
+}
+
+func testResourceKeycloakOpenidClientAuthorizationGroupPolicyDestroy() resource.TestCheckFunc {
+	return func(s *terraform.State) error {
+		for _, rs := range s.RootModule().Resources {
+			if rs.Type != "keycloak_openid_client_group_policy" {
+				continue
+			}
+
+			realm := rs.Primary.Attributes["realm_id"]
+			resourceServerId := rs.Primary.Attributes["resource_server_id"]
+			policyId := rs.Primary.ID
+
+			keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient)
+
+			policy, _ := keycloakClient.GetOpenidClientAuthorizationGroupPolicy(realm, resourceServerId, policyId)
+			if policy != nil {
+				return fmt.Errorf("policy config with id %s still exists", policyId)
+			}
+		}
+
+		return nil
+	}
+}
+
+func testResourceKeycloakOpenidClientAuthorizationGroupPolicyExists(resourceName string) resource.TestCheckFunc {
+	return func(s *terraform.State) error {
+		_, err := getResourceKeycloakOpenidClientAuthorizationGroupPolicyFromState(s, resourceName)
+
+		if err != nil {
+			return err
+		}
+
+		return nil
+	}
+}
+
+func testResourceKeycloakOpenidClientAuthorizationGroupPolicy_basic(realm, clientId string) string {
+	return fmt.Sprintf(`
+	resource keycloak_realm test {
+		realm = "%s"
+	}
+	
+	resource keycloak_openid_client test {
+		client_id                = "%s"
+		realm_id                 = "${keycloak_realm.test.id}"
+		access_type              = "CONFIDENTIAL"
+		service_accounts_enabled = true
+		authorization {
+			policy_enforcement_mode = "ENFORCING"
+		}
+	}
+
+	resource "keycloak_group" "test" {
+		realm_id = "${keycloak_realm.test.id}"
+		name     = "foo"
+	}
+
+	resource keycloak_openid_client_group_policy test {
+		resource_server_id = "${keycloak_openid_client.test.resource_server_id}"
+		realm_id = "${keycloak_realm.test.id}"
+		name = "client_group_policy_test"
+		groups {
+			id = "${keycloak_group.test.id}"
+			path = "${keycloak_group.test.path}"
+			extend_children = false
+		}
+		logic = "POSITIVE"
+		decision_strategy = "UNANIMOUS"
+	}
+	`, realm, clientId)
+}
diff --git a/provider/resource_keycloak_openid_client_authorization_js_policy_test.go b/provider/resource_keycloak_openid_client_authorization_js_policy_test.go
new file mode 100644
index 0000000..664891a
--- /dev/null
+++ b/provider/resource_keycloak_openid_client_authorization_js_policy_test.go
@@ -0,0 +1,111 @@
+package provider
+
+import (
+	"fmt"
+	"testing"
+
+	"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
+	"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
+	"github.com/hashicorp/terraform-plugin-sdk/terraform"
+	"github.com/mrparkers/terraform-provider-keycloak/keycloak"
+)
+
+func TestResourceKeycloakOpenidClientAuthorizationJSPolicy(t *testing.T) {
+	realmName := "terraform-" + acctest.RandString(10)
+	clientId := "terraform-" + acctest.RandString(10)
+
+	resource.Test(t, resource.TestCase{
+		Providers:    testAccProviders,
+		PreCheck:     func() { testAccPreCheck(t) },
+		CheckDestroy: testResourceKeycloakOpenidClientAuthorizationJSPolicyDestroy(),
+		Steps: []resource.TestStep{
+			{
+				Config: testResourceKeycloakOpenidClientAuthorizationJSPolicy_basic(realmName, clientId),
+				Check:  testResourceKeycloakOpenidClientAuthorizationJSPolicyExists("keycloak_openid_client_js_policy.test"),
+			},
+		},
+	})
+}
+
+func getResourceKeycloakOpenidClientAuthorizationJSPolicyFromState(s *terraform.State, resourceName string) (*keycloak.OpenidClientAuthorizationJSPolicy, error) {
+	keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient)
+
+	rs, ok := s.RootModule().Resources[resourceName]
+	if !ok {
+		return nil, fmt.Errorf("resource not found: %s", resourceName)
+	}
+
+	realm := rs.Primary.Attributes["realm_id"]
+	resourceServerId := rs.Primary.Attributes["resource_server_id"]
+	policyId := rs.Primary.ID
+
+	policy, err := keycloakClient.GetOpenidClientAuthorizationJSPolicy(realm, resourceServerId, policyId)
+	if err != nil {
+		return nil, fmt.Errorf("error getting openid client auth role policy config with alias %s: %s", resourceServerId, err)
+	}
+
+	return policy, nil
+}
+
+func testResourceKeycloakOpenidClientAuthorizationJSPolicyDestroy() resource.TestCheckFunc {
+	return func(s *terraform.State) error {
+		for _, rs := range s.RootModule().Resources {
+			if rs.Type != "keycloak_openid_client_js_policy" {
+				continue
+			}
+
+			realm := rs.Primary.Attributes["realm_id"]
+			resourceServerId := rs.Primary.Attributes["resource_server_id"]
+			policyId := rs.Primary.ID
+
+			keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient)
+
+			policy, _ := keycloakClient.GetOpenidClientAuthorizationJSPolicy(realm, resourceServerId, policyId)
+			if policy != nil {
+				return fmt.Errorf("policy config with id %s still exists", policyId)
+			}
+		}
+
+		return nil
+	}
+}
+
+func testResourceKeycloakOpenidClientAuthorizationJSPolicyExists(resourceName string) resource.TestCheckFunc {
+	return func(s *terraform.State) error {
+		_, err := getResourceKeycloakOpenidClientAuthorizationJSPolicyFromState(s, resourceName)
+
+		if err != nil {
+			return err
+		}
+
+		return nil
+	}
+}
+
+func testResourceKeycloakOpenidClientAuthorizationJSPolicy_basic(realm, clientId string) string {
+	return fmt.Sprintf(`
+	resource keycloak_realm test {
+		realm = "%s"
+	}
+	
+	resource keycloak_openid_client test {
+		client_id                = "%s"
+		realm_id                 = "${keycloak_realm.test.id}"
+		access_type              = "CONFIDENTIAL"
+		service_accounts_enabled = true
+		authorization {
+			policy_enforcement_mode = "ENFORCING"
+		}
+	}
+
+	resource keycloak_openid_client_js_policy test {
+		resource_server_id = "${keycloak_openid_client.test.resource_server_id}"
+		realm_id = "${keycloak_realm.test.id}"
+		name = "client_js_policy_test"
+		logic = "POSITIVE"
+		decision_strategy = "UNANIMOUS"
+		code = "test"
+		description = "description"
+	}
+	`, realm, clientId)
+}
diff --git a/provider/resource_keycloak_openid_client_authorization_role_policy_test.go b/provider/resource_keycloak_openid_client_authorization_role_policy_test.go
new file mode 100644
index 0000000..9a73af6
--- /dev/null
+++ b/provider/resource_keycloak_openid_client_authorization_role_policy_test.go
@@ -0,0 +1,121 @@
+package provider
+
+import (
+	"fmt"
+	"testing"
+
+	"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
+	"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
+	"github.com/hashicorp/terraform-plugin-sdk/terraform"
+	"github.com/mrparkers/terraform-provider-keycloak/keycloak"
+)
+
+func TestResourceKeycloakOpenidClientAuthorizationRolePolicy(t *testing.T) {
+	realmName := "terraform-" + acctest.RandString(10)
+	clientId := "terraform-" + acctest.RandString(10)
+	roleName := "terraform-" + acctest.RandString(10)
+
+	resource.Test(t, resource.TestCase{
+		Providers:    testAccProviders,
+		PreCheck:     func() { testAccPreCheck(t) },
+		CheckDestroy: testResourceKeycloakOpenidClientAuthorizationRolePolicyDestroy(),
+		Steps: []resource.TestStep{
+			{
+				Config: testResourceKeycloakOpenidClientAuthorizationRolePolicy_basic(realmName, roleName, clientId),
+				Check:  testResourceKeycloakOpenidClientAuthorizationRolePolicyExists("keycloak_openid_client_role_policy.test"),
+			},
+		},
+	})
+}
+
+func testResourceKeycloakOpenidClientAuthorizationRolePolicy_basic(realm, roleName, clientId string) string {
+
+	return fmt.Sprintf(`
+	resource keycloak_realm test {
+		realm = "%s"
+	}
+	
+	resource keycloak_openid_client test {
+		client_id                = "%s"
+		realm_id                 = "${keycloak_realm.test.id}"
+		access_type              = "CONFIDENTIAL"
+		service_accounts_enabled = true
+		authorization {
+			policy_enforcement_mode = "ENFORCING"
+		}
+	}
+	
+	resource "keycloak_role" "test" {
+    realm_id    = "${keycloak_realm.test.id}"
+    name        = "%s"
+	}
+
+	resource keycloak_openid_client_role_policy test {
+		resource_server_id = "${keycloak_openid_client.test.resource_server_id}"
+		realm_id = "${keycloak_realm.test.id}"
+		name = "keycloak_openid_client_role_policy"
+		decision_strategy = "AFFIRMATIVE"
+		logic = "POSITIVE"
+		type = "role"
+		role  {
+			id = "${keycloak_role.test.id}" 
+			required = false
+		}
+	}
+	`, realm, roleName, clientId)
+}
+
+func getResourceKeycloakOpenidClientAuthorizationRolePolicyFromState(s *terraform.State, resourceName string) (*keycloak.OpenidClientAuthorizationRolePolicy, error) {
+	keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient)
+
+	rs, ok := s.RootModule().Resources[resourceName]
+	if !ok {
+		return nil, fmt.Errorf("resource not found: %s", resourceName)
+	}
+
+	realm := rs.Primary.Attributes["realm_id"]
+	resourceServerId := rs.Primary.Attributes["resource_server_id"]
+	policyId := rs.Primary.ID
+
+	policy, err := keycloakClient.GetOpenidClientAuthorizationRolePolicy(realm, resourceServerId, policyId)
+	if err != nil {
+		return nil, fmt.Errorf("error getting openid client auth role policy config with alias %s: %s", resourceServerId, err)
+	}
+
+	return policy, nil
+}
+
+func testResourceKeycloakOpenidClientAuthorizationRolePolicyDestroy() resource.TestCheckFunc {
+	return func(s *terraform.State) error {
+		for _, rs := range s.RootModule().Resources {
+			if rs.Type != "keycloak_openid_client_role_policy" {
+				continue
+			}
+
+			realm := rs.Primary.Attributes["realm_id"]
+			resourceServerId := rs.Primary.Attributes["resource_server_id"]
+			policyId := rs.Primary.ID
+
+			keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient)
+
+			policy, _ := keycloakClient.GetOpenidClientAuthorizationRolePolicy(realm, resourceServerId, policyId)
+			if policy != nil {
+				return fmt.Errorf("policy config with id %s still exists", policyId)
+			}
+		}
+
+		return nil
+	}
+}
+
+func testResourceKeycloakOpenidClientAuthorizationRolePolicyExists(resourceName string) resource.TestCheckFunc {
+	return func(s *terraform.State) error {
+		_, err := getResourceKeycloakOpenidClientAuthorizationRolePolicyFromState(s, resourceName)
+
+		if err != nil {
+			return err
+		}
+
+		return nil
+	}
+}
diff --git a/provider/resource_keycloak_openid_client_authorization_time_policy_test.go b/provider/resource_keycloak_openid_client_authorization_time_policy_test.go
new file mode 100644
index 0000000..fb27b52
--- /dev/null
+++ b/provider/resource_keycloak_openid_client_authorization_time_policy_test.go
@@ -0,0 +1,123 @@
+package provider
+
+import (
+	"fmt"
+	"testing"
+
+	"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
+	"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
+	"github.com/hashicorp/terraform-plugin-sdk/terraform"
+	"github.com/mrparkers/terraform-provider-keycloak/keycloak"
+)
+
+func TestResourceKeycloakOpenidClientAuthorizationTimePolicy(t *testing.T) {
+	realmName := "terraform-" + acctest.RandString(10)
+	clientId := "terraform-" + acctest.RandString(10)
+	policyName := "terraform-" + acctest.RandString(10)
+
+	resource.Test(t, resource.TestCase{
+		Providers:    testAccProviders,
+		PreCheck:     func() { testAccPreCheck(t) },
+		CheckDestroy: testResourceKeycloakOpenidClientAuthorizationTimePolicyDestroy(),
+		Steps: []resource.TestStep{
+			{
+				Config: testResourceKeycloakOpenidClientAuthorizationTimePolicy_basic(realmName, policyName, clientId),
+				Check:  testResourceKeycloakOpenidClientAuthorizationTimePolicyExists("keycloak_openid_client_time_policy.test"),
+			},
+		},
+	})
+}
+
+func getResourceKeycloakOpenidClientAuthorizationTimePolicyFromState(s *terraform.State, resourceName string) (*keycloak.OpenidClientAuthorizationTimePolicy, error) {
+	keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient)
+
+	rs, ok := s.RootModule().Resources[resourceName]
+	if !ok {
+		return nil, fmt.Errorf("resource not found: %s", resourceName)
+	}
+
+	realm := rs.Primary.Attributes["realm_id"]
+	resourceServerId := rs.Primary.Attributes["resource_server_id"]
+	policyId := rs.Primary.ID
+
+	policy, err := keycloakClient.GetOpenidClientAuthorizationTimePolicy(realm, resourceServerId, policyId)
+	if err != nil {
+		return nil, fmt.Errorf("error getting openid client auth role policy config with alias %s: %s", resourceServerId, err)
+	}
+
+	return policy, nil
+}
+
+func testResourceKeycloakOpenidClientAuthorizationTimePolicyDestroy() resource.TestCheckFunc {
+	return func(s *terraform.State) error {
+		for _, rs := range s.RootModule().Resources {
+			if rs.Type != "keycloak_openid_client_time_policy" {
+				continue
+			}
+
+			realm := rs.Primary.Attributes["realm_id"]
+			resourceServerId := rs.Primary.Attributes["resource_server_id"]
+			policyId := rs.Primary.ID
+
+			keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient)
+
+			policy, _ := keycloakClient.GetOpenidClientAuthorizationTimePolicy(realm, resourceServerId, policyId)
+			if policy != nil {
+				return fmt.Errorf("policy config with id %s still exists", policyId)
+			}
+		}
+
+		return nil
+	}
+}
+
+func testResourceKeycloakOpenidClientAuthorizationTimePolicyExists(resourceName string) resource.TestCheckFunc {
+	return func(s *terraform.State) error {
+		_, err := getResourceKeycloakOpenidClientAuthorizationTimePolicyFromState(s, resourceName)
+
+		if err != nil {
+			return err
+		}
+
+		return nil
+	}
+}
+
+func testResourceKeycloakOpenidClientAuthorizationTimePolicy_basic(realm, policyName, clientId string) string {
+
+	return fmt.Sprintf(`
+	resource keycloak_realm test {
+		realm = "%s"
+	}
+	
+	resource keycloak_openid_client test {
+		client_id                = "%s"
+		realm_id                 = "${keycloak_realm.test.id}"
+		access_type              = "CONFIDENTIAL"
+		service_accounts_enabled = true
+		authorization {
+			policy_enforcement_mode = "ENFORCING"
+		}
+	}
+
+	resource keycloak_openid_client_time_policy test {
+		resource_server_id = "${keycloak_openid_client.test.resource_server_id}"
+		realm_id = "${keycloak_realm.test.id}"
+		name = "%s"
+		not_on_or_after = "2500-12-12 01:01:11"
+		not_before = "2400-12-12 01:01:11"
+		day_month = "1"
+		day_month_end = "2"
+		year = "2500"
+		year_end = "2501"
+		month = "1"
+		month_end = "5"
+		hour = "1"
+		hour_end = "5"
+		minute = "10"
+		minute_end = "30"
+		logic = "POSITIVE"
+		decision_strategy = "UNANIMOUS"
+	}
+	`, realm, clientId, policyName)
+}
diff --git a/provider/resource_keycloak_openid_client_authorization_user_policy_test.go b/provider/resource_keycloak_openid_client_authorization_user_policy_test.go
new file mode 100644
index 0000000..6e75f6c
--- /dev/null
+++ b/provider/resource_keycloak_openid_client_authorization_user_policy_test.go
@@ -0,0 +1,119 @@
+package provider
+
+import (
+	"fmt"
+	"testing"
+
+	"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
+	"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
+	"github.com/hashicorp/terraform-plugin-sdk/terraform"
+	"github.com/mrparkers/terraform-provider-keycloak/keycloak"
+)
+
+func TestResourceKeycloakOpenidClientAuthorizationUserPolicy(t *testing.T) {
+	realmName := "terraform-" + acctest.RandString(10)
+	clientId := "terraform-" + acctest.RandString(10)
+
+	resource.Test(t, resource.TestCase{
+		Providers:    testAccProviders,
+		PreCheck:     func() { testAccPreCheck(t) },
+		CheckDestroy: testResourceKeycloakOpenidClientAuthorizationUserPolicyDestroy(),
+		Steps: []resource.TestStep{
+			{
+				Config: testResourceKeycloakOpenidClientAuthorizationUserPolicy_basic(realmName, clientId),
+				Check:  testResourceKeycloakOpenidClientAuthorizationUserPolicyExists("keycloak_openid_client_user_policy.test"),
+			},
+		},
+	})
+}
+
+func getResourceKeycloakOpenidClientAuthorizationUserPolicyFromState(s *terraform.State, resourceName string) (*keycloak.OpenidClientAuthorizationUserPolicy, error) {
+	keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient)
+
+	rs, ok := s.RootModule().Resources[resourceName]
+	if !ok {
+		return nil, fmt.Errorf("resource not found: %s", resourceName)
+	}
+
+	realm := rs.Primary.Attributes["realm_id"]
+	resourceServerId := rs.Primary.Attributes["resource_server_id"]
+	policyId := rs.Primary.ID
+
+	policy, err := keycloakClient.GetOpenidClientAuthorizationUserPolicy(realm, resourceServerId, policyId)
+	if err != nil {
+		return nil, fmt.Errorf("error getting openid client auth role policy config with alias %s: %s", resourceServerId, err)
+	}
+
+	return policy, nil
+}
+
+func testResourceKeycloakOpenidClientAuthorizationUserPolicyDestroy() resource.TestCheckFunc {
+	return func(s *terraform.State) error {
+		for _, rs := range s.RootModule().Resources {
+			if rs.Type != "keycloak_openid_client_user_policy" {
+				continue
+			}
+
+			realm := rs.Primary.Attributes["realm_id"]
+			resourceServerId := rs.Primary.Attributes["resource_server_id"]
+			policyId := rs.Primary.ID
+
+			keycloakClient := testAccProvider.Meta().(*keycloak.KeycloakClient)
+
+			policy, _ := keycloakClient.GetOpenidClientAuthorizationUserPolicy(realm, resourceServerId, policyId)
+			if policy != nil {
+				return fmt.Errorf("policy config with id %s still exists", policyId)
+			}
+		}
+
+		return nil
+	}
+}
+
+func testResourceKeycloakOpenidClientAuthorizationUserPolicyExists(resourceName string) resource.TestCheckFunc {
+	return func(s *terraform.State) error {
+		_, err := getResourceKeycloakOpenidClientAuthorizationUserPolicyFromState(s, resourceName)
+
+		if err != nil {
+			return err
+		}
+
+		return nil
+	}
+}
+
+func testResourceKeycloakOpenidClientAuthorizationUserPolicy_basic(realm, clientId string) string {
+	return fmt.Sprintf(`
+	resource keycloak_realm test {
+		realm = "%s"
+	}
+	
+	resource keycloak_openid_client test {
+		client_id                = "%s"
+		realm_id                 = "${keycloak_realm.test.id}"
+		access_type              = "CONFIDENTIAL"
+		service_accounts_enabled = true
+		authorization {
+			policy_enforcement_mode = "ENFORCING"
+		}
+	}
+
+	resource keycloak_user test {
+		realm_id = "${keycloak_realm.test.id}"
+		username = "test-user"
+	
+		email      = "test-user@fakedomain.com"
+		first_name = "Testy"
+		last_name  = "Tester"
+	}
+
+	resource keycloak_openid_client_user_policy test {
+		resource_server_id = "${keycloak_openid_client.test.resource_server_id}"
+		realm_id = "${keycloak_realm.test.id}"
+		name = "client_user_policy_test"
+		users = ["${keycloak_user.test.id}"]
+		logic = "POSITIVE"
+		decision_strategy = "UNANIMOUS"
+	}
+	`, realm, clientId)
+}
diff --git a/provider/resource_keycloak_role_test.go b/provider/resource_keycloak_role_test.go
index 1940af5..ef44144 100644
--- a/provider/resource_keycloak_role_test.go
+++ b/provider/resource_keycloak_role_test.go
@@ -308,6 +308,7 @@ func testAccCheckKeycloakRoleFetch(resourceName string, role *keycloak.Role) res
 		role.Id = fetchedRole.Id
 		role.Name = fetchedRole.Name
 		role.RealmId = fetchedRole.RealmId
+		role.ClientId = fetchedRole.ClientId
 
 		return nil
 	}