UMFA APIs for Native iOS Applications

The Universal MFA (UMFA) module provides a flexible solution for handling multi-factor authentication processes. It leverages FIDO2 technology to enable secure credentials bound to the user's device.

Interface Definitions

Jump to: Swift, Objective-C

Getting the version number of the SDK library: UMFAClient.versionString

To retrieve the version number of the SDK library use the class property UMFAClient.versionString. It will return the version number in semantic versioning format, major.minor.patch.

Swift

Creating a UMFA Client

UMFAClient(ZSMConfig)
UMFAClient(ZSMConfig, relyingParty: RelyingParty)

Parameters

Parameter NameData TypeDescription
configZSMConfigConfiguration for the UMFA client
relyingPartyRelyingPartyAn instance of RelyingParty to handle WebAuthn authentication (optional)

Check Enrollment Status

func checkEnrollment(userId: String, completion: @escaping ([String: Any]?, [String: String]?, ZSMError?) -> Void)

Description

Checks if a user has previously registered credentials on this device and retrieves the enrollment status.

Parameters

Parameter NameData TypeDescription
userIdStringThe unique identifier for the user
completion([String: Any]?, [String: String]?, ZSMError?) -> VoidCompletion handler called with enrollment data or error

Returns in Completion Handler

Parameter NameData TypeDescription
data[String: Any]?The enrollment status information if user is enrolled
metadata[String: String]?Additional metadata related to the enrollment status
errorZSMError?Error object in case of failure; otherwise, nil

Enrollment

func enroll(userId: String, completion: @escaping ([String: Any]?, [String: String]?, ZSMError?) -> Void)

Description

Initiates the enrollment process for a user, creating and storing credentials on the device.

Parameters

Parameter NameData TypeDescription
userIdStringThe unique identifier for the user
completion([String: Any]?, [String: String]?, ZSMError?) -> VoidCompletion handler called with enrollment result or error

Returns in Completion Handler

Parameter NameData TypeDescription
data[String: Any]?The enrollment data including token
metadata[String: String]?Additional metadata related to the enrollment
errorZSMError?Error object in case of failure; otherwise, nil

Authentication

func authenticate(userId: String, completion: @escaping ([String: Any]?, [String: String]?, ZSMError?) -> Void)

Description

Authenticates a previously enrolled user using their device credentials.

Parameters

Parameter NameData TypeDescription
userIdStringThe unique identifier for the user
completion([String: Any]?, [String: String]?, ZSMError?) -> VoidCompletion handler called with authentication result or error

Returns in Completion Handler

Parameter NameData TypeDescription
data[String: Any]?The authentication result data, including authentication token
metadata[String: String]?Additional metadata related to the authentication
errorZSMError?Error object in case of failure; otherwise, nil

Unenrollment

func unenroll(userId: String, completion: @escaping (Bool) -> Void)

Description

Unenrolls a user by removing their stored credentials from the device.

Parameters

Parameter NameData TypeDescription
userIdStringThe unique identifier for the user to unenroll
completion(Bool) -> VoidCompletion handler called with success status of the unenrollment

Returns in Completion Handler

Parameter NameData TypeDescription
successBoolIndicates whether the unenrollment was successful

Objective-C

Creating a UMFA Client

- (instancetype)initWithConfig:(nonnull ZSMConfig *)config;
- (instancetype)initWithConfig:(nonnull ZSMConfig *)config relyingParty:(nonnull RelyingParty *)relyingParty;

Parameters

Parameter NameData TypeDescription
configZSMConfig *Configuration for the UMFA client
relyingPartyRelyingParty *An instance of RelyingParty to handle WebAuthn authentication (optional)

Check Enrollment Status

- (void)checkEnrollment:(NSString *)userId
             completion:(void (^)(NSDictionary * _Nullable data, NSDictionary<NSString *, NSString *> * _Nullable metadata, ZSMError * _Nullable error))completion;

Description

Checks if a user has previously registered credentials on this device and retrieves the enrollment status.

Parameters

Parameter NameData TypeDescription
userIdNSString *The unique identifier for the user
completionvoid (^)(NSDictionary * _Nullable, NSDictionary<NSString *, NSString *> * _Nullable, ZSMError * _Nullable)Completion handler called with enrollment data or error

Returns in Completion Handler

Parameter NameData TypeDescription
dataNSDictionary * _NullableThe enrollment status information if user is enrolled
metadataNSDictionary<NSString *, NSString *> *Additional metadata related to the enrollment status
errorZSMError * _NullableError object in case of failure; otherwise, nil

Enrollment

- (void)enroll:(NSString *)userId
    completion:(void (^)(NSDictionary * _Nullable data, NSDictionary<NSString *, NSString *> * _Nullable metadata, ZSMError * _Nullable error))completion;

