Skip to content

The IBM Security Verify WebAuthn Relying Party Server for Swift exposes endpoints that proxies OAuth and FIDO2 requests to IBM Security Verify from web and mobile clients.

License

Notifications You must be signed in to change notification settings

ibm-security-verify/webauthn-relying-party-server-swift

Repository files navigation

IBM Security Verify WebAuthn Relying Party Server for Swift

The IBM Security Verify WebAuthn Relying Party Server for Swift is based on the Vapor framework and exposes endpoints that proxies OAuth and FIDO2 requests to IBM Security Verify from web and mobile clients.

Getting started

The resource links in the prerequisites explain and demonstrate how you create a new tenant and automate the application and FIDO2 configuration used by the Relying Party Server.

Prerequisites

  • Create a free trial tenant here: https://www.ibm.com/account/reg/us-en/signup?formid=urx-30041.

    You'll need to have an IBMid but this can be done at the same time.

    This link explains setting up your tenant: https://docs.verify.ibm.com/verify/docs/signing-up-for-a-free-trial

  • Create an API client on the trial tenant. See this configuration guide for instructions.

    Ensure the API client has the following entitlements:

    • Read identity providers
    • Manage application lifecycle
    • Read application configuration
    • Manage second-factor authentication method configuration
  • Clone the relying party repository. Run this command in a Terminal window:

    git clone https://github.com/ibm-security-verify/webauthn-relying-party-server.git
    

    Modify the config.json to use the client identifier and client secret from the API client created in the previous step.

    The relyingPartyHostname is the Docker host where you'll run the relying party server.

    Below is a sample of config.json.

    {
        "tenantUrl":"https://example.verify.ibm.com",
        "clientSecret":"abc123",
        "clientId":"abc123-a1b2-4567-a1b2-c3d4e5f6", 
        "appName": "Passkey Starter Kit",
        "relyingPartyHostname": "example.com"
    }
    

    Use the starter-kit.py to create the application and a FIDO2 relying party on your tenant.

    Run this command to create the application and a FIDO2 relying party:

    python3 starter-kit.py -f config.json
    

    NOTE: On an MAC M1 pre-fix the Python command as:

    arch -arm64 python3 starter-kit.py -f config.json
    

    The output of starter-kit.py is an .env.env file which can be used to configure the relying party server environment variables. The .env file will be located in the same folder where starter-lit.py is executed from.

Configuring the server

Environment variables

The relying-party-server requires several environment variables to launch.

PLATFORM

The platform flag indicates if the relying party server is IBM Security Verify (ISV) or IBM Security Verify Access (ISVA). For example:

PLATFORM=ISV

AUTH_SESSION

(OPTIONAL) When PLATFORM=ISVA, the AUTH_SESSION allows the relying party server to parse JSON data from the /v1/signin response to generate an authenticated session. The availble values are:

Name Description
EAI Requires the FIDO2 mediator to provide additional credential information in credentialData JSON payload.
TOKEN This is the default value if AUTH_SESSION has not (or an invalid value) been provided. For a token to be returned, it requires the FIDO2 mediator to inject access_token into the responseData element of the JSON payload.
COOKIE Returns the response from the FIDO assertion/result endpoint back to the calling client.

See IBM Security Verify Access FIDO Mediation for more information.


APPLE_APP_SITE_ASSOC

This is a string to represent the JSON for Apple to establish a secure association between domains and your app. The following JSON code represent the contents of a simple association:

{
    "webcredentials":{
        "apps":[
            "ABCDE12345.com.example.app"
        ]
    }
}

The JSON content should be minified when assigned to the environment variable. For example:

APPLE_APP_SITE_ASSOC={"webcredentials":{"apps":["ABCDE12345.com.example.app"]}}

In addition, your iOS mobile app requires an assoicated domain entry that references the relyingPartyHostname. For example:

webcredential:example.com

See Supporting associated domains for more information.

GOOGLE_ASSET_LINKS

This is a string to represent the JSON for Google to associate login credentials between an app and website. The following JSON code represent the contents of a simple assetlink format:

