Skip to main content

Kubernetes

OIDC Dynamic Client Registration

The IBM Application Gateway operator allows for the IBM Application Gateway configuration definition to be split across multiple sources. See IBM Application Gateway Kubernetes operator for more information on the operator. One of the configuration sources allows an Open ID provider (OIDC OP) to be specified such that when the operator is invoked to create a new IBM Application Gateway instance, as part of the configuration source merging an HTTP POST request will be made to the OIDC OP to register a new client. This new client will then be added to the merged configuration as a new OIDC identity provider.

OIDC Registration Configuration Source

A single oidc_registration configuration source may be added to the list of sources defined in the custom resource definition. Defining more than one oidc_registration source will result in an error. This configuration source requires the following properties are specified:

  • discoveryEndpoint. This is the endpoint that can be used to discover the registration endpoint and token endpoint of the OIDC OP.
  • postData. Specifies any POST data that is required to be sent as part of the registration request.
  • secret. Specifies a Kubernetes secret that may contain authorization data for the registration request. This is also the location where the resulting client ID and secret are stored upon successful registration.

The following definition:

apiVersion: ibm.com/v1
kind: IBMApplicationGateway
metadata:
  name: iag-instance
spec:
  configuration:
    - type: oidc_registration
      discoveryEndpoint: https://iag.ibmcloudsecurity.com/oidc/endpoint/default/.well-known/openid-configuration
      postData:
        - name: redirect_uris
          values:
            - https://127.0.0.1:30112/pkmsoidc
      secret: oidc-client

will result in the operator:

  1. Calling the discoveryEndpoint to retrieve the registration endpoint
  2. Possibly making an HTTP POST request to the token endpoint to retrieve an authorization token for the registration. The need for this step is dependent on the type of authorization data that has been provided in the Kubernetes secret. For more details on this see Secret.
  3. Making an HTTP POST request to the registration endpoint to register a new client, passing the specified POST data.
  4. Storing the client ID and secret from the response as data entries in the Kubernetes secret named "oidc-client" using the keys "client_id" and "client_secret".
  5. Merging a new OIDC identity configuration entry into the IBM Application Gateway configuration.

The resulting IBM Application Gateway configuration YAML will include:

identity:
  oidc:
    client_id: secret:oidc-client/client_id
    client_secret: secret:oidc-client/client_secret
    discovery_endpoint: https://iag.ibmcloudsecurity.com/oidc/endpoint/default/.well-known/openid-configuration

The oidc_registration source will always be handled last by the operator when merging the list of configuration sources. This is to ensure that the newly registered OIDC client is not overwritten by other sources. If other sources do define their own identity sources the following will occur:

  1. If the existing identity provider is an OIDC provider, the new client ID and secret along with the discovery endpoint will be merged into the existing OIDC identity configuration.
  2. If the existing identity provider is not an OIDC provider it will be removed and the new OIDC identity provider will be used instead.

Discovery Endpoint

As stated above the discoveryEndpoint is a required property when adding an oidc_registration configuration source. The entry will be used for 2 purposes:

  1. It will be added to the resulting OIDC identity provider configuration as the "discovery_endpoint".
  2. It will be used by the operator to retrieve the necessary registration endpoint and possibly the token endpoint if required.

As such the OIDC OP must support discovery and also dynamic client registration. The response from the GET call to the discovery endpoint must include:

  • registration_endpoint
  • token_endpoint (if an authorization token is required for client registration)

POST Data

The request to an OIDC OP to dynamically register a new client will require certain properties to be provided in the form of POST data. The properties are defined as part of the OpenID Connect Dynamic Client Registration specification. Each individual OIDC OP implementation may also include their own list of additional properties that may be set.

IBM Security Verify properties are defined in the IBM Knowledge Center.

POST data properties may be added in one of 2 ways:

  1. As a single string value using the "value" YAML key; or
  2. As an array of string values using the "values" YAML key

If an entry contains both "value" and "values" the single entry "value" will take precedence and the "values" entry will be ignored.

For example the following definition:

postData:
  - name: redirect_uris
    values:
      - https://127.0.0.1:30112/pkmsoidc
      - https://127.0.0.1:30113/pkmsoidc
  - name: client_name
    value: IAGInstance
  - name: enforce_pkce
    value: "false"
  - name: all_users_entitled
    value: "true"
  - name: consent_action
    value: never_prompt

will result in the following POST data:

{
	"redirect_uris":["https://127.0.0.1:30112/pkmsoidc", "https://127.0.0.1:30113/pkmsoidc"],
	"client_name": "IAGInstance",
	"enforce_pkce": "false",
	"all_users_entitled": "true",
	"consent_action": "never_prompt"
}

Note: While the primary use of the postData entry is to provide data for the registration request the "scopes" entry (if specified) will also be used in the request to the token endpoint if an authorization token needs to be retrieved.

Secret

The OIDC registration configuration source requires a valid and existing Kubernetes secret. This secret has a dual purpose:

  1. The operator will retrieve the authorization data used to authorize the OIDC dynamic client registration.
  2. Once the new client has been registered, the new client ID and secret will be stored in the secret and referenced by the IBM Application Gateway configuration.

The authorization data can be specified in 4 different ways. The following table shows the different methods. The precedence shows the order in which the operator will attempt to lookup the secret data. If the data for a particular method is found, that method will be used for authorization.

Precedence Secret Data Encoding Description When to use
1 baUsername, baPassword base64 Client registration will be attempted with a BA authorization header. The OIDC OP supports basic authentication to authorize the client registration.
2 initialAccessToken base64 Client registration will be attempted with a bearer token authorization header. A token exists that will not expire or will be managed manually.
3 tokenRetrievalClientId, tokenRetrievalClientSecret base64 The ID and secret will be used to firstly authorize a token retrieve request to the OIDC OP. This token will subsequently be used to authorize the client registration. The authorization token can not be stored long term but an intermediate client ID and secret exist that can be used to retrieve a token on demand.
4 None None Client registration will be attempted without an authorization header. OIDC OP does not require authorization for client registration.

For example, the following YAML shows a Kubernetes secret that contains the tokenRetrievalClientId, tokenRetrievalClientSecret and the created client_id and client_secret that were returned by the OIDC OP.

apiVersion: v1
kind: Secret
type: Opaque
data:
  tokenRetrievalClientId: YzEwZTVlPKLDTAxNy00OWI4LWI3ZTItNjAwYWY5MzEwZTA5Cg==
  tokenRetrievalClientSecret: dtHdEsfk4Mgo=
  client_id: sfUfJfsfSfgdfdf1j5kk45=
  client_secret: klj345a9HeLH234JKjjk

Note: If the tokenRetrievalClientId and tokenRetrievalClientSecret are specified the OIDC OP discovery request must return the token endpoint. This is the case whereby the client registration will result in three HTTP calls:

  1. GET discovery_endpoint (No authorization).
  2. POST token_endpoint (BA using tokenRetrievalClientId and tokenRetrievalClientSecret).
  3. POST registration_endpoint (Bearer token using the response from step 2).

OIDC Client Lifecycle Management

The IBM Application Gateway operator will call the OIDC OP to register a new client if the custom object includes an oidc_registration configuration source. Once the client has been registered the ID and secret are stored in a Kubernetes secret. At this point the operator and IBM Application Gateway instance will continue to use the registered client even if it expires or is deleted from the OIDC OP. Note that the operator will not register a new client if the specified secret already contains a client_id and client_secret.

The administrator is responsible for any further lifecycle management of the client.

If a new client registration is required the administrator should:

  1. Update the secret to remove the client_id and client_secret.
  2. Trigger an update of the IBM Application Gateway custom resource.

The operator will then be invoked and should register a new client with the OIDC OP and update the IBM Application Gateway instance identity provider.

Trust OIDC OP Certificate

The IBM Application Gateway operator will load its own CA certificates by default in order to validate trust with the OIDC OP. There may be scenarios whereby the OIDC OP certificate cannot be trusted by default. In this case there are two methods that can alleviate the problem.

  1. For a non production scenario where the trust validation is not required a flag named insecureTLS can be set in the Kubernetes secret data that will disable trust validation. This is the same secret that has been specified in the oidc_registration configuration source. Setting the flag to true will disable trust validation.

Note: As the flag is being set in a Kubernetes secret the value must be base64 encoded. First use a base64 encoding tool to get the value to set. For example on linux:

$ echo -n "true" | base64
dHJ1ZQ==
apiVersion: v1
kind: Secret
type: Opaque
data:
  insecureTLS: dHJ1ZQ==
  1. The OIDC OP certificate can be added to the Kubernetes operator service account data and it will then be added to the trusted certificates when the call to the OIDC OP is made. The certificate should be extracted from the OIDC OP and added to the operator service account token secret as a new entry "service-ca.crt".

For example. If the operator is running with the service account "ibm-application-gateway-operator" there will be a service account token secret named "ibm-application-gateway-operator-token-<random>" that exists in Kubernetes. Add the base 64 encoded certificate to this secret.

apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token
data:
  service-ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk.....