This implementation adds support for managing Keycloak Client Registration Policies via Terraform. Client Registration Policies control how clients can be dynamically registered through the Keycloak Client Registration Service.
This addresses the upstream issue: keycloak#715
-
keycloak/realm_client_registration_policy.go
- Keycloak API client methods for client registration policies
- CRUD operations using the Keycloak Components API
- Helper functions for config conversion
-
provider/resource_keycloak_realm_client_registration_policy.go
- Terraform resource implementation
- Schema definition with validation
- CRUD handlers
- Import support
-
provider/resource_keycloak_realm_client_registration_policy_test.go
- Comprehensive test suite
- Tests for basic functionality, import, validation, and updates
- Tests for trusted-hosts policy with multiple hosts
-
docs/resources/realm_client_registration_policy.md
- User documentation
- Usage examples for different policy types
- Configuration reference
-
keycloak/component.go
- Added
SubTypefield to component struct to support client registration policy sub-types
- Added
-
provider/provider.go
- Registered new resource
keycloak_realm_client_registration_policy
- Registered new resource
The implementation supports all Keycloak client registration policy types:
- trusted-hosts - Controls which hosts can register clients
- allowed-protocol-mappers - Controls allowed protocol mappers
- allowed-client-templates - Controls allowed client scopes
- consent-required - Requires consent for registered clients
- scope - Full scope disabled policy
- max-clients - Maximum clients limit
- anonymous - Applies to anonymous client registration requests
- authenticated - Applies to authenticated client registration requests
- Full CRUD operations (Create, Read, Update, Delete)
- Import support with format:
{{realmId}}/{{policyId}} - Validation for provider_id and sub_type fields
- Flexible config map for policy-specific settings
- Smart handling of comma-separated values (e.g., trusted-hosts)
- Comprehensive test coverage
resource "keycloak_realm" "staging" {
realm = "staging"
enabled = true
}
resource "keycloak_realm_client_registration_policy" "trusted_hosts" {
realm_id = keycloak_realm.staging.id
name = "Trusted Hosts"
provider_id = "trusted-hosts"
sub_type = "anonymous"
config = {
"trusted-hosts" = "claude.ai,opencode.ai"
"host-sending-registration-request-must-match" = "true"
"client-uris-must-match" = "true"
}
}resource "keycloak_realm_client_registration_policy" "max_clients" {
realm_id = keycloak_realm.staging.id
name = "Max Clients"
provider_id = "max-clients"
sub_type = "anonymous"
config = {
"max-clients" = "100"
}
}resource "keycloak_realm_client_registration_policy" "consent_required" {
realm_id = keycloak_realm.staging.id
name = "Consent Required"
provider_id = "consent-required"
sub_type = "authenticated"
}The implementation includes comprehensive tests:
- Basic functionality - Create and read policy
- Import test - Verify import with correct format
- Update test - Modify trusted-hosts list
- Validation tests - Ensure invalid provider_id and sub_type are rejected
- Manual destroy test - Verify recreation after manual deletion
# Format code
make fmt
# Run vet
make vet
# Build provider
make build
# Run acceptance tests (requires local Keycloak)
make testacc TESTARGS='-run=TestAccKeycloakRealmClientRegistrationPolicy'Client Registration Policies are managed via the Keycloak Components API:
Base endpoint: /admin/realms/{realm}/components
Provider type: org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy
Component structure:
{
"id": "3080544e-a34a-4f75-afd3-a464b7373f2a",
"name": "Trusted Hosts",
"providerId": "trusted-hosts",
"providerType": "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy",
"parentId": "staging",
"subType": "anonymous",
"config": {
"host-sending-registration-request-must-match": ["true"],
"client-uris-must-match": ["true"],
"trusted-hosts": ["claude.ai", "opencode.ai"]
}
}The implementation handles config values intelligently:
- Single values are stored as
[]stringwith one element - Comma-separated values (like trusted-hosts) are split into arrays in the API
- On read, arrays are joined with commas for Terraform state
- This allows users to specify:
"trusted-hosts" = "claude.ai,opencode.ai"
The following fields require resource recreation:
realm_id- Policies cannot be moved between realmsprovider_id- Policy type is immutablesub_type- Sub-type is immutable
Policies can be imported using: {{realmId}}/{{policyId}}
Example:
terraform import keycloak_realm_client_registration_policy.trusted_hosts staging/3080544e-a34a-4f75-afd3-a464b7373f2aThe implementation successfully compiles and builds:
$ make build
# Build successful: terraform-provider-keycloak_v5.6.0+bf.2- Test with local Keycloak instance - Run acceptance tests
- Create PR - Submit to upstream repository
- Document in changelog - Add entry for new resource
- Update examples - Add to provider examples directory
- Upstream Issue: keycloak#715
- Keycloak Components API: https://www.keycloak.org/docs-api/latest/rest-api/index.html#_component_resource
- Client Registration: https://www.keycloak.org/docs/latest/securing_apps/index.html#_client_registration