mirror of
https://github.com/zitadel/zitadel.git
synced 2025-01-11 09:53:39 +00:00
fb8cd18f93
# Which Problems Are Solved Some organizations / customers have the requirement, that there users regularly need to change their password. ZITADEL already had the possibility to manage a `password age policy` ( thought the API) with the maximum amount of days a password should be valid, resp. days after with the user should be warned of the upcoming expiration. The policy could not be managed though the Console UI and was not checked in the Login UI. # How the Problems Are Solved - The policy can be managed in the Console UI's settings sections on an instance and organization level. - During an authentication in the Login UI, if a policy is set with an expiry (>0) and the user's last password change exceeds the amount of days set, the user will be prompted to change their password. - The prompt message of the Login UI can be customized in the Custom Login Texts though the Console and API on the instance and each organization. - The information when the user last changed their password is returned in the Auth, Management and User V2 API. - The policy can be retrieved in the settings service as `password expiry settings`. # Additional Changes None. # Additional Context - closes #8081 --------- Co-authored-by: Tim Möhlmann <tim+github@zitadel.com>
405 lines
16 KiB
Protocol Buffer
405 lines
16 KiB
Protocol Buffer
syntax = "proto3";
|
|
|
|
import "zitadel/object.proto";
|
|
import "zitadel/idp.proto";
|
|
import "google/protobuf/duration.proto";
|
|
import "protoc-gen-openapiv2/options/annotations.proto";
|
|
import "validate/validate.proto";
|
|
|
|
package zitadel.policy.v1;
|
|
|
|
option go_package ="github.com/zitadel/zitadel/pkg/grpc/policy";
|
|
|
|
//deprecated: please use DomainPolicy instead
|
|
message OrgIAMPolicy {
|
|
zitadel.v1.ObjectDetails details = 1;
|
|
bool user_login_must_be_domain = 2 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "the username has to end with the domain of its organization"
|
|
}
|
|
];
|
|
bool is_default = 3 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "defines if the organization's admin changed the policy"
|
|
}
|
|
];
|
|
}
|
|
|
|
message DomainPolicy {
|
|
zitadel.v1.ObjectDetails details = 1;
|
|
bool user_login_must_be_domain = 2 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "the username has to end with the domain of its organization"
|
|
}
|
|
];
|
|
bool is_default = 3 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "defines if the organization's admin changed the policy"
|
|
}
|
|
];
|
|
bool validate_org_domains = 4 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "defines if organization domains should be validated org count as validated automatically"
|
|
}
|
|
];
|
|
bool smtp_sender_address_matches_instance_domain = 5 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "defines if the SMTP sender address domain should match an existing domain on the instance"
|
|
}
|
|
];
|
|
}
|
|
|
|
message LabelPolicy {
|
|
zitadel.v1.ObjectDetails details = 1;
|
|
// hex value for primary color
|
|
string primary_color = 2 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "hex value for primary color";
|
|
example: "\"#5469d4\"";
|
|
}
|
|
];
|
|
// defines if the organization's admin changed the policy
|
|
bool is_default = 4 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "defines if the organization's admin changed the policy"
|
|
}
|
|
];
|
|
// hides the org suffix on the login form if the scope \"urn:zitadel:iam:org:domain:primary:{domainname}\" is set
|
|
bool hide_login_name_suffix = 5 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "hides the org suffix on the login form if the scope \"urn:zitadel:iam:org:domain:primary:{domainname}\" is set";
|
|
}
|
|
];
|
|
// hex value for secondary color
|
|
string warn_color = 6 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "hex value for warn color";
|
|
example: "\"#CD3D56\"";
|
|
}
|
|
];
|
|
// hex value for background color
|
|
string background_color = 7 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "hex value for background color";
|
|
example: "\"#FAFAFA\"";
|
|
}
|
|
];
|
|
// hex value for font color
|
|
string font_color = 8 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "hex value for font color";
|
|
example: "\"#000000\"";
|
|
}
|
|
];
|
|
// hex value for primary color dark theme
|
|
string primary_color_dark = 9 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "hex value for the primary color dark theme";
|
|
example: "\"#BBBAFA\"";
|
|
}
|
|
];
|
|
// hex value for background color dark theme
|
|
string background_color_dark = 10 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "hex value for background color dark theme";
|
|
example: "\"#111827\"";
|
|
}
|
|
];
|
|
// hex value for warning color dark theme
|
|
string warn_color_dark = 11 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "hex value for warning color dark theme";
|
|
example: "\"#FF3B5B\"";
|
|
}
|
|
];
|
|
// hex value for font color dark theme
|
|
string font_color_dark = 12 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "hex value for font color dark theme";
|
|
example: "\"#FFFFFF\"";
|
|
}
|
|
];
|
|
bool disable_watermark = 13;
|
|
string logo_url = 14 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "hex value for font color dark theme";
|
|
example: "\"https://acme.com/assets/v1/165617850692654601/policy/label/logo-180950416321494657\"";
|
|
}
|
|
];
|
|
string icon_url = 15 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "hex value for font color dark theme";
|
|
example: "\"https://acme.com/assets/v1/165617850692654601/policy/label/icon-180950498874178817\"";
|
|
}
|
|
];
|
|
string logo_url_dark = 16 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "hex value for font color dark theme";
|
|
example: "\"https://acme.com/assets/v1/165617850692654601/policy/label/logo-dark-180950229376461345\"";
|
|
}
|
|
];
|
|
string icon_url_dark = 17 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "hex value for font color dark theme";
|
|
example: "\"https://acme.com/assets/v1/165617850692654601/policy/label/icon-dark-180950243237405441\"";
|
|
}
|
|
];
|
|
string font_url = 18;
|
|
ThemeMode theme_mode = 19;
|
|
}
|
|
|
|
enum ThemeMode {
|
|
THEME_MODE_UNSPECIFIED = 0;
|
|
THEME_MODE_AUTO = 1;
|
|
THEME_MODE_DARK = 2;
|
|
THEME_MODE_LIGHT = 3;
|
|
}
|
|
|
|
message LoginPolicy {
|
|
zitadel.v1.ObjectDetails details = 1;
|
|
bool allow_username_password = 2 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "defines if a user is allowed to log in with username and password"
|
|
}
|
|
];
|
|
bool allow_register = 3 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "defines if a person is allowed to register a user on this organization"
|
|
}
|
|
];
|
|
bool allow_external_idp = 4 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "defines if a user is allowed to add a defined identity provider. E.g. Google auth"
|
|
}
|
|
];
|
|
bool force_mfa = 5 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "defines if a user MUST use a multi-factor to log in"
|
|
}
|
|
];
|
|
PasswordlessType passwordless_type = 6 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "defines if passwordless is allowed for users"
|
|
}
|
|
];
|
|
bool is_default = 7 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "defines if the organization's admin changed the policy"
|
|
}
|
|
];
|
|
bool hide_password_reset = 8 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "defines if password reset link should be shown in the login screen"
|
|
}
|
|
];
|
|
bool ignore_unknown_usernames = 9 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "defines if unknown username on login screen directly returns an error or always displays the password screen"
|
|
}
|
|
];
|
|
string default_redirect_uri = 10 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "defines where the user will be redirected to if the login is started without app context (e.g. from mail)";
|
|
example: "\"https://acme.com/ui/console\"";
|
|
}
|
|
];
|
|
google.protobuf.Duration password_check_lifetime = 11 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
example: "\"864000s\"";
|
|
}
|
|
];
|
|
google.protobuf.Duration external_login_check_lifetime = 12 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
example: "\"864000s\"";
|
|
}
|
|
];
|
|
google.protobuf.Duration mfa_init_skip_lifetime = 13 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
example: "\"2592000s\"";
|
|
}
|
|
];
|
|
google.protobuf.Duration second_factor_check_lifetime = 14 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
example: "\"64800s\"";
|
|
}
|
|
];
|
|
google.protobuf.Duration multi_factor_check_lifetime = 15 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
example: "\"43200s\"";
|
|
}
|
|
];
|
|
repeated SecondFactorType second_factors = 16;
|
|
repeated MultiFactorType multi_factors = 17;
|
|
repeated zitadel.idp.v1.IDPLoginPolicyLink idps = 18;
|
|
// If set to true, the suffix (@domain.com) of an unknown username input on the login screen will be matched against the org domains and will redirect to the registration of that organization on success.
|
|
bool allow_domain_discovery = 19 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "If set to true, the suffix (@domain.com) of an unknown username input on the login screen will be matched against the org domains and will redirect to the registration of that organization on success."
|
|
}
|
|
];
|
|
bool disable_login_with_email = 20 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "defines if the user can additionally (to the login name) be identified by their verified email address"
|
|
}
|
|
];
|
|
bool disable_login_with_phone = 21 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "defines if the user can additionally (to the login name) be identified by their verified phone number"
|
|
}
|
|
];
|
|
bool force_mfa_local_only = 22 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "if activated, only local authenticated users are forced to use MFA. Authentication through IDPs won't prompt a MFA step in the login."
|
|
}
|
|
];
|
|
}
|
|
|
|
enum SecondFactorType {
|
|
SECOND_FACTOR_TYPE_UNSPECIFIED = 0;
|
|
// SECOND_FACTOR_TYPE_OTP is the type for TOTP
|
|
SECOND_FACTOR_TYPE_OTP = 1;
|
|
SECOND_FACTOR_TYPE_U2F = 2;
|
|
SECOND_FACTOR_TYPE_OTP_EMAIL = 3;
|
|
SECOND_FACTOR_TYPE_OTP_SMS = 4;
|
|
}
|
|
|
|
enum MultiFactorType {
|
|
MULTI_FACTOR_TYPE_UNSPECIFIED = 0;
|
|
MULTI_FACTOR_TYPE_U2F_WITH_VERIFICATION = 1;
|
|
}
|
|
|
|
enum PasswordlessType {
|
|
PASSWORDLESS_TYPE_NOT_ALLOWED = 0;
|
|
PASSWORDLESS_TYPE_ALLOWED = 1;
|
|
//PLANNED: PASSWORDLESS_TYPE_WITH_CERT
|
|
}
|
|
|
|
message PasswordComplexityPolicy {
|
|
zitadel.v1.ObjectDetails details = 1;
|
|
uint64 min_length = 2 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
example: "\"8\""
|
|
}
|
|
];
|
|
bool has_uppercase = 3 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "defines if the password MUST contain an upper case letter"
|
|
}
|
|
];
|
|
bool has_lowercase = 4 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "defines if the password MUST contain a lowercase letter"
|
|
}
|
|
];
|
|
bool has_number = 5 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "defines if the password MUST contain a number"
|
|
}
|
|
];
|
|
bool has_symbol = 6 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "defines if the password MUST contain a symbol. E.g. \"$\""
|
|
}
|
|
];
|
|
bool is_default = 7 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "defines if the organization's admin changed the policy"
|
|
}
|
|
];
|
|
}
|
|
|
|
message PasswordAgePolicy {
|
|
zitadel.v1.ObjectDetails details = 1;
|
|
// Amount of days after which a password will expire. The user will be forced to change the password on the following authentication.
|
|
uint64 max_age_days = 2 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
example: "\"365\""
|
|
}
|
|
];
|
|
// Amount of days after which the user should be notified of the upcoming expiry. ZITADEL will not notify the user.
|
|
uint64 expire_warn_days = 3 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
example: "\"10\""
|
|
}
|
|
];
|
|
// If true, the returned values represent the instance settings, e.g. by an organization without custom settings.
|
|
bool is_default = 4;
|
|
}
|
|
|
|
message LockoutPolicy {
|
|
zitadel.v1.ObjectDetails details = 1;
|
|
uint64 max_password_attempts = 2 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "Maximum password check attempts before the account gets locked. Attempts are reset as soon as the password is entered correctly or the password is reset. If set to 0 the account will never be locked."
|
|
example: "\"10\""
|
|
}
|
|
];
|
|
uint64 max_otp_attempts = 3 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "Maximum failed attempts for a single OTP type (TOTP, SMS, Email) before the account gets locked. Attempts are reset as soon as the OTP is entered correctly. If set to 0 the account will never be locked."
|
|
example: "\"10\""
|
|
}
|
|
];
|
|
bool is_default = 4 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "defines if the organization's admin changed the policy"
|
|
}
|
|
];
|
|
}
|
|
|
|
message PrivacyPolicy {
|
|
zitadel.v1.ObjectDetails details = 1;
|
|
string tos_link = 2 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
example: "\"https://zitadel.com/docs/legal/terms-of-service\"";
|
|
}
|
|
];
|
|
string privacy_link = 3 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
example: "\"https://zitadel.com/docs/legal/privacy-policy\"";
|
|
}
|
|
];
|
|
bool is_default = 4;
|
|
string help_link = 5 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
example: "\"https://zitadel.com/docs/manuals/introduction\"";
|
|
}
|
|
];
|
|
string support_email = 6 [
|
|
(validate.rules).string = {ignore_empty: true, max_len: 320, email: true},
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
example: "\"support-email@test.com\"";
|
|
description: "help / support email address."
|
|
}
|
|
];
|
|
string docs_link = 7 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "Link to documentation to be shown in the console.";
|
|
example: "\"https://zitadel.com/docs\"";
|
|
}
|
|
];
|
|
string custom_link = 8 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "Link to an external resource that will be available to users in the console.";
|
|
example: "\"https://external.link\"";
|
|
}
|
|
];
|
|
string custom_link_text = 9 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "The button text that would be shown in console pointing to custom link.";
|
|
example: "\"External\"";
|
|
}
|
|
];
|
|
|
|
}
|
|
|
|
message NotificationPolicy {
|
|
zitadel.v1.ObjectDetails details = 1;
|
|
bool is_default = 2;
|
|
bool password_change = 3 [
|
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
description: "If set to true the users will get a notification whenever their password has been changed.";
|
|
}
|
|
];
|
|
}
|