update kubeflow dip-catalog
This commit is contained in:
+43
@@ -0,0 +1,43 @@
|
||||
# Unauthenticated Issuer Discovery
|
||||
|
||||
If you are using Kubernetes with tools like kind, vCluster, minikube, or similar solutions for local
|
||||
development, it's highly likely that the Kubernetes OIDC Issuer operates within the cluster and is
|
||||
secured with self-signed certificates.
|
||||
|
||||
To facilitate the use of m2m tokens with `oauth2-proxy` and Istio, both tools must perform OIDC
|
||||
Connect Discovery on the Token Issuer. Kubernetes offers OIDC Discovery functionality at a specific
|
||||
URI:
|
||||
```
|
||||
https://kubernetes.default.svc.cluster.local/.well-known/openid-configuration
|
||||
```
|
||||
|
||||
Access to this endpoint is blocked by default due to RBAC policies, but it can be enabled by
|
||||
creating a `ClusterRoleBinding`. This binding associates the predefined `ClusterRole`
|
||||
`system:service-account-issuer-discovery` with the `system:unauthenticated` group. The
|
||||
configuration for this is detailed in the resource file `clusterrolebinding.unauthenticated-oidc-viewer.yaml`.
|
||||
|
||||
Once this step is completed, the endpoint can be accessed to reveal the Issuer URL:
|
||||
```bash
|
||||
$ curl -k https://kubernetes.default.svc.cluster.local/.well-known/openid-configuration
|
||||
|
||||
# Example output in kind:
|
||||
{"issuer":"https://kubernetes.default.svc.cluster.local","jwks_uri":"https://172.18.0.5:6443/openid/v1/jwks","response_types_supported":["id_token"],"subject_types_supported":["public"],"id_token_signing_alg_values_supported":["RS256"]}
|
||||
|
||||
# Example output in vCluster:
|
||||
{"issuer":"https://kubernetes.default.svc.cluster.local","jwks_uri":"https://1.2.3.4:6443/openid/v1/jwks","response_types_supported":["id_token"],"subject_types_supported":["public"],"id_token_signing_alg_values_supported":["RS256"]}
|
||||
|
||||
# Example output in AWS EKS:
|
||||
{"issuer":"https://oidc.eks.region.amazonaws.com/id/123abc","jwks_uri":"https://ip-1-2-3-4.eu-central-1.compute.internal:443/openid/v1/jwks","response_types_supported":["id_token"],"subject_types_supported":["public"],"id_token_signing_alg_values_supported":["RS256"]}
|
||||
```
|
||||
|
||||
If you're operating in a `vCluster`, access to the endpoint specified under `jwks_uri` (for example,
|
||||
`https://1.2.3.4:6443/openid/v1/jwks`) is managed separately, and merely creating the previously
|
||||
mentioned `ClusterRoleBinding` is insufficient. To circumvent this limitation, you can configure the
|
||||
`kube-apiserver` to allow anonymous authentication by setting `--anonymous-auth=true`. This is
|
||||
achieved by appending `--kube-apiserver-arg=anonymous-auth=true` to the list of arguments in the
|
||||
Helm Chart Values file:
|
||||
```yaml
|
||||
vcluster:
|
||||
extraArgs:
|
||||
- --kube-apiserver-arg=anonymous-auth=true
|
||||
```
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: unauthenticated-oidc-viewer
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: system:service-account-issuer-discovery
|
||||
subjects:
|
||||
- apiGroup: rbac.authorization.k8s.io
|
||||
kind: Group
|
||||
name: system:unauthenticated
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1alpha1
|
||||
kind: Component
|
||||
|
||||
resources:
|
||||
- clusterrolebinding.unauthenticated-oidc-viewer.yaml
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1alpha1
|
||||
kind: Component
|
||||
|
||||
patches:
|
||||
- path: patches/deployment.logout-url.yaml
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: centraldashboard
|
||||
namespace: kubeflow
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: centraldashboard
|
||||
env:
|
||||
# This successfully logs out the user but the user is not redirected to
|
||||
# the home page. This is because of custom integration with
|
||||
# oidc-authservice which will provide response with 'afterLogoutURL'.
|
||||
# https://github.com/arrikto/oidc-authservice/blob/0c4ea9a/server.go#L509
|
||||
# https://github.com/kubeflow/kubeflow/blob/c6c4492/components/centraldashboard/public/components/logout-button.js#L50
|
||||
# Please refresh the page after logging out.
|
||||
- name: LOGOUT_URL
|
||||
value: /oauth2/sign_out
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
# Configure Istio with Self-Signed Kubernetes OIDC Issuer
|
||||
|
||||
## Overview
|
||||
|
||||
This kustomize component is designed for scenarios where the Kubernetes OIDC Issuer is behind
|
||||
self-signed certificates, causing trust issues with Istio in retrieving the JWKS. It creates a
|
||||
Kubernetes Job and necessary RBAC configurations to address this issue. The job facilitates the
|
||||
retrieval of JWKS from the OIDC Issuer and embeds it directly into Istio's configuration, thereby
|
||||
bypassing trust issues with self-signed certificates.
|
||||
|
||||
## Configuration Persistence and JWKS Public Accessibility
|
||||
|
||||
The configuration created by this job is stored exclusively in etcd and is not persisted elsewhere.
|
||||
This setup is compatible with ArgoCD, which by default does not delete properties absent in the
|
||||
desired manifest. However, if the `RequestAuthentication` resource is modified erroneously or
|
||||
deleted, the configuration would be lost, necessitating a rerun of the job.
|
||||
|
||||
To circumvent the need for rerunning the job, it is advisable to store the JWKS in a repository.
|
||||
JWKS are typically publicly accessible and contain no sensitive information, making them safe for
|
||||
repository storage. By persisting the JWKS in a repository, consistent access is ensured regardless
|
||||
of changes in the cluster or accidental deletions.
|
||||
|
||||
## Functionality
|
||||
|
||||
- **Reading OIDC Issuer URL**: The Job reads the `RequestAuthentication` resource to extract the
|
||||
OIDC Issuer URL.
|
||||
- **Fetching JWKS**: After identifying the Issuer URL, the Job retrieves the JWKS.
|
||||
- **Patching RequestAuthentication**: The JWKS is used to patch the `RequestAuthentication`
|
||||
resource, embedding the JWKS directly.
|
||||
- **Static JWKS Configuration for Istio**: Ensures that Istio uses the JWKS provided by the Job
|
||||
instead of requesting it independently.
|
||||
|
||||
## Use Case
|
||||
|
||||
This setup is particularly useful when:
|
||||
- Kubernetes serves as an OIDC provider.
|
||||
- The Kubernetes API is not served with publicly trusted certificates.
|
||||
|
||||
This component ensures seamless M2M authentication by handling JWKS retrieval and configuration
|
||||
internally, thus circumventing certificate validation issues for Istio fetching JWKS from an OIDC
|
||||
provider with self-signed or private CA certificates.
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
apiVersion: batch/v1
|
||||
kind: CronJob
|
||||
metadata:
|
||||
name: kubeflow-m2m-oidc-configurator
|
||||
namespace: istio-system
|
||||
spec:
|
||||
schedule: '*/5 * * * *'
|
||||
concurrencyPolicy: Forbid
|
||||
jobTemplate:
|
||||
spec:
|
||||
backoffLimit: 3
|
||||
ttlSecondsAfterFinished: 600
|
||||
template:
|
||||
metadata:
|
||||
labels: {}
|
||||
spec:
|
||||
restartPolicy: OnFailure
|
||||
serviceAccountName: kubeflow-m2m-oidc-configurator
|
||||
containers:
|
||||
- image: docker.io/curlimages/curl
|
||||
name: kubeflow-m2m-oidc-configurator
|
||||
command:
|
||||
- /script.sh
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: kubeflow-m2m-oidc-configurator-envs
|
||||
volumeMounts:
|
||||
- mountPath: /script.sh
|
||||
name: script
|
||||
subPath: script.sh
|
||||
resources: {}
|
||||
volumes:
|
||||
- name: script
|
||||
configMap:
|
||||
name: kubeflow-m2m-oidc-configurator-script
|
||||
defaultMode: 0777
|
||||
items:
|
||||
- key: script.sh
|
||||
path: script.sh
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1alpha1
|
||||
kind: Component
|
||||
|
||||
resources:
|
||||
- cronjob.kubeflow-m2m-oidc-configurator.yaml
|
||||
- rbac.yaml
|
||||
|
||||
configMapGenerator:
|
||||
- name: kubeflow-m2m-oidc-configurator-script
|
||||
namespace: istio-system
|
||||
files:
|
||||
- script.sh=script.sh
|
||||
|
||||
- name: kubeflow-m2m-oidc-configurator-envs
|
||||
namespace: istio-system
|
||||
literals:
|
||||
- ISTIO_ROOT_NAMESPACE=istio-system
|
||||
- REQUEST_AUTHENTICATION_NAME=m2m-token-issuer
|
||||
- KUBERNETES_API_SERVER_URL=https://kubernetes.default.svc
|
||||
|
||||
- name: oauth2-proxy-parameters
|
||||
behavior: merge
|
||||
literals:
|
||||
- ALLOW_SELF_SIGNED_ISSUER=true
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: kubeflow-m2m-oidc-configurator
|
||||
namespace: istio-system
|
||||
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: kubeflow-m2m-oidc-configurator
|
||||
namespace: istio-system
|
||||
rules:
|
||||
- apiGroups:
|
||||
- security.istio.io
|
||||
resources:
|
||||
- requestauthentications
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: kubeflow-m2m-oidc-configurator
|
||||
namespace: istio-system
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: kubeflow-m2m-oidc-configurator
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: kubeflow-m2m-oidc-configurator
|
||||
namespace: istio-system
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
KUBERNETES_API_SERVER_URL="${KUBERNETES_API_SERVER_URL:-https://kubernetes.default.svc}"
|
||||
ISTIO_ROOT_NAMESPACE="${ISTIO_ROOT_NAMESPACE:-istio-system}"
|
||||
REQUEST_AUTHENTICATION_NAME="${REQUEST_AUTHENTICATION_NAME:-m2m-token-issuer}"
|
||||
|
||||
RESOURCE_URL="\
|
||||
${KUBERNETES_API_SERVER_URL}\
|
||||
/apis/security.istio.io/v1/namespaces/\
|
||||
${ISTIO_ROOT_NAMESPACE}\
|
||||
/requestauthentications/\
|
||||
${REQUEST_AUTHENTICATION_NAME}"
|
||||
|
||||
wait_for_resource_ready() {
|
||||
while true; do
|
||||
response="$(
|
||||
curl -s -o /dev/null \
|
||||
--url "${RESOURCE_URL}" \
|
||||
-w "%{http_code}" \
|
||||
--header "Authorization: Bearer $(cat /run/secrets/kubernetes.io/serviceaccount/token)" \
|
||||
--insecure
|
||||
)"
|
||||
if [ "${response}" = "200" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 5
|
||||
done
|
||||
}
|
||||
|
||||
get_request_authentication_obj() {
|
||||
curl -s --request GET \
|
||||
--url "${RESOURCE_URL}" \
|
||||
--header "Authorization: Bearer $(cat /run/secrets/kubernetes.io/serviceaccount/token)" \
|
||||
--insecure
|
||||
}
|
||||
|
||||
get_issuer_url_from_obj() {
|
||||
obj="${1}"
|
||||
echo "${obj}" | awk -F'"' '/"issuer":/ { print $4 }'
|
||||
}
|
||||
|
||||
get_current_escaped_jwks_from_obj() {
|
||||
obj="${1}"
|
||||
echo "${obj}" | awk -F'"' '/"jwks":/' | sed -n 's/^.*"jwks": "\(.*\)".*$/\1/p'
|
||||
}
|
||||
|
||||
get_jwks_uri() {
|
||||
issuer_url="${1}"
|
||||
curl -s --request GET \
|
||||
--url "${issuer_url}/.well-known/openid-configuration" \
|
||||
--header "Authorization: Bearer $(cat /run/secrets/kubernetes.io/serviceaccount/token)" \
|
||||
--insecure |
|
||||
grep -o '"jwks_uri":"https:\/\/[^"]\+"' |
|
||||
sed 's/"jwks_uri":"\(.*\)"/\1/'
|
||||
}
|
||||
|
||||
get_jwks_from_uri() {
|
||||
jwks_uri="${1}"
|
||||
curl -s --request GET \
|
||||
--url "${jwks_uri}" \
|
||||
--header "Authorization: Bearer $(cat /run/secrets/kubernetes.io/serviceaccount/token)" \
|
||||
--insecure
|
||||
}
|
||||
|
||||
# Format JWKS in a way that can be accepted in resource patch.
|
||||
parse_escaped_jwks() {
|
||||
jwks="${1}"
|
||||
echo "${jwks}" | sed 's/"/\\"/g'
|
||||
}
|
||||
|
||||
are_jwks_equal() {
|
||||
jwks1="${1}"
|
||||
jwks2="${2}"
|
||||
test "$(echo "${jwks1}" | base64 -w0)" = "$(echo "${jwks2}" | base64 -w0)"
|
||||
}
|
||||
|
||||
patch_request_authentication_with_escaped_jwks() {
|
||||
jwks_escaped="${1}"
|
||||
curl -s --request PATCH \
|
||||
--url "${RESOURCE_URL}" \
|
||||
--header "Content-Type: application/json-patch+json" \
|
||||
--header "Authorization: Bearer $(cat /run/secrets/kubernetes.io/serviceaccount/token)" \
|
||||
-d '[{ "op": "add", "path": "/spec/jwtRules/0/jwks", "value": "'"${jwks_escaped}"'" }]' \
|
||||
--insecure
|
||||
echo
|
||||
}
|
||||
|
||||
patch_request_authentication_with_jwks_if_required() {
|
||||
echo "Getting RequestAuthentication object."
|
||||
REQUEST_AUTHENTICATION_OBJ="$(get_request_authentication_obj)"
|
||||
|
||||
ISSUER_URL="$(get_issuer_url_from_obj "${REQUEST_AUTHENTICATION_OBJ}")"
|
||||
echo "Issuer Url in RequestAuthentication: ${ISSUER_URL}"
|
||||
|
||||
CURRENT_JWKS_ESCAPED="$(get_current_escaped_jwks_from_obj "${REQUEST_AUTHENTICATION_OBJ}")"
|
||||
printf "Current Jwks (escaped):\n%s\n" "${CURRENT_JWKS_ESCAPED}"
|
||||
|
||||
JWKS_URI="$(get_jwks_uri "${ISSUER_URL}")"
|
||||
echo "Jwks Uri from Well Known OpenID Configuration: ${JWKS_URI}"
|
||||
|
||||
JWKS="$(get_jwks_from_uri "${JWKS_URI}")"
|
||||
JWKS_ESCAPED="$(parse_escaped_jwks "${JWKS}")"
|
||||
printf "JWKS from Well Known OpenID Configuration (escaped): \n%s\n" "${JWKS_ESCAPED}"
|
||||
|
||||
if are_jwks_equal "${JWKS_ESCAPED}" "${CURRENT_JWKS_ESCAPED}"; then
|
||||
echo "JWKS in RequestAuthentication ${REQUEST_AUTHENTICATION_NAME} is configured correctly."
|
||||
else
|
||||
echo "JWKS in RequestAuthentication ${REQUEST_AUTHENTICATION_NAME} needs to be configured."
|
||||
patch_request_authentication_with_escaped_jwks "${JWKS_ESCAPED}"
|
||||
fi
|
||||
}
|
||||
|
||||
verify_jwks_in_request_authentication() {
|
||||
REQUEST_AUTHENTICATION_OBJ="$(get_request_authentication_obj)"
|
||||
ISSUER_URL="$(get_issuer_url_from_obj "${REQUEST_AUTHENTICATION_OBJ}")"
|
||||
CURRENT_JWKS_ESCAPED="$(get_current_escaped_jwks_from_obj "${REQUEST_AUTHENTICATION_OBJ}")"
|
||||
JWKS_URI="$(get_jwks_uri "${ISSUER_URL}")"
|
||||
JWKS="$(get_jwks_from_uri "${JWKS_URI}")"
|
||||
JWKS_ESCAPED="$(parse_escaped_jwks "${JWKS}")"
|
||||
if ! are_jwks_equal "${JWKS_ESCAPED}" "${CURRENT_JWKS_ESCAPED}"; then
|
||||
echo "JWKS not properly configured, exit with error code 1"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
echo "Wait until resource RequestAuthentication ${REQUEST_AUTHENTICATION_NAME} in namespace ${ISTIO_ROOT_NAMESPACE} is ready."
|
||||
wait_for_resource_ready
|
||||
echo "Resource RequestAuthentication ${REQUEST_AUTHENTICATION_NAME} in namespace ${ISTIO_ROOT_NAMESPACE} is ready."
|
||||
|
||||
echo "Patch RequestAuthentication with JWKS if required."
|
||||
patch_request_authentication_with_jwks_if_required
|
||||
|
||||
echo "Wait 5 seconds before verifying RequestAuthentication JWKS configuration."
|
||||
sleep 5
|
||||
|
||||
echo "Verify if RequestAuthentication is properly configured with JWKS..."
|
||||
verify_jwks_in_request_authentication
|
||||
echo "RequestAuthentication is properly configured with JWKS."
|
||||
}
|
||||
|
||||
main
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1alpha1
|
||||
kind: Component
|
||||
|
||||
patches:
|
||||
- path: patches/cm.enable-oauth2-proxy.yaml
|
||||
- path: patches/deployment.jwt-refresh-interval.yaml
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: istio
|
||||
namespace: istio-system
|
||||
data:
|
||||
mesh: |-
|
||||
accessLogFile: /dev/stdout
|
||||
defaultConfig:
|
||||
discoveryAddress: istiod.istio-system.svc:15012
|
||||
proxyMetadata: {}
|
||||
tracing: {}
|
||||
enablePrometheusMerge: true
|
||||
rootNamespace: istio-system
|
||||
tcpKeepalive:
|
||||
interval: 5s
|
||||
probes: 3
|
||||
time: 10s
|
||||
trustDomain: cluster.local
|
||||
extensionProviders:
|
||||
- envoyExtAuthzHttp:
|
||||
headersToDownstreamOnDeny:
|
||||
- content-type
|
||||
- set-cookie
|
||||
headersToUpstreamOnAllow:
|
||||
- authorization
|
||||
- path
|
||||
- x-auth-request-email
|
||||
- x-auth-request-groups
|
||||
- x-auth-request-user
|
||||
includeRequestHeadersInCheck:
|
||||
- authorization
|
||||
- cookie
|
||||
service: oauth2-proxy.oauth2-proxy.svc.cluster.local
|
||||
port: 80
|
||||
name: oauth2-proxy
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: istiod
|
||||
namespace: istio-system
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: discovery
|
||||
env:
|
||||
# Istio will refresh the JWT Public Keys provided with
|
||||
# RequestAuthentication by default every 20 minutes. For deployment
|
||||
# from scratch this is not ideal because there is a high chance that
|
||||
# the istiod will be available before dex is available, triggering
|
||||
# Istio mechanism to use a placeholder jwt until refreshed.
|
||||
- name: PILOT_JWT_PUB_KEY_REFRESH_INTERVAL
|
||||
value: "1m"
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
apiVersion: security.istio.io/v1beta1
|
||||
kind: AuthorizationPolicy
|
||||
metadata:
|
||||
name: istio-ingressgateway-oauth2-proxy
|
||||
namespace: istio-system
|
||||
spec:
|
||||
action: CUSTOM
|
||||
provider:
|
||||
name: oauth2-proxy
|
||||
selector:
|
||||
matchLabels:
|
||||
app: istio-ingressgateway
|
||||
rules:
|
||||
- to:
|
||||
- operation:
|
||||
notPaths:
|
||||
- /favicon*
|
||||
- /webcomponentsjs*
|
||||
- /vendor.bundle.js
|
||||
- /app.bundle.js
|
||||
- /dashboard_lib.bundle.js
|
||||
- /assets*
|
||||
- /app.css
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
apiVersion: security.istio.io/v1beta1
|
||||
kind: AuthorizationPolicy
|
||||
metadata:
|
||||
name: istio-ingressgateway-oauth2-proxy
|
||||
namespace: istio-system
|
||||
spec:
|
||||
action: CUSTOM
|
||||
provider:
|
||||
name: oauth2-proxy
|
||||
selector:
|
||||
matchLabels:
|
||||
app: istio-ingressgateway
|
||||
rules:
|
||||
- {}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1alpha1
|
||||
kind: Component
|
||||
|
||||
resources:
|
||||
- authorizationpolicy.istio-ingressgateway-oauth2-proxy.yaml
|
||||
|
||||
# If you're running Kubeflow behind CloudFlare, use
|
||||
# authorizationpolicy.istio-ingressgateway-oauth2-proxy-cloudflare.yaml
|
||||
# instead of
|
||||
# authorizationpolicy.istio-ingressgateway-oauth2-proxy.yaml
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
apiVersion: security.istio.io/v1beta1
|
||||
kind: RequestAuthentication
|
||||
metadata:
|
||||
name: dex-jwt
|
||||
namespace: istio-system
|
||||
spec:
|
||||
jwtRules:
|
||||
# forwardOriginalToken must be set to true so the authorization header will
|
||||
# be passed between Kubeflow Components and Istio can configure the
|
||||
# Kubeflow Auth Headers based on this request authorization header.
|
||||
- forwardOriginalToken: true
|
||||
issuer: http://dex.auth.svc.cluster.local:5556/dex
|
||||
# These 5 lines provides integration of istio/oauth2-proxy with
|
||||
# Kubeflow custom auth headers.
|
||||
outputClaimToHeaders:
|
||||
- header: kubeflow-userid
|
||||
claim: email
|
||||
- header: kubeflow-groups
|
||||
claim: groups
|
||||
@@ -0,0 +1,19 @@
|
||||
# Kubernetes M2M Authentication with Istio and RequestAuthentication
|
||||
|
||||
## Overview
|
||||
|
||||
This kustomize component enables M2M (Machine-to-Machine) authentication in Kubernetes, using
|
||||
Istio and the `RequestAuthentication` object. It configures Istio to trust JWTs (JSON Web Tokens)
|
||||
in Authorization Bearer tokens when the JWT issuer matches the one in `RequestAuthentication`. The
|
||||
default setup uses Kubernetes' self-served OIDC issuer with self-signed certificates.
|
||||
|
||||
In Kubernetes clusters managed by platform providers, the OIDC issuer is usually managed by the
|
||||
provider and served behind publicly trusted certificates. In these cases, it's advisable to use
|
||||
the platform-managed Kubernetes OIDC issuer in the `RequestAuthentication` for seamless integration
|
||||
and authentication compliance with the platform's security standards.
|
||||
|
||||
For scenarios where the OIDC issuer is served behind self-signed certificates, the kustomize
|
||||
overlay using this component should include the `common/oidc-client/oauth2-proxy/components/configure-self-signed-kubernetes-oidc-issuer`
|
||||
component. This additional configuration is necessary to handle the self-signed nature of the
|
||||
certificates. This setup is the default in the Kustomize overlay defined in `common/oidc-client/oauth2-proxy/overlays/m2m-self-signed`,
|
||||
which is tailored for environments with self-signed OIDC issuers.
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1alpha1
|
||||
kind: Component
|
||||
|
||||
resources:
|
||||
- requestauthentication.yaml
|
||||
|
||||
configMapGenerator:
|
||||
- name: istio-m2m-params
|
||||
envs:
|
||||
- m2m.env
|
||||
|
||||
replacements:
|
||||
- source:
|
||||
kind: ConfigMap
|
||||
version: v1
|
||||
name: istio-m2m-params
|
||||
fieldPath: data.M2M_TOKEN_ISSUER
|
||||
targets:
|
||||
- fieldPaths:
|
||||
- spec.jwtRules.0.issuer
|
||||
select:
|
||||
group: security.istio.io
|
||||
version: v1beta1
|
||||
kind: RequestAuthentication
|
||||
name: m2m-token-issuer
|
||||
namespace: istio-system
|
||||
|
||||
configurations:
|
||||
- params.yaml
|
||||
@@ -0,0 +1 @@
|
||||
M2M_TOKEN_ISSUER=issuer
|
||||
@@ -0,0 +1,21 @@
|
||||
apiVersion: v1
|
||||
data:
|
||||
M2M_TOKEN_ISSUER: issuer
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: istio-m2m-params-gfd5m8bd92
|
||||
---
|
||||
apiVersion: security.istio.io/v1beta1
|
||||
kind: RequestAuthentication
|
||||
metadata:
|
||||
name: m2m-token-issuer
|
||||
namespace: istio-system
|
||||
spec:
|
||||
jwtRules:
|
||||
- forwardOriginalToken: true
|
||||
issuer: issuer
|
||||
outputClaimToHeaders:
|
||||
- claim: sub
|
||||
header: x-auth-request-user
|
||||
- claim: sub
|
||||
header: kubeflow-userid
|
||||
@@ -0,0 +1,3 @@
|
||||
varReference:
|
||||
- path: spec/jwtRules/issuer
|
||||
kind: RequestAuthentication
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
apiVersion: security.istio.io/v1beta1
|
||||
kind: RequestAuthentication
|
||||
metadata:
|
||||
name: m2m-token-issuer
|
||||
namespace: istio-system
|
||||
spec:
|
||||
jwtRules:
|
||||
- forwardOriginalToken: true
|
||||
issuer: M2M_TOKEN_ISSUER_PLACEHOLDER
|
||||
outputClaimToHeaders:
|
||||
- claim: sub
|
||||
header: x-auth-request-user
|
||||
- claim: email
|
||||
header: kubeflow-userid
|
||||
Reference in New Issue
Block a user