Contents

ibm-verify/verify-webauthn-rp-server-swift

The IBM Verify WebAuthn Relying Party Server for Swift is based on the [Vapor](https://vapor.codes) framework and exposes endpoints that proxies OAuth and FIDO2 requests to IBM Verify from web and mobile clients.

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 Verify (ISV) or IBM 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 Verify Access FIDO Mediation](https://www.ibm.com/docs/en/sva/10.0.0?topic=support-fido2-mediation) for more information.

<br/>


#### `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](https://developer.apple.com/documentation/xcode/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](https://developers.google.com/digital-asset-links/v1/getting-started) for more information.



#### `FIDO2_RELYING_PARTY_ID`

This is the unique identifier (UUID) that is created when the FIDO2 service is created in IBM Verify.  For example:
```
FIDO2_RELYING_PARTY_ID=634cd513-dc6a-5e28-06fg-40c3dc81a79e
```

See [Retrieve the list of relying party configurations](https://docs.verify.ibm.com/verify/reference/list_3-2) for more information or [Look up Relying Party ID](https://docs.verify.ibm.com/verify/docs/fido2-login#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](https://docs.verify.ibm.com/verify/docs/fido2-login) 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](https://docs.verify.ibm.com/verify/docs/get-an-access-token) 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)](https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dictionary-assertion-options) 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)](https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dictionary-makecredentialoptions) 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.

Package Metadata

Repository: ibm-verify/verify-webauthn-rp-server-swift

Default branch: main

README: README.md