Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/resources/realm.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ Each of these attributes are blocks with the following attributes:
- `avoid_same_authenticator_register` - (Optional) When `true`, Keycloak will avoid registering the authenticator for WebAuthn if it has already been registered. Defaults to `false`.
- `acceptable_aaguids` - (Optional) A set of AAGUIDs for which an authenticator can be registered.
- `extra_origins` - (Optional) A set of extra origins for non-web applications.
- `passwordless_passkeys_enabled` - (Optional) When `true`, Keycloak will enable passwordless passkey support. Defaults to `false`.

## Default Client Scopes

Expand Down
1 change: 1 addition & 0 deletions keycloak/realm.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ type Realm struct {
WebAuthnPolicyPasswordlessRpId string `json:"webAuthnPolicyPasswordlessRpId"`
WebAuthnPolicyPasswordlessSignatureAlgorithms []string `json:"webAuthnPolicyPasswordlessSignatureAlgorithms"`
WebAuthnPolicyPasswordlessUserVerificationRequirement string `json:"webAuthnPolicyPasswordlessUserVerificationRequirement"`
WebAuthnPolicyPasswordlessPasskeysEnabled bool `json:"webAuthnPolicyPasswordlessPasskeysEnabled"`

// Roles
DefaultRole *Role `json:"defaultRole,omitempty"`
Expand Down
4 changes: 4 additions & 0 deletions provider/data_source_keycloak_realm.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ func dataSourceKeycloakRealm() *schema.Resource {
Description: "Either required, preferred or discouraged",
Computed: true,
},
"passwordless_passkeys_enabled": {
Type: schema.TypeBool,
Computed: true,
},
}
return &schema.Resource{
ReadContext: dataSourceKeycloakRealmRead,
Expand Down
5 changes: 5 additions & 0 deletions provider/resource_keycloak_realm.go
Original file line number Diff line number Diff line change
Expand Up @@ -1220,6 +1220,10 @@ func getRealmFromData(data *schema.ResourceData, keycloakVersion *version.Versio
if webAuthnPolicyPasswordlessUserVerificationRequirement, ok := webAuthnPasswordlessPolicy["user_verification_requirement"]; ok {
realm.WebAuthnPolicyPasswordlessUserVerificationRequirement = webAuthnPolicyPasswordlessUserVerificationRequirement.(string)
}

if webAuthnPolicyPasswordlessPasskeysEnabled, ok := webAuthnPasswordlessPolicy["passwordless_passkeys_enabled"]; ok {
realm.WebAuthnPolicyPasswordlessPasskeysEnabled = webAuthnPolicyPasswordlessPasskeysEnabled.(bool)
}
}

return realm, nil
Expand Down Expand Up @@ -1423,6 +1427,7 @@ func setRealmData(data *schema.ResourceData, realm *keycloak.Realm, keycloakVers
webAuthnPasswordlessPolicy["relying_party_id"] = realm.WebAuthnPolicyPasswordlessRpId
webAuthnPasswordlessPolicy["signature_algorithms"] = realm.WebAuthnPolicyPasswordlessSignatureAlgorithms
webAuthnPasswordlessPolicy["user_verification_requirement"] = realm.WebAuthnPolicyPasswordlessUserVerificationRequirement
webAuthnPasswordlessPolicy["passwordless_passkeys_enabled"] = realm.WebAuthnPolicyPasswordlessPasskeysEnabled
data.Set("web_authn_passwordless_policy", []interface{}{webAuthnPasswordlessPolicy})

attributes := map[string]interface{}{}
Expand Down
8 changes: 5 additions & 3 deletions provider/resource_keycloak_realm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -989,6 +989,7 @@ func TestAccKeycloakRealm_webauthn(t *testing.T) {
userVerificationRequirement := randomStringInSlice([]string{"not specified", "required", "preferred", "discouraged"})
signatureAlgorithms := randomStringSliceSubset([]string{"ES256", "ES384", "ES512", "RS256", "ES384", "ES512"})
avoidSameAuthenticatorRegister := randomBool()
passwordlessPasskeysEnabled := randomBool()

resource.Test(t, resource.TestCase{
ProviderFactories: testAccProviderFactories,
Expand All @@ -1000,7 +1001,7 @@ func TestAccKeycloakRealm_webauthn(t *testing.T) {
Check: testAccCheckKeycloakRealmExists("keycloak_realm.realm"),
},
{
Config: testKeycloakRealm_webauthn_passwordless_policy(realmName, realmDisplayName, realmDisplayNameHtml, rpName, rpId, attestationConveyancePreference, authenticatorAttachment, requireResidentKey, userVerificationRequirement, signatureAlgorithms, avoidSameAuthenticatorRegister),
Config: testKeycloakRealm_webauthn_passwordless_policy(realmName, realmDisplayName, realmDisplayNameHtml, rpName, rpId, attestationConveyancePreference, authenticatorAttachment, requireResidentKey, userVerificationRequirement, signatureAlgorithms, avoidSameAuthenticatorRegister, passwordlessPasskeysEnabled),
Check: testAccCheckKeycloakRealmExists("keycloak_realm.realm"),
},
{
Expand Down Expand Up @@ -1781,7 +1782,7 @@ resource "keycloak_realm" "realm" {
`, realm, realmDisplayName, realmDisplayNameHtml, rpName, rpId, arrayOfStringsForTerraformResource(signatureAlgorithms), attestationConveyancePreference, authenticatorAttachment, avoidSameAuthenticatorRegister, requireResidentKey, userVerificationRequirement)
}

func testKeycloakRealm_webauthn_passwordless_policy(realm, realmDisplayName, realmDisplayNameHtml, rpName, rpId, attestationConveyancePreference, authenticatorAttachment, requireResidentKey, userVerificationRequirement string, signatureAlgorithms []string, avoidSameAuthenticatorRegister bool) string {
func testKeycloakRealm_webauthn_passwordless_policy(realm, realmDisplayName, realmDisplayNameHtml, rpName, rpId, attestationConveyancePreference, authenticatorAttachment, requireResidentKey, userVerificationRequirement string, signatureAlgorithms []string, avoidSameAuthenticatorRegister bool, passwordlessPasskeysEnabled bool) string {
return fmt.Sprintf(`
resource "keycloak_realm" "realm" {
realm = "%s"
Expand All @@ -1799,9 +1800,10 @@ resource "keycloak_realm" "realm" {
avoid_same_authenticator_register = %t
require_resident_key = "%s"
user_verification_requirement = "%s"
passwordless_passkeys_enabled = %t
}
}
`, realm, realmDisplayName, realmDisplayNameHtml, rpName, rpId, arrayOfStringsForTerraformResource(signatureAlgorithms), attestationConveyancePreference, authenticatorAttachment, avoidSameAuthenticatorRegister, requireResidentKey, userVerificationRequirement)
`, realm, realmDisplayName, realmDisplayNameHtml, rpName, rpId, arrayOfStringsForTerraformResource(signatureAlgorithms), attestationConveyancePreference, authenticatorAttachment, avoidSameAuthenticatorRegister, requireResidentKey, userVerificationRequirement, passwordlessPasskeysEnabled)
}

func testKeycloakRealm_basicInternalId(realm, internalId string) string {
Expand Down
Loading