1. Registry
  2. Packages
  3. Keycloak Provider
  4. API Docs
  5. openid
  6. getClientAuthorizationScope
Viewing docs for Keycloak v6.13.0
published on Saturday, Aug 1, 2026 by Pulumi
keycloak logo keycloak logo
Viewing docs for Keycloak v6.13.0
published on Saturday, Aug 1, 2026 by Pulumi

    This data source fetches an authorization scope by name from an OpenID client that has authorization enabled.

    The primary use case is looking up scopes that Keycloak creates automatically — for example, the view, manage, view-members, manage-members, and manage-membership scopes that Keycloak creates on the realm-management client when Fine-Grained Admin Permissions are enabled for a group. These scopes need to be referenced by ID in keycloak.openid.ClientAuthorizationPermission, but their IDs are not known until after the permissions have been initialized. Providing a scope name directly (instead of an ID) causes plan instability because Keycloak always stores and returns scope IDs.

    Example Usage

    The following example demonstrates the primary use case: resolving an authorization scope by name so it can be referenced by ID in a keycloak.openid.ClientAuthorizationPermission. Using a scope name directly causes plan instability because Keycloak normalises the value to an ID on write — this data source fixes that.

    import * as pulumi from "@pulumi/pulumi";
    import * as keycloak from "@pulumi/keycloak";
    
    const realm = new keycloak.Realm("realm", {realm: "my-realm"});
    // An application client with authorization enabled.
    const app = new keycloak.openid.Client("app", {
        realmId: realm.id,
        clientId: "my-app",
        accessType: "CONFIDENTIAL",
        serviceAccountsEnabled: true,
        authorization: {
            policyEnforcementMode: "ENFORCING",
        },
    });
    // A named scope on the authorization-enabled client.
    const readOrdersClientAuthorizationScope = new keycloak.openid.ClientAuthorizationScope("read_orders", {
        realmId: realm.id,
        resourceServerId: app.resourceServerId,
        name: "read:orders",
    });
    // Resolve the scope ID by name — stable across plan/apply cycles.
    const readOrders = keycloak.openid.getClientAuthorizationScopeOutput({
        realmId: realm.id,
        resourceServerId: app.resourceServerId,
        name: "read:orders",
    });
    const orders = new keycloak.openid.ClientAuthorizationResource("orders", {
        realmId: realm.id,
        resourceServerId: app.resourceServerId,
        name: "orders",
        uris: ["/orders/*"],
    });
    const readOrdersClientAuthorizationPermission = new keycloak.openid.ClientAuthorizationPermission("read_orders", {
        realmId: realm.id,
        resourceServerId: app.resourceServerId,
        name: "read-orders-permission",
        type: "scope",
        decisionStrategy: "UNANIMOUS",
        resources: [orders.id],
        scopes: [readOrders.apply(readOrders => readOrders.id)],
    });
    
    import pulumi
    import pulumi_keycloak as keycloak
    
    realm = keycloak.Realm("realm", realm="my-realm")
    # An application client with authorization enabled.
    app = keycloak.openid.Client("app",
        realm_id=realm.id,
        client_id="my-app",
        access_type="CONFIDENTIAL",
        service_accounts_enabled=True,
        authorization={
            "policy_enforcement_mode": "ENFORCING",
        })
    # A named scope on the authorization-enabled client.
    read_orders_client_authorization_scope = keycloak.openid.ClientAuthorizationScope("read_orders",
        realm_id=realm.id,
        resource_server_id=app.resource_server_id,
        name="read:orders")
    # Resolve the scope ID by name — stable across plan/apply cycles.
    read_orders = keycloak.openid.get_client_authorization_scope_output(realm_id=realm.id,
        resource_server_id=app.resource_server_id,
        name="read:orders")
    orders = keycloak.openid.ClientAuthorizationResource("orders",
        realm_id=realm.id,
        resource_server_id=app.resource_server_id,
        name="orders",
        uris=["/orders/*"])
    read_orders_client_authorization_permission = keycloak.openid.ClientAuthorizationPermission("read_orders",
        realm_id=realm.id,
        resource_server_id=app.resource_server_id,
        name="read-orders-permission",
        type="scope",
        decision_strategy="UNANIMOUS",
        resources=[orders.id],
        scopes=[read_orders.id])
    
    package main
    
    import (
    	"github.com/pulumi/pulumi-keycloak/sdk/v6/go/keycloak"
    	"github.com/pulumi/pulumi-keycloak/sdk/v6/go/keycloak/openid"
    	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
    )
    
    func main() {
    	pulumi.Run(func(ctx *pulumi.Context) error {
    		realm, err := keycloak.NewRealm(ctx, "realm", &keycloak.RealmArgs{
    			Realm: pulumi.String("my-realm"),
    		})
    		if err != nil {
    			return err
    		}
    		// An application client with authorization enabled.
    		app, err := openid.NewClient(ctx, "app", &openid.ClientArgs{
    			RealmId:                realm.ID(),
    			ClientId:               pulumi.String("my-app"),
    			AccessType:             pulumi.String("CONFIDENTIAL"),
    			ServiceAccountsEnabled: pulumi.Bool(true),
    			Authorization: &openid.ClientAuthorizationArgs{
    				PolicyEnforcementMode: pulumi.String("ENFORCING"),
    			},
    		})
    		if err != nil {
    			return err
    		}
    		// A named scope on the authorization-enabled client.
    		_, err = openid.NewClientAuthorizationScope(ctx, "read_orders", &openid.ClientAuthorizationScopeArgs{
    			RealmId:          realm.ID(),
    			ResourceServerId: app.ResourceServerId,
    			Name:             pulumi.String("read:orders"),
    		})
    		if err != nil {
    			return err
    		}
    		// Resolve the scope ID by name — stable across plan/apply cycles.
    		readOrders := openid.LookupClientAuthorizationScopeOutput(ctx, openid.GetClientAuthorizationScopeOutputArgs{
    			RealmId:          realm.ID(),
    			ResourceServerId: app.ResourceServerId,
    			Name:             pulumi.String("read:orders"),
    		}, nil)
    		orders, err := openid.NewClientAuthorizationResource(ctx, "orders", &openid.ClientAuthorizationResourceArgs{
    			RealmId:          realm.ID(),
    			ResourceServerId: app.ResourceServerId,
    			Name:             pulumi.String("orders"),
    			Uris: pulumi.StringArray{
    				pulumi.String("/orders/*"),
    			},
    		})
    		if err != nil {
    			return err
    		}
    		_, err = openid.NewClientAuthorizationPermission(ctx, "read_orders", &openid.ClientAuthorizationPermissionArgs{
    			RealmId:          realm.ID(),
    			ResourceServerId: app.ResourceServerId,
    			Name:             pulumi.String("read-orders-permission"),
    			Type:             pulumi.String("scope"),
    			DecisionStrategy: pulumi.String("UNANIMOUS"),
    			Resources: pulumi.StringArray{
    				orders.ID(),
    			},
    			Scopes: pulumi.StringArray{
    				pulumi.String(readOrders.ApplyT(func(readOrders openid.GetClientAuthorizationScopeResult) (*string, error) {
    					return readOrders.Id, nil
    				}).(pulumi.StringPtrOutput)),
    			},
    		})
    		if err != nil {
    			return err
    		}
    		return nil
    	})
    }
    
    using System.Collections.Generic;
    using System.Linq;
    using Pulumi;
    using Keycloak = Pulumi.Keycloak;
    
    return await Deployment.RunAsync(() => 
    {
        var realm = new Keycloak.Realm("realm", new()
        {
            RealmName = "my-realm",
        });
    
        // An application client with authorization enabled.
        var app = new Keycloak.OpenId.Client("app", new()
        {
            RealmId = realm.Id,
            ClientId = "my-app",
            AccessType = "CONFIDENTIAL",
            ServiceAccountsEnabled = true,
            Authorization = new Keycloak.OpenId.Inputs.ClientAuthorizationArgs
            {
                PolicyEnforcementMode = "ENFORCING",
            },
        });
    
        // A named scope on the authorization-enabled client.
        var readOrdersClientAuthorizationScope = new Keycloak.OpenId.ClientAuthorizationScope("read_orders", new()
        {
            RealmId = realm.Id,
            ResourceServerId = app.ResourceServerId,
            Name = "read:orders",
        });
    
        // Resolve the scope ID by name — stable across plan/apply cycles.
        var readOrders = Keycloak.OpenId.GetClientAuthorizationScope.Invoke(new()
        {
            RealmId = realm.Id,
            ResourceServerId = app.ResourceServerId,
            Name = "read:orders",
        });
    
        var orders = new Keycloak.OpenId.ClientAuthorizationResource("orders", new()
        {
            RealmId = realm.Id,
            ResourceServerId = app.ResourceServerId,
            Name = "orders",
            Uris = new[]
            {
                "/orders/*",
            },
        });
    
        var readOrdersClientAuthorizationPermission = new Keycloak.OpenId.ClientAuthorizationPermission("read_orders", new()
        {
            RealmId = realm.Id,
            ResourceServerId = app.ResourceServerId,
            Name = "read-orders-permission",
            Type = "scope",
            DecisionStrategy = "UNANIMOUS",
            Resources = new[]
            {
                orders.Id,
            },
            Scopes = new[]
            {
                readOrders.Apply(getClientAuthorizationScopeResult => getClientAuthorizationScopeResult.Id),
            },
        });
    
    });
    
    package generated_program;
    
    import com.pulumi.Context;
    import com.pulumi.Pulumi;
    import com.pulumi.core.Output;
    import com.pulumi.keycloak.Realm;
    import com.pulumi.keycloak.RealmArgs;
    import com.pulumi.keycloak.openid.Client;
    import com.pulumi.keycloak.openid.ClientArgs;
    import com.pulumi.keycloak.openid.inputs.ClientAuthorizationArgs;
    import com.pulumi.keycloak.openid.ClientAuthorizationScope;
    import com.pulumi.keycloak.openid.ClientAuthorizationScopeArgs;
    import com.pulumi.keycloak.openid.OpenidFunctions;
    import com.pulumi.keycloak.openid.inputs.GetClientAuthorizationScopeArgs;
    import com.pulumi.keycloak.openid.ClientAuthorizationResource;
    import com.pulumi.keycloak.openid.ClientAuthorizationResourceArgs;
    import com.pulumi.keycloak.openid.ClientAuthorizationPermission;
    import com.pulumi.keycloak.openid.ClientAuthorizationPermissionArgs;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Map;
    import java.io.File;
    import java.nio.file.Files;
    import java.nio.file.Paths;
    
    public class App {
        public static void main(String[] args) {
            Pulumi.run(App::stack);
        }
    
        public static void stack(Context ctx) {
            var realm = new Realm("realm", RealmArgs.builder()
                .realm("my-realm")
                .build());
    
            // An application client with authorization enabled.
            var app = new Client("app", ClientArgs.builder()
                .realmId(realm.id())
                .clientId("my-app")
                .accessType("CONFIDENTIAL")
                .serviceAccountsEnabled(true)
                .authorization(ClientAuthorizationArgs.builder()
                    .policyEnforcementMode("ENFORCING")
                    .build())
                .build());
    
            // A named scope on the authorization-enabled client.
            var readOrdersClientAuthorizationScope = new ClientAuthorizationScope("readOrdersClientAuthorizationScope", ClientAuthorizationScopeArgs.builder()
                .realmId(realm.id())
                .resourceServerId(app.resourceServerId())
                .name("read:orders")
                .build());
    
            // Resolve the scope ID by name — stable across plan/apply cycles.
            final var readOrders = OpenidFunctions.getClientAuthorizationScope(GetClientAuthorizationScopeArgs.builder()
                .realmId(realm.id())
                .resourceServerId(app.resourceServerId())
                .name("read:orders")
                .build());
    
            var orders = new ClientAuthorizationResource("orders", ClientAuthorizationResourceArgs.builder()
                .realmId(realm.id())
                .resourceServerId(app.resourceServerId())
                .name("orders")
                .uris("/orders/*")
                .build());
    
            var readOrdersClientAuthorizationPermission = new ClientAuthorizationPermission("readOrdersClientAuthorizationPermission", ClientAuthorizationPermissionArgs.builder()
                .realmId(realm.id())
                .resourceServerId(app.resourceServerId())
                .name("read-orders-permission")
                .type("scope")
                .decisionStrategy("UNANIMOUS")
                .resources(orders.id())
                .scopes(readOrders.applyValue(_readOrders -> _readOrders.id()))
                .build());
    
        }
    }
    
    resources:
      realm:
        type: keycloak:Realm
        properties:
          realm: my-realm
      # An application client with authorization enabled.
      app:
        type: keycloak:openid:Client
        properties:
          realmId: ${realm.id}
          clientId: my-app
          accessType: CONFIDENTIAL
          serviceAccountsEnabled: true
          authorization:
            policyEnforcementMode: ENFORCING
      # A named scope on the authorization-enabled client.
      readOrdersClientAuthorizationScope:
        type: keycloak:openid:ClientAuthorizationScope
        name: read_orders
        properties:
          realmId: ${realm.id}
          resourceServerId: ${app.resourceServerId}
          name: read:orders
      orders:
        type: keycloak:openid:ClientAuthorizationResource
        properties:
          realmId: ${realm.id}
          resourceServerId: ${app.resourceServerId}
          name: orders
          uris:
            - /orders/*
      readOrdersClientAuthorizationPermission:
        type: keycloak:openid:ClientAuthorizationPermission
        name: read_orders
        properties:
          realmId: ${realm.id}
          resourceServerId: ${app.resourceServerId}
          name: read-orders-permission
          type: scope
          decisionStrategy: UNANIMOUS
          resources:
            - ${orders.id}
          scopes:
            - ${readOrders.id}
    variables:
      # Resolve the scope ID by name — stable across plan/apply cycles.
      readOrders:
        fn::invoke:
          function: keycloak:openid:getClientAuthorizationScope
          arguments:
            realmId: ${realm.id}
            resourceServerId: ${app.resourceServerId}
            name: read:orders
    
    pulumi {
      required_providers {
        keycloak = {
          source = "pulumi/keycloak"
        }
      }
    }
    
    data "keycloak_openid_getclientauthorizationscope" "readOrders" {
      realm_id           = keycloak_realm.realm.id
      resource_server_id = keycloak_openid_client.app.resource_server_id
      name               = "read:orders"
    }
    
    resource "keycloak_realm" "realm" {
      realm = "my-realm"
    }
    # An application client with authorization enabled.
    resource "keycloak_openid_client" "app" {
      realm_id                 = keycloak_realm.realm.id
      client_id                = "my-app"
      access_type              = "CONFIDENTIAL"
      service_accounts_enabled = true
      authorization = {
        policy_enforcement_mode = "ENFORCING"
      }
    }
    # A named scope on the authorization-enabled client.
    resource "keycloak_openid_clientauthorizationscope" "read_orders" {
      realm_id           = keycloak_realm.realm.id
      resource_server_id = keycloak_openid_client.app.resource_server_id
      name               = "read:orders"
    }
    resource "keycloak_openid_clientauthorizationresource" "orders" {
      realm_id           = keycloak_realm.realm.id
      resource_server_id = keycloak_openid_client.app.resource_server_id
      name               = "orders"
      uris               = ["/orders/*"]
    }
    resource "keycloak_openid_clientauthorizationpermission" "read_orders" {
      realm_id           = keycloak_realm.realm.id
      resource_server_id = keycloak_openid_client.app.resource_server_id
      name               = "read-orders-permission"
      type               = "scope"
      decision_strategy  = "UNANIMOUS"
      resources          = [keycloak_openid_clientauthorizationresource.orders.id]
      scopes             = [data.keycloak_openid_getclientauthorizationscope.readOrders.id]
    }
    # Resolve the scope ID by name — stable across plan/apply cycles.
    

    FGAPv2 example: role-based map-role permission

    The following shows how to use FGAPv2 (admin-fine-grained-authz:v2) to grant members of an hr-managers group permission to map an hr-viewer role. The map-role scope lives on the admin-permissions resource server; this data source resolves its ID for use in a custom scope-based permission alongside the one managed by keycloak.RoleAdminPermissions.

    import * as pulumi from "@pulumi/pulumi";
    import * as keycloak from "@pulumi/keycloak";
    
    const realm = new keycloak.Realm("realm", {
        realm: "my-realm",
        adminPermissionsEnabled: true,
    });
    const adminPermissions = keycloak.openid.getClientOutput({
        realmId: realm.id,
        clientId: "admin-permissions",
    });
    const hrViewer = new keycloak.Role("hr_viewer", {
        realmId: realm.id,
        name: "hr-viewer",
    });
    const hrViewerRoleAdminPermissions = new keycloak.RoleAdminPermissions("hr_viewer", {
        realmId: realm.id,
        name: "map-role-hr-viewer",
        roleIds: [hrViewer.id],
        scopes: ["map-role"],
    });
    // Resolve the map-role scope by name for use in a custom permission.
    const mapRole = keycloak.openid.getClientAuthorizationScopeOutput({
        realmId: realm.id,
        resourceServerId: adminPermissions.apply(adminPermissions => adminPermissions.id),
        name: "map-role",
    });
    const hrManagers = new keycloak.Group("hr_managers", {
        realmId: realm.id,
        name: "hr-managers",
    });
    const hrManagersClientGroupPolicy = new keycloak.openid.ClientGroupPolicy("hr_managers", {
        realmId: realm.id,
        resourceServerId: adminPermissions.apply(adminPermissions => adminPermissions.id),
        name: "policy-hr-managers",
        decisionStrategy: "UNANIMOUS",
        logic: "POSITIVE",
        groups: [{
            id: hrManagers.id,
            path: hrManagers.path,
            extendChildren: false,
        }],
    });
    const hrManagersMapRole = new keycloak.openid.ClientAuthorizationPermission("hr_managers_map_role", {
        realmId: realm.id,
        resourceServerId: adminPermissions.apply(adminPermissions => adminPermissions.id),
        name: "hr-managers-map-hr-viewer-role",
        type: "scope",
        decisionStrategy: "UNANIMOUS",
        resources: [hrViewer.id],
        scopes: [mapRole.apply(mapRole => mapRole.id)],
        policies: [hrManagersClientGroupPolicy.id],
    });
    
    import pulumi
    import pulumi_keycloak as keycloak
    
    realm = keycloak.Realm("realm",
        realm="my-realm",
        admin_permissions_enabled=True)
    admin_permissions = keycloak.openid.get_client_output(realm_id=realm.id,
        client_id="admin-permissions")
    hr_viewer = keycloak.Role("hr_viewer",
        realm_id=realm.id,
        name="hr-viewer")
    hr_viewer_role_admin_permissions = keycloak.RoleAdminPermissions("hr_viewer",
        realm_id=realm.id,
        name="map-role-hr-viewer",
        role_ids=[hr_viewer.id],
        scopes=["map-role"])
    # Resolve the map-role scope by name for use in a custom permission.
    map_role = keycloak.openid.get_client_authorization_scope_output(realm_id=realm.id,
        resource_server_id=admin_permissions.id,
        name="map-role")
    hr_managers = keycloak.Group("hr_managers",
        realm_id=realm.id,
        name="hr-managers")
    hr_managers_client_group_policy = keycloak.openid.ClientGroupPolicy("hr_managers",
        realm_id=realm.id,
        resource_server_id=admin_permissions.id,
        name="policy-hr-managers",
        decision_strategy="UNANIMOUS",
        logic="POSITIVE",
        groups=[{
            "id": hr_managers.id,
            "path": hr_managers.path,
            "extend_children": False,
        }])
    hr_managers_map_role = keycloak.openid.ClientAuthorizationPermission("hr_managers_map_role",
        realm_id=realm.id,
        resource_server_id=admin_permissions.id,
        name="hr-managers-map-hr-viewer-role",
        type="scope",
        decision_strategy="UNANIMOUS",
        resources=[hr_viewer.id],
        scopes=[map_role.id],
        policies=[hr_managers_client_group_policy.id])
    
    package main
    
    import (
    	"github.com/pulumi/pulumi-keycloak/sdk/v6/go/keycloak"
    	"github.com/pulumi/pulumi-keycloak/sdk/v6/go/keycloak/openid"
    	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
    )
    
    func main() {
    	pulumi.Run(func(ctx *pulumi.Context) error {
    		realm, err := keycloak.NewRealm(ctx, "realm", &keycloak.RealmArgs{
    			Realm:                   pulumi.String("my-realm"),
    			AdminPermissionsEnabled: pulumi.Bool(true),
    		})
    		if err != nil {
    			return err
    		}
    		adminPermissions := openid.LookupClientOutput(ctx, openid.GetClientOutputArgs{
    			RealmId:  realm.ID(),
    			ClientId: pulumi.String("admin-permissions"),
    		}, nil)
    		hrViewer, err := keycloak.NewRole(ctx, "hr_viewer", &keycloak.RoleArgs{
    			RealmId: realm.ID(),
    			Name:    pulumi.String("hr-viewer"),
    		})
    		if err != nil {
    			return err
    		}
    		_, err = keycloak.NewRoleAdminPermissions(ctx, "hr_viewer", &keycloak.RoleAdminPermissionsArgs{
    			RealmId: realm.ID(),
    			Name:    pulumi.String("map-role-hr-viewer"),
    			RoleIds: pulumi.StringArray{
    				hrViewer.ID(),
    			},
    			Scopes: pulumi.StringArray{
    				pulumi.String("map-role"),
    			},
    		})
    		if err != nil {
    			return err
    		}
    		// Resolve the map-role scope by name for use in a custom permission.
    		mapRole := openid.LookupClientAuthorizationScopeOutput(ctx, openid.GetClientAuthorizationScopeOutputArgs{
    			RealmId: realm.ID(),
    			ResourceServerId: adminPermissions.ApplyT(func(adminPermissions openid.GetClientResult) (*string, error) {
    				return adminPermissions.Id, nil
    			}).(pulumi.StringPtrOutput),
    			Name: pulumi.String("map-role"),
    		}, nil)
    		hrManagers, err := keycloak.NewGroup(ctx, "hr_managers", &keycloak.GroupArgs{
    			RealmId: realm.ID(),
    			Name:    pulumi.String("hr-managers"),
    		})
    		if err != nil {
    			return err
    		}
    		hrManagersClientGroupPolicy, err := openid.NewClientGroupPolicy(ctx, "hr_managers", &openid.ClientGroupPolicyArgs{
    			RealmId: realm.ID(),
    			ResourceServerId: pulumi.String(adminPermissions.ApplyT(func(adminPermissions openid.GetClientResult) (*string, error) {
    				return adminPermissions.Id, nil
    			}).(pulumi.StringPtrOutput)),
    			Name:             pulumi.String("policy-hr-managers"),
    			DecisionStrategy: pulumi.String("UNANIMOUS"),
    			Logic:            pulumi.String("POSITIVE"),
    			Groups: openid.ClientGroupPolicyGroupArray{
    				&openid.ClientGroupPolicyGroupArgs{
    					Id:             hrManagers.ID(),
    					Path:           hrManagers.Path,
    					ExtendChildren: pulumi.Bool(false),
    				},
    			},
    		})
    		if err != nil {
    			return err
    		}
    		_, err = openid.NewClientAuthorizationPermission(ctx, "hr_managers_map_role", &openid.ClientAuthorizationPermissionArgs{
    			RealmId: realm.ID(),
    			ResourceServerId: pulumi.String(adminPermissions.ApplyT(func(adminPermissions openid.GetClientResult) (*string, error) {
    				return adminPermissions.Id, nil
    			}).(pulumi.StringPtrOutput)),
    			Name:             pulumi.String("hr-managers-map-hr-viewer-role"),
    			Type:             pulumi.String("scope"),
    			DecisionStrategy: pulumi.String("UNANIMOUS"),
    			Resources: pulumi.StringArray{
    				hrViewer.ID(),
    			},
    			Scopes: pulumi.StringArray{
    				pulumi.String(mapRole.ApplyT(func(mapRole openid.GetClientAuthorizationScopeResult) (*string, error) {
    					return mapRole.Id, nil
    				}).(pulumi.StringPtrOutput)),
    			},
    			Policies: pulumi.StringArray{
    				hrManagersClientGroupPolicy.ID(),
    			},
    		})
    		if err != nil {
    			return err
    		}
    		return nil
    	})
    }
    
    using System.Collections.Generic;
    using System.Linq;
    using Pulumi;
    using Keycloak = Pulumi.Keycloak;
    
    return await Deployment.RunAsync(() => 
    {
        var realm = new Keycloak.Realm("realm", new()
        {
            RealmName = "my-realm",
            AdminPermissionsEnabled = true,
        });
    
        var adminPermissions = Keycloak.OpenId.GetClient.Invoke(new()
        {
            RealmId = realm.Id,
            ClientId = "admin-permissions",
        });
    
        var hrViewer = new Keycloak.Role("hr_viewer", new()
        {
            RealmId = realm.Id,
            Name = "hr-viewer",
        });
    
        var hrViewerRoleAdminPermissions = new Keycloak.RoleAdminPermissions("hr_viewer", new()
        {
            RealmId = realm.Id,
            Name = "map-role-hr-viewer",
            RoleIds = new[]
            {
                hrViewer.Id,
            },
            Scopes = new[]
            {
                "map-role",
            },
        });
    
        // Resolve the map-role scope by name for use in a custom permission.
        var mapRole = Keycloak.OpenId.GetClientAuthorizationScope.Invoke(new()
        {
            RealmId = realm.Id,
            ResourceServerId = adminPermissions.Apply(getClientResult => getClientResult.Id),
            Name = "map-role",
        });
    
        var hrManagers = new Keycloak.Group("hr_managers", new()
        {
            RealmId = realm.Id,
            Name = "hr-managers",
        });
    
        var hrManagersClientGroupPolicy = new Keycloak.OpenId.ClientGroupPolicy("hr_managers", new()
        {
            RealmId = realm.Id,
            ResourceServerId = adminPermissions.Apply(getClientResult => getClientResult.Id),
            Name = "policy-hr-managers",
            DecisionStrategy = "UNANIMOUS",
            Logic = "POSITIVE",
            Groups = new[]
            {
                new Keycloak.OpenId.Inputs.ClientGroupPolicyGroupArgs
                {
                    Id = hrManagers.Id,
                    Path = hrManagers.Path,
                    ExtendChildren = false,
                },
            },
        });
    
        var hrManagersMapRole = new Keycloak.OpenId.ClientAuthorizationPermission("hr_managers_map_role", new()
        {
            RealmId = realm.Id,
            ResourceServerId = adminPermissions.Apply(getClientResult => getClientResult.Id),
            Name = "hr-managers-map-hr-viewer-role",
            Type = "scope",
            DecisionStrategy = "UNANIMOUS",
            Resources = new[]
            {
                hrViewer.Id,
            },
            Scopes = new[]
            {
                mapRole.Apply(getClientAuthorizationScopeResult => getClientAuthorizationScopeResult.Id),
            },
            Policies = new[]
            {
                hrManagersClientGroupPolicy.Id,
            },
        });
    
    });
    
    package generated_program;
    
    import com.pulumi.Context;
    import com.pulumi.Pulumi;
    import com.pulumi.core.Output;
    import com.pulumi.keycloak.Realm;
    import com.pulumi.keycloak.RealmArgs;
    import com.pulumi.keycloak.openid.OpenidFunctions;
    import com.pulumi.keycloak.openid.inputs.GetClientArgs;
    import com.pulumi.keycloak.Role;
    import com.pulumi.keycloak.RoleArgs;
    import com.pulumi.keycloak.RoleAdminPermissions;
    import com.pulumi.keycloak.RoleAdminPermissionsArgs;
    import com.pulumi.keycloak.openid.inputs.GetClientAuthorizationScopeArgs;
    import com.pulumi.keycloak.Group;
    import com.pulumi.keycloak.GroupArgs;
    import com.pulumi.keycloak.openid.ClientGroupPolicy;
    import com.pulumi.keycloak.openid.ClientGroupPolicyArgs;
    import com.pulumi.keycloak.openid.inputs.ClientGroupPolicyGroupArgs;
    import com.pulumi.keycloak.openid.ClientAuthorizationPermission;
    import com.pulumi.keycloak.openid.ClientAuthorizationPermissionArgs;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Map;
    import java.io.File;
    import java.nio.file.Files;
    import java.nio.file.Paths;
    
    public class App {
        public static void main(String[] args) {
            Pulumi.run(App::stack);
        }
    
        public static void stack(Context ctx) {
            var realm = new Realm("realm", RealmArgs.builder()
                .realm("my-realm")
                .adminPermissionsEnabled(true)
                .build());
    
            final var adminPermissions = OpenidFunctions.getClient(GetClientArgs.builder()
                .realmId(realm.id())
                .clientId("admin-permissions")
                .build());
    
            var hrViewer = new Role("hrViewer", RoleArgs.builder()
                .realmId(realm.id())
                .name("hr-viewer")
                .build());
    
            var hrViewerRoleAdminPermissions = new RoleAdminPermissions("hrViewerRoleAdminPermissions", RoleAdminPermissionsArgs.builder()
                .realmId(realm.id())
                .name("map-role-hr-viewer")
                .roleIds(hrViewer.id())
                .scopes("map-role")
                .build());
    
            // Resolve the map-role scope by name for use in a custom permission.
            final var mapRole = OpenidFunctions.getClientAuthorizationScope(GetClientAuthorizationScopeArgs.builder()
                .realmId(realm.id())
                .resourceServerId(adminPermissions.applyValue(_adminPermissions -> _adminPermissions.id()))
                .name("map-role")
                .build());
    
            var hrManagers = new Group("hrManagers", GroupArgs.builder()
                .realmId(realm.id())
                .name("hr-managers")
                .build());
    
            var hrManagersClientGroupPolicy = new ClientGroupPolicy("hrManagersClientGroupPolicy", ClientGroupPolicyArgs.builder()
                .realmId(realm.id())
                .resourceServerId(adminPermissions.applyValue(_adminPermissions -> _adminPermissions.id()))
                .name("policy-hr-managers")
                .decisionStrategy("UNANIMOUS")
                .logic("POSITIVE")
                .groups(ClientGroupPolicyGroupArgs.builder()
                    .id(hrManagers.id())
                    .path(hrManagers.path())
                    .extendChildren(false)
                    .build())
                .build());
    
            var hrManagersMapRole = new ClientAuthorizationPermission("hrManagersMapRole", ClientAuthorizationPermissionArgs.builder()
                .realmId(realm.id())
                .resourceServerId(adminPermissions.applyValue(_adminPermissions -> _adminPermissions.id()))
                .name("hr-managers-map-hr-viewer-role")
                .type("scope")
                .decisionStrategy("UNANIMOUS")
                .resources(hrViewer.id())
                .scopes(mapRole.applyValue(_mapRole -> _mapRole.id()))
                .policies(hrManagersClientGroupPolicy.id())
                .build());
    
        }
    }
    
    resources:
      realm:
        type: keycloak:Realm
        properties:
          realm: my-realm
          adminPermissionsEnabled: true
      hrViewer:
        type: keycloak:Role
        name: hr_viewer
        properties:
          realmId: ${realm.id}
          name: hr-viewer
      hrViewerRoleAdminPermissions:
        type: keycloak:RoleAdminPermissions
        name: hr_viewer
        properties:
          realmId: ${realm.id}
          name: map-role-hr-viewer
          roleIds:
            - ${hrViewer.id}
          scopes:
            - map-role
      hrManagers:
        type: keycloak:Group
        name: hr_managers
        properties:
          realmId: ${realm.id}
          name: hr-managers
      hrManagersClientGroupPolicy:
        type: keycloak:openid:ClientGroupPolicy
        name: hr_managers
        properties:
          realmId: ${realm.id}
          resourceServerId: ${adminPermissions.id}
          name: policy-hr-managers
          decisionStrategy: UNANIMOUS
          logic: POSITIVE
          groups:
            - id: ${hrManagers.id}
              path: ${hrManagers.path}
              extendChildren: false
      hrManagersMapRole:
        type: keycloak:openid:ClientAuthorizationPermission
        name: hr_managers_map_role
        properties:
          realmId: ${realm.id}
          resourceServerId: ${adminPermissions.id}
          name: hr-managers-map-hr-viewer-role
          type: scope
          decisionStrategy: UNANIMOUS
          resources:
            - ${hrViewer.id}
          scopes:
            - ${mapRole.id}
          policies:
            - ${hrManagersClientGroupPolicy.id}
    variables:
      adminPermissions:
        fn::invoke:
          function: keycloak:openid:getClient
          arguments:
            realmId: ${realm.id}
            clientId: admin-permissions
      # Resolve the map-role scope by name for use in a custom permission.
      mapRole:
        fn::invoke:
          function: keycloak:openid:getClientAuthorizationScope
          arguments:
            realmId: ${realm.id}
            resourceServerId: ${adminPermissions.id}
            name: map-role
    
    pulumi {
      required_providers {
        keycloak = {
          source = "pulumi/keycloak"
        }
      }
    }
    
    data "keycloak_openid_getclient" "adminPermissions" {
      realm_id  = keycloak_realm.realm.id
      client_id = "admin-permissions"
    }
    data "keycloak_openid_getclientauthorizationscope" "mapRole" {
      realm_id           = keycloak_realm.realm.id
      resource_server_id = data.keycloak_openid_getclient.adminPermissions.id
      name               = "map-role"
    }
    
    resource "keycloak_realm" "realm" {
      realm                     = "my-realm"
      admin_permissions_enabled = true
    }
    resource "keycloak_role" "hr_viewer" {
      realm_id = keycloak_realm.realm.id
      name     = "hr-viewer"
    }
    resource "keycloak_roleadminpermissions" "hr_viewer" {
      realm_id = keycloak_realm.realm.id
      name     = "map-role-hr-viewer"
      role_ids = [keycloak_role.hr_viewer.id]
      scopes   = ["map-role"]
    }
    resource "keycloak_group" "hr_managers" {
      realm_id = keycloak_realm.realm.id
      name     = "hr-managers"
    }
    resource "keycloak_openid_clientgrouppolicy" "hr_managers" {
      realm_id           = keycloak_realm.realm.id
      resource_server_id = data.keycloak_openid_getclient.adminPermissions.id
      name               = "policy-hr-managers"
      decision_strategy  = "UNANIMOUS"
      logic              = "POSITIVE"
      groups {
        id              = keycloak_group.hr_managers.id
        path            = keycloak_group.hr_managers.path
        extend_children = false
      }
    }
    resource "keycloak_openid_clientauthorizationpermission" "hr_managers_map_role" {
      realm_id           = keycloak_realm.realm.id
      resource_server_id = data.keycloak_openid_getclient.adminPermissions.id
      name               = "hr-managers-map-hr-viewer-role"
      type               = "scope"
      decision_strategy  = "UNANIMOUS"
      resources          = [keycloak_role.hr_viewer.id]
      scopes             = [data.keycloak_openid_getclientauthorizationscope.mapRole.id]
      policies           = [keycloak_openid_clientgrouppolicy.hr_managers.id]
    }
    # Resolve the map-role scope by name for use in a custom permission.
    

    Using getClientAuthorizationScope

    Two invocation forms are available. The direct form accepts plain arguments and either blocks until the result value is available, or returns a Promise-wrapped result. The output form accepts Input-wrapped arguments and returns an Output-wrapped result.

    function getClientAuthorizationScope(args: GetClientAuthorizationScopeArgs, opts?: InvokeOptions): Promise<GetClientAuthorizationScopeResult>
    function getClientAuthorizationScopeOutput(args: GetClientAuthorizationScopeOutputArgs, opts?: InvokeOutputOptions): Output<GetClientAuthorizationScopeResult>
    def get_client_authorization_scope(name: Optional[str] = None,
                                       realm_id: Optional[str] = None,
                                       resource_server_id: Optional[str] = None,
                                       opts: Optional[InvokeOptions] = None) -> GetClientAuthorizationScopeResult
    def get_client_authorization_scope_output(name: pulumi.Input[Optional[str]] = None,
                                       realm_id: pulumi.Input[Optional[str]] = None,
                                       resource_server_id: pulumi.Input[Optional[str]] = None,
                                       opts: Optional[InvokeOutputOptions] = None) -> Output[GetClientAuthorizationScopeResult]
    func LookupClientAuthorizationScope(ctx *Context, args *LookupClientAuthorizationScopeArgs, opts ...InvokeOption) (*LookupClientAuthorizationScopeResult, error)
    func LookupClientAuthorizationScopeOutput(ctx *Context, args *LookupClientAuthorizationScopeOutputArgs, opts ...InvokeOption) LookupClientAuthorizationScopeResultOutput

    > Note: This function is named LookupClientAuthorizationScope in the Go SDK.

    public static class GetClientAuthorizationScope 
    {
        public static Task<GetClientAuthorizationScopeResult> InvokeAsync(GetClientAuthorizationScopeArgs args, InvokeOptions? opts = null)
        public static Output<GetClientAuthorizationScopeResult> Invoke(GetClientAuthorizationScopeInvokeArgs args, InvokeOptions? opts = null)
        public static Output<GetClientAuthorizationScopeResult> Invoke(GetClientAuthorizationScopeInvokeArgs args, InvokeOutputOptions opts)
    }
    public static CompletableFuture<GetClientAuthorizationScopeResult> getClientAuthorizationScope(GetClientAuthorizationScopeArgs args, InvokeOptions options)
    public static Output<GetClientAuthorizationScopeResult> getClientAuthorizationScope(GetClientAuthorizationScopeArgs args, InvokeOptions options)
    public static Output<GetClientAuthorizationScopeResult> getClientAuthorizationScope(GetClientAuthorizationScopeArgs args, InvokeOutputOptions options)
    
    fn::invoke:
      function: keycloak:openid/getClientAuthorizationScope:getClientAuthorizationScope
      arguments:
        # arguments dictionary
    data "keycloak_openid_get_client_authorization_scope" "name" {
        # arguments
    }

    The following arguments are supported:

    Name string
    The name of the authorization scope to look up.
    RealmId string
    The realm this authorization scope exists within.
    ResourceServerId string
    The ID of the resource server (client) this authorization scope belongs to.
    Name string
    The name of the authorization scope to look up.
    RealmId string
    The realm this authorization scope exists within.
    ResourceServerId string
    The ID of the resource server (client) this authorization scope belongs to.
    name string
    The name of the authorization scope to look up.
    realm_id string
    The realm this authorization scope exists within.
    resource_server_id string
    The ID of the resource server (client) this authorization scope belongs to.
    name String
    The name of the authorization scope to look up.
    realmId String
    The realm this authorization scope exists within.
    resourceServerId String
    The ID of the resource server (client) this authorization scope belongs to.
    name string
    The name of the authorization scope to look up.
    realmId string
    The realm this authorization scope exists within.
    resourceServerId string
    The ID of the resource server (client) this authorization scope belongs to.
    name str
    The name of the authorization scope to look up.
    realm_id str
    The realm this authorization scope exists within.
    resource_server_id str
    The ID of the resource server (client) this authorization scope belongs to.
    name String
    The name of the authorization scope to look up.
    realmId String
    The realm this authorization scope exists within.
    resourceServerId String
    The ID of the resource server (client) this authorization scope belongs to.

    getClientAuthorizationScope Result

    The following output properties are available:

    DisplayName string
    (Computed) The display name of the scope.
    IconUri string
    (Computed) The icon URI of the scope.
    Id string
    The provider-assigned unique ID for this managed resource.
    Name string
    RealmId string
    ResourceServerId string
    DisplayName string
    (Computed) The display name of the scope.
    IconUri string
    (Computed) The icon URI of the scope.
    Id string
    The provider-assigned unique ID for this managed resource.
    Name string
    RealmId string
    ResourceServerId string
    display_name string
    (Computed) The display name of the scope.
    icon_uri string
    (Computed) The icon URI of the scope.
    id string
    The provider-assigned unique ID for this managed resource.
    name string
    realm_id string
    resource_server_id string
    displayName String
    (Computed) The display name of the scope.
    iconUri String
    (Computed) The icon URI of the scope.
    id String
    The provider-assigned unique ID for this managed resource.
    name String
    realmId String
    resourceServerId String
    displayName string
    (Computed) The display name of the scope.
    iconUri string
    (Computed) The icon URI of the scope.
    id string
    The provider-assigned unique ID for this managed resource.
    name string
    realmId string
    resourceServerId string
    display_name str
    (Computed) The display name of the scope.
    icon_uri str
    (Computed) The icon URI of the scope.
    id str
    The provider-assigned unique ID for this managed resource.
    name str
    realm_id str
    resource_server_id str
    displayName String
    (Computed) The display name of the scope.
    iconUri String
    (Computed) The icon URI of the scope.
    id String
    The provider-assigned unique ID for this managed resource.
    name String
    realmId String
    resourceServerId String

    Package Details

    Repository
    Keycloak pulumi/pulumi-keycloak
    License
    Apache-2.0
    Notes
    This Pulumi package is based on the keycloak Terraform Provider.
    keycloak logo keycloak logo
    Viewing docs for Keycloak v6.13.0
    published on Saturday, Aug 1, 2026 by Pulumi

      Try Pulumi Cloud free.
      Your team will thank you.

      Start free trial