Description

Initiates the enrollment process for a user, creating and storing credentials on the device.

Parameters

Parameter NameData TypeDescription
userIdNSString *The unique identifier for the user
completionvoid (^)(NSDictionary * _Nullable, NSDictionary<NSString *, NSString *> * _Nullable, ZSMError * _Nullable)Completion handler called with enrollment result or error

Returns in Completion Handler

Parameter NameData TypeDescription
dataNSDictionary * _NullableThe enrollment data including token
metadataNSDictionary<NSString *, NSString *> *Additional metadata related to the enrollment
errorZSMError * _NullableError object in case of failure; otherwise, nil

Authentication

- (void)authenticate:(NSString *)userId
          completion:(void (^)(NSDictionary * _Nullable data, NSDictionary<NSString *, NSString *> * _Nullable metadata, ZSMError * _Nullable error))completion;

Description

Authenticates a previously enrolled user using their device credentials.

Parameters

Parameter NameData TypeDescription
userIdNSString *The unique identifier for the user
completionvoid (^)(NSDictionary * _Nullable, NSDictionary<NSString *, NSString *> * _Nullable, ZSMError * _Nullable)Completion handler called with authentication result or error

Returns in Completion Handler

Parameter NameData TypeDescription
dataNSDictionary * _NullableThe authentication result data, including authentication token
metadataNSDictionary<NSString *, NSString *> *Additional metadata related to the authentication
errorZSMError * _NullableError object in case of failure; otherwise, nil

Unenrollment

- (void)unenroll:(NSString *)userId
      completion:(void (^)(BOOL success))completion;

Description

Unenrolls a user by removing their stored credentials from the device.

Parameters

Parameter NameData TypeDescription
userIdNSString *The unique identifier for the user to unenroll
completionvoid (^)(BOOL)Completion handler called with success status of the unenrollment

Returns in Completion Handler

Parameter NameData TypeDescription
successBOOLIndicates whether the unenrollment was successful

Out-of-Band Token Validation

For out-of-band validation of the token returned by enroll and authenticate, use the /api/umfa/validate-token endpoint.

HTTP Method

POST

URL

$ZSM_AUTHENTICATOR_HOST/api/umfa/validate-token

Request Headers

HeaderValueDescription
Content-Typeapplication/jsonIndicates the payload format
AuthorizationBearer XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXAuthorizes the API (API Key expected)

Request Body

FieldTypeRequiredDescription
application_idstringYesThe unique identifier for the request's (server-to-server) application, parsed as a UUID.
user_idstringYesThe unique identifier for the user.
tokenstringYesThe token received from a previous UMFA authentication operation.
token_typestringNoAn optional token type specifying the type of validation. Can be "credential" to validate a get() PublicKeyCredential.
trace_idstringNoAn optional identifier for the validate-token operation. If a trace_id is not provided, then a random trace_id will be generated.

Successful Response (HTTP 200)

{
  "user_id": "janedoe@gmail.com",
  "trace_id": "7a626fe9-ce25-4b87-8eb2-b12a7ee20143"
}
FieldTypeDescription
user_idstringThe unique identifier for the user that was validated.
trace_idstringThe trace identifier for the validate-token operation.

Error Responses

{
  "status": 400,
  "trace_id": "7a626fe9-ce25-4b87-8eb2-b12a7ee20143",
  "message": "Validate token failed with: MFA login JWT was invalid: Invalid JWT: There is no user_id claim"
}
FieldTypeDescription
statusintegerThe HTTP response code.
trace_idstringThe trace identifier for the verification operation.
messagestringAdditional information about the validation failure.
Status CodeDescriptionExample Response
400 Bad RequestIncorrectly formed request{ ... "message": "No data provided." }
401 UnauthorizedInvalid or expired token{ ... "message": "Validate token failed with: MFA login JWT was invalid: Invalid JWT: There is no webauthn_time claim" }
500 Internal Server ErrorServer encountered an issue{ ... "message": "Server encountered an internal error" }

Example cURL Commands

HTTP Success (200) JWT Validation

$ curl -s - X POST -H "Content-Type: application/json"
-H "Authorization: Bearer XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
-d '{"application_id": "bf468b21-308f-49d2-9031-83556e0781d2", 
"user_id": "janedoe@gmail.com", "token": "eyJ0eX ... Nk9uWg"}' 
$ZSM_AUTHENTICATOR_HOST/api/umfa/validate-token | jq
{
  "user_id": "c7d7d44b-385e-4e83-bdd5-37e4fb3c8b7d",
  "trace_id": "7a626fe9-ce25-4b87-8eb2-b12a7ee20143"
}

HTTP Success (200) Credential Validation

