authenticationMethods missing from okta/models/possession_constraints but visible in raw api
Hello,
authenticationMethods field is missing in okta/models/possession_constraints?
https://github.com/okta/okta-sdk-python/blob/master/okta/models/possession_constraint.py
but visible in raw api
https://tenant-admin.okta.com/api/v1/policies/<ruleid>/rules
eg (you can test via gui by clicking
Authentication methods->Allow specific authentication methods
Could you please add it in ?
e.g
"actions": {
"appSignOn": {
"access": "ALLOW",
"verificationMethod": {
"factorMode": "2FA",
"type": "ASSURANCE",
"reauthenticateIn": "PT0S",
"constraints": [
{
"knowledge": {
"required": true,
"types": [
"password"
],
"reauthenticateIn": "PT0S"
},
"possession": {
"required": true,
"authenticationMethods": [
{
"key": "okta_verify",
"method": "signed_nonce"
}
],
"hardwareProtection": "REQUIRED",
"phishingResistant": "REQUIRED",
"userPresence": "REQUIRED",
"userVerification": "REQUIRED"
}
}
]
}
}
},
ps https://developer.okta.com/docs/reference/api/policy/#authenticator-key-type-method-and-characteristic-relationships-for-constraints
ran into this problem and validated this - here is an example
returned in response.get_body()
{'id': 'rul123', 'status': 'ACTIVE', 'name': 'Okta Verify Device Trust', 'priority': 5, 'created': '2025-05-15T18:36:16.000Z', 'lastUpdated': '2025-06-03T19:51:51.000Z', 'system': False, 'conditions': {'people': {'users': {'exclude': []}, 'groups': {'include': ['00g16']}}, 'network': {'connection': 'ANYWHERE'}, 'device': {'registered': True, 'managed': True, 'assurance': {'include': ['dae16']}}, 'riskScore': {'level': 'ANY'}, 'userType': {'include': [], 'exclude': []}}, 'actions': {'appSignOn': {'access': 'ALLOW', 'verificationMethod': {'factorMode': '2FA', 'type': 'ASSURANCE', 'reauthenticateIn': 'PT12H', 'constraints': [{'knowledge': {'methods': [], 'reauthenticate_in': 'PT12H', 'types': ['password']}, 'possession': {'methods': [], 'reauthenticate_in': None, 'types': [], 'device_bound': None, 'hardware_protection': None, 'phishing_resistant': None, 'user_presence': 'OPTIONAL'}}]}}}, '_links': {'self': {'href': 'https://example.okta.com/api/v1/policies/rstpty123/rules/rul123', 'hints': {'allow': ['GET', 'PUT', 'DELETE']}}, 'deactivate': {'href': 'https://example.okta.com/api/v1/policies/rstpty123/rules/rul123/lifecycle/deactivate', 'hints': {'allow': ['POST']}}}, 'type': 'ACCESS_POLICY'},
returned as part of rule iterator
{'actions': {'enroll': None, 'idp': None, 'password_change': None, 'self_service_password_reset': None, 'self_service_unlock': None, 'signon': None, 'app_sign_on': {'access': 'ALLOW', 'verification_method': {'constraints': [{'knowledge': {'methods': [], 'reauthenticate_in': 'PT12H', 'types': ['password']}, 'possession': {'methods': [], 'reauthenticate_in': None, 'types': [], 'device_bound': None, 'hardware_protection': None, 'phishing_resistant': None, 'user_presence': 'OPTIONAL'}}], 'factor_mode': '2FA', 'inactivity_period': None, 'reauthenticate_in': 'PT12H', 'type': 'ASSURANCE'}}}, 'conditions': {'app': None, 'apps': None, 'auth_context': None, 'auth_provider': None, 'before_scheduled_action': None, 'clients': None, 'context': None, 'device': {'migrated': None, 'platform': None, 'rooted': None, 'trust_level': None, 'managed': True, 'registered': True}, 'grant_types': None, 'groups': None, 'identity_provider': None, 'mdm_enrollment': None, 'network': {'connection': 'ANYWHERE', 'exclude': [], 'include': []}, 'people': {'groups': {'exclude': [], 'include': ['00g16']}, 'users': {'exclude': [], 'include': []}}, 'platform': None, 'risk': None, 'risk_score': {'level': 'ANY'}, 'scopes': None, 'user_identifier': None, 'user_status': None, 'users': None, 'el_condition': None, 'user_type': {'exclude': [], 'include': []}}, 'created': '2025-05-15T18:36:16.000Z', 'id': 'rul123', 'last_updated': '2025-06-03T19:51:51.000Z', 'name': 'Okta Verify Device Trust', 'priority': 5, 'status': 'ACTIVE', 'system': False, 'type': 'ACCESS_POLICY'}
Returned from manual API request
{'id': 'rul123', 'status': 'ACTIVE', 'name': 'Okta Verify Device Trust', 'priority': 5, 'created': '2025-05-15T18:36:16.000Z', 'lastUpdated': '2025-06-03T19:51:51.000Z', 'system': False, 'conditions': {'people': {'users': {'exclude': []}, 'groups': {'include': ['00g16']}}, 'network': {'connection': 'ANYWHERE'}, 'device': {'registered': True, 'managed': True, 'assurance': {'include': ['dae16']}}, 'riskScore': {'level': 'ANY'}, 'userType': {'include': [], 'exclude': []}}, 'actions': {'appSignOn': {'access': 'ALLOW', 'verificationMethod': {'factorMode': '2FA', 'type': 'ASSURANCE', 'reauthenticateIn': 'PT12H', 'constraints': [{'knowledge': {'required': True, 'types': ['password'], 'reauthenticateIn': 'PT12H'}, 'possession': {'required': True, 'authenticationMethods': [{'key': 'okta_verify', 'method': 'signed_nonce'}, {'key': 'webauthn', 'method': 'webauthn'}], 'userPresence': 'OPTIONAL'}}]}}}, '_links': {'self': {'href': 'https://example.okta.com/api/v1/policies/rstpty123/rules/rul123', 'hints': {'allow': ['GET', 'PUT', 'DELETE']}}, 'deactivate': {'href': 'https://example.okta.com/api/v1/policies/rstpty123/rules/rul123/lifecycle/deactivate', 'hints': {'allow': ['POST']}}}, 'type': 'ACCESS_POLICY'},
Given that the data is missing from response.get_body() i'm inclined to think error lies further upstream with the generic request_executor function, which may mean that this is broken for other API calls - it may again be that the hardcoded API structure isn't being updated - in which case it needs to be.
In the mean time
def make_manual_request(okta_client, url):
domain = "https://xyz.okta.com"
path = f"{domain}{url}"
headers = {
"Authorization": f"SSWS {okta_client._api_token}",
"Accept": "application/json",
"Content-Type": "application/json"
}
resp = requests.get(path, headers=headers)
if resp.status_code == 200:
return resp.json()
else:
print(resp.text)
return None
and resp2 = make_manual_request(client, f'/api/v1/policies/{policy.id}/rules') will get yah where you need to go as a hack