Implement confidential OIDC authentication boundary
This commit is contained in:
parent
0f888986d7
commit
a4e615096c
5 changed files with 1896 additions and 329 deletions
|
|
@ -207,6 +207,9 @@ spec:
|
|||
spec:
|
||||
automountServiceAccountToken: false
|
||||
enableServiceLinks: false
|
||||
volumes:
|
||||
- name: bootstrap
|
||||
emptyDir: {}
|
||||
containers:
|
||||
- name: zitadel
|
||||
image: @@ZITADEL_IMAGE@@
|
||||
|
|
@ -220,6 +223,21 @@ spec:
|
|||
- {name: ZITADEL_EXTERNALPORT, value: "8080"}
|
||||
- {name: ZITADEL_FIRSTINSTANCE_ORG_HUMAN_USERNAME, value: nuthatch-admin}
|
||||
- {name: ZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORD, value: Synthetic-Zitadel-1!}
|
||||
- {name: ZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORDCHANGEREQUIRED, value: "false"}
|
||||
- {name: ZITADEL_FIRSTINSTANCE_PATPATH, value: /bootstrap/admin.pat}
|
||||
- {name: ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINE_USERNAME, value: nuthatch-provisioner}
|
||||
- {name: ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINE_NAME, value: Nuthatch Provisioner}
|
||||
- {name: ZITADEL_FIRSTINSTANCE_ORG_MACHINE_PAT_EXPIRATIONDATE, value: "2036-01-01T00:00:00Z"}
|
||||
- {name: ZITADEL_FIRSTINSTANCE_LOGINCLIENTPATPATH, value: /bootstrap/login-client.pat}
|
||||
- {name: ZITADEL_FIRSTINSTANCE_ORG_LOGINCLIENT_MACHINE_USERNAME, value: nuthatch-login-client}
|
||||
- {name: ZITADEL_FIRSTINSTANCE_ORG_LOGINCLIENT_MACHINE_NAME, value: Nuthatch Login Client}
|
||||
- {name: ZITADEL_FIRSTINSTANCE_ORG_LOGINCLIENT_PAT_EXPIRATIONDATE, value: "2036-01-01T00:00:00Z"}
|
||||
- {name: ZITADEL_DEFAULTINSTANCE_OIDCSETTINGS_ACCESSTOKENLIFETIME, value: 5m}
|
||||
- {name: ZITADEL_DEFAULTINSTANCE_OIDCSETTINGS_IDTOKENLIFETIME, value: 5m}
|
||||
- {name: ZITADEL_DEFAULTINSTANCE_OIDCSETTINGS_REFRESHTOKENIDLEEXPIRATION, value: 1h}
|
||||
- {name: ZITADEL_DEFAULTINSTANCE_OIDCSETTINGS_REFRESHTOKENEXPIRATION, value: 2h}
|
||||
volumeMounts:
|
||||
- {name: bootstrap, mountPath: /bootstrap}
|
||||
ports:
|
||||
- {name: http, containerPort: 8080}
|
||||
readinessProbe:
|
||||
|
|
@ -233,6 +251,25 @@ spec:
|
|||
resources:
|
||||
requests: {cpu: 200m, memory: 512Mi}
|
||||
limits: {cpu: "2", memory: 1Gi}
|
||||
- name: oidc-provisioner
|
||||
image: @@CURL_IMAGE@@
|
||||
imagePullPolicy: Never
|
||||
command: [/bin/sh, -ec]
|
||||
args:
|
||||
- |
|
||||
while [ ! -s /bootstrap/admin.pat ] || [ ! -s /bootstrap/login-client.pat ]; do
|
||||
sleep 1
|
||||
done
|
||||
exec sleep 2147483647
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities: {drop: ["ALL"]}
|
||||
runAsUser: 0
|
||||
volumeMounts:
|
||||
- {name: bootstrap, mountPath: /bootstrap, readOnly: true}
|
||||
resources:
|
||||
requests: {cpu: 10m, memory: 16Mi}
|
||||
limits: {cpu: 100m, memory: 32Mi}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
|
|
|
|||
|
|
@ -197,6 +197,7 @@ render_manifests() {
|
|||
-e "s|@@GARAGE_IMAGE@@|$garage|g" \
|
||||
-e "s|@@VERSITYGW_IMAGE@@|$versitygw|g" \
|
||||
-e "s|@@COREDNS_IMAGE@@|$coredns|g" \
|
||||
-e "s|@@CURL_IMAGE@@|$curl|g" \
|
||||
-e "s|@@AWS_CLI_IMAGE@@|$aws_cli|g" \
|
||||
-e "s|@@POSTGRES_REPLICAS@@|$postgres_replicas|g" \
|
||||
-e "s|@@REDIS_REPLICAS@@|$redis_replicas|g" \
|
||||
|
|
@ -528,6 +529,153 @@ provision_lane_target_principal() {
|
|||
printf -v "$secret_key_var" '%s' "$secret_key"
|
||||
}
|
||||
|
||||
keycloak_admin_token() {
|
||||
kube --namespace "$FIXTURE_NAMESPACE" exec deployment/keycloak -- \
|
||||
sh -ec '
|
||||
/opt/keycloak/bin/kcadm.sh config credentials \
|
||||
--server http://127.0.0.1:8080 \
|
||||
--realm master \
|
||||
--user nuthatch-admin \
|
||||
--password synthetic-keycloak >/dev/null
|
||||
/opt/keycloak/bin/kcadm.sh get serverinfo >/dev/null
|
||||
' >/dev/null
|
||||
}
|
||||
|
||||
provision_lane_keycloak_registration() {
|
||||
local lane="$1"
|
||||
local redirect_uri="$2"
|
||||
local client_id_var="$3"
|
||||
local client_secret_var="$4"
|
||||
local additional_audiences_var="$5"
|
||||
local user_a_var="$6"
|
||||
local user_b_var="$7"
|
||||
local client_id="nuthatch-$lane"
|
||||
local client_secret="synthetic-keycloak-client-secret-$lane"
|
||||
local username
|
||||
keycloak_admin_token || return
|
||||
kube --namespace "$FIXTURE_NAMESPACE" exec deployment/keycloak -- \
|
||||
/opt/keycloak/bin/kcadm.sh create clients \
|
||||
--realm master \
|
||||
-s "clientId=$client_id" \
|
||||
-s enabled=true \
|
||||
-s protocol=openid-connect \
|
||||
-s publicClient=false \
|
||||
-s clientAuthenticatorType=client-secret \
|
||||
-s standardFlowEnabled=true \
|
||||
-s directAccessGrantsEnabled=false \
|
||||
-s "secret=$client_secret" \
|
||||
-s "redirectUris=[\"$redirect_uri\"]" \
|
||||
-s 'attributes={"pkce.code.challenge.method":"S256"}' >/dev/null || return
|
||||
for username in "nuthatch-$lane-a" "nuthatch-$lane-b"; do
|
||||
kube --namespace "$FIXTURE_NAMESPACE" exec deployment/keycloak -- \
|
||||
/opt/keycloak/bin/kcadm.sh create users \
|
||||
--realm master \
|
||||
-s "username=$username" \
|
||||
-s enabled=true \
|
||||
-s "firstName=$username" >/dev/null || return
|
||||
kube --namespace "$FIXTURE_NAMESPACE" exec deployment/keycloak -- \
|
||||
/opt/keycloak/bin/kcadm.sh set-password \
|
||||
--realm master \
|
||||
--username "$username" \
|
||||
--new-password Synthetic-OIDC-1! >/dev/null || return
|
||||
done
|
||||
printf -v "$client_id_var" '%s' "$client_id"
|
||||
printf -v "$client_secret_var" '%s' "$client_secret"
|
||||
printf -v "$additional_audiences_var" ''
|
||||
printf -v "$user_a_var" '%s' "nuthatch-$lane-a"
|
||||
printf -v "$user_b_var" '%s' "nuthatch-$lane-b"
|
||||
}
|
||||
|
||||
zitadel_api() {
|
||||
local token_path="$1"
|
||||
local method="$2"
|
||||
local path="$3"
|
||||
local body="$4"
|
||||
kube --namespace "$FIXTURE_NAMESPACE" exec \
|
||||
deployment/zitadel \
|
||||
--container oidc-provisioner \
|
||||
-- sh -ec '
|
||||
token="$(tr -d "\r\n" < "$1")"
|
||||
curl --fail --silent --show-error \
|
||||
--request "$2" \
|
||||
--header "Host: zitadel.nuthatch.test" \
|
||||
--header "Authorization: Bearer $token" \
|
||||
--header "Content-Type: application/json" \
|
||||
--data "$4" \
|
||||
"http://127.0.0.1:8080$3"
|
||||
' sh "$token_path" "$method" "$path" "$body"
|
||||
}
|
||||
|
||||
provision_lane_zitadel_registration() {
|
||||
local lane="$1"
|
||||
local redirect_uri="$2"
|
||||
local client_id_var="$3"
|
||||
local client_secret_var="$4"
|
||||
local additional_audiences_var="$5"
|
||||
local user_a_var="$6"
|
||||
local user_b_var="$7"
|
||||
local project_response
|
||||
local project_id
|
||||
local app_response
|
||||
local client_id
|
||||
local client_secret
|
||||
local username
|
||||
local user_response
|
||||
local user_ids=()
|
||||
project_response="$(
|
||||
zitadel_api \
|
||||
/bootstrap/admin.pat \
|
||||
POST \
|
||||
/management/v1/projects \
|
||||
"{\"name\":\"Nuthatch lane $lane\"}"
|
||||
)" || return
|
||||
project_id="$(jq -er .id <<< "$project_response")" || return
|
||||
app_response="$(
|
||||
zitadel_api \
|
||||
/bootstrap/admin.pat \
|
||||
POST \
|
||||
"/management/v1/projects/$project_id/apps/oidc" \
|
||||
"{\"projectId\":\"$project_id\",\"name\":\"Nuthatch lane $lane\",\"redirectUris\":[\"$redirect_uri\"],\"responseTypes\":[\"OIDC_RESPONSE_TYPE_CODE\"],\"grantTypes\":[\"OIDC_GRANT_TYPE_AUTHORIZATION_CODE\"],\"appType\":\"OIDC_APP_TYPE_WEB\",\"authMethodType\":\"OIDC_AUTH_METHOD_TYPE_BASIC\",\"version\":\"OIDC_VERSION_1_0\",\"devMode\":false}"
|
||||
)" || return
|
||||
client_id="$(jq -er .clientId <<< "$app_response")" || return
|
||||
client_secret="$(jq -er .clientSecret <<< "$app_response")" || return
|
||||
for username in "nuthatch-$lane-a" "nuthatch-$lane-b"; do
|
||||
user_response="$(
|
||||
zitadel_api \
|
||||
/bootstrap/admin.pat \
|
||||
POST \
|
||||
/management/v1/users/human \
|
||||
"{\"userName\":\"$username\",\"profile\":{\"firstName\":\"Nuthatch\",\"lastName\":\"$username\",\"displayName\":\"$username\",\"preferredLanguage\":\"en\"},\"email\":{\"email\":\"$username@example.test\",\"isEmailVerified\":true},\"initialPassword\":\"Synthetic-OIDC-1!\"}"
|
||||
)" || return
|
||||
user_ids+=("$(jq -er .userId <<< "$user_response")") || return
|
||||
done
|
||||
printf -v "$client_id_var" '%s' "$client_id"
|
||||
printf -v "$client_secret_var" '%s' "$client_secret"
|
||||
printf -v "$additional_audiences_var" '%s' "$project_id"
|
||||
printf -v "$user_a_var" '%s' "${user_ids[0]}"
|
||||
printf -v "$user_b_var" '%s' "${user_ids[1]}"
|
||||
}
|
||||
|
||||
create_oidc_automation_secret() {
|
||||
local lane="$1"
|
||||
local provider="$2"
|
||||
local login_pat=unused
|
||||
if [[ "$provider" = zitadel ]]; then
|
||||
login_pat="$(
|
||||
kube --namespace "$FIXTURE_NAMESPACE" exec \
|
||||
deployment/zitadel \
|
||||
--container oidc-provisioner \
|
||||
-- sh -ec 'tr -d "\r\n" < /bootstrap/login-client.pat'
|
||||
)" || return
|
||||
fi
|
||||
kube create secret generic "nuthatch-oidc-automation-$lane" \
|
||||
--namespace "$FIXTURE_NAMESPACE" \
|
||||
--from-literal="NUTHATCH_OIDC_LOGIN_PAT=$login_pat" \
|
||||
--dry-run=client \
|
||||
--output yaml |
|
||||
kube apply --filename - >/dev/null
|
||||
}
|
||||
|
||||
write_lane_profile() {
|
||||
local lane="$1"
|
||||
local coordination="$2"
|
||||
|
|
@ -538,6 +686,12 @@ write_lane_profile() {
|
|||
local database=
|
||||
local coordination_database=
|
||||
local oidc_issuer=
|
||||
local oidc_client_id=
|
||||
local oidc_client_secret=
|
||||
local oidc_additional_audiences=
|
||||
local oidc_redirect_uri=
|
||||
local oidc_user_a=
|
||||
local oidc_user_b=
|
||||
local target_url=
|
||||
local target_bucket=
|
||||
local target_region=
|
||||
|
|
@ -550,11 +704,36 @@ write_lane_profile() {
|
|||
coordination_database="$(reset_lane_coordination_store "$coordination" "$lane")" || return
|
||||
fi
|
||||
if fixture_has_family oidc; then
|
||||
oidc_redirect_uri="https://nuthatch-$lane:8080/oidc/callback"
|
||||
case "$oidc" in
|
||||
keycloak) oidc_issuer=http://keycloak.nuthatch.test:8080/realms/master ;;
|
||||
zitadel) oidc_issuer=http://zitadel.nuthatch.test:8080 ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
case "$oidc" in
|
||||
keycloak)
|
||||
provision_lane_keycloak_registration \
|
||||
"$lane" \
|
||||
"$oidc_redirect_uri" \
|
||||
oidc_client_id \
|
||||
oidc_client_secret \
|
||||
oidc_additional_audiences \
|
||||
oidc_user_a \
|
||||
oidc_user_b || return
|
||||
;;
|
||||
zitadel)
|
||||
provision_lane_zitadel_registration \
|
||||
"$lane" \
|
||||
"$oidc_redirect_uri" \
|
||||
oidc_client_id \
|
||||
oidc_client_secret \
|
||||
oidc_additional_audiences \
|
||||
oidc_user_a \
|
||||
oidc_user_b || return
|
||||
;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
create_oidc_automation_secret "$lane" "$oidc" || return
|
||||
fi
|
||||
if fixture_has_family target; then
|
||||
target_bucket="nuthatch-lane-$lane"
|
||||
|
|
@ -581,6 +760,12 @@ write_lane_profile() {
|
|||
printf 'NUTHATCH_PG_CONN=host=postgres port=5432 user=nuthatch password=synthetic-postgres dbname=%s\n' "$database"
|
||||
printf 'NUTHATCH_REDIS_URL=redis://%s:6379/%s\n' "$coordination" "$coordination_database"
|
||||
printf 'NUTHATCH_OIDC_ISSUER=%s\n' "$oidc_issuer"
|
||||
printf 'NUTHATCH_OIDC_CLIENT_ID=%s\n' "$oidc_client_id"
|
||||
printf 'NUTHATCH_OIDC_ADDITIONAL_AUDIENCES=%s\n' "$oidc_additional_audiences"
|
||||
printf 'NUTHATCH_OIDC_REDIRECT_URI=%s\n' "$oidc_redirect_uri"
|
||||
printf 'NUTHATCH_OIDC_USER_A=%s\n' "$oidc_user_a"
|
||||
printf 'NUTHATCH_OIDC_USER_B=%s\n' "$oidc_user_b"
|
||||
printf 'NUTHATCH_OIDC_USER_PASSWORD=Synthetic-OIDC-1!\n'
|
||||
printf 'NUTHATCH_S3_ENDPOINT=%s\n' "$target_url"
|
||||
printf 'NUTHATCH_S3_BUCKET=%s\n' "$target_bucket"
|
||||
printf 'NUTHATCH_S3_REGION=%s\n' "$target_region"
|
||||
|
|
@ -588,6 +773,10 @@ write_lane_profile() {
|
|||
printf 'NUTHATCH_S3_SECRET_KEY=%s\n' "$target_secret_key"
|
||||
printf 'NUTHATCH_S3_PATH_STYLE=true\n'
|
||||
} > "$profile_file" || return
|
||||
if fixture_has_family oidc; then
|
||||
printf '%s' "$oidc_client_secret" > "$profile_file.oidc-secret" || return
|
||||
chmod 0600 "$profile_file.oidc-secret" || return
|
||||
fi
|
||||
kube create configmap "$profile" \
|
||||
--namespace "$FIXTURE_NAMESPACE" \
|
||||
--from-env-file="$profile_file" \
|
||||
|
|
@ -682,8 +871,12 @@ cleanup_lane_resources() {
|
|||
"job/$job" \
|
||||
"configmap/$profile" \
|
||||
"configmap/$profile-file" \
|
||||
"secret/nuthatch-oidc-automation-${profile##*-}" \
|
||||
--ignore-not-found >/dev/null || return
|
||||
rm -f "$RUNTIME/$profile.env" "$RUNTIME/$job.yaml"
|
||||
rm -f \
|
||||
"$RUNTIME/$profile.env" \
|
||||
"$RUNTIME/$profile.env.oidc-secret" \
|
||||
"$RUNTIME/$job.yaml"
|
||||
}
|
||||
|
||||
run_job_matrix() {
|
||||
|
|
@ -722,6 +915,7 @@ destroy_fixture() {
|
|||
"$RUNTIME/probe.yaml" \
|
||||
"$RUNTIME/fixture.env" \
|
||||
"$RUNTIME"/nuthatch-fixture-lane-*.env \
|
||||
"$RUNTIME"/nuthatch-fixture-lane-*.env.oidc-secret \
|
||||
"$RUNTIME"/wp05-app-*.yaml || status=1
|
||||
return "$status"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,8 +21,14 @@ spec:
|
|||
envFrom:
|
||||
- configMapRef: {name: @@PROFILE_NAME@@}
|
||||
env:
|
||||
- {name: NUTHATCH_JWT_SECRET, value: synthetic-wp04-jwt-secret}
|
||||
- {name: NUTHATCH_JWT_SECRET, value: synthetic-wp04-session-jwt-secret}
|
||||
- {name: NUTHATCH_REDIS_URL, value: "redis://127.0.0.1:6379/0"}
|
||||
- {name: NUTHATCH_PUBLIC_BASE_URL, value: "https://wp04.invalid"}
|
||||
- {name: NUTHATCH_OIDC_ISSUER, value: "https://issuer.invalid"}
|
||||
- {name: NUTHATCH_OIDC_CLIENT_ID, value: wp04}
|
||||
- {name: NUTHATCH_OIDC_ADDITIONAL_AUDIENCES, value: ""}
|
||||
- {name: NUTHATCH_OIDC_CLIENT_SECRET, value: synthetic-wp04-oidc-client-secret}
|
||||
- {name: NUTHATCH_OIDC_REDIRECT_URI, value: "https://wp04.invalid/oidc/callback"}
|
||||
resources:
|
||||
requests: {cpu: 100m, memory: 32Mi}
|
||||
limits: {cpu: "2", memory: 96Mi}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,15 @@ spec:
|
|||
spec:
|
||||
automountServiceAccountToken: false
|
||||
enableServiceLinks: false
|
||||
dnsPolicy: None
|
||||
dnsConfig:
|
||||
nameservers: [10.96.0.53]
|
||||
searches:
|
||||
- nuthatch-testbed.svc.cluster.local
|
||||
- svc.cluster.local
|
||||
- cluster.local
|
||||
options:
|
||||
- {name: ndots, value: "5"}
|
||||
restartPolicy: Never
|
||||
initContainers:
|
||||
- name: credential-negative
|
||||
|
|
@ -57,18 +66,301 @@ spec:
|
|||
command: [/bin/sh, -ec]
|
||||
args:
|
||||
- |
|
||||
base="http://nuthatch-@@LANE@@:8080"
|
||||
curl --fail --silent --show-error "$base/healthz" | grep -F '"ok":true'
|
||||
curl --fail --silent --show-error "$base/readyz" | grep -F '"ready":true'
|
||||
curl --fail --silent --show-error \
|
||||
--cookie-jar /tmp/cookies \
|
||||
--dump-header /tmp/login-headers \
|
||||
--header 'Accept: application/json' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{"username":"wp05-smoke"}' \
|
||||
"$base/login" >/tmp/login.json
|
||||
csrf="$(awk 'BEGIN{IGNORECASE=1} $1=="X-CSRF-Token:"{gsub("\r","",$2); print $2}' /tmp/login-headers)"
|
||||
base="https://nuthatch-@@LANE@@:8080"
|
||||
|
||||
curl() {
|
||||
command curl --insecure "$@"
|
||||
}
|
||||
|
||||
header_value() {
|
||||
awk -v expected="$2" '
|
||||
BEGIN { IGNORECASE=1 }
|
||||
$1 == expected ":" {
|
||||
sub(/^[^:]*:[[:space:]]*/, "")
|
||||
sub(/\r$/, "")
|
||||
print
|
||||
exit
|
||||
}
|
||||
' "$1"
|
||||
}
|
||||
|
||||
json_field() {
|
||||
tr -d '\n' < "$1" |
|
||||
sed -n 's/.*"'"$2"'"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p'
|
||||
}
|
||||
|
||||
oidc_callback_for() {
|
||||
user="$1"
|
||||
suffix="$2"
|
||||
authorization_url="$3"
|
||||
printf 'Completing %s authorization %s\n' \
|
||||
"$NUTHATCH_OIDC_PROVIDER" "$suffix" >&2
|
||||
case "$NUTHATCH_OIDC_PROVIDER" in
|
||||
keycloak)
|
||||
curl --fail --silent --show-error \
|
||||
--cookie-jar "/tmp/idp-$suffix" \
|
||||
--dump-header "/tmp/idp-start-$suffix.headers" \
|
||||
"$authorization_url" >"/tmp/idp-$suffix.html"
|
||||
action="$(
|
||||
sed -n 's/.*action="\([^"]*\)".*/\1/p' "/tmp/idp-$suffix.html" |
|
||||
head -n 1 |
|
||||
sed 's/&/\&/g'
|
||||
)"
|
||||
test -n "$action"
|
||||
curl --silent --show-error \
|
||||
--cookie "/tmp/idp-$suffix" \
|
||||
--cookie-jar "/tmp/idp-$suffix" \
|
||||
--dump-header "/tmp/idp-finish-$suffix.headers" \
|
||||
--data-urlencode "username=$user" \
|
||||
--data-urlencode "password=$NUTHATCH_OIDC_USER_PASSWORD" \
|
||||
--data-urlencode credentialId= \
|
||||
"$action" >"/tmp/idp-finish-$suffix.body"
|
||||
header_value "/tmp/idp-finish-$suffix.headers" Location
|
||||
;;
|
||||
zitadel)
|
||||
curl --silent --show-error \
|
||||
--dump-header "/tmp/idp-start-$suffix.headers" \
|
||||
"$authorization_url" >"/tmp/idp-start-$suffix.body"
|
||||
login_location="$(
|
||||
header_value "/tmp/idp-start-$suffix.headers" Location
|
||||
)"
|
||||
auth_request="${login_location##*authRequest=}"
|
||||
auth_request="${auth_request%%&*}"
|
||||
test -n "$auth_request"
|
||||
curl --fail --silent --show-error \
|
||||
--header "Authorization: Bearer $NUTHATCH_OIDC_LOGIN_PAT" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data "{\"checks\":{\"user\":{\"userId\":\"$user\"},\"password\":{\"password\":\"$NUTHATCH_OIDC_USER_PASSWORD\"}},\"lifetime\":\"300s\"}" \
|
||||
"$NUTHATCH_OIDC_ISSUER/v2/sessions" \
|
||||
>"/tmp/session-$suffix.json"
|
||||
session_id="$(json_field "/tmp/session-$suffix.json" sessionId)"
|
||||
session_token="$(json_field "/tmp/session-$suffix.json" sessionToken)"
|
||||
test -n "$session_id"
|
||||
test -n "$session_token"
|
||||
curl --fail --silent --show-error \
|
||||
--header "Authorization: Bearer $NUTHATCH_OIDC_LOGIN_PAT" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data "{\"session\":{\"sessionId\":\"$session_id\",\"sessionToken\":\"$session_token\"}}" \
|
||||
"$NUTHATCH_OIDC_ISSUER/v2/oidc/auth_requests/$auth_request" \
|
||||
>"/tmp/finalize-$suffix.json"
|
||||
json_field "/tmp/finalize-$suffix.json" callbackUrl |
|
||||
sed 's/\\u0026/\&/g; s#\\/#/#g'
|
||||
;;
|
||||
*)
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
login() {
|
||||
user="$1"
|
||||
suffix="$2"
|
||||
cookies="/tmp/cookies-$suffix"
|
||||
printf 'Starting login %s\n' "$suffix" >&2
|
||||
curl --insecure --silent --show-error \
|
||||
--cookie-jar "$cookies" \
|
||||
--dump-header "/tmp/login-$suffix.headers" \
|
||||
"$base/login" >"/tmp/login-$suffix.body"
|
||||
test "$(header_value "/tmp/login-$suffix.headers" Status 2>/dev/null || true)" = ""
|
||||
authorization_url="$(
|
||||
header_value "/tmp/login-$suffix.headers" Location
|
||||
)"
|
||||
test -n "$authorization_url"
|
||||
grep -i '^set-cookie: nuthatch_oidc=' "/tmp/login-$suffix.headers" |
|
||||
grep -i 'secure' |
|
||||
grep -i 'httponly' |
|
||||
grep -i 'samesite=lax' |
|
||||
grep -i 'path=/oidc/callback' >/dev/null
|
||||
state="$(
|
||||
printf '%s' "$authorization_url" |
|
||||
sed -n 's/.*[?&]state=\([^&]*\).*/\1/p'
|
||||
)"
|
||||
test -n "$state"
|
||||
if [ "$suffix" = a ]; then
|
||||
wrong_redirect_url="$(
|
||||
printf '%s' "$authorization_url" |
|
||||
sed 's#redirect_uri=[^&]*#redirect_uri=https%3A%2F%2Finvalid.example%2Fcallback#'
|
||||
)"
|
||||
wrong_redirect_status="$(
|
||||
curl --silent --output /dev/null \
|
||||
--write-out '%{http_code}' \
|
||||
"$wrong_redirect_url"
|
||||
)"
|
||||
test "$wrong_redirect_status" -ge 400
|
||||
printf 'Redirect URI rejection passed\n' >&2
|
||||
fi
|
||||
if curl --insecure --fail --silent \
|
||||
--cookie "$cookies" \
|
||||
"$base/oidc/callback?code=unused&state=invalid-$state" >/dev/null; then
|
||||
exit 1
|
||||
fi
|
||||
if [ "$suffix" = a ]; then
|
||||
transaction="$(
|
||||
awk -F '\t' '$6 == "nuthatch_oidc" { print $7 }' "$cookies"
|
||||
)"
|
||||
test "${#transaction}" -gt 1
|
||||
tampered_transaction="x${transaction#?}"
|
||||
test "$(
|
||||
curl --insecure --silent --output /dev/null \
|
||||
--write-out '%{http_code}' \
|
||||
--header 'Cookie: nuthatch_oidc=malformed' \
|
||||
"$base/oidc/callback?code=unused&state=$state"
|
||||
)" = 400
|
||||
test "$(
|
||||
curl --insecure --silent --output /dev/null \
|
||||
--write-out '%{http_code}' \
|
||||
--header "Cookie: nuthatch_oidc=$tampered_transaction" \
|
||||
"$base/oidc/callback?code=unused&state=$state"
|
||||
)" = 400
|
||||
fi
|
||||
callback="$(
|
||||
oidc_callback_for "$user" "$suffix" "$authorization_url"
|
||||
)"
|
||||
test -n "$callback"
|
||||
printf 'Authorization callback received %s\n' "$suffix" >&2
|
||||
callback_status="$(
|
||||
curl --insecure --silent --show-error \
|
||||
--output "/tmp/callback-$suffix.body" \
|
||||
--write-out '%{http_code}' \
|
||||
--cookie "$cookies" \
|
||||
--cookie-jar "$cookies" \
|
||||
--dump-header "/tmp/callback-$suffix.headers" \
|
||||
"$callback"
|
||||
)"
|
||||
printf 'Application callback status=%s %s\n' \
|
||||
"$callback_status" "$suffix" >&2
|
||||
if [ "$callback_status" != 303 ]; then
|
||||
sed -n '1,8p' "/tmp/callback-$suffix.body" >&2
|
||||
exit 1
|
||||
fi
|
||||
test "$(header_value "/tmp/callback-$suffix.headers" Location)" = "/"
|
||||
printf 'Application callback accepted %s\n' "$suffix" >&2
|
||||
sed -n \
|
||||
's/^\([Ss]et-[Cc]ookie: [^=]*\)=.*/\1=<redacted>/p' \
|
||||
"/tmp/callback-$suffix.headers" >&2
|
||||
session_cookie="$(
|
||||
grep -i '^set-cookie: nuthatch_session=' "/tmp/callback-$suffix.headers"
|
||||
)"
|
||||
csrf_cookie="$(
|
||||
grep -i '^set-cookie: nuthatch_csrf=' "/tmp/callback-$suffix.headers"
|
||||
)"
|
||||
transaction_cookie="$(
|
||||
grep -i '^set-cookie: nuthatch_oidc=' "/tmp/callback-$suffix.headers"
|
||||
)"
|
||||
printf '%s' "$session_cookie" |
|
||||
grep -i secure |
|
||||
grep -i httponly |
|
||||
grep -i samesite=lax |
|
||||
grep -i 'path=/;' >/dev/null
|
||||
printf '%s' "$csrf_cookie" |
|
||||
grep -i secure |
|
||||
grep -i samesite=lax |
|
||||
grep -iv httponly |
|
||||
grep -i 'path=/;' >/dev/null
|
||||
printf '%s' "$transaction_cookie" |
|
||||
grep -i 'max-age=0' |
|
||||
grep -i 'path=/oidc/callback;' >/dev/null
|
||||
if printf '%s\n%s\n%s\n' \
|
||||
"$session_cookie" "$csrf_cookie" "$transaction_cookie" |
|
||||
grep -qi 'domain='; then
|
||||
exit 1
|
||||
fi
|
||||
printf 'Cookie attributes passed %s\n' "$suffix" >&2
|
||||
awk -F '\t' '
|
||||
NF == 7 {
|
||||
printf "Stored cookie %s value-length=%d\n", $6, length($7) > "/dev/stderr"
|
||||
}
|
||||
$6 == "nuthatch_csrf" { print $7 }
|
||||
' "$cookies"
|
||||
}
|
||||
|
||||
curl --insecure --fail --silent --show-error "$base/healthz" |
|
||||
grep -F '"ok":true'
|
||||
curl --insecure --fail --silent --show-error "$base/readyz" |
|
||||
grep -F '"ready":true'
|
||||
curl --insecure --fail --silent --show-error "$base/nuthatch.js" |
|
||||
grep -F 'nuthatch'
|
||||
{
|
||||
curl --insecure --fail --silent --show-error "$base/nuthatch.js"
|
||||
curl --insecure --silent --show-error "$base/login"
|
||||
} > /tmp/browser-visible
|
||||
if grep -Ei \
|
||||
'NUTHATCH_S3|AWS_ACCESS_KEY|AWS_SECRET_ACCESS_KEY|client_secret' \
|
||||
/tmp/browser-visible; then
|
||||
exit 1
|
||||
fi
|
||||
test "$(
|
||||
curl --insecure --silent --output /dev/null \
|
||||
--write-out '%{http_code}' \
|
||||
--request POST \
|
||||
"$base/login"
|
||||
)" = 405
|
||||
test "$(
|
||||
curl --insecure --silent --output /dev/null \
|
||||
--write-out '%{http_code}' \
|
||||
"$base/"
|
||||
)" = 303
|
||||
test "$(
|
||||
curl --insecure --silent --output /dev/null \
|
||||
--write-out '%{http_code}' \
|
||||
"$base/download?root=personal&path=unauthenticated"
|
||||
)" = 303
|
||||
unauthenticated_digest="$(
|
||||
printf x | sha256sum | cut -d' ' -f1
|
||||
)"
|
||||
test "$(
|
||||
curl --insecure --silent --output /dev/null \
|
||||
--write-out '%{http_code}' \
|
||||
--header 'X-Declared-Size: 1' \
|
||||
--header "X-Content-SHA256: $unauthenticated_digest" \
|
||||
--header 'X-CSRF-Token: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' \
|
||||
--data x \
|
||||
"$base/upload?root=personal&path=unauthenticated&operation_id=40000000-0000-4000-8000-000000000001"
|
||||
)" = 303
|
||||
test "$(
|
||||
curl --insecure --silent --output /dev/null \
|
||||
--write-out '%{http_code}' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{"root":"personal","path":"unauthenticated","operation_id":"40000000-0000-4000-8000-000000000002","csrf":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}' \
|
||||
"$base/delete"
|
||||
)" = 303
|
||||
test "$(
|
||||
curl --insecure --silent --output /dev/null \
|
||||
--write-out '%{http_code}' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{"root":"personal","path":"unauthenticated","csrf":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}' \
|
||||
"$base/delete-prefix"
|
||||
)" = 303
|
||||
test "$(
|
||||
curl --insecure --silent --output /dev/null \
|
||||
--write-out '%{http_code}' \
|
||||
--header 'X-CSRF-Token: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' \
|
||||
--request POST \
|
||||
"$base/logout"
|
||||
)" = 303
|
||||
printf 'Unauthenticated boundary probes passed\n'
|
||||
|
||||
csrf="$(login "$NUTHATCH_OIDC_USER_A" a)"
|
||||
test -n "$csrf"
|
||||
cookies=/tmp/cookies-a
|
||||
printf 'Login a completed csrf-length=%d\n' "${#csrf}"
|
||||
authenticated_status="$(
|
||||
curl --insecure --silent --output /tmp/authenticated.body \
|
||||
--write-out '%{http_code}' \
|
||||
--cookie "$cookies" \
|
||||
"$base/"
|
||||
)"
|
||||
printf 'Authenticated browse status=%s\n' "$authenticated_status"
|
||||
test "$authenticated_status" = 200
|
||||
curl --insecure --fail --silent --show-error \
|
||||
--cookie "$cookies" \
|
||||
--header 'Accept: application/json' \
|
||||
"$base/" >/tmp/authenticated.json
|
||||
if grep -Ei \
|
||||
'NUTHATCH_S3|AWS_ACCESS_KEY|AWS_SECRET_ACCESS_KEY|client_secret' \
|
||||
/tmp/authenticated.body /tmp/authenticated.json; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exercise_root() {
|
||||
root="$1"
|
||||
|
|
@ -78,22 +370,28 @@ spec:
|
|||
printf '%s' "$first" >/tmp/body
|
||||
size="$(wc -c </tmp/body | tr -d ' ')"
|
||||
digest="$(sha256sum /tmp/body | cut -d' ' -f1)"
|
||||
curl --fail --silent --show-error \
|
||||
--cookie /tmp/cookies \
|
||||
upload_status="$(
|
||||
curl --silent --show-error \
|
||||
--output /tmp/upload.json \
|
||||
--write-out '%{http_code}' \
|
||||
--cookie "$cookies" \
|
||||
--header 'Content-Type: application/octet-stream' \
|
||||
--header "X-Declared-Size: $size" \
|
||||
--header "X-Content-SHA256: $digest" \
|
||||
--header "X-CSRF-Token: $csrf" \
|
||||
--data-binary @/tmp/body \
|
||||
"$base/upload?root=$root&path=smoke-$suffix.txt&operation_id=00000000-0000-4000-8000-0000000000${suffix}" |
|
||||
grep -F '"result":"succeeded"'
|
||||
"$base/upload?root=$root&path=smoke-$suffix.txt&operation_id=00000000-0000-4000-8000-0000000000${suffix}"
|
||||
)"
|
||||
printf 'Upload %s status=%s\n' "$root" "$upload_status"
|
||||
test "$upload_status" = 200
|
||||
grep -F '"result":"succeeded"' /tmp/upload.json
|
||||
curl --fail --silent --show-error \
|
||||
--cookie /tmp/cookies \
|
||||
--cookie "$cookies" \
|
||||
--header 'Accept: application/json' \
|
||||
"$base/?root=$root" |
|
||||
grep -F "smoke-$suffix.txt"
|
||||
curl --fail --silent --show-error \
|
||||
--cookie /tmp/cookies \
|
||||
--cookie "$cookies" \
|
||||
"$base/download?root=$root&path=smoke-$suffix.txt" >/tmp/download
|
||||
test "$(cat /tmp/download)" = "$first"
|
||||
|
||||
|
|
@ -101,7 +399,7 @@ spec:
|
|||
size="$(wc -c </tmp/body | tr -d ' ')"
|
||||
digest="$(sha256sum /tmp/body | cut -d' ' -f1)"
|
||||
curl --fail --silent --show-error \
|
||||
--cookie /tmp/cookies \
|
||||
--cookie "$cookies" \
|
||||
--header 'Content-Type: application/octet-stream' \
|
||||
--header "X-Declared-Size: $size" \
|
||||
--header "X-Content-SHA256: $digest" \
|
||||
|
|
@ -110,18 +408,18 @@ spec:
|
|||
"$base/upload?root=$root&path=smoke-$suffix.txt&operation_id=10000000-0000-4000-8000-0000000000${suffix}" |
|
||||
grep -F '"result":"succeeded"'
|
||||
curl --fail --silent --show-error \
|
||||
--cookie /tmp/cookies \
|
||||
--cookie "$cookies" \
|
||||
"$base/download?root=$root&path=smoke-$suffix.txt" >/tmp/download
|
||||
test "$(cat /tmp/download)" = "$second"
|
||||
|
||||
curl --fail --silent --show-error \
|
||||
--cookie /tmp/cookies \
|
||||
--cookie "$cookies" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data "{\"root\":\"$root\",\"path\":\"smoke-$suffix.txt\",\"operation_id\":\"20000000-0000-4000-8000-0000000000${suffix}\",\"csrf\":\"$csrf\"}" \
|
||||
"$base/delete" |
|
||||
grep -F '"result":"succeeded"'
|
||||
if curl --fail --silent \
|
||||
--cookie /tmp/cookies \
|
||||
--cookie "$cookies" \
|
||||
"$base/download?root=$root&path=smoke-$suffix.txt" >/dev/null; then
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -129,7 +427,152 @@ spec:
|
|||
|
||||
exercise_root personal 01
|
||||
exercise_root shared 02
|
||||
printf 'WP-05 app smoke passed\n'
|
||||
printf private-a >/tmp/body
|
||||
size="$(wc -c </tmp/body | tr -d ' ')"
|
||||
digest="$(sha256sum /tmp/body | cut -d' ' -f1)"
|
||||
curl --insecure --fail --silent --show-error \
|
||||
--cookie "$cookies" \
|
||||
--header 'Content-Type: application/octet-stream' \
|
||||
--header "X-Declared-Size: $size" \
|
||||
--header "X-Content-SHA256: $digest" \
|
||||
--header "X-CSRF-Token: $csrf" \
|
||||
--data-binary @/tmp/body \
|
||||
"$base/upload?root=personal&path=cross-user.txt&operation_id=30000000-0000-4000-8000-000000000001" |
|
||||
grep -F '"result":"succeeded"'
|
||||
curl --insecure --fail --silent --show-error \
|
||||
--cookie "$cookies" \
|
||||
--header 'Content-Type: application/octet-stream' \
|
||||
--header "X-Declared-Size: $size" \
|
||||
--header "X-Content-SHA256: $digest" \
|
||||
--header "X-CSRF-Token: $csrf" \
|
||||
--data-binary @/tmp/body \
|
||||
"$base/upload?root=shared&path=cross-user.txt&operation_id=30000000-0000-4000-8000-000000000002" |
|
||||
grep -F '"result":"succeeded"'
|
||||
|
||||
csrf_b="$(login "$NUTHATCH_OIDC_USER_B" b)"
|
||||
test -n "$csrf_b"
|
||||
|
||||
curl --insecure --silent --show-error \
|
||||
--cookie-jar /tmp/cookies-pkce \
|
||||
--dump-header /tmp/login-pkce.headers \
|
||||
"$base/login" >/tmp/login-pkce.body
|
||||
pkce_authorization_url="$(
|
||||
header_value /tmp/login-pkce.headers Location
|
||||
)"
|
||||
pkce_callback="$(
|
||||
oidc_callback_for \
|
||||
"$NUTHATCH_OIDC_USER_A" \
|
||||
pkce \
|
||||
"$pkce_authorization_url"
|
||||
)"
|
||||
pkce_code="$(
|
||||
printf '%s' "$pkce_callback" |
|
||||
sed -n 's/.*[?&]code=\([^&]*\).*/\1/p'
|
||||
)"
|
||||
test -n "$pkce_code"
|
||||
curl --fail --silent --show-error \
|
||||
"$NUTHATCH_OIDC_ISSUER/.well-known/openid-configuration" \
|
||||
>/tmp/discovery.json
|
||||
token_endpoint="$(json_field /tmp/discovery.json token_endpoint)"
|
||||
test -n "$token_endpoint"
|
||||
pkce_status="$(
|
||||
curl --silent --output /tmp/pkce-error.json \
|
||||
--write-out '%{http_code}' \
|
||||
--user "$NUTHATCH_OIDC_CLIENT_ID:$NUTHATCH_OIDC_CLIENT_SECRET" \
|
||||
--data-urlencode grant_type=authorization_code \
|
||||
--data-urlencode "code=$pkce_code" \
|
||||
--data-urlencode "redirect_uri=$NUTHATCH_OIDC_REDIRECT_URI" \
|
||||
--data-urlencode code_verifier=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \
|
||||
"$token_endpoint"
|
||||
)"
|
||||
test "$pkce_status" -ge 400
|
||||
if curl --insecure --fail --silent --show-error \
|
||||
--cookie /tmp/cookies-b \
|
||||
--header 'Accept: application/json' \
|
||||
"$base/?root=personal" |
|
||||
grep -F cross-user.txt; then
|
||||
exit 1
|
||||
fi
|
||||
curl --insecure --fail --silent --show-error \
|
||||
--cookie /tmp/cookies-b \
|
||||
--header 'Accept: application/json' \
|
||||
"$base/?root=shared" |
|
||||
grep -F cross-user.txt
|
||||
|
||||
if curl --insecure --fail --silent \
|
||||
--cookie "$cookies" \
|
||||
--header 'X-CSRF-Token: invalid' \
|
||||
--request POST \
|
||||
"$base/logout" >/dev/null; then
|
||||
exit 1
|
||||
fi
|
||||
curl --insecure --fail --silent --show-error \
|
||||
--cookie "$cookies" \
|
||||
--cookie-jar "$cookies" \
|
||||
--dump-header /tmp/logout.headers \
|
||||
--header "X-CSRF-Token: $csrf" \
|
||||
--request POST \
|
||||
"$base/logout" >/dev/null
|
||||
grep -i '^set-cookie: nuthatch_session=' /tmp/logout.headers |
|
||||
grep -i 'max-age=0' >/dev/null
|
||||
grep -i '^set-cookie: nuthatch_csrf=' /tmp/logout.headers |
|
||||
grep -i 'max-age=0' >/dev/null
|
||||
grep -i '^set-cookie: nuthatch_oidc=' /tmp/logout.headers |
|
||||
grep -i 'max-age=0' |
|
||||
grep -i 'path=/oidc/callback' >/dev/null
|
||||
test "$(
|
||||
curl --insecure --silent --output /dev/null \
|
||||
--write-out '%{http_code}' \
|
||||
--cookie "$cookies" \
|
||||
"$base/"
|
||||
)" = 303
|
||||
printf 'OIDC app smoke passed\n'
|
||||
env:
|
||||
- name: NUTHATCH_OIDC_PROVIDER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: @@PROFILE_NAME@@
|
||||
key: NUTHATCH_OIDC_PROVIDER
|
||||
- name: NUTHATCH_OIDC_ISSUER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: @@PROFILE_NAME@@
|
||||
key: NUTHATCH_OIDC_ISSUER
|
||||
- name: NUTHATCH_OIDC_USER_A
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: @@PROFILE_NAME@@
|
||||
key: NUTHATCH_OIDC_USER_A
|
||||
- name: NUTHATCH_OIDC_USER_B
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: @@PROFILE_NAME@@
|
||||
key: NUTHATCH_OIDC_USER_B
|
||||
- name: NUTHATCH_OIDC_USER_PASSWORD
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: @@PROFILE_NAME@@
|
||||
key: NUTHATCH_OIDC_USER_PASSWORD
|
||||
- name: NUTHATCH_OIDC_CLIENT_ID
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: @@PROFILE_NAME@@
|
||||
key: NUTHATCH_OIDC_CLIENT_ID
|
||||
- name: NUTHATCH_OIDC_REDIRECT_URI
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: @@PROFILE_NAME@@
|
||||
key: NUTHATCH_OIDC_REDIRECT_URI
|
||||
- name: NUTHATCH_OIDC_CLIENT_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: nuthatch-@@LANE@@
|
||||
key: NUTHATCH_OIDC_CLIENT_SECRET
|
||||
- name: NUTHATCH_OIDC_LOGIN_PAT
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: nuthatch-oidc-automation-@@LANE@@
|
||||
key: NUTHATCH_OIDC_LOGIN_PAT
|
||||
resources:
|
||||
requests: {cpu: 50m, memory: 32Mi}
|
||||
limits: {cpu: "1", memory: 128Mi}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,10 @@ render_application() {
|
|||
local profile_file="$2"
|
||||
local pg_conn
|
||||
local redis_url
|
||||
local oidc_issuer
|
||||
local oidc_client_id
|
||||
local oidc_additional_audiences
|
||||
local oidc_client_secret
|
||||
local s3_endpoint
|
||||
local s3_region
|
||||
local s3_bucket
|
||||
|
|
@ -43,6 +47,12 @@ render_application() {
|
|||
local s3_secret_key
|
||||
pg_conn="$(sed -n 's/^NUTHATCH_PG_CONN=//p' "$profile_file")"
|
||||
redis_url="$(sed -n 's/^NUTHATCH_REDIS_URL=//p' "$profile_file")"
|
||||
oidc_issuer="$(sed -n 's/^NUTHATCH_OIDC_ISSUER=//p' "$profile_file")"
|
||||
oidc_client_id="$(sed -n 's/^NUTHATCH_OIDC_CLIENT_ID=//p' "$profile_file")"
|
||||
oidc_additional_audiences="$(
|
||||
sed -n 's/^NUTHATCH_OIDC_ADDITIONAL_AUDIENCES=//p' "$profile_file"
|
||||
)"
|
||||
oidc_client_secret="$(<"$profile_file.oidc-secret")"
|
||||
s3_endpoint="$(sed -n 's/^NUTHATCH_S3_ENDPOINT=//p' "$profile_file")"
|
||||
s3_region="$(sed -n 's/^NUTHATCH_S3_REGION=//p' "$profile_file")"
|
||||
s3_bucket="$(sed -n 's/^NUTHATCH_S3_BUCKET=//p' "$profile_file")"
|
||||
|
|
@ -53,6 +63,10 @@ render_application() {
|
|||
-e "s|@@APP_IMAGE@@|$APP_IMAGE|g" \
|
||||
-e "s|@@PG_CONN@@|$pg_conn|g" \
|
||||
-e "s|@@REDIS_URL@@|$redis_url|g" \
|
||||
-e "s|@@OIDC_ISSUER@@|$oidc_issuer|g" \
|
||||
-e "s|@@OIDC_CLIENT_ID@@|$oidc_client_id|g" \
|
||||
-e "s|@@OIDC_ADDITIONAL_AUDIENCES@@|$oidc_additional_audiences|g" \
|
||||
-e "s|@@OIDC_CLIENT_SECRET@@|$oidc_client_secret|g" \
|
||||
-e "s|@@S3_ENDPOINT@@|$s3_endpoint|g" \
|
||||
-e "s|@@S3_REGION@@|$s3_region|g" \
|
||||
-e "s|@@S3_BUCKET@@|$s3_bucket|g" \
|
||||
|
|
@ -74,7 +88,7 @@ cleanup_application() {
|
|||
|
||||
acquire_fixture_lock
|
||||
OWNS_FIXTURE=true
|
||||
setup_fixture durable coordination target
|
||||
setup_fixture durable coordination oidc target
|
||||
source "$RUNTIME/fixture.env"
|
||||
"$NUTHATCH_REAL_NERDCTL" --namespace "$NERDCTL_NAMESPACE" build \
|
||||
--file "$ROOT/Dockerfile" \
|
||||
|
|
@ -104,12 +118,13 @@ while IFS=$'\t' read -r lane coordination oidc target; do
|
|||
"$CURL_LOCAL_IMAGE" \
|
||||
"$profile"
|
||||
sed -i "s|@@LANE@@|$lane|g" "$RUNTIME/$job.yaml"
|
||||
printf 'Running lane %s: coordination=%s target=%s\n' "$lane" "$coordination" "$target"
|
||||
printf 'Running lane %s: coordination=%s oidc=%s target=%s\n' \
|
||||
"$lane" "$coordination" "$oidc" "$target"
|
||||
run_job_manifest "$job" "$RUNTIME/$job.yaml"
|
||||
cleanup_application "$lane"
|
||||
cleanup_lane_state "$lane" "$coordination" "$oidc" "$target"
|
||||
cleanup_lane_resources "$job" "$profile"
|
||||
done < <(expand_fixture_matrix coordination target)
|
||||
done < <(expand_fixture_matrix coordination oidc target)
|
||||
|
||||
SUCCEEDED=true
|
||||
printf 'Nuthatch WP-05 app gate passed\n'
|
||||
printf 'Nuthatch OIDC app gate passed\n'
|
||||
|
|
|
|||
Loading…
Reference in a new issue