fix: relax two SDK model gaps blocking list_policies on Okta for Government tenants - #102
fix: relax two SDK model gaps blocking list_policies on Okta for Government tenants#102jackvaughanjr wants to merge 1 commit into
Conversation
…rnment tenants
Two distinct, reproducible pydantic ValidationErrors abort list_policies/list_policy_rules
entirely, observed against a live Okta for Government (FedRAMP) tenant:
1. `Policy.embedded` is typed `Dict[str, Dict[str, Any]]`, but an ACCESS_POLICY mapped to
an app returns `_embedded: {"resourceType": "APP"}` — a flat string value, not a nested
object. This aborts `list_policies(type="ACCESS_POLICY")` and `get_policy` for every
policy in the tenant as soon as one carries this shape.
2. `AuthenticatorEnrollmentPolicyAuthenticatorType` (used by MFA_ENROLL policy authenticator
settings) omits `smart_card_idp`, even though the SDK's own `AuthenticatorKeyEnum`
recognizes it elsewhere. Smart-card/PIV-CAC authenticators are common in Okta for
Government and rare in commercial Okta, which is presumably why this was missed. This
aborts `list_policies(type="MFA_ENROLL")` for the whole page.
Both are fixed the same way the existing LogSecurityContext.user_behaviors workaround in
system_logs.py handles an analogous SDK gap: relax the overly strict field annotation and
force a Pydantic schema rebuild, rather than waiting on an SDK release. The Policy fix
rebuilds AccessPolicy and any other loaded Policy subclass explicitly (not just the base
class) so it isn't sensitive to which module happens to import the subclass first.
Verified against the live tenant: list_policies(ACCESS_POLICY), list_policies(MFA_ENROLL),
and list_policy_rules on a real rst... access policy all now succeed where they previously
raised on every call.
Fixes okta#100, Fixes okta#101
|
Closing in favour of #107, which supersedes this. #107 covers the same two defects (#100 and #101) plus two more of the same kind: the five required The patches move out of The |
Summary
Fixes #100 and #101, two distinct pydantic
ValidationErrors that abortlist_policies/list_policy_rulesentirely, both found while testing against a live Okta for Government (FedRAMP) tenant.Policy.embeddedis typedDict[str, Dict[str, Any]], but anACCESS_POLICYmapped to an app returns_embedded: {"resourceType": "APP"}(a flat string value). Abortslist_policies(type="ACCESS_POLICY")/get_policyfor the whole tenant as soon as one policy has this shape.AuthenticatorEnrollmentPolicyAuthenticatorTypedoesn't includesmart_card_idp, even thoughAuthenticatorKeyEnumrecognizes it elsewhere in the SDK. Abortslist_policies(type="MFA_ENROLL")for any tenant with a smart-card/PIV-CAC MFA enrollment policy (common in gov tenants, rare commercially).Fix
Both follow the same pattern as the existing
LogSecurityContext.user_behaviorsworkaround already insystem_logs.py: relax the overly strict field annotation and force a Pydantic schema rebuild at import time, rather than waiting on anoktaSDK release.Policy.embedded→Optional[Dict[str, Any]], rebuilt onPolicy,AccessPolicy, and any other already-loadedPolicysubclass explicitly, not just the base class, so the fix isn't sensitive to which module happens to import a given subclass first (pydantic v2 subclasses cache their own core schema at class-definition time).AuthenticatorEnrollmentPolicyAuthenticatorSettings.key→Optional[str], so any authenticator key Okta returns is accepted instead of maintaining a second, hand-kept enum that can drift fromAuthenticatorKeyEnum.Verification
Confirmed against a live Okta for Government tenant, before and after this change:
list_policies(type="ACCESS_POLICY")ValidationError: _embedded.resourceTypelist_policies(type="MFA_ENROLL")ValidationError: key ... 'smart_card_idp'list_policy_rules(<rst... access policy id>)PASSWORDandOKTA_SIGN_ONpolicies were unaffected before and after, confirming the bug is specific to these two shapes, not a general policy-parsing regression.Tests
New
tests/test_policy_model_workarounds.py: both workarounds, plus backward-compatibility cases confirming previously-valid shapes (nested-dict_embeddedvalues, already-valid enum keys) still validate identically. Full suite: 535 passed.