Keycloak Operations

A service may need to access Keycloak to perform various tasks. The typical uses for a service to access Keycloak include creating a new service account, creating a new user, etc. These operations require Keycloak administrative access. As part of the System Management Services (SMS) installation process, Keycloak is initialized with a Master realm. An administrative client and user are created within this realm. The system installation process adds the information needed for the Keycloak administrator’s authentication into a Kubernetes secret that can be accessed by any pod. Using this information and the Keycloak REST API, a service can create an account in the Shasta realm. The Keycloak master administrative authentication information is located in the keycloak-master-admin-auth secret, which includes the following fields:

  • client-id - Client ID for administrative operations
  • user - Username for the Keycloak Master admin.
  • password - Password for the Keycloak Master admin.
  • internal_token_url - URL that can be used to get a token, such as https://istio-ingressgateway.istio-system.svc.cluster.local/keycloak/realms/master/protocol/openid-connect/token.

The pod in the following example gets a Keycloak Master admin token and makes a request to create a client with a user ID attribute mapper.

kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: kc-admin-example
  namespace: services
spec:
  containers:
    - name: kc-admin-example
      image: alpine
      command:
      - sh
      - -c
      - >-
        apk update &&
        apk add --no-cache curl jq &&
        echo endpoint: \$(cat /mnt/auth/internal_token_url) &&
        echo client_id: \$(cat /mnt/auth/client-id) &&
        echo user: \$(cat /mnt/auth/user) &&
        TOKEN=\$(curl -s
        --cacert /mnt/shasta-ca/certificate_authority.crt
        -d grant_type=password
        -d client_id=\$(cat /mnt/auth/client-id)
        -d username=\$(cat /mnt/auth/user)
        -d password=\$(cat /mnt/auth/password)
        \$(cat /mnt/auth/internal_token_url) | jq -r .access_token) &&
        echo "=== Making request with token \$(echo \$TOKEN | head -c10)... ===" &&
        curl -is
        --cacert /mnt/shasta-ca/certificate_authority.crt
        -H "Authorization: Bearer \$TOKEN"
        -H "Content-Type: application/json"
        -d '{"clientId": "example", "publicClient": true,
        "standardFlowEnabled": false, "implicitFlowEnabled": false,
        "directAccessGrantsEnabled": true,
        "protocolMappers": [
        {"name": "uid-user-attribute-mapper",
        "protocolMapper": "oidc-usermodel-attribute-mapper",
        "protocol": "openid-connect",
        "config": {"user.attribute": "uid", "claim.name": "uid",
        "access.token.claim": false, "userinfo.token.claim": true}}]}'
        https://istio-ingressgateway.istio-system.svc.cluster.local/keycloak/admin/realms/shasta/clients
      volumeMounts:
      - name: ca-vol
        mountPath: /mnt/shasta-ca
      - name: auth-vol
        mountPath: '/mnt/auth'
        readOnly: true
  volumes:
    - name: ca-vol
      configMap:
        name: cray-configmap-ca-public-key
    - name: auth-vol
      secret:
        secretName: keycloak-master-admin-auth
  restartPolicy: Never
EOF
kubectl logs -n services kc-admin-example

Example output:

fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/community/x86_64/APKINDEX.tar.gz
v3.8.1-115-ge3ed6b4e31 [http://dl-cdn.alpinelinux.org/alpine/v3.8/main]
v3.8.1-112-g45bdd0edfb [http://dl-cdn.alpinelinux.org/alpine/v3.8/community]
OK: 9546 distinct packages available
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/community/x86_64/APKINDEX.tar.gz
(1/7) Installing ca-certificates (20171114-r3)
(2/7) Installing nghttp2-libs (1.32.0-r0)
(3/7) Installing libssh2 (1.8.0-r3)
(4/7) Installing libcurl (7.61.1-r1)
(5/7) Installing curl (7.61.1-r1)
(6/7) Installing oniguruma (6.8.2-r0)
(7/7) Installing jq (1.6_rc1-r1)
Executing busybox-1.28.4-r1.trigger
Executing ca-certificates-20171114-r3.trigger
OK: 7 MiB in 20 packages
endpoint: https://istio-ingressgateway.istio-system.svc.cluster.local/keycloak/realms/master/protocol/openid-connect/token
client_id: admin-cli
user: admin
=== Making request with token eyJhbGciOi... ===
HTTP/1.1 201 Created
Content-Length: 0
Connection: keep-alive
Location: https://istio-ingressgateway.istio-system.svc.cluster.local/keycloak/admin/realms/shasta/clients/070c8537-6c46-43a4-b0bb-209b3c4b94c6
Date: Fri, 30 Nov 2018 20:07:39 GMT
X-Kong-Upstream-Latency: 27
X-Kong-Proxy-Latency: 1
Via: kong/0.14.1

The new example client is now visible in the Keycloak administrative web application.