Skip to content

Pydantic validation errors block listing/retrieving Okta App Catalog SAML apps and Atlassian SWA apps; single bad record poisons entire response page #48

Description

New issue?

  • I have reviewed the Existing Issues and confirm this is not an existing issue.

Bug

Multiple pydantic_core.ValidationError failures in the application response models prevent listing or retrieving applications created from the Okta App Catalog (SAML templates) and the Atlassian SWA template. A single invalid record poisons the entire response page — list_applications, list_applications with q=/filter=, and get_application(id) all fail with the same error. A separate latent bug silently drops data in SAML attribute statements (anyOf discriminator never resolves; actual_instance is always null).

Expected behavior

  • list_applications() returns all apps in the tenant, paginated, regardless of which catalog templates are in use.
  • list_applications(filter='user.id eq "<id>"') returns the apps assigned to that user.
  • get_application(app_id) returns a single app's full record.
  • settings.signOn.attributeStatements returns the actual configured statements, not anyOf wrapper objects with actual_instance: null.

Per Okta's Apps API schema, only signOnMode and label are guaranteed at the application level; settings fields vary by app type and template, so the response models should reflect that.

Observed behavior

Five distinct issues, ordered by severity:

Bug 1 — SamlApplication rejects App Catalog SAML responses (15 missing fields)

Trigger: Any SAML app derived from the Okta App Catalog (rValue starts with Okta_<vendor>_).

Reproduction: list_applications(q='aws'), list_applications(q='ninja'), get_application('<catalog_jira_app_id>').

Error:


### Relevant log output

```text
=== Bug 1: get_application on catalog SAML app ===

15 validation errors for SamlApplication
settings.signOn.allowMultipleAcsEndpoints
  Field required [type=missing, input_value={'defaultRelayState': Non...rValue': 'Okta_Jira_'}]}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.13/v/missing
settings.signOn.assertionSigned
  Field required [type=missing, input_value={'defaultRelayState': Non...rValue': 'Okta_Jira_'}]}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.13/v/missing
settings.signOn.audience
  Field required [type=missing, input_value={'defaultRelayState': Non...rValue': 'Okta_Jira_'}]}, input_type=dict]
settings.signOn.authnContextClassRef
  Field required [type=missing, input_value={'defaultRelayState': Non...rValue': 'Okta_Jira_'}]}, input_type=dict]
settings.signOn.destination
  Field required [type=missing, input_value={'defaultRelayState': Non...rValue': 'Okta_Jira_'}]}, input_type=dict]
settings.signOn.digestAlgorithm
  Field required [type=missing, input_value={'defaultRelayState': Non...rValue': 'Okta_Jira_'}]}, input_type=dict]
settings.signOn.honorForceAuthn
  Field required [type=missing, input_value={'defaultRelayState': Non...rValue': 'Okta_Jira_'}]}, input_type=dict]
settings.signOn.idpIssuer
  Field required [type=missing, input_value={'defaultRelayState': Non...rValue': 'Okta_Jira_'}]}, input_type=dict]
settings.signOn.recipient
  Field required [type=missing, input_value={'defaultRelayState': Non...rValue': 'Okta_Jira_'}]}, input_type=dict]
settings.signOn.requestCompressed
  Field required [type=missing, input_value={'defaultRelayState': Non...rValue': 'Okta_Jira_'}]}, input_type=dict]
settings.signOn.responseSigned
  Field required [type=missing, input_value={'defaultRelayState': Non...rValue': 'Okta_Jira_'}]}, input_type=dict]
settings.signOn.signatureAlgorithm
  Field required [type=missing, input_value={'defaultRelayState': Non...rValue': 'Okta_Jira_'}]}, input_type=dict]
settings.signOn.ssoAcsUrl
  Field required [type=missing, input_value={'defaultRelayState': Non...rValue': 'Okta_Jira_'}]}, input_type=dict]
settings.signOn.subjectNameIdFormat
  Field required [type=missing, input_value={'defaultRelayState': Non...rValue': 'Okta_Jira_'}]}, input_type=dict]
settings.signOn.subjectNameIdTemplate
  Field required [type=missing, input_value={'defaultRelayState': Non...rValue': 'Okta_Jira_'}]}, input_type=dict]


=== Bug 1 variant: AWS catalog template (14 fields, honorForceAuthn present) ===

14 validation errors for SamlApplication
settings.signOn.allowMultipleAcsEndpoints
  Field required [type=missing, input_value={'defaultRelayState': Non...erValue': 'Okta_AWS_'}]}, input_type=dict]
[...same 13 fields as Bug 1, minus honorForceAuthn...]


=== Bug 3: list_applications(q='jira') hits Atlassian SWA ===

5 validation errors for BrowserPluginApplication
name
  Value error, must be one of enum values ('template_swa', 'template_swa3field') [type=value_error, input_value='atlassian', input_type=str]
    For further information visit https://errors.pydantic.dev/2.13/v/value_error
settings.app.buttonField
  Field required [type=missing, input_value={'compassUrl': None, 'jir...https://app.stride.com'}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.13/v/missing
settings.app.passwordField
  Field required [type=missing, input_value={'compassUrl': None, 'jir...https://app.stride.com'}, input_type=dict]
settings.app.url
  Field required [type=missing, input_value={'compassUrl': None, 'jir...https://app.stride.com'}, input_type=dict]
settings.app.usernameField
  Field required [type=missing, input_value={'compassUrl': None, 'jir...https://app.stride.com'}, input_type=dict]


=== Bug 4: SamlAttributeStatement anyOf returning null actual_instance (no error raised) ===

"attributeStatements": [
  {
    "anyof_schema_1_validator": null,
    "anyof_schema_2_validator": null,
    "actual_instance": null,
    "any_of_schemas": [
      "SamlAttributeStatementExpression",
      "SamlAttributeStatementGroup"
    ],
    "discriminator_value_class_map": {}
  }
]


=== Bug 5: Group.profile anyOf returning raw wrapper (no error raised) ===

"profile": {
  "anyof_schema_1_validator": null,
  "anyof_schema_2_validator": null,
  "actual_instance": {
    "description": "...",
    "name": "<group_name>",
    "objectClass": null,
    "additional_properties": {}
  },
  "any_of_schemas": [
    "OktaActiveDirectoryGroupProfile",
    "OktaUserGroupProfile"
  ]
}

Additional information

Investigation method: Bugs found while attempting to enumerate application assignments for a single user via list_applications(filter='user.id eq "..."'). Investigation expanded to characterize all failure modes after the user-filter call kept hitting different validation errors page-by-page.

Tested workarounds (all blocked):

  • list_applications(filter='user.id eq "..."') — fails on first page containing a catalog SAML app
  • list_applications(q='<substring>') — works only when the substring matches no broken records; cannot be used to enumerate broken apps
  • get_application(<broken_app_id>) — fails with the same validation error as the list path, ruling out per-record retrieval as a workaround
  • list_groups + list_group_apps — would face the same models; partially tested (group with only OIDC apps parsed cleanly; SAML-heavy groups not tested but expected to fail)

Net effect: for a tenant with App Catalog SAML deployments, there is no MCP-side path to fully enumerate apps. The only working fallback is the Okta admin console UI, which uses the raw API directly without Pydantic interpretation.

Suggestion for prioritization: Bug 1 + the cross-cutting "fail open" recommendation together would unblock all enumeration use cases even before Bugs 2-5 are individually addressed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions