okta-sdk-python icon indicating copy to clipboard operation
okta-sdk-python copied to clipboard

authenticationMethods missing from okta/models/possession_constraints but visible in raw api

Open ghals13 opened this issue 1 year ago • 2 comments

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"
                            }
                        }
                    ]
                }
            }
        },

ghals13 avatar Sep 19 '24 06:09 ghals13

ps https://developer.okta.com/docs/reference/api/policy/#authenticator-key-type-method-and-characteristic-relationships-for-constraints

ghals13 avatar Sep 19 '24 08:09 ghals13

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

csanders-git avatar Jun 12 '25 17:06 csanders-git