terraform-provider-keycloak icon indicating copy to clipboard operation
terraform-provider-keycloak copied to clipboard

Support for setting realm keys

Open ringods opened this issue 3 years ago • 3 comments

There is support for retrieving the realm keys (#126), but this is a request to add support for configuring the keys of a realm.

imgpsh_mobile_save

659e9f82-dd6e-4685-b26d-b90ad0abf89f

14786ea6-440a-4be9-98bd-458d228238c0

Admin Guide section: https://www.keycloak.org/docs/latest/server_admin/index.html#realm_keys

After some debugging together with my colleague @vlad-kirichenko, we found out that this part of the admin UI calls into this set of REST endpoints:

  • /{realm}/components
  • /{realm}/components/{id}

These endpoints not only support managing the Keystores, but also the Client Registration section of a realm.

Retrieving all the components (keystores & client registrations) is done with a GET:

https://www.keycloak.org/docs-api/15.0/rest-api/index.html#_getcomponents

Response:

[
    {
        "id": "8b3b314c-bde3-44f6-ae4f-269b0aefac54",
        "name": "Full Scope Disabled",
        "providerId": "scope",
        "providerType": "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy",
        "parentId": "agent",
        "subType": "anonymous",
        "config": {}
    },
    {
        "id": "405cbfa7-c739-45dd-a986-fbc081638dfc",
        "name": "rsa-generated",
        "providerId": "rsa-generated",
        "providerType": "org.keycloak.keys.KeyProvider",
        "parentId": "agent",
        "config": {
            "priority": [
                "100"
            ]
        }
    },
    {
        "id": "ed5c36eb-10c3-44f1-a71b-69b2c0c45e5f",
        "name": "Trusted Hosts",
        "providerId": "trusted-hosts",
        "providerType": "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy",
        "parentId": "agent",
        "subType": "anonymous",
        "config": {
            "host-sending-registration-request-must-match": [
                "true"
            ],
            "client-uris-must-match": [
                "true"
            ]
        }
    },
    {
        "id": "487e6d8a-5598-40f5-9368-238077954c68",
        "name": "Allowed Client Scopes",
        "providerId": "allowed-client-templates",
        "providerType": "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy",
        "parentId": "agent",
        "subType": "authenticated",
        "config": {
            "allow-default-scopes": [
                "true"
            ]
        }
    },
    {
        "id": "c1dc9c70-d635-4c60-90de-f9a4505f5003",
        "name": "rsa",
        "providerId": "rsa-generated",
        "providerType": "org.keycloak.keys.KeyProvider",
        "parentId": "agent",
        "config": {
            "active": [
                "true"
            ],
            "priority": [
                "0"
            ],
            "enabled": [
                "true"
            ],
            "algorithm": [
                "RS256"
            ]
        }
    },
    {
        "id": "be741641-d8f1-47ab-985b-9384b62b8ea7",
        "name": "Allowed Protocol Mapper Types",
        "providerId": "allowed-protocol-mappers",
        "providerType": "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy",
        "parentId": "agent",
        "subType": "authenticated",
        "config": {
            "allowed-protocol-mapper-types": [
                "saml-user-property-mapper",
                "saml-role-list-mapper",
                "oidc-address-mapper",
                "oidc-full-name-mapper",
                "oidc-usermodel-attribute-mapper",
                "oidc-usermodel-property-mapper",
                "oidc-sha256-pairwise-sub-mapper",
                "saml-user-attribute-mapper"
            ]
        }
    },
    {
        "id": "157ba9ce-245e-4669-b119-bdc3c8d31b68",
        "name": "Allowed Client Scopes",
        "providerId": "allowed-client-templates",
        "providerType": "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy",
        "parentId": "agent",
        "subType": "anonymous",
        "config": {
            "allow-default-scopes": [
                "true"
            ]
        }
    },
    {
        "id": "ad055ee2-d912-47d7-b213-a4440e2255d8",
        "name": "Max Clients Limit",
        "providerId": "max-clients",
        "providerType": "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy",
        "parentId": "agent",
        "subType": "anonymous",
        "config": {
            "max-clients": [
                "200"
            ]
        }
    },
    {
        "id": "e0369980-b108-4913-afc5-e9a4538c5d86",
        "name": "Consent Required",
        "providerId": "consent-required",
        "providerType": "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy",
        "parentId": "agent",
        "subType": "anonymous",
        "config": {}
    }
]

Creating a new keystore is done with a POST to /{realm}/components with a payload like this:

{
    "name": "rsa",
    "providerId": "rsa",
    "providerType": "org.keycloak.keys.KeyProvider",
    "parentId": "agent",
    "config": {
        "priority": [
            "0"
        ],
        "enabled": [
            "true"
        ],
        "active": [
            "true"
        ],
        "algorithm": [
            "RS256"
        ],
        "privateKey": [ <private key string here> ],
        "certificate": [ <certificate string here> ]
    }
}

Implementation question: given a single REST endpoint serves two purposes (keys & client registrations), would the provider expose two resource types named keystore and client_registration, or a single component resource? I would favor two separate resource types because the config you have to pass for each is very specific to that Keycloak component type.

ringods avatar Aug 03 '21 14:08 ringods

Hi @ringods, thanks for the issue. To answer your question, I agree with you that there should be two dedicated resource types for this. The Keycloak component API is used for a lot of things, and so far we've been making dedicated resources instead of exposing the underlying component API to end users.

As an example, here is how LDAP Group Mappers are configured using the component API: https://github.com/mrparkers/terraform-provider-keycloak/blob/5494ced093114e2e08980dd785827ccad9be59ef/keycloak/ldap_group_mapper.go#L34

It sounds like you're looking at taking a stab at implementing this, which is great! Feel free to let me know if you have any questions or need any assistance with this.

mrparkers avatar Aug 03 '21 15:08 mrparkers

Hi guys, I started working on implementing on this issue.

Vlad-Kirichenko avatar Aug 17 '21 09:08 Vlad-Kirichenko

Is there any way to set the 'enabled' or 'active' flag of built-in realm key providers? I would like to deactivate the built-in 'rsa-generated' key provider.

ToniA avatar Jun 13 '23 06:06 ToniA