Files
homelab/scripts/authentik-disable-2fa.sh
T
k.rennerandClaude Opus 4.7 80945a38d7
ci/woodpecker/manual/migrate-authentik-db Pipeline was successful
ci/woodpecker/manual/migrate-paperless Pipeline failed
fix: Scope OBC health check to each app's own bucket
Previously the OBC CEL health check lived on infrastructure-ceph-cluster,
which holds OBCs for every app. A slow bind in one namespace stalled
every other app that depends on infrastructure-ceph-cluster. Move each
OBC into its own app Kustomization (paperless-db, authentik-db) and
apply the health check there so each app only waits on its own bucket.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 00:39:52 +02:00

70 lines
2.7 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# Emergency 2FA removal for a single Authentik user.
# Deletes every authenticator device (TOTP, WebAuthn, static backup codes,
# SMS, Duo, mobile, endpoint) directly in Postgres — bypasses the API so it
# works even if you can't complete the MFA challenge to log in.
#
# Usage: ./scripts/authentik-disable-2fa.sh [username]
# Defaults to akadmin.
USER_NAME="${1:-akadmin}"
NS="authentik"
CLUSTER="ak-pg"
DEVICE_TABLES=(
authentik_stages_authenticator_totp_totpdevice
authentik_stages_authenticator_webauthn_webauthndevice
authentik_stages_authenticator_static_staticdevice
authentik_stages_authenticator_sms_smsdevice
authentik_stages_authenticator_duo_duodevice
authentik_stages_authenticator_mobile_mobiledevice
authentik_stages_authenticator_endpoint_gdtc_endpointdevice
)
# Find the current primary instance
PRIMARY=$(kubectl get cluster -n "$NS" "$CLUSTER" -o jsonpath='{.status.currentPrimary}' 2>/dev/null || true)
[[ -n "$PRIMARY" ]] || { echo "Could not find CNPG primary for $NS/$CLUSTER — is the cluster running?"; exit 1; }
echo "Primary: $PRIMARY"
# Sanity check user exists
USER_ID=$(kubectl exec -n "$NS" "$PRIMARY" -c postgres -- \
psql -At -U postgres authentik \
-c "SELECT id FROM authentik_core_user WHERE username = '$USER_NAME';" | tr -d '[:space:]')
[[ -n "$USER_ID" ]] || { echo "User '$USER_NAME' not found in authentik_core_user"; exit 1; }
echo "User id: $USER_ID"
# Build a DELETE for every device table, combined in a single transaction
SQL="BEGIN;"
for t in "${DEVICE_TABLES[@]}"; do
# Skip tables that don't exist in this Authentik version (older/newer schemas)
SQL+=" DO \$\$ BEGIN
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = '$t') THEN
EXECUTE 'DELETE FROM $t WHERE user_id = $USER_ID';
END IF;
END \$\$;"
done
SQL+=" COMMIT;"
echo "Removing all MFA devices for $USER_NAME..."
kubectl exec -n "$NS" "$PRIMARY" -c postgres -- \
psql -v ON_ERROR_STOP=1 -U postgres authentik -c "$SQL"
echo
echo "Remaining device counts for $USER_NAME:"
for t in "${DEVICE_TABLES[@]}"; do
count=$(kubectl exec -n "$NS" "$PRIMARY" -c postgres -- \
psql -At -U postgres authentik \
-c "SELECT count(*) FROM information_schema.tables WHERE table_name = '$t';" | tr -d '[:space:]')
[[ "$count" == "1" ]] || continue
n=$(kubectl exec -n "$NS" "$PRIMARY" -c postgres -- \
psql -At -U postgres authentik \
-c "SELECT count(*) FROM $t WHERE user_id = $USER_ID;" | tr -d '[:space:]')
printf " %-60s %s\n" "$t" "$n"
done
echo
echo "Done. User '$USER_NAME' can now log in with just the password."
echo "Re-enroll MFA from the user's settings after logging in."