Files
authentik/blueprints/example/flow-default-account-lockdown.yaml
T
Dominic R b5deeaa822 enterprise: fix account lockdown target handling (#22246)
- Use the pending lockdown target in the example blueprint warning and avoid repeating the username when email/name is not distinct.

- Hide the admin Account Lockdown action for internal service accounts.
2026-05-12 01:59:00 +00:00

300 lines
12 KiB
YAML

version: 1
metadata:
name: Example - Account lockdown flow
labels:
blueprints.goauthentik.io/instantiate: "false"
entries:
flows:
# Main lockdown flow - requires authentication
- conditions:
- !Context goauthentik.io/enterprise/licensed
attrs:
designation: stage_configuration
name: Account Lockdown
title: Lock Account
authentication: require_authenticated
identifiers:
slug: default-account-lockdown
model: authentik_flows.flow
id: flow
# Self-service completion flow - no authentication required
- conditions:
- !Context goauthentik.io/enterprise/licensed
attrs:
designation: stage_configuration
name: Account Lockdown Complete
title: Account Locked
authentication: none
identifiers:
slug: default-account-lockdown-complete
model: authentik_flows.flow
id: completion-flow
prompt_fields:
# Warning field - danger alert box (content varies based on self-service vs admin)
- conditions:
- !Context goauthentik.io/enterprise/licensed
attrs:
order: 50
initial_value: |
actor_uuid = str(getattr(http_request.user, "pk", ""))
pending_user = user if getattr(user, "is_authenticated", False) else None
target_uuid = str(getattr(pending_user, "pk", ""))
is_self_service = not target_uuid or target_uuid == actor_uuid
if is_self_service:
return (
"<p><strong>You are about to lock down your own account.</strong></p>"
"<p>This is an emergency action for cutting off access to your account right away.</p>"
"<p><strong>This will immediately:</strong></p>"
"<ul>"
"<li><strong>Invalidate your password</strong> - Your password will be set to a random value "
"and cannot be recovered</li>"
"<li><strong>Deactivate your account</strong> - Your account will be disabled</li>"
"<li><strong>Terminate all your sessions</strong> - You will be logged out everywhere</li>"
"<li><strong>Revoke all your tokens</strong> - All your API, app password, recovery, "
"verification, and OAuth2 tokens and grants will be revoked</li>"
"</ul>"
"<p><strong>This action cannot be easily undone.</strong></p>"
)
from django.utils.html import escape
if pending_user:
detail = pending_user.email or pending_user.name
user_html = f"<code>{escape(pending_user.username)}</code>"
if detail and detail != pending_user.username:
user_html = f"{user_html} ({escape(detail)})"
else:
user_html = "the account selected when this one-time lockdown link was created"
return (
f"<p><strong>You are about to lock down the following account:</strong> {user_html}</p>"
"<p>This is an emergency action for cutting off access to the account right away. "
"It does not lock the administrator who opened this page.</p>"
"<p><strong>This will immediately:</strong></p>"
"<ul>"
"<li>Invalidate the user's password</li>"
"<li>Deactivate the user</li>"
"<li>Terminate all sessions - All active sessions will be ended</li>"
"<li>Revoke all tokens - All API, app password, recovery, verification, and OAuth2 "
"tokens and grants will be revoked</li>"
"</ul>"
"<p><strong>This action cannot be easily undone.</strong></p>"
)
initial_value_expression: true
required: false
type: alert_danger
field_key: lockdown_warning
label: Warning
sub_text: ""
identifiers:
name: default-account-lockdown-field-warning
id: prompt-field-warning
model: authentik_stages_prompt.prompt
# Info field - when to use lockdown (content varies based on self-service vs admin)
- conditions:
- !Context goauthentik.io/enterprise/licensed
attrs:
order: 100
initial_value: |
actor_uuid = str(getattr(http_request.user, "pk", ""))
target_uuid = str(getattr(user, "pk", ""))
is_self_service = not target_uuid or target_uuid == actor_uuid
if is_self_service:
info = (
"Use this if you no longer trust your current password or sessions. "
"After lockdown, you will need help from your administrator or security team to regain access."
)
else:
info = (
"Use this for incident response on the listed account, for example after a compromise report "
"or suspicious activity. The reason you enter below will be recorded in the audit log."
)
return (
f"<p>{info}</p>"
'<p><a href="https://docs.goauthentik.io/docs/security/'
'account-lockdown?utm_source=authentik" '
'target="_blank" rel="noopener noreferrer">Learn more about account lockdown</a></p>'
)
initial_value_expression: true
required: false
type: alert_info
field_key: lockdown_info
label: Information
sub_text: ""
identifiers:
name: default-account-lockdown-field-info
id: prompt-field-info
model: authentik_stages_prompt.prompt
# Reason field - text area for lockdown reason
- conditions:
- !Context goauthentik.io/enterprise/licensed
attrs:
order: 200
placeholder: |
actor_uuid = str(getattr(http_request.user, "pk", ""))
target_uuid = str(getattr(user, "pk", ""))
is_self_service = not target_uuid or target_uuid == actor_uuid
if is_self_service:
return "Describe why you are locking your account..."
return "Describe why this account is being locked down..."
placeholder_expression: true
required: true
type: text_area
field_key: lockdown_reason
label: Reason
sub_text: This explanation will be recorded in the audit log.
identifiers:
name: default-account-lockdown-field-reason
id: prompt-field-reason
model: authentik_stages_prompt.prompt
prompt_stages:
# Prompt stage for warnings and reason input
- conditions:
- !Context goauthentik.io/enterprise/licensed
attrs:
fields:
- !KeyOf prompt-field-warning
- !KeyOf prompt-field-info
- !KeyOf prompt-field-reason
identifiers:
name: default-account-lockdown-prompt
id: default-account-lockdown-prompt
model: authentik_stages_prompt.promptstage
lockdown_stage:
# Account lockdown stage - performs the actual lockdown
- conditions:
- !Context goauthentik.io/enterprise/licensed
identifiers:
name: default-account-lockdown-stage
id: default-account-lockdown-stage
model: authentik_stages_account_lockdown.accountlockdownstage
attrs:
deactivate_user: true
set_unusable_password: true
delete_sessions: true
revoke_tokens: true
self_service_completion_flow: !Find [authentik_flows.flow, [slug, default-account-lockdown-complete]]
completion_prompt:
# Completion message field - confirmation shown after an admin-triggered lockdown
- conditions:
- !Context goauthentik.io/enterprise/licensed
attrs:
order: 300
initial_value: |
from django.utils.html import escape
if getattr(user, "is_authenticated", False):
return f"<p><code>{escape(user.username)}</code> has been locked down.</p>"
return "<p>The selected account has been locked down.</p>"
initial_value_expression: true
required: false
type: alert_info
field_key: lockdown_complete
label: Result
sub_text: ""
identifiers:
name: default-account-lockdown-field-complete
id: prompt-field-complete
model: authentik_stages_prompt.prompt
# Prompt stage for admin completion message
- conditions:
- !Context goauthentik.io/enterprise/licensed
attrs:
fields:
- !KeyOf prompt-field-complete
identifiers:
name: default-account-lockdown-complete-prompt
id: default-account-lockdown-complete-prompt
model: authentik_stages_prompt.promptstage
policies:
# Expression policy to check if this is NOT a self-service lockdown (admin)
- conditions:
- !Context goauthentik.io/enterprise/licensed
attrs:
name: default-account-lockdown-admin-policy
expression: |
actor_uuid = str(getattr(request.http_request.user, "pk", ""))
target_uuid = str(getattr(request.user, "pk", ""))
return bool(target_uuid) and target_uuid != actor_uuid
identifiers:
name: default-account-lockdown-admin-policy
id: admin-policy
model: authentik_policies_expression.expressionpolicy
bindings:
# Stage bindings
- conditions:
- !Context goauthentik.io/enterprise/licensed
identifiers:
order: 0
stage: !KeyOf default-account-lockdown-prompt
target: !KeyOf flow
model: authentik_flows.flowstagebinding
- conditions:
- !Context goauthentik.io/enterprise/licensed
identifiers:
order: 10
stage: !KeyOf default-account-lockdown-stage
target: !KeyOf flow
model: authentik_flows.flowstagebinding
# Admin completion stage binding - shown for admin lockdown only
- conditions:
- !Context goauthentik.io/enterprise/licensed
identifiers:
order: 20
stage: !KeyOf default-account-lockdown-complete-prompt
target: !KeyOf flow
id: admin-completion-binding
model: authentik_flows.flowstagebinding
# Bind the admin policy to the admin completion stage
- conditions:
- !Context goauthentik.io/enterprise/licensed
attrs:
enabled: true
negate: false
order: 0
identifiers:
policy: !KeyOf admin-policy
target: !KeyOf admin-completion-binding
model: authentik_policies.policybinding
self_service_completion:
# Self-service completion message field (for the unauthenticated completion flow)
- conditions:
- !Context goauthentik.io/enterprise/licensed
attrs:
order: 100
initial_value: |
return (
"<h1>Your account has been locked</h1>"
"<p>You have been logged out of all sessions and your password has been invalidated.</p>"
"<p>To regain access to your account, please contact your IT administrator or security team.</p>"
)
initial_value_expression: true
required: false
type: alert_warning
field_key: self_lockdown_complete
label: Account locked
sub_text: ""
identifiers:
name: default-account-lockdown-self-field-complete
id: self-prompt-field-complete
model: authentik_stages_prompt.prompt
# Prompt stage for self-service completion (unauthenticated)
- conditions:
- !Context goauthentik.io/enterprise/licensed
attrs:
fields:
- !KeyOf self-prompt-field-complete
identifiers:
name: default-account-lockdown-self-complete-prompt
id: default-account-lockdown-self-complete-prompt
model: authentik_stages_prompt.promptstage
# Bind self-service completion stage to the completion flow
- conditions:
- !Context goauthentik.io/enterprise/licensed
identifiers:
order: 0
stage: !KeyOf default-account-lockdown-self-complete-prompt
target: !Find [authentik_flows.flow, [slug, default-account-lockdown-complete]]
model: authentik_flows.flowstagebinding