[{
  "relation": ["delegate_permission/common.get_login_creds"],
  "target": {
    "namespace": "web",
    "site": "https://example.com"
  }
 },
 {
  "relation": ["delegate_permission/common.get_login_creds"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example.app",
    "sha256_cert_fingerprints": [
      "DE:AD:BE:EF:****"
    ]
  }
 }]

The JSON content should be minified when assigned to the environment variable. For example:

GOOGLE_ASSET_LINKS=[{"relation":["delegate_permission/common.get_login_creds"],"target":{"namespace":"web","site":"https://example.com"}},{"relation":["delegate_permission/common.get_login_creds"],"target":{"namespace":"android_app","package_name":"com.exampl.app","sha256_cert_fingerprints":["DE:AD:BE:EF:****"]}}]

See Google digital asset links for more information.

FIDO2_RELYING_PARTY_ID

This is the unique identifier (UUID) that is created when the FIDO2 service is created in IBM Security Verify. For example:

FIDO2_RELYING_PARTY_ID=634cd513-dc6a-5e28-06fg-40c3dc81a79e

See Retrieve the list of relying party configurations for more information or Look up Relying Party ID.

API_CLIENT_ID and API_CLIENT_SECRET

This is the unique client identifier and confidential client secret that the relying party server uses internally to establlished an authenticated session with the FIDO2 and factors endpoints. For example:

API_CLIENT_ID=40c3dc81a79e-dc6a-5e28-06fg-634cd513
API_CLIENT_SECRET=a1b2c3d4

See FIDO2 for more information.

AUTH_CLIENT_ID and AUTH_CLIENT_SECRET

This is the unique client identifier and confidential client secret that the relying party server uses internally to establlished an authenticated session with the OIDC token endpoints. For example:

AUTH_CLIENT_ID=40c3dc81a79e-dc6a-5e28-06fg-634cd513
AUTH_CLIENT_SECRET=a1b2c3d4

See Client Credentials for more information.

BASE_URL

The base URL is the fully qualified hostname of your tenant. For example:

BASE_URL=https://example.verify.ibm.com

HTTP_PROXY

(OPTIONAL) Enable proxy requests to the relying party server to be forwarded to host defined by BASE_URL. For example:

HTTP_PROXY=https://proxy.example.verify.ibm.com:8888

NOTE: Authenticated proxy is supported by setting the environment variable as:

HTTP_PROXY=https://username:password@proxy.example.verify.ibm.com:8888

ROOT_CA

(OPTIONAL) Add an additional certificate to the trust store for TLS request validation. For example:

ROOT_CA=t4Ck1jbktkQT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=

NOTE: The ROOT_CA value must be base64 encoded from Privacy Enhanced Mail (PEM) certificate text.

LOG_LEVEL

(OPTIONAL) Output log messages for diagnostic purposes. Below are the acceptable values and descriptions.

Name Description
TRACE Appropriate for messages that contain information normally of use only when tracing the execution of a program.
DEBUG Appropriate for messages that contain information normally of use only when debugging a program.
INFO Appropriate for informational messages.
NOTICE Appropriate for conditions that are not error conditions, but that may require special handling.
WARNING Appropriate for messages that are not error conditions, but more severe than notice.
ERROR Appropriate for error conditions.
CRITICAL Appropriate for critical error conditions that usually require immediate attention.

NOTE: Default is the INFO logging level. When run with the production environment, NOTICE is used to improve performance.

Endpoints

GET /.well-known/apple-app-site-association

Returns the JSON content representing the APPLE_APP_SITE_ASSOC environment variable.

GET /.well-known/assetlinks.json

Returns the JSON content representing the GOOGLE_ASSET_LINKS environment variable.

POST /v1/authenticate

Used when the user has an existing account with a password executing an ROPC request to token endpoint. Below is a sample request payload:

{
    "username": "anne_johnson@icloud.com",
    "password": "a1b2c3d4"
}

If successful, the response format is as follows:

{
    "id_token": "eyJ0eXA.2NDUxMjV9.5Od-8LjVM",
    "token_type": "Bearer",
    "access_token": "6ImNsb3VkSWRlbnRpdHlSZW",
    "expires_in": 604800
}

POST /v1/signup

Allows a new account to be created where ownership of an email is validated. Below is a sample request payload:

