keycloak: add Hermes automation identity
This commit is contained in:
parent
521d1190c6
commit
aa376c0ee9
@ -1,9 +1,9 @@
|
||||
# services/keycloak/bootstrap-jobs/hermes-access-oidc-client-job.yaml
|
||||
# Purpose: create isolated chat, Brad-only agent, and Brad-only triage clients.
|
||||
# Purpose: create Hermes browser clients and its automation identity.
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: hermes-access-oidc-client-ensure-6
|
||||
name: hermes-access-oidc-client-ensure-7
|
||||
namespace: sso
|
||||
spec:
|
||||
backoffLimit: 3
|
||||
|
||||
@ -208,6 +208,89 @@ ensure_proxy_client() {
|
||||
echo "Hermes OIDC client ${client_id} is ready"
|
||||
}
|
||||
|
||||
ensure_service_account_client() {
|
||||
client_id="$1"
|
||||
vault_path="$2"
|
||||
payload="$(jq -nc \
|
||||
--arg client_id "${client_id}" \
|
||||
'{
|
||||
clientId:$client_id,
|
||||
name:"Hermes Automation",
|
||||
description:"Machine identity for Hermes development and delivery integrations",
|
||||
enabled:true,
|
||||
protocol:"openid-connect",
|
||||
publicClient:false,
|
||||
bearerOnly:false,
|
||||
clientAuthenticatorType:"client-secret",
|
||||
standardFlowEnabled:false,
|
||||
implicitFlowEnabled:false,
|
||||
directAccessGrantsEnabled:false,
|
||||
serviceAccountsEnabled:true,
|
||||
fullScopeAllowed:false,
|
||||
attributes:{"access.token.lifespan":"1200"}
|
||||
}')"
|
||||
|
||||
query="$(curl -sS -H "Authorization: Bearer ${ACCESS_TOKEN}" \
|
||||
"${KC_URL}/admin/realms/atlas/clients?clientId=${client_id}" || true)"
|
||||
internal_id="$(printf '%s' "${query}" | jq -r '.[0].id' 2>/dev/null || true)"
|
||||
if [ -z "${internal_id}" ] || [ "${internal_id}" = "null" ]; then
|
||||
status="$(curl -sS -o /dev/null -w '%{http_code}' -X POST \
|
||||
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d "${payload}" \
|
||||
"${KC_URL}/admin/realms/atlas/clients")"
|
||||
if [ "${status}" != "201" ] && [ "${status}" != "204" ] && [ "${status}" != "409" ]; then
|
||||
echo "Keycloak service account client ${client_id} create failed (status ${status})" >&2
|
||||
exit 1
|
||||
fi
|
||||
query="$(curl -sS -H "Authorization: Bearer ${ACCESS_TOKEN}" \
|
||||
"${KC_URL}/admin/realms/atlas/clients?clientId=${client_id}" || true)"
|
||||
internal_id="$(printf '%s' "${query}" | jq -r '.[0].id' 2>/dev/null || true)"
|
||||
fi
|
||||
if [ -z "${internal_id}" ] || [ "${internal_id}" = "null" ]; then
|
||||
echo "Keycloak service account client ${client_id} was not found after create" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
status="$(curl -sS -o /dev/null -w '%{http_code}' -X PUT \
|
||||
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d "${payload}" \
|
||||
"${KC_URL}/admin/realms/atlas/clients/${internal_id}")"
|
||||
if [ "${status}" != "204" ]; then
|
||||
echo "Keycloak service account client ${client_id} update failed (status ${status})" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
client_secret="$(curl -sS -H "Authorization: Bearer ${ACCESS_TOKEN}" \
|
||||
"${KC_URL}/admin/realms/atlas/clients/${internal_id}/client-secret" \
|
||||
| jq -r '.value' 2>/dev/null || true)"
|
||||
if [ -z "${client_secret}" ] || [ "${client_secret}" = "null" ]; then
|
||||
echo "Keycloak service account client ${client_id} secret was not returned" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
issuer="https://sso.bstein.dev/realms/atlas"
|
||||
token_url="${KC_URL}/realms/atlas/protocol/openid-connect/token"
|
||||
state_file="/tmp/hermes-$(printf '%s' "${client_id}" | tr -c 'a-zA-Z0-9' '-').json"
|
||||
vault_payload="$(jq -nc \
|
||||
--arg client_id "${client_id}" \
|
||||
--arg client_secret "${client_secret}" \
|
||||
--arg issuer "${issuer}" \
|
||||
--arg token_url "${token_url}" \
|
||||
'{data:{client_id:$client_id,client_secret:$client_secret,issuer:$issuer,token_url:$token_url}}')"
|
||||
write_status="$(curl -sS -o "${state_file}" -w '%{http_code}' -X POST \
|
||||
-H "X-Vault-Token: ${vault_token}" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d "${vault_payload}" \
|
||||
"${VAULT_ADDR}/v1/kv/data/atlas/${vault_path}")"
|
||||
if [ "${write_status}" != "200" ] && [ "${write_status}" != "204" ]; then
|
||||
echo "Vault ${vault_path} write failed (status ${write_status})" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Hermes machine identity ${client_id} is ready"
|
||||
}
|
||||
|
||||
ensure_telegram_config() {
|
||||
vault_path="hermes/chat-telegram"
|
||||
state_file="/tmp/hermes-chat-telegram.json"
|
||||
@ -247,4 +330,5 @@ ensure_hermes_owner
|
||||
ensure_proxy_client "hermes-chat-proxy" "https://chat.hermes.bstein.dev" "hermes/chat-oidc"
|
||||
ensure_proxy_client "hermes-agent-proxy" "https://agent.hermes.bstein.dev" "hermes/agent-oidc"
|
||||
ensure_proxy_client "hermes-triage-proxy" "https://triage.hermes.bstein.dev" "hermes/triage-oidc"
|
||||
ensure_service_account_client "hermes-automation" "hermes/developer-keycloak"
|
||||
ensure_telegram_config
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user