Repository: cloudflare/cloudflare-go
Pull request #1373 (2023-08-25 03:07:02)

AUTH-5494 added custom_non_identity_deny_url to access_applications

## Description

Added custom_non_identity_deny_url field to access_applications
## Has your change been tested?

local unit tests

## Screenshots (if appropriate):

## Types of changes

What sort of change does your code introduce/modify?

- [ ] Bug fix (non-breaking change which fixes an issue)
- [ x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)

## Checklist:

- [x ] My code follows the code style of this project.
- [ x] My change requires a change to the documentation.
- [ x] I have updated the documentation accordingly.
- [x ] I have added tests to cover my changes.
- [x ] All new and existing tests passed.
- [ ] This change is using publicly documented in [cloudflare/api-schemas](https://github.com/cloudflare/api-schemas) 
      and relies on stable APIs.

[1]: https://help.github.com/articles/closing-issues-using-keywords/


github-actions[bot]: changelog detected :white_check_mark:

Patch:
diff --git a/.changelog/1373.txt b/.changelog/1373.txt
new file mode 100644
index 000000000..9276016d9
--- /dev/null
+++ b/.changelog/1373.txt
@@ -0,0 +1,3 @@
+```release-note:enhancement
+access_application: added custom_non_identity_deny_url
+```
\ No newline at end of file
diff --git a/access_application.go b/access_application.go
index 4357fa0d1..898b3a637 100644
--- a/access_application.go
+++ b/access_application.go
@@ -26,32 +26,33 @@ const (
 
 // AccessApplication represents an Access application.
 type AccessApplication struct {
-	GatewayRules            []AccessApplicationGatewayRule `json:"gateway_rules,omitempty"`
-	AllowedIdps             []string                       `json:"allowed_idps,omitempty"`
-	CustomDenyMessage       string                         `json:"custom_deny_message,omitempty"`
-	LogoURL                 string                         `json:"logo_url,omitempty"`
-	AUD                     string                         `json:"aud,omitempty"`
-	Domain                  string                         `json:"domain"`
-	SelfHostedDomains       []string                       `json:"self_hosted_domains"`
-	Type                    AccessApplicationType          `json:"type,omitempty"`
-	SessionDuration         string                         `json:"session_duration,omitempty"`
-	SameSiteCookieAttribute string                         `json:"same_site_cookie_attribute,omitempty"`
-	CustomDenyURL           string                         `json:"custom_deny_url,omitempty"`
-	Name                    string                         `json:"name"`
-	ID                      string                         `json:"id,omitempty"`
-	PrivateAddress          string                         `json:"private_address"`
-	CorsHeaders             *AccessApplicationCorsHeaders  `json:"cors_headers,omitempty"`
-	CreatedAt               *time.Time                     `json:"created_at,omitempty"`
-	UpdatedAt               *time.Time                     `json:"updated_at,omitempty"`
-	SaasApplication         *SaasApplication               `json:"saas_app,omitempty"`
-	AutoRedirectToIdentity  *bool                          `json:"auto_redirect_to_identity,omitempty"`
-	SkipInterstitial        *bool                          `json:"skip_interstitial,omitempty"`
-	AppLauncherVisible      *bool                          `json:"app_launcher_visible,omitempty"`
-	EnableBindingCookie     *bool                          `json:"enable_binding_cookie,omitempty"`
-	HttpOnlyCookieAttribute *bool                          `json:"http_only_cookie_attribute,omitempty"`
-	ServiceAuth401Redirect  *bool                          `json:"service_auth_401_redirect,omitempty"`
-	PathCookieAttribute     *bool                          `json:"path_cookie_attribute,omitempty"`
-	CustomPages             []string                       `json:"custom_pages,omitempty"`
+	GatewayRules             []AccessApplicationGatewayRule `json:"gateway_rules,omitempty"`
+	AllowedIdps              []string                       `json:"allowed_idps,omitempty"`
+	CustomDenyMessage        string                         `json:"custom_deny_message,omitempty"`
+	LogoURL                  string                         `json:"logo_url,omitempty"`
+	AUD                      string                         `json:"aud,omitempty"`
+	Domain                   string                         `json:"domain"`
+	SelfHostedDomains        []string                       `json:"self_hosted_domains"`
+	Type                     AccessApplicationType          `json:"type,omitempty"`
+	SessionDuration          string                         `json:"session_duration,omitempty"`
+	SameSiteCookieAttribute  string                         `json:"same_site_cookie_attribute,omitempty"`
+	CustomDenyURL            string                         `json:"custom_deny_url,omitempty"`
+	CustomNonIdentityDenyURL string                         `json:"custom_non_identity_deny_url,omitempty"`
+	Name                     string                         `json:"name"`
+	ID                       string                         `json:"id,omitempty"`
+	PrivateAddress           string                         `json:"private_address"`
+	CorsHeaders              *AccessApplicationCorsHeaders  `json:"cors_headers,omitempty"`
+	CreatedAt                *time.Time                     `json:"created_at,omitempty"`
+	UpdatedAt                *time.Time                     `json:"updated_at,omitempty"`
+	SaasApplication          *SaasApplication               `json:"saas_app,omitempty"`
+	AutoRedirectToIdentity   *bool                          `json:"auto_redirect_to_identity,omitempty"`
+	SkipInterstitial         *bool                          `json:"skip_interstitial,omitempty"`
+	AppLauncherVisible       *bool                          `json:"app_launcher_visible,omitempty"`
+	EnableBindingCookie      *bool                          `json:"enable_binding_cookie,omitempty"`
+	HttpOnlyCookieAttribute  *bool                          `json:"http_only_cookie_attribute,omitempty"`
+	ServiceAuth401Redirect   *bool                          `json:"service_auth_401_redirect,omitempty"`
+	PathCookieAttribute      *bool                          `json:"path_cookie_attribute,omitempty"`
+	CustomPages              []string                       `json:"custom_pages,omitempty"`
 }
 
 type AccessApplicationGatewayRule struct {
@@ -119,56 +120,58 @@ type ListAccessApplicationsParams struct {
 }
 
 type CreateAccessApplicationParams struct {
-	AllowedIdps             []string                       `json:"allowed_idps,omitempty"`
-	AppLauncherVisible      *bool                          `json:"app_launcher_visible,omitempty"`
-	AUD                     string                         `json:"aud,omitempty"`
-	AutoRedirectToIdentity  *bool                          `json:"auto_redirect_to_identity,omitempty"`
-	CorsHeaders             *AccessApplicationCorsHeaders  `json:"cors_headers,omitempty"`
-	CustomDenyMessage       string                         `json:"custom_deny_message,omitempty"`
-	CustomDenyURL           string                         `json:"custom_deny_url,omitempty"`
-	Domain                  string                         `json:"domain"`
-	EnableBindingCookie     *bool                          `json:"enable_binding_cookie,omitempty"`
-	GatewayRules            []AccessApplicationGatewayRule `json:"gateway_rules,omitempty"`
-	HttpOnlyCookieAttribute *bool                          `json:"http_only_cookie_attribute,omitempty"`
-	LogoURL                 string                         `json:"logo_url,omitempty"`
-	Name                    string                         `json:"name"`
-	PathCookieAttribute     *bool                          `json:"path_cookie_attribute,omitempty"`
-	PrivateAddress          string                         `json:"private_address"`
-	SaasApplication         *SaasApplication               `json:"saas_app,omitempty"`
-	SameSiteCookieAttribute string                         `json:"same_site_cookie_attribute,omitempty"`
-	SelfHostedDomains       []string                       `json:"self_hosted_domains"`
-	ServiceAuth401Redirect  *bool                          `json:"service_auth_401_redirect,omitempty"`
-	SessionDuration         string                         `json:"session_duration,omitempty"`
-	SkipInterstitial        *bool                          `json:"skip_interstitial,omitempty"`
-	Type                    AccessApplicationType          `json:"type,omitempty"`
-	CustomPages             []string                       `json:"custom_pages,omitempty"`
+	AllowedIdps              []string                       `json:"allowed_idps,omitempty"`
+	AppLauncherVisible       *bool                          `json:"app_launcher_visible,omitempty"`
+	AUD                      string                         `json:"aud,omitempty"`
+	AutoRedirectToIdentity   *bool                          `json:"auto_redirect_to_identity,omitempty"`
+	CorsHeaders              *AccessApplicationCorsHeaders  `json:"cors_headers,omitempty"`
+	CustomDenyMessage        string                         `json:"custom_deny_message,omitempty"`
+	CustomDenyURL            string                         `json:"custom_deny_url,omitempty"`
+	CustomNonIdentityDenyURL string                         `json:"custom_non_identity_deny_url,omitempty"`
+	Domain                   string                         `json:"domain"`
+	EnableBindingCookie      *bool                          `json:"enable_binding_cookie,omitempty"`
+	GatewayRules             []AccessApplicationGatewayRule `json:"gateway_rules,omitempty"`
+	HttpOnlyCookieAttribute  *bool                          `json:"http_only_cookie_attribute,omitempty"`
+	LogoURL                  string                         `json:"logo_url,omitempty"`
+	Name                     string                         `json:"name"`
+	PathCookieAttribute      *bool                          `json:"path_cookie_attribute,omitempty"`
+	PrivateAddress           string                         `json:"private_address"`
+	SaasApplication          *SaasApplication               `json:"saas_app,omitempty"`
+	SameSiteCookieAttribute  string                         `json:"same_site_cookie_attribute,omitempty"`
+	SelfHostedDomains        []string                       `json:"self_hosted_domains"`
+	ServiceAuth401Redirect   *bool                          `json:"service_auth_401_redirect,omitempty"`
+	SessionDuration          string                         `json:"session_duration,omitempty"`
+	SkipInterstitial         *bool                          `json:"skip_interstitial,omitempty"`
+	Type                     AccessApplicationType          `json:"type,omitempty"`
+	CustomPages              []string                       `json:"custom_pages,omitempty"`
 }
 
 type UpdateAccessApplicationParams struct {
-	ID                      string                         `json:"id,omitempty"`
-	AllowedIdps             []string                       `json:"allowed_idps,omitempty"`
-	AppLauncherVisible      *bool                          `json:"app_launcher_visible,omitempty"`
-	AUD                     string                         `json:"aud,omitempty"`
-	AutoRedirectToIdentity  *bool                          `json:"auto_redirect_to_identity,omitempty"`
-	CorsHeaders             *AccessApplicationCorsHeaders  `json:"cors_headers,omitempty"`
-	CustomDenyMessage       string                         `json:"custom_deny_message,omitempty"`
-	CustomDenyURL           string                         `json:"custom_deny_url,omitempty"`
-	Domain                  string                         `json:"domain"`
-	EnableBindingCookie     *bool                          `json:"enable_binding_cookie,omitempty"`
-	GatewayRules            []AccessApplicationGatewayRule `json:"gateway_rules,omitempty"`
-	HttpOnlyCookieAttribute *bool                          `json:"http_only_cookie_attribute,omitempty"`
-	LogoURL                 string                         `json:"logo_url,omitempty"`
-	Name                    string                         `json:"name"`
-	PathCookieAttribute     *bool                          `json:"path_cookie_attribute,omitempty"`
-	PrivateAddress          string                         `json:"private_address"`
-	SaasApplication         *SaasApplication               `json:"saas_app,omitempty"`
-	SameSiteCookieAttribute string                         `json:"same_site_cookie_attribute,omitempty"`
-	SelfHostedDomains       []string                       `json:"self_hosted_domains"`
-	ServiceAuth401Redirect  *bool                          `json:"service_auth_401_redirect,omitempty"`
-	SessionDuration         string                         `json:"session_duration,omitempty"`
-	SkipInterstitial        *bool                          `json:"skip_interstitial,omitempty"`
-	Type                    AccessApplicationType          `json:"type,omitempty"`
-	CustomPages             []string                       `json:"custom_pages,omitempty"`
+	ID                       string                         `json:"id,omitempty"`
+	AllowedIdps              []string                       `json:"allowed_idps,omitempty"`
+	AppLauncherVisible       *bool                          `json:"app_launcher_visible,omitempty"`
+	AUD                      string                         `json:"aud,omitempty"`
+	AutoRedirectToIdentity   *bool                          `json:"auto_redirect_to_identity,omitempty"`
+	CorsHeaders              *AccessApplicationCorsHeaders  `json:"cors_headers,omitempty"`
+	CustomDenyMessage        string                         `json:"custom_deny_message,omitempty"`
+	CustomDenyURL            string                         `json:"custom_deny_url,omitempty"`
+	CustomNonIdentityDenyURL string                         `json:"custom_non_identity_deny_url,omitempty"`
+	Domain                   string                         `json:"domain"`
+	EnableBindingCookie      *bool                          `json:"enable_binding_cookie,omitempty"`
+	GatewayRules             []AccessApplicationGatewayRule `json:"gateway_rules,omitempty"`
+	HttpOnlyCookieAttribute  *bool                          `json:"http_only_cookie_attribute,omitempty"`
+	LogoURL                  string                         `json:"logo_url,omitempty"`
+	Name                     string                         `json:"name"`
+	PathCookieAttribute      *bool                          `json:"path_cookie_attribute,omitempty"`
+	PrivateAddress           string                         `json:"private_address"`
+	SaasApplication          *SaasApplication               `json:"saas_app,omitempty"`
+	SameSiteCookieAttribute  string                         `json:"same_site_cookie_attribute,omitempty"`
+	SelfHostedDomains        []string                       `json:"self_hosted_domains"`
+	ServiceAuth401Redirect   *bool                          `json:"service_auth_401_redirect,omitempty"`
+	SessionDuration          string                         `json:"session_duration,omitempty"`
+	SkipInterstitial         *bool                          `json:"skip_interstitial,omitempty"`
+	Type                     AccessApplicationType          `json:"type,omitempty"`
+	CustomPages              []string                       `json:"custom_pages,omitempty"`
 }
 
 // ListAccessApplications returns all applications within an account or zone.


Test patch:
diff --git a/access_application_test.go b/access_application_test.go
index ffba809fa..d3423837c 100644
--- a/access_application_test.go
+++ b/access_application_test.go
@@ -39,6 +39,7 @@ func TestAccessApplications(t *testing.T) {
 					"auto_redirect_to_identity": false,
 					"enable_binding_cookie": false,
 					"custom_deny_url": "https://www.example.com",
+					"custom_non_identity_deny_url": "https://blocked.com",
 					"custom_deny_message": "denied!",
 					"http_only_cookie_attribute": true,
 					"same_site_cookie_attribute": "strict",
@@ -64,27 +65,28 @@ func TestAccessApplications(t *testing.T) {
 	updatedAt, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00.12345Z")
 
 	want := []AccessApplication{{
-		ID:                      "480f4f69-1a28-4fdd-9240-1ed29f0ac1db",
-		CreatedAt:               &createdAt,
-		UpdatedAt:               &updatedAt,
-		AUD:                     "737646a56ab1df6ec9bddc7e5ca84eaf3b0768850f3ffb5d74f1534911fe3893",
-		Name:                    "Admin Site",
-		Domain:                  "test.example.com/admin",
-		Type:                    "self_hosted",
-		SessionDuration:         "24h",
-		AllowedIdps:             []string{"f174e90a-fafe-4643-bbbc-4a0ed4fc8415"},
-		AutoRedirectToIdentity:  BoolPtr(false),
-		EnableBindingCookie:     BoolPtr(false),
-		AppLauncherVisible:      BoolPtr(true),
-		ServiceAuth401Redirect:  BoolPtr(true),
-		CustomDenyMessage:       "denied!",
-		CustomDenyURL:           "https://www.example.com",
-		SameSiteCookieAttribute: "strict",
-		HttpOnlyCookieAttribute: BoolPtr(true),
-		LogoURL:                 "https://www.example.com/example.png",
-		SkipInterstitial:        BoolPtr(true),
-		PathCookieAttribute:     BoolPtr(true),
-		CustomPages:             []string{"480f4f69-1a28-4fdd-9240-1ed29f0ac1dc"},
+		ID:                       "480f4f69-1a28-4fdd-9240-1ed29f0ac1db",
+		CreatedAt:                &createdAt,
+		UpdatedAt:                &updatedAt,
+		AUD:                      "737646a56ab1df6ec9bddc7e5ca84eaf3b0768850f3ffb5d74f1534911fe3893",
+		Name:                     "Admin Site",
+		Domain:                   "test.example.com/admin",
+		Type:                     "self_hosted",
+		SessionDuration:          "24h",
+		AllowedIdps:              []string{"f174e90a-fafe-4643-bbbc-4a0ed4fc8415"},
+		AutoRedirectToIdentity:   BoolPtr(false),
+		EnableBindingCookie:      BoolPtr(false),
+		AppLauncherVisible:       BoolPtr(true),
+		ServiceAuth401Redirect:   BoolPtr(true),
+		CustomDenyMessage:        "denied!",
+		CustomDenyURL:            "https://www.example.com",
+		SameSiteCookieAttribute:  "strict",
+		HttpOnlyCookieAttribute:  BoolPtr(true),
+		LogoURL:                  "https://www.example.com/example.png",
+		SkipInterstitial:         BoolPtr(true),
+		PathCookieAttribute:      BoolPtr(true),
+		CustomPages:              []string{"480f4f69-1a28-4fdd-9240-1ed29f0ac1dc"},
+		CustomNonIdentityDenyURL: "https://blocked.com",
 	}}
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/access/apps", handler)
@@ -129,6 +131,7 @@ func TestAccessApplication(t *testing.T) {
 				"auto_redirect_to_identity": false,
 				"enable_binding_cookie": false,
 				"custom_deny_url": "https://www.example.com",
+				"custom_non_identity_deny_url": "https://blocked.com",
 				"custom_deny_message": "denied!",
 				"logo_url": "https://www.example.com/example.png",
 				"skip_interstitial": true,
@@ -145,26 +148,27 @@ func TestAccessApplication(t *testing.T) {
 	updatedAt, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00.12345Z")
 
 	want := AccessApplication{
-		ID:                      "480f4f69-1a28-4fdd-9240-1ed29f0ac1db",
-		CreatedAt:               &createdAt,
-		UpdatedAt:               &updatedAt,
-		AUD:                     "737646a56ab1df6ec9bddc7e5ca84eaf3b0768850f3ffb5d74f1534911fe3893",
-		Name:                    "Admin Site",
-		Domain:                  "test.example.com/admin",
-		SelfHostedDomains:       []string{"test.example.com/admin", "test.example.com/admin2"},
-		Type:                    "self_hosted",
-		SessionDuration:         "24h",
-		AllowedIdps:             []string{"f174e90a-fafe-4643-bbbc-4a0ed4fc8415"},
-		AutoRedirectToIdentity:  BoolPtr(false),
-		EnableBindingCookie:     BoolPtr(false),
-		AppLauncherVisible:      BoolPtr(true),
-		ServiceAuth401Redirect:  BoolPtr(true),
-		CustomDenyMessage:       "denied!",
-		CustomDenyURL:           "https://www.example.com",
-		LogoURL:                 "https://www.example.com/example.png",
-		SkipInterstitial:        BoolPtr(true),
-		HttpOnlyCookieAttribute: BoolPtr(false),
-		PathCookieAttribute:     BoolPtr(false),
+		ID:                       "480f4f69-1a28-4fdd-9240-1ed29f0ac1db",
+		CreatedAt:                &createdAt,
+		UpdatedAt:                &updatedAt,
+		AUD:                      "737646a56ab1df6ec9bddc7e5ca84eaf3b0768850f3ffb5d74f1534911fe3893",
+		Name:                     "Admin Site",
+		Domain:                   "test.example.com/admin",
+		SelfHostedDomains:        []string{"test.example.com/admin", "test.example.com/admin2"},
+		Type:                     "self_hosted",
+		SessionDuration:          "24h",
+		AllowedIdps:              []string{"f174e90a-fafe-4643-bbbc-4a0ed4fc8415"},
+		AutoRedirectToIdentity:   BoolPtr(false),
+		EnableBindingCookie:      BoolPtr(false),
+		AppLauncherVisible:       BoolPtr(true),
+		ServiceAuth401Redirect:   BoolPtr(true),
+		CustomDenyMessage:        "denied!",
+		CustomDenyURL:            "https://www.example.com",
+		LogoURL:                  "https://www.example.com/example.png",
+		SkipInterstitial:         BoolPtr(true),
+		HttpOnlyCookieAttribute:  BoolPtr(false),
+		PathCookieAttribute:      BoolPtr(false),
+		CustomNonIdentityDenyURL: "https://blocked.com",
 	}
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/access/apps/480f4f69-1a28-4fdd-9240-1ed29f0ac1db", handler)
@@ -210,6 +214,7 @@ func TestCreateAccessApplications(t *testing.T) {
 				"enable_binding_cookie": false,
 				"custom_deny_url": "https://www.example.com",
 				"custom_deny_message": "denied!",
+				"custom_non_identity_deny_url": "https://blocked.com",
 				"logo_url": "https://www.example.com/example.png",
 				"skip_interstitial": true,
 				"app_launcher_visible": true,
@@ -222,24 +227,25 @@ func TestCreateAccessApplications(t *testing.T) {
 	createdAt, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00.12345Z")
 	updatedAt, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00.12345Z")
 	fullAccessApplication := AccessApplication{
-		ID:                     "480f4f69-1a28-4fdd-9240-1ed29f0ac1db",
-		Name:                   "Admin Site",
-		Domain:                 "test.example.com/admin",
-		SelfHostedDomains:      []string{"test.example.com/admin", "test.example.com/admin2"},
-		Type:                   "self_hosted",
-		SessionDuration:        "24h",
-		AUD:                    "737646a56ab1df6ec9bddc7e5ca84eaf3b0768850f3ffb5d74f1534911fe3893",
-		AllowedIdps:            []string{"f174e90a-fafe-4643-bbbc-4a0ed4fc8415"},
-		AutoRedirectToIdentity: BoolPtr(false),
-		EnableBindingCookie:    BoolPtr(false),
-		AppLauncherVisible:     BoolPtr(true),
-		ServiceAuth401Redirect: BoolPtr(true),
-		CustomDenyMessage:      "denied!",
-		CustomDenyURL:          "https://www.example.com",
-		LogoURL:                "https://www.example.com/example.png",
-		SkipInterstitial:       BoolPtr(true),
-		CreatedAt:              &createdAt,
-		UpdatedAt:              &updatedAt,
+		ID:                       "480f4f69-1a28-4fdd-9240-1ed29f0ac1db",
+		Name:                     "Admin Site",
+		Domain:                   "test.example.com/admin",
+		SelfHostedDomains:        []string{"test.example.com/admin", "test.example.com/admin2"},
+		Type:                     "self_hosted",
+		SessionDuration:          "24h",
+		AUD:                      "737646a56ab1df6ec9bddc7e5ca84eaf3b0768850f3ffb5d74f1534911fe3893",
+		AllowedIdps:              []string{"f174e90a-fafe-4643-bbbc-4a0ed4fc8415"},
+		AutoRedirectToIdentity:   BoolPtr(false),
+		EnableBindingCookie:      BoolPtr(false),
+		AppLauncherVisible:       BoolPtr(true),
+		ServiceAuth401Redirect:   BoolPtr(true),
+		CustomDenyMessage:        "denied!",
+		CustomDenyURL:            "https://www.example.com",
+		LogoURL:                  "https://www.example.com/example.png",
+		SkipInterstitial:         BoolPtr(true),
+		CreatedAt:                &createdAt,
+		UpdatedAt:                &updatedAt,
+		CustomNonIdentityDenyURL: "https://blocked.com",
 	}
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/access/apps", handler)
@@ -293,6 +299,7 @@ func TestUpdateAccessApplication(t *testing.T) {
 				"enable_binding_cookie": false,
 				"custom_deny_url": "https://www.example.com",
 				"custom_deny_message": "denied!",
+				"custom_non_identity_deny_url": "https://blocked.com",
 				"logo_url": "https://www.example.com/example.png",
 				"skip_interstitial": true,
 				"app_launcher_visible": true,
@@ -303,43 +310,45 @@ func TestUpdateAccessApplication(t *testing.T) {
 	}
 
 	fullAccessApplication := AccessApplication{
-		ID:                     "480f4f69-1a28-4fdd-9240-1ed29f0ac1db",
-		Name:                   "Admin Site",
-		Domain:                 "test.example.com/admin",
-		SelfHostedDomains:      []string{"test.example.com/admin", "test.example.com/admin2"},
-		Type:                   "self_hosted",
-		SessionDuration:        "24h",
-		AUD:                    "737646a56ab1df6ec9bddc7e5ca84eaf3b0768850f3ffb5d74f1534911fe3893",
-		AllowedIdps:            []string{"f174e90a-fafe-4643-bbbc-4a0ed4fc8415"},
-		AutoRedirectToIdentity: BoolPtr(false),
-		EnableBindingCookie:    BoolPtr(false),
-		AppLauncherVisible:     BoolPtr(true),
-		ServiceAuth401Redirect: BoolPtr(true),
-		CustomDenyMessage:      "denied!",
-		CustomDenyURL:          "https://www.example.com",
-		LogoURL:                "https://www.example.com/example.png",
-		SkipInterstitial:       BoolPtr(true),
-		CreatedAt:              &createdAt,
-		UpdatedAt:              &updatedAt,
+		ID:                       "480f4f69-1a28-4fdd-9240-1ed29f0ac1db",
+		Name:                     "Admin Site",
+		Domain:                   "test.example.com/admin",
+		SelfHostedDomains:        []string{"test.example.com/admin", "test.example.com/admin2"},
+		Type:                     "self_hosted",
+		SessionDuration:          "24h",
+		AUD:                      "737646a56ab1df6ec9bddc7e5ca84eaf3b0768850f3ffb5d74f1534911fe3893",
+		AllowedIdps:              []string{"f174e90a-fafe-4643-bbbc-4a0ed4fc8415"},
+		AutoRedirectToIdentity:   BoolPtr(false),
+		EnableBindingCookie:      BoolPtr(false),
+		AppLauncherVisible:       BoolPtr(true),
+		ServiceAuth401Redirect:   BoolPtr(true),
+		CustomDenyMessage:        "denied!",
+		CustomDenyURL:            "https://www.example.com",
+		LogoURL:                  "https://www.example.com/example.png",
+		CustomNonIdentityDenyURL: "https://blocked.com",
+		SkipInterstitial:         BoolPtr(true),
+		CreatedAt:                &createdAt,
+		UpdatedAt:                &updatedAt,
 	}
 
 	params := UpdateAccessApplicationParams{
-		ID:                     "480f4f69-1a28-4fdd-9240-1ed29f0ac1db",
-		Name:                   "Admin Site",
-		Domain:                 "test.example.com/admin",
-		SelfHostedDomains:      []string{"test.example.com/admin", "test.example.com/admin2"},
-		Type:                   "self_hosted",
-		SessionDuration:        "24h",
-		AUD:                    "737646a56ab1df6ec9bddc7e5ca84eaf3b0768850f3ffb5d74f1534911fe3893",
-		AllowedIdps:            []string{"f174e90a-fafe-4643-bbbc-4a0ed4fc8415"},
-		AutoRedirectToIdentity: BoolPtr(false),
-		EnableBindingCookie:    BoolPtr(false),
-		AppLauncherVisible:     BoolPtr(true),
-		ServiceAuth401Redirect: BoolPtr(true),
-		CustomDenyMessage:      "denied!",
-		CustomDenyURL:          "https://www.example.com",
-		LogoURL:                "https://www.example.com/example.png",
-		SkipInterstitial:       BoolPtr(true),
+		ID:                       "480f4f69-1a28-4fdd-9240-1ed29f0ac1db",
+		Name:                     "Admin Site",
+		Domain:                   "test.example.com/admin",
+		SelfHostedDomains:        []string{"test.example.com/admin", "test.example.com/admin2"},
+		Type:                     "self_hosted",
+		SessionDuration:          "24h",
+		AUD:                      "737646a56ab1df6ec9bddc7e5ca84eaf3b0768850f3ffb5d74f1534911fe3893",
+		AllowedIdps:              []string{"f174e90a-fafe-4643-bbbc-4a0ed4fc8415"},
+		AutoRedirectToIdentity:   BoolPtr(false),
+		EnableBindingCookie:      BoolPtr(false),
+		AppLauncherVisible:       BoolPtr(true),
+		ServiceAuth401Redirect:   BoolPtr(true),
+		CustomDenyMessage:        "denied!",
+		CustomDenyURL:            "https://www.example.com",
+		LogoURL:                  "https://www.example.com/example.png",
+		SkipInterstitial:         BoolPtr(true),
+		CustomNonIdentityDenyURL: "https://blocked.com",
 	}
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/access/apps/480f4f69-1a28-4fdd-9240-1ed29f0ac1db", handler)
@@ -353,22 +362,23 @@ func TestUpdateAccessApplication(t *testing.T) {
 	mux.HandleFunc("/zones/"+testZoneID+"/access/apps/480f4f69-1a28-4fdd-9240-1ed29f0ac1db", handler)
 
 	actual, err = client.UpdateAccessApplication(context.Background(), ZoneIdentifier(testZoneID), UpdateAccessApplicationParams{
-		ID:                     "480f4f69-1a28-4fdd-9240-1ed29f0ac1db",
-		Name:                   "Admin Site",
-		Domain:                 "test.example.com/admin",
-		SelfHostedDomains:      []string{"test.example.com/admin", "test.example.com/admin2"},
-		Type:                   "self_hosted",
-		SessionDuration:        "24h",
-		AUD:                    "737646a56ab1df6ec9bddc7e5ca84eaf3b0768850f3ffb5d74f1534911fe3893",
-		AllowedIdps:            []string{"f174e90a-fafe-4643-bbbc-4a0ed4fc8415"},
-		AutoRedirectToIdentity: BoolPtr(false),
-		EnableBindingCookie:    BoolPtr(false),
-		AppLauncherVisible:     BoolPtr(true),
-		ServiceAuth401Redirect: BoolPtr(true),
-		CustomDenyMessage:      "denied!",
-		CustomDenyURL:          "https://www.example.com",
-		LogoURL:                "https://www.example.com/example.png",
-		SkipInterstitial:       BoolPtr(true),
+		ID:                       "480f4f69-1a28-4fdd-9240-1ed29f0ac1db",
+		Name:                     "Admin Site",
+		Domain:                   "test.example.com/admin",
+		SelfHostedDomains:        []string{"test.example.com/admin", "test.example.com/admin2"},
+		Type:                     "self_hosted",
+		SessionDuration:          "24h",
+		AUD:                      "737646a56ab1df6ec9bddc7e5ca84eaf3b0768850f3ffb5d74f1534911fe3893",
+		AllowedIdps:              []string{"f174e90a-fafe-4643-bbbc-4a0ed4fc8415"},
+		AutoRedirectToIdentity:   BoolPtr(false),
+		EnableBindingCookie:      BoolPtr(false),
+		AppLauncherVisible:       BoolPtr(true),
+		ServiceAuth401Redirect:   BoolPtr(true),
+		CustomDenyMessage:        "denied!",
+		CustomDenyURL:            "https://www.example.com",
+		LogoURL:                  "https://www.example.com/example.png",
+		SkipInterstitial:         BoolPtr(true),
+		CustomNonIdentityDenyURL: "https://blocked.com",
 	})
 
 	if assert.NoError(t, err) {
@@ -623,6 +633,7 @@ func TestCreateSaasAccessApplications(t *testing.T) {
 				"skip_interstitial": true,
 				"app_launcher_visible": true,
 				"service_auth_401_redirect": true,
+				"custom_non_identity_deny_url": "https://blocked.com",
 				"saas_app": {
 					"consumer_service_url": "https://saas.example.com",
 					"sp_entity_id": "dash.example.com",
@@ -702,8 +713,9 @@ func TestCreateSaasAccessApplications(t *testing.T) {
 				},
 			},
 		},
-		CreatedAt: &createdAt,
-		UpdatedAt: &updatedAt,
+		CreatedAt:                &createdAt,
+		UpdatedAt:                &updatedAt,
+		CustomNonIdentityDenyURL: "https://blocked.com",
 	}
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/access/apps", handler)