{
    "name": "Anne Johnson", 
    "email": "anne_johnson@icloud.com"
}

If successful, the response format is as follows:

{
    "expiry": "2022-11-28T12:26:34Z",
    "correlation": "1719",
    "transactionId": "95f36a22-558a-438b-bdac-1490f279bb0d"
}

POST /v1/validate

Validate the one-time password generated by the signup. Below is a sample request payload:

{
    "transactionId": "95f36a22-558a-438b-bdac-1490f279bb0d",
    "otp": "12345"
}

If successful, the response format is as follows:

{
    "id_token": "eyJ0eXA.2NDUxMjV9.5Od-8LjVM",
    "token_type": "Bearer",
    "access_token": "6ImNsb3VkSWRlbnRpdHlSZW",
    "expires_in": 604800
}

POST /v1/register

Registers a new public-key credential for a user. Below is a sample request payload:

{
    "nickname": "John's iPhone",
    "clientDataJSON": "eyUyBg8Li8GH...",
    "attestationObject": "o2M884Yt0a3B7...",
    "credentialId": "VGhpcyBpcyBh..."
}

If successful, the response status a 201 Created.

The access_token must be presented in the request authorization header. Authenticated session-cookies can also be passed in the request headers. For example:

Authorization: Bearer NLL8EtOJFdbPiwPwZ

A 401 Unauthorized will result otherwise.

POST /v1/challenge

Generates a new challenge to perform a WebAuthn registrations or verifications.

Verification (assertion)

Below is a sample request payload for a assertion (signin):

{
    "type": "assertion"
}

If successful, the response format is a JSON structure based on Web Authentication: An API for assertion generation (PublicKeyCredentialRequestOptions) as follows:

{
    "rpId": "example.com",
    "timeout": 240000,
    "challenge": "3W9xV1-n6Qvvs9y0YrAr5MpNNba8Q9czsGH4hRdGFwk"
}

Registration (attestation)

Below is a sample request payload for an attestation:

{
    "displayName": "Anne's iPhone",
    "type": "attestation"
}

If successful, the response format is a JSON structure based on Web Authentication: An API for credential creation (PublicKeyCredentialCreationOptions) as follows:

{
    "rp": {
        "id": "example.com",
        "name": "IBM Cloud Relying Party"
    },
    "user": {
        "id": "ePGatpTNRBaoHdQ",
        "name": "anne",
        "displayName": "Anne's iPhone"
    },
    "timeout": 240000,
    "challenge": "g9yz-s_rsH4c_ulfLujO96U1wybV_Zut5tQeoKIcmtk",
    "excludeCredentials": [],
    "extensions": {},
    "authenticatorSelection": {},
    "pubKeyCredParams": [
        {
            "alg": -7,
            "type": "public-key"
        },
        {
            "alg": -257,
            "type": "public-key"
        }
    ]
}

The access_token must be presented in the request authorization header. For example:

Authorization: Bearer NLL8EtOJFdbPiwPwZ

A 401 Unauthorized will result otherwise.

POST /v1/signin

Validates a public-key credential for a user with an existing registration. Below is a sample request payload:

{
    "clientDataJSON": "eyUyBg8Li8GH...",
    "authenticatorData": "o2M884Yt0a3B7...",
    "credentialId": "VGhpcyBpcyBh...",
    "signature": "OP84jBpcyB...",
    "userHandle": "ePGatpTNR..."
}

If successful, the response format is as follows:

{
    "id_token": "eyJ0eXA.2NDUxMjV9.5Od-8LjVM",
    "token_type": "Bearer",
    "access_token": "6ImNsb3VkSWRlbnRpdHlSZW",
    "expires_in": 604800
}

The access_token can be used to make requests to other custom endpoints in the relying party server project.

Deploying the server

Vapor supports several deployment options. The relying-party-server includes a dockerfile to build an image via docker-compose build. For alternate hosting, refer to the Vapor Docs.

License

This package contains code licensed under the MIT License (the "License"). You may view the License in the LICENSE file within this package.

About

The IBM Security Verify WebAuthn Relying Party Server for Swift exposes endpoints that proxies OAuth and FIDO2 requests to IBM Security Verify from web and mobile clients.

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages