diff --git a/okta/policy.go b/okta/policy.go index cffd52597..c543c03ee 100644 --- a/okta/policy.go +++ b/okta/policy.go @@ -81,6 +81,13 @@ var ( Default: statusActive, ValidateDiagFunc: elemInSlice([]string{statusActive, statusInactive}), } + + isOieSchema = &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Is the policy using Okta Identity Engine (OIE) with authenticators instead of factors?", + } ) func findPolicy(ctx context.Context, m interface{}, name, policyType string) (*okta.Policy, error) { @@ -137,6 +144,20 @@ func buildPolicySchema(target map[string]*schema.Schema) map[string]*schema.Sche return buildSchema(basePolicySchema, target) } +func buildDefaultMfaPolicySchema(target map[string]*schema.Schema) map[string]*schema.Schema { + schema := buildDefaultPolicySchema(target) + schema["is_oie"] = isOieSchema + + return schema +} + +func buildMfaPolicySchema(target map[string]*schema.Schema) map[string]*schema.Schema { + schema := buildPolicySchema(target) + schema["is_oie"] = isOieSchema + + return schema +} + func createPolicy(ctx context.Context, d *schema.ResourceData, m interface{}, template sdk.Policy) error { logger(m).Info("creating policy", "name", template.Name, "type", template.Type) if err := ensureNotDefaultPolicy(d); err != nil { diff --git a/okta/resource_okta_authenticator.go b/okta/resource_okta_authenticator.go index 60c3c8451..9412b9ac1 100644 --- a/okta/resource_okta_authenticator.go +++ b/okta/resource_okta_authenticator.go @@ -21,14 +21,11 @@ func resourceAuthenticator() *schema.Resource { }, Schema: map[string]*schema.Schema{ "key": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - Description: "A human-readable string that identifies the Authenticator", - ValidateDiagFunc: elemInSlice([]string{ - "okta_email", "google_otp", "okta_verify", "onprem_mfa", "okta_password", - "phone_number", "rsa_token", "security_question", "duo", - }), + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "A human-readable string that identifies the Authenticator", + ValidateDiagFunc: elemInSlice(sdk.AuthenticatorProviders), }, "name": { Type: schema.TypeString, diff --git a/okta/resource_okta_factor.go b/okta/resource_okta_factor.go index fb7f7951f..18be71784 100644 --- a/okta/resource_okta_factor.go +++ b/okta/resource_okta_factor.go @@ -25,27 +25,11 @@ func resourceFactor() *schema.Resource { }, Schema: map[string]*schema.Schema{ "provider_id": { - Type: schema.TypeString, - Required: true, - ValidateDiagFunc: elemInSlice([]string{ - sdk.DuoFactor, - sdk.FidoU2fFactor, - sdk.FidoWebauthnFactor, - sdk.GoogleOtpFactor, - sdk.OktaCallFactor, - sdk.OktaOtpFactor, - sdk.OktaPasswordFactor, - sdk.OktaPushFactor, - sdk.OktaQuestionFactor, - sdk.OktaSmsFactor, - sdk.OktaEmailFactor, - sdk.RsaTokenFactor, - sdk.SymantecVipFactor, - sdk.YubikeyTokenFactor, - sdk.HotpFactor, - }), - Description: "Factor provider ID", - ForceNew: true, + Type: schema.TypeString, + Required: true, + ValidateDiagFunc: elemInSlice(sdk.FactorProviders), + Description: "Factor provider ID", + ForceNew: true, }, "active": { Type: schema.TypeBool, diff --git a/okta/resource_okta_policy_mfa.go b/okta/resource_okta_policy_mfa.go index 1ab6dfd1f..b7f6b6679 100644 --- a/okta/resource_okta_policy_mfa.go +++ b/okta/resource_okta_policy_mfa.go @@ -20,7 +20,7 @@ func resourcePolicyMfa() *schema.Resource { Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, - Schema: buildPolicySchema(buildFactorProviders()), + Schema: buildMfaPolicySchema(buildFactorSchemaProviders()), } } @@ -41,21 +41,9 @@ func resourcePolicyMfaRead(ctx context.Context, d *schema.ResourceData, m interf if policy == nil { return nil } - syncFactor(d, sdk.DuoFactor, policy.Settings.Factors.Duo) - syncFactor(d, sdk.FidoU2fFactor, policy.Settings.Factors.FidoU2f) - syncFactor(d, sdk.FidoWebauthnFactor, policy.Settings.Factors.FidoWebauthn) - syncFactor(d, sdk.GoogleOtpFactor, policy.Settings.Factors.GoogleOtp) - syncFactor(d, sdk.OktaCallFactor, policy.Settings.Factors.OktaCall) - syncFactor(d, sdk.OktaOtpFactor, policy.Settings.Factors.OktaOtp) - syncFactor(d, sdk.OktaPasswordFactor, policy.Settings.Factors.OktaPassword) - syncFactor(d, sdk.OktaPushFactor, policy.Settings.Factors.OktaPush) - syncFactor(d, sdk.OktaQuestionFactor, policy.Settings.Factors.OktaQuestion) - syncFactor(d, sdk.OktaSmsFactor, policy.Settings.Factors.OktaSms) - syncFactor(d, sdk.OktaEmailFactor, policy.Settings.Factors.OktaEmail) - syncFactor(d, sdk.RsaTokenFactor, policy.Settings.Factors.RsaToken) - syncFactor(d, sdk.SymantecVipFactor, policy.Settings.Factors.SymantecVip) - syncFactor(d, sdk.YubikeyTokenFactor, policy.Settings.Factors.YubikeyToken) - syncFactor(d, sdk.HotpFactor, policy.Settings.Factors.Hotp) + + syncSettings(d, policy.Settings) + err = syncPolicyFromUpstream(d, policy) if err != nil { return diag.Errorf("failed to sync policy: %v", err) @@ -80,23 +68,6 @@ func resourcePolicyMfaDelete(ctx context.Context, d *schema.ResourceData, m inte return nil } -func buildFactorProvider(d *schema.ResourceData, key string) *sdk.PolicyFactor { - rawFactor := d.Get(key).(map[string]interface{}) - consent := rawFactor["consent_type"] - enroll := rawFactor["enroll"] - if consent == nil && enroll == nil { - return nil - } - f := &sdk.PolicyFactor{} - if consent != nil { - f.Consent = &sdk.Consent{Type: consent.(string)} - } - if enroll != nil { - f.Enroll = &sdk.Enroll{Self: enroll.(string)} - } - return f -} - // create or update a MFA policy func buildMFAPolicy(d *schema.ResourceData) sdk.Policy { policy := sdk.MfaPolicy() @@ -106,12 +77,47 @@ func buildMFAPolicy(d *schema.ResourceData) sdk.Policy { if priority, ok := d.GetOk("priority"); ok { policy.Priority = int64(priority.(int)) } - policy.Settings = &sdk.PolicySettings{ + policy.Settings = buildSettings(d) + policy.Conditions = &okta.PolicyRuleConditions{ + People: getGroups(d), + } + return policy +} + +// Opposite of syncSettings(): Build the corresponding sdk.PolicySettings based on the schema.ResourceData +func buildSettings(d *schema.ResourceData) *sdk.PolicySettings { + if d.Get("is_oie") == true { + authenticators := []*sdk.PolicyAuthenticator{} + + for _, key := range remove(sdk.AuthenticatorProviders, sdk.OktaPasswordFactor) { + rawFactor := d.Get(key).(map[string]interface{}) + enroll := rawFactor["enroll"] + if enroll == nil { + continue + } + + authenticator := &sdk.PolicyAuthenticator{} + authenticator.Key = key + if enroll != nil { + authenticator.Enroll = &sdk.Enroll{Self: enroll.(string)} + } + authenticators = append(authenticators, authenticator) + } + + return &sdk.PolicySettings{ + Type: "AUTHENTICATORS", + Authenticators: authenticators, + } + } + + return &sdk.PolicySettings{ + Type: "FACTORS", Factors: &sdk.PolicyFactorsSettings{ Duo: buildFactorProvider(d, sdk.DuoFactor), FidoU2f: buildFactorProvider(d, sdk.FidoU2fFactor), FidoWebauthn: buildFactorProvider(d, sdk.FidoWebauthnFactor), GoogleOtp: buildFactorProvider(d, sdk.GoogleOtpFactor), + Hotp: buildFactorProvider(d, sdk.HotpFactor), OktaCall: buildFactorProvider(d, sdk.OktaCallFactor), OktaOtp: buildFactorProvider(d, sdk.OktaOtpFactor), OktaPassword: buildFactorProvider(d, sdk.OktaPasswordFactor), @@ -122,51 +128,84 @@ func buildMFAPolicy(d *schema.ResourceData) sdk.Policy { RsaToken: buildFactorProvider(d, sdk.RsaTokenFactor), SymantecVip: buildFactorProvider(d, sdk.SymantecVipFactor), YubikeyToken: buildFactorProvider(d, sdk.YubikeyTokenFactor), - Hotp: buildFactorProvider(d, sdk.HotpFactor), }, } - policy.Conditions = &okta.PolicyRuleConditions{ - People: getGroups(d), +} + +func buildFactorProvider(d *schema.ResourceData, key string) *sdk.PolicyFactor { + rawFactor := d.Get(key).(map[string]interface{}) + consent := rawFactor["consent_type"] + enroll := rawFactor["enroll"] + if consent == nil && enroll == nil { + return nil + } + f := &sdk.PolicyFactor{} + if consent != nil { + f.Consent = &sdk.Consent{Type: consent.(string)} + } + if enroll != nil { + f.Enroll = &sdk.Enroll{Self: enroll.(string)} + } + return f +} + +// Syncs either classic factors or OIE authenticators into the resource data. +func syncSettings(d *schema.ResourceData, settings *sdk.PolicySettings) { + _ = d.Set("is_oie", settings.Type == "AUTHENTICATORS") + + if settings.Type == "AUTHENTICATORS" { + for _, key := range remove(sdk.AuthenticatorProviders, sdk.OktaPasswordFactor) { + syncAuthenticator(d, key, settings.Authenticators) + } + } else { + syncFactor(d, sdk.DuoFactor, settings.Factors.Duo) + syncFactor(d, sdk.HotpFactor, settings.Factors.YubikeyToken) + syncFactor(d, sdk.FidoU2fFactor, settings.Factors.FidoU2f) + syncFactor(d, sdk.FidoWebauthnFactor, settings.Factors.FidoWebauthn) + syncFactor(d, sdk.GoogleOtpFactor, settings.Factors.GoogleOtp) + syncFactor(d, sdk.OktaCallFactor, settings.Factors.OktaCall) + syncFactor(d, sdk.OktaOtpFactor, settings.Factors.OktaOtp) + syncFactor(d, sdk.OktaPasswordFactor, settings.Factors.OktaPassword) + syncFactor(d, sdk.OktaPushFactor, settings.Factors.OktaPush) + syncFactor(d, sdk.OktaQuestionFactor, settings.Factors.OktaQuestion) + syncFactor(d, sdk.OktaSmsFactor, settings.Factors.OktaSms) + syncFactor(d, sdk.OktaEmailFactor, settings.Factors.OktaEmail) + syncFactor(d, sdk.RsaTokenFactor, settings.Factors.RsaToken) + syncFactor(d, sdk.SymantecVipFactor, settings.Factors.SymantecVip) + syncFactor(d, sdk.YubikeyTokenFactor, settings.Factors.YubikeyToken) } - return policy } func syncFactor(d *schema.ResourceData, k string, f *sdk.PolicyFactor) { - if f == nil { + if f != nil { _ = d.Set(k, map[string]interface{}{ - "consent_type": "NONE", - "enroll": "NOT_ALLOWED", + "consent_type": f.Consent.Type, + "enroll": f.Enroll.Self, }) - return } - _ = d.Set(k, map[string]interface{}{ - "consent_type": f.Consent.Type, - "enroll": f.Enroll.Self, - }) } -var factorProviders = []string{ - sdk.DuoFactor, - sdk.FidoU2fFactor, - sdk.FidoWebauthnFactor, - sdk.GoogleOtpFactor, - sdk.OktaCallFactor, - sdk.OktaOtpFactor, - sdk.OktaPasswordFactor, - sdk.OktaPushFactor, - sdk.OktaQuestionFactor, - sdk.OktaSmsFactor, - sdk.OktaEmailFactor, - sdk.RsaTokenFactor, - sdk.SymantecVipFactor, - sdk.YubikeyTokenFactor, - sdk.HotpFactor, +func syncAuthenticator(d *schema.ResourceData, k string, authenticators []*sdk.PolicyAuthenticator) { + for _, authenticator := range authenticators { + if authenticator.Key == k { + // Skip OktaPassword as this should never be returned for MFA policies using authenticator. + // Enrollment policy changes for OIE for password + // https://help.okta.com/okta_help.htm?type=oie&id=ext-about-mfa-enrol-policies + if k != sdk.OktaPasswordFactor { + _ = d.Set(k, map[string]interface{}{ + "enroll": authenticator.Enroll.Self, + }) + } + return + } + } } // List of factor provider above, they all follow the same schema -func buildFactorProviders() map[string]*schema.Schema { +func buildFactorSchemaProviders() map[string]*schema.Schema { res := make(map[string]*schema.Schema) - for _, key := range factorProviders { + // Note: It's okay to append and have duplicates as we're setting back into a map here + for _, key := range append(sdk.FactorProviders, sdk.AuthenticatorProviders...) { res[key] = &schema.Schema{ Optional: true, Type: schema.TypeMap, diff --git a/okta/resource_okta_policy_mfa_default.go b/okta/resource_okta_policy_mfa_default.go index d4130c289..173886275 100644 --- a/okta/resource_okta_policy_mfa_default.go +++ b/okta/resource_okta_policy_mfa_default.go @@ -24,7 +24,7 @@ func resourcePolicyMfaDefault() *schema.Resource { return []*schema.ResourceData{d}, nil }, }, - Schema: buildDefaultPolicySchema(buildFactorProviders()), + Schema: buildDefaultMfaPolicySchema(buildFactorSchemaProviders()), } } @@ -52,21 +52,9 @@ func resourcePolicyMfaDefaultRead(ctx context.Context, d *schema.ResourceData, m if policy == nil { return nil } - syncFactor(d, sdk.DuoFactor, policy.Settings.Factors.Duo) - syncFactor(d, sdk.FidoU2fFactor, policy.Settings.Factors.FidoU2f) - syncFactor(d, sdk.FidoWebauthnFactor, policy.Settings.Factors.FidoWebauthn) - syncFactor(d, sdk.GoogleOtpFactor, policy.Settings.Factors.GoogleOtp) - syncFactor(d, sdk.OktaCallFactor, policy.Settings.Factors.OktaCall) - syncFactor(d, sdk.OktaOtpFactor, policy.Settings.Factors.OktaOtp) - syncFactor(d, sdk.OktaPasswordFactor, policy.Settings.Factors.OktaPassword) - syncFactor(d, sdk.OktaPushFactor, policy.Settings.Factors.OktaPush) - syncFactor(d, sdk.OktaQuestionFactor, policy.Settings.Factors.OktaQuestion) - syncFactor(d, sdk.OktaSmsFactor, policy.Settings.Factors.OktaSms) - syncFactor(d, sdk.OktaEmailFactor, policy.Settings.Factors.OktaEmail) - syncFactor(d, sdk.RsaTokenFactor, policy.Settings.Factors.RsaToken) - syncFactor(d, sdk.SymantecVipFactor, policy.Settings.Factors.SymantecVip) - syncFactor(d, sdk.YubikeyTokenFactor, policy.Settings.Factors.YubikeyToken) - syncFactor(d, sdk.HotpFactor, policy.Settings.Factors.YubikeyToken) + + syncSettings(d, policy.Settings) + return nil } @@ -81,25 +69,7 @@ func buildDefaultMFAPolicy(d *schema.ResourceData) sdk.Policy { policy.Status = d.Get("status").(string) policy.Description = d.Get("description").(string) policy.Priority = int64(d.Get("priority").(int)) - policy.Settings = &sdk.PolicySettings{ - Factors: &sdk.PolicyFactorsSettings{ - Duo: buildFactorProvider(d, sdk.DuoFactor), - FidoU2f: buildFactorProvider(d, sdk.FidoU2fFactor), - FidoWebauthn: buildFactorProvider(d, sdk.FidoWebauthnFactor), - GoogleOtp: buildFactorProvider(d, sdk.GoogleOtpFactor), - OktaCall: buildFactorProvider(d, sdk.OktaCallFactor), - OktaOtp: buildFactorProvider(d, sdk.OktaOtpFactor), - OktaPassword: buildFactorProvider(d, sdk.OktaPasswordFactor), - OktaPush: buildFactorProvider(d, sdk.OktaPushFactor), - OktaQuestion: buildFactorProvider(d, sdk.OktaQuestionFactor), - OktaSms: buildFactorProvider(d, sdk.OktaSmsFactor), - OktaEmail: buildFactorProvider(d, sdk.OktaEmailFactor), - RsaToken: buildFactorProvider(d, sdk.RsaTokenFactor), - SymantecVip: buildFactorProvider(d, sdk.SymantecVipFactor), - YubikeyToken: buildFactorProvider(d, sdk.YubikeyTokenFactor), - Hotp: buildFactorProvider(d, sdk.HotpFactor), - }, - } + policy.Settings = buildSettings(d) policy.Conditions = &okta.PolicyRuleConditions{ People: &okta.PolicyPeopleCondition{ Groups: &okta.GroupCondition{ diff --git a/sdk/org_factor.go b/sdk/org_factor.go index 08b36185b..48fb23636 100644 --- a/sdk/org_factor.go +++ b/sdk/org_factor.go @@ -17,23 +17,64 @@ type OrgFactor struct { // Current available org factors for MFA const ( - DuoFactor = "duo" - FidoU2fFactor = "fido_u2f" - FidoWebauthnFactor = "fido_webauthn" - GoogleOtpFactor = "google_otp" - OktaCallFactor = "okta_call" - OktaOtpFactor = "okta_otp" - OktaPasswordFactor = "okta_password" - OktaPushFactor = "okta_push" - OktaQuestionFactor = "okta_question" - OktaSmsFactor = "okta_sms" - OktaEmailFactor = "okta_email" - RsaTokenFactor = "rsa_token" - SymantecVipFactor = "symantec_vip" - YubikeyTokenFactor = "yubikey_token" - HotpFactor = "hotp" + DuoFactor = "duo" + ExternalIdpFactor = "external_idp" + FidoU2fFactor = "fido_u2f" + FidoWebauthnFactor = "fido_webauthn" + GoogleOtpFactor = "google_otp" + HotpFactor = "hotp" + OktaCallFactor = "okta_call" + OktaEmailFactor = "okta_email" + OktaOtpFactor = "okta_otp" + OktaPasswordFactor = "okta_password" // Not configurable for OIE + OktaPushFactor = "okta_push" + OktaQuestionFactor = "okta_question" + OktaSmsFactor = "okta_sms" + OktaVerifyFactor = "okta_verify" // OIE only (Combo of OktaOtp, OktaPush) + OnPremMfaFactor = "onprem_mfa" // OIE only + PhoneNumberFactor = "phone_number" // OIE only (Combo of OktaSms + OktaCall) + RsaTokenFactor = "rsa_token" + SecurityQuestionFactor = "security_question" // OIE only (Evolution/rename from okta_question) + SymantecVipFactor = "symantec_vip" + WebauthnFactor = "webauthn" // OIE only (Evolution/rename from fido_webauthn) + YubikeyTokenFactor = "yubikey_token" ) +// List of factors that are applicable to Okta Classic Engine +var FactorProviders = []string{ + DuoFactor, + FidoU2fFactor, + FidoWebauthnFactor, + HotpFactor, + GoogleOtpFactor, + OktaCallFactor, + OktaEmailFactor, + OktaOtpFactor, + OktaPasswordFactor, + OktaPushFactor, + OktaQuestionFactor, + OktaSmsFactor, + RsaTokenFactor, + SymantecVipFactor, + YubikeyTokenFactor, +} + +// List of factors that are applicable to Okta Identity Engine (OIE) +var AuthenticatorProviders = []string{ + DuoFactor, + ExternalIdpFactor, + GoogleOtpFactor, + OktaEmailFactor, + OktaPasswordFactor, // Note: Not configurable in OIE policies (Handle downstream as necessary) + OktaVerifyFactor, + OnPremMfaFactor, + PhoneNumberFactor, + RsaTokenFactor, + SecurityQuestionFactor, + WebauthnFactor, + YubikeyTokenFactor, +} + // GetOrgFactor gets a factor by ID. func (m *APISupplement) GetOrgFactor(ctx context.Context, id string) (*OrgFactor, *okta.Response, error) { url := fmt.Sprintf("/api/v1/org/factors/%s", id) diff --git a/sdk/policy.go b/sdk/policy.go index b05525353..50aa3c61c 100644 --- a/sdk/policy.go +++ b/sdk/policy.go @@ -58,10 +58,12 @@ type Policy struct { } type PolicySettings struct { - Factors *PolicyFactorsSettings `json:"factors,omitempty"` - Delegation *okta.PasswordPolicyDelegationSettings `json:"delegation,omitempty"` - Password *PasswordPolicyPasswordSettings `json:"password,omitempty"` - Recovery *PasswordPolicyRecoverySettings `json:"recovery,omitempty"` + Authenticators []*PolicyAuthenticator `json:"authenticators,omitempty"` + Delegation *okta.PasswordPolicyDelegationSettings `json:"delegation,omitempty"` + Factors *PolicyFactorsSettings `json:"factors,omitempty"` + Password *PasswordPolicyPasswordSettings `json:"password,omitempty"` + Recovery *PasswordPolicyRecoverySettings `json:"recovery,omitempty"` + Type string `json:"type,omitempty"` } type PasswordPolicyPasswordSettings struct { @@ -136,6 +138,7 @@ type PolicyFactorsSettings struct { Duo *PolicyFactor `json:"duo,omitempty"` FidoU2f *PolicyFactor `json:"fido_u2f,omitempty"` FidoWebauthn *PolicyFactor `json:"fido_webauthn,omitempty"` + Hotp *PolicyFactor `json:"hotp,omitempty"` GoogleOtp *PolicyFactor `json:"google_otp,omitempty"` OktaCall *PolicyFactor `json:"okta_call,omitempty"` OktaOtp *PolicyFactor `json:"okta_otp,omitempty"` @@ -147,7 +150,6 @@ type PolicyFactorsSettings struct { RsaToken *PolicyFactor `json:"rsa_token,omitempty"` SymantecVip *PolicyFactor `json:"symantec_vip,omitempty"` YubikeyToken *PolicyFactor `json:"yubikey_token,omitempty"` - Hotp *PolicyFactor `json:"hotp,omitempty"` } type PolicyFactor struct { @@ -155,6 +157,11 @@ type PolicyFactor struct { Enroll *Enroll `json:"enroll,omitempty"` } +type PolicyAuthenticator struct { + Key string `json:"key,omitempty"` + Enroll *Enroll `json:"enroll,omitempty"` +} + type Consent struct { Terms *Terms `json:"terms,omitempty"` Type string `json:"type,omitempty"` diff --git a/website/docs/r/authenticator.html.markdown b/website/docs/r/authenticator.html.markdown index d96d66630..e621f46cc 100644 --- a/website/docs/r/authenticator.html.markdown +++ b/website/docs/r/authenticator.html.markdown @@ -12,6 +12,8 @@ description: |- This resource allows you to configure different authenticators. +-> **NOTE:** An authenticator can only be deleted if it's not in use by any policy. + ## Example Usage ```hcl @@ -30,7 +32,7 @@ resource "okta_authenticator" "test" { The following arguments are supported: -- `key` (Required) A human-readable string that identifies the authenticator. +- `key` (Required) A human-readable string that identifies the authenticator. Possible values inclue: `"duo"`, `"external_idp"`, `"google_otp"`, `"okta_email"`, `"okta_password"`, `"okta_verify"`, `"onprem_mfa"`, `"phone_number"`, `"rsa_token"`, `"security_question"`, `"webauthn"`, and `"yubikey_token"`. - `name` - (Required) Name of the authenticator. diff --git a/website/docs/r/policy_mfa.html.markdown b/website/docs/r/policy_mfa.html.markdown index b30b70579..cb094a0ad 100644 --- a/website/docs/r/policy_mfa.html.markdown +++ b/website/docs/r/policy_mfa.html.markdown @@ -15,10 +15,11 @@ This resource allows you to create and configure an MFA Policy. ## Example Usage ```hcl -resource "okta_policy_mfa" "example" { - name = "example" +resource "okta_policy_mfa" "classic_example" { + name = "MFA Policy Classic" status = "ACTIVE" - description = "Example" + description = "Example MFA policy using Okta Classic engine with factors." + is_oie = false okta_otp = { enroll = "REQUIRED" @@ -26,6 +27,20 @@ resource "okta_policy_mfa" "example" { groups_included = ["${data.okta_group.everyone.id}"] } + +resource "okta_policy_mfa" "oie_example" { + name = "MFA Policy OIE" + status = "ACTIVE" + description = "Example MFA policy that uses Okta Identity Engine (OIE) with authenticators" + is_oie = true + + # The following authenticator can only be used when `is_oie` is set to true + okta_verify = { + enroll = "REQUIRED" + } + + groups_included = ["${data.okta_group.everyone.id}"] +} ``` ## Argument Reference @@ -40,37 +55,52 @@ The following arguments are supported: - `status` - (Optional) Policy Status: `"ACTIVE"` or `"INACTIVE"`. +- `is_oie` - (Optional) Boolean that specifies whether to use the newer Okta Identity Engine (OIE) with policy authenticators instead of the classic engine with Factors. This value determines which of the following policy factor settings can be configured. (Default = `false`) + ~> **WARNING:** Tenant must have the Okta Identity Engine enabled in order to use this feature. + - `groups_included` - (Optional) List of Group IDs to Include. -- `duo` - (Optional) DUO [MFA policy settings](#mfa-settings). +- `duo` - (Optional) DUO [MFA policy settings](#mfa-settings) (✓ Classic, ✓ OIE). + +- `external_idp` - (Optional) External IDP [MFA policy settings](#mfa-settings) (✓ OIE). + +- `fido_u2f` - (Optional) Fido U2F [MFA policy settings](#mfa-settings) (✓ Classic). + +- `fido_webauthn` - (Optional) Fido Web Authn [MFA policy settings](#mfa-settings) (✓ Classic). + +- `google_otp` - (Optional) Google OTP [MFA policy settings](#mfa-settings) (✓ Classic, ✓ OIE). + +- `hotp` - (Optional) HMAC-based One-Time Password [MFA policy settings](#mfa-settings) (✓ Classic). + +- `okta_call` - (Optional) Okta Call [MFA policy settings](#mfa-settings) (✓ Classic). + +- `okta_email` - (Optional) Okta Email [MFA policy settings](#mfa-settings) (✓ Classic, ✓ OIE). + +- `okta_otp` - (Optional) Okta OTP (via the Okta Verify app) [MFA policy settings](#mfa-settings) (✓ Classic). -- `fido_u2f` - (Optional) Fido U2F [MFA policy settings](#mfa-settings). +- `okta_password` - (Optional) Okta Password [MFA policy settings](#mfa-settings) (✓ Classic, ✓ OIE). -- `fido_webauthn` - (Optional) Fido Web Authn [MFA policy settings](#mfa-settings). +- `okta_push` - (Optional) Okta Push [MFA policy settings](#mfa-settings) (✓ Classic). -- `google_otp` - (Optional) Google OTP [MFA policy settings](#mfa-settings). +- `okta_question` - (Optional) Okta Question [MFA policy settings](#mfa-settings) (✓ Classic). -- `okta_call` - (Optional) Okta Call [MFA policy settings](#mfa-settings). +- `okta_sms` - (Optional) Okta SMS [MFA policy settings](#mfa-settings) (✓ Classic). -- `okta_otp` - (Optional) Okta OTP (via the Okta Verify app) [MFA policy settings](#mfa-settings). +- `okta_verify` - (Optional) Okta Verify [MFA policy settings](#mfa-settings) (✓ OIE). -- `okta_password` - (Optional) Okta Password [MFA policy settings](#mfa-settings). +- `onprem_mfa` - (Optional) On-Prem MFA [MFA policy settings](#mfa-settings) (✓ OIE). -- `okta_push` - (Optional) Okta Push [MFA policy settings](#mfa-settings). +- `phone_number` - (Optional) Phone Number [MFA policy settings](#mfa-settings) (✓ OIE). -- `okta_question` - (Optional) Okta Question [MFA policy settings](#mfa-settings). +- `rsa_token` - (Optional) RSA Token [MFA policy settings](#mfa-settings) (✓ Classic, ✓ OIE). -- `okta_sms` - (Optional) Okta SMS [MFA policy settings](#mfa-settings). - -- `okta_email` - (Optional) Okta Email [MFA policy settings](#mfa-settings). +- `security_question` - (Optional) Security Question [MFA policy settings](#mfa-settings) (✓ OIE). -- `rsa_token` - (Optional) RSA Token [MFA policy settings](#mfa-settings). +- `symantec_vip` - (Optional) Symantec VIP [MFA policy settings](#mfa-settings) (✓ Classic). -- `symantec_vip` - (Optional) Symantec VIP [MFA policy settings](#mfa-settings). +- `webauthn` - (Optional) FIDO2 (WebAuthn) [MFA policy settings](#mfa-settings) (✓ OIE). -- `yubikey_token` - (Optional) Yubikey Token [MFA policy settings](#mfa-settings). - -- `hotp` - (Optional) HMAC-based One-Time Password [MFA policy settings](#mfa-settings). +- `yubikey_token` - (Optional) Yubikey Token [MFA policy settings](#mfa-settings) (✓ Classic, ✓ OIE). ### MFA Settings @@ -79,6 +109,7 @@ All MFA settings above have the following structure. - `enroll` - (Optional) Requirements for user initiated enrollment. Can be `"NOT_ALLOWED"`, `"OPTIONAL"`, or `"REQUIRED"`. By default, it is `"OPTIONAL"`. - `consent_type` - (Optional) User consent type required before enrolling in the factor: `"NONE"` or `"TERMS_OF_SERVICE"`. By default, it is `"NONE"`. + ~> **NOTE:** Only applicable when using Classic mode with Factors (not OIE). When using OIE, `consent_type` is not used ## Attributes Reference diff --git a/website/docs/r/policy_mfa_default.html.markdown b/website/docs/r/policy_mfa_default.html.markdown index d41212294..46028856a 100644 --- a/website/docs/r/policy_mfa_default.html.markdown +++ b/website/docs/r/policy_mfa_default.html.markdown @@ -10,49 +10,79 @@ description: |- Configures default MFA Policy. -This resource allows you to configure default MFA Policy. +This resource allows you to configure default MFA Policy. ## Example Usage ```hcl -resource "okta_policy_mfa_default" "default" { +resource "okta_policy_mfa_default" "classic_example" { + is_oie = false + okta_otp = { + enroll = "REQUIRED" + } +} + +resource "okta_policy_mfa_default" "oie_example" { + is_oie = true + + # The following authenticator can only be used when `is_oie` is set to true + okta_verify = { + enroll = "REQUIRED" + } } ``` +-> If the `okta_policy_mfa_default` is used in conjunction with `okta_policy_mfa` resources, ensure to use a `depends_on` attribute for the default policy to ensure that all other policies are created/updated first such that the `priority` field can be appropriately computed on the first plan/apply. + ## Argument Reference The following arguments are supported: -- `duo` - (Optional) DUO [MFA policy settings](#mfa-settings). +- `is_oie` - (Optional) Boolean that specifies whether to use the newer Okta Identity Engine (OIE) with policy authenticators instead of the classic engine with Factors. This value determines which of the following policy factor settings can be configured. (Default = `false`) + ~> **WARNING:** Tenant must have the Okta Identity Engine enabled in order to use this feature. + +- `duo` - (Optional) DUO [MFA policy settings](#mfa-settings) (✓ Classic, ✓ OIE). + +- `external_idp` - (Optional) External IDP [MFA policy settings](#mfa-settings) (✓ OIE). + +- `fido_u2f` - (Optional) Fido U2F [MFA policy settings](#mfa-settings) (✓ Classic). + +- `fido_webauthn` - (Optional) Fido Web Authn [MFA policy settings](#mfa-settings) (✓ Classic). + +- `google_otp` - (Optional) Google OTP [MFA policy settings](#mfa-settings) (✓ Classic, ✓ OIE). + +- `hotp` - (Optional) HMAC-based One-Time Password [MFA policy settings](#mfa-settings) (✓ Classic). + +- `okta_call` - (Optional) Okta Call [MFA policy settings](#mfa-settings) (✓ Classic). + +- `okta_email` - (Optional) Okta Email [MFA policy settings](#mfa-settings) (✓ Classic, ✓ OIE). + +- `okta_otp` - (Optional) Okta OTP (via the Okta Verify app) [MFA policy settings](#mfa-settings) (✓ Classic). -- `fido_u2f` - (Optional) Fido U2F [MFA policy settings](#mfa-settings). +- `okta_password` - (Optional) Okta Password [MFA policy settings](#mfa-settings) (✓ Classic, ✓ OIE). -- `fido_webauthn` - (Optional) Fido Web Authn [MFA policy settings](#mfa-settings). +- `okta_push` - (Optional) Okta Push [MFA policy settings](#mfa-settings) (✓ Classic). -- `google_otp` - (Optional) Google OTP [MFA policy settings](#mfa-settings). +- `okta_question` - (Optional) Okta Question [MFA policy settings](#mfa-settings) (✓ Classic). -- `okta_call` - (Optional) Okta Call [MFA policy settings](#mfa-settings). +- `okta_sms` - (Optional) Okta SMS [MFA policy settings](#mfa-settings) (✓ Classic). -- `okta_otp` - (Optional) Okta OTP [MFA policy settings](#mfa-settings). +- `okta_verify` - (Optional) Okta Verify [MFA policy settings](#mfa-settings) (✓ OIE). -- `okta_password` - (Optional) Okta Password [MFA policy settings](#mfa-settings). +- `onprem_mfa` - (Optional) On-Prem MFA [MFA policy settings](#mfa-settings) (✓ OIE). -- `okta_push` - (Optional) Okta Push [MFA policy settings](#mfa-settings). +- `phone_number` - (Optional) Phone Number [MFA policy settings](#mfa-settings) (✓ OIE). -- `okta_question` - (Optional) Okta Question [MFA policy settings](#mfa-settings). +- `rsa_token` - (Optional) RSA Token [MFA policy settings](#mfa-settings) (✓ Classic, ✓ OIE). -- `okta_sms` - (Optional) Okta SMS [MFA policy settings](#mfa-settings). - -- `okta_email` - (Optional) Okta Email [MFA policy settings](#mfa-settings). +- `security_question` - (Optional) Security Question [MFA policy settings](#mfa-settings) (✓ OIE). -- `rsa_token` - (Optional) RSA Token [MFA policy settings](#mfa-settings). +- `symantec_vip` - (Optional) Symantec VIP [MFA policy settings](#mfa-settings) (✓ Classic). -- `symantec_vip` - (Optional) Symantec VIP [MFA policy settings](#mfa-settings). +- `webauthn` - (Optional) FIDO2 (WebAuthn) [MFA policy settings](#mfa-settings) (✓ OIE). -- `yubikey_token` - (Optional) Yubikey Token [MFA policy settings](#mfa-settings). - -- `hotp` - (Optional) HMAC-based One-Time Password [MFA policy settings](#mfa-settings). +- `yubikey_token` - (Optional) Yubikey Token [MFA policy settings](#mfa-settings) (✓ Classic, ✓ OIE). ### MFA Settings @@ -61,6 +91,7 @@ All MFA settings above have the following structure. - `enroll` - (Optional) Requirements for user initiated enrollment. Can be `"NOT_ALLOWED"`, `"OPTIONAL"`, or `"REQUIRED"`. By default, it is `"OPTIONAL"`. - `consent_type` - (Optional) User consent type required before enrolling in the factor: `"NONE"` or `"TERMS_OF_SERVICE"`. By default, it is `"NONE"`. + ~> **NOTE:** Only applicable when using Classic mode with Factors (not OIE). When using OIE, `consent_type` is not used ## Attributes Reference diff --git a/website/docs/r/policy_password_default.html.markdown b/website/docs/r/policy_password_default.html.markdown index e961a00e5..bf014db92 100644 --- a/website/docs/r/policy_password_default.html.markdown +++ b/website/docs/r/policy_password_default.html.markdown @@ -1,8 +1,8 @@ --- -layout: 'okta' -page_title: 'Okta: okta_policy_password_default' -sidebar_current: 'docs-okta-resource-policy-password-default' -description: |- +layout: 'okta' +page_title: 'Okta: okta_policy_password_default' +sidebar_current: 'docs-okta-resource-policy-password-default' +description: |- Configures default password policy. ---