$ curl -s - X POST -H "Content-Type: application/json"
-H "Authorization: Bearer XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
-d '{"application_id": "bf468b21-308f-49d2-9031-83556e0781d2", 
"user_id": "janedoe@gmail.com", 
"token":
{
  "id":"",
  "rawId":"rF2kHiKUQCO0d0Y4Wek9kA",
  "response":
  {
    "clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiNWtMb2tjOXpkZzhuU2RFT2hzV1o5MUwzZTNGdjlqbERlRU9KcF93SnRkayIsIm9yaWdpbiI6Imh0dHBzOi8venNtLmFwcCJ9","authenticatorData":"ZxcNEwlh6TBKTTC5FMSFPTOboOZWzGeOSiYY7rm67WUFAAAAAQ","signature":"UOOoSBAwemLSPvqLVG2MDw41cqKLcHEUp4LAFGuvrVPsR1GWBYTWtmpqG_Jtjn-DXq5tGGAE58SYvu7uvcw7oHqquoNG4VEdm4Tz7UNe5kdSoc3RFpEGGDLCIz28iKXaBPbv3jdHi4xGoCIJKIIeHyh0-g7LUb4ZjYFIZHyXds7cdH9ozXRt5ERWUVvH1axDnPDKpntGQXG8FC4VXd0Rc01-4bBklNSGHOVgbO-Rpm8HgeFj3J4uOZDJ0xP7pnIkwOo5Uw_0ZO9xI66S8NQEtVzXVUKXs98f38LpLiLGEPlWtr_RIdf9xgsmHx-oVRJxC37gzV2ydSGKJaV6bNsXOw"},
    "type":"public-key"
  }
},
"token-type": "credential"}' 
$ZSM_AUTHENTICATOR_HOST/api/umfa/validate-token | jq
{
  "user_id": "c7d7d44b-385e-4e83-bdd5-37e4fb3c8b7d",
  "trace_id": "7a626fe9-ce25-4b87-8eb2-b12a7ee20143"
}

Bad Request (400)

$ curl -s - X POST -H "Content-Type: application/json"
-H "Authorization: Bearer XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
-d '{"application_id": "bf468b21-308f-49d2-9031-83556e0781d2", 
"user_id": "janedoe@gmail.com"}' 
$ZSM_AUTHENTICATOR_HOST/api/umfa/validate-token | jq
{
  "status": 400,
  "trace_id": "7a626fe9-ce25-4b87-8eb2-b12a7ee20143",
  "message": "Invalid data provided" 
}

Unauthorized (401)

$ curl -s - X POST -H "Content-Type: application/json"
-H "Authorization: Bearer XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
-d '{"application_id": "bf468b21-308f-49d2-9031-83556e0781d2", 
"user_id": "janedoe@gmail.com", "token": "eyJ0eX ... Nk9uWg"}' 
$ZSM_AUTHENTICATOR_HOST/api/umfa/validate-token | jq
{
  "status": 401,
  "trace_id": "7a626fe9-ce25-4b87-8eb2-b12a7ee20143",
  "message": "Validate token failed with: MFA login JWT was invalid: Invalid JWT: Invalid claim: The token has expired: 2024-12-10 18:41:03.0 +00:00:00" 
}

Validate Token Failures

The server's token validation can fail for two general reasons:

  • HTTP 400 Response: The request was malformed (i.e., token was not included)
  • HTTP 401 Response: The token was invalid, which could have various causes
    • Token's user_id did not match the supplied user_id
    • Token has expired (the token's "exp" claim has passed)
    • Token was missing required claims ("iss", "sub", "iat", "exp", "user_id", "webauthn_time")
    • Token was not signed by the expected ZSM server's certificate
    • Token was not a valid PublicKeyCredential when supplied "token_type" = "credential"

Decoded JWT

Below, we illustrate an example of a decoded UMFA JWT (Header and Payload). The validation performs standard JWT validation like signature, liveness, and structure. The validation also ensures that the payload claim user_id matches that of the supplied user_id.

{
  "typ": "JWT",
  "alg": "RS256",
  "iss": "Ideem::Authenticator"
}
{
  "sub": "UMFA_login",
  "iss": "Ideem::Authenticator",
  "aud": [
    "Ideem::Authenticator",
    "Ideem::ZSM",
    "Ideem::ZSM_CLI"
  ],
  "iat": 1729280408,
  "exp": 1729366808,
  "jti": "042142c1-40c8-4d9b-bf5e-1fa84e0f3f03",
  "user_id": "c7d7d44b-385e-4e83-bdd5-37e4fb3c8b7d",
  "userpw_time": "2024-10-18T19:40:07.053364351+00:00",
  "webauthn_time": "2024-10-18T19:40:08.053364351+00:00"
}