# Authenticating Users

{% hint style="info" %}
Currently, Hyphen only supports [**Firebase Auth**](https://firebase.google.com/docs/auth) for OAuth 2.0 Provider. To add your own provider, please get in touch with us!&#x20;
{% endhint %}

## Process

1. **Request Firebase Auth to the user.** The client will get a Firebase ID token.&#x20;
2. In the client, **check that&#x20;*****the device key*****&#x20;exists on the keystore.**
   1. If It does, go to [**A. Signing In with Challenge**](#a.-signing-in-with-challenge)
   2. Else, go to [**B. Signing In with 2FA.**](#b.-signing-in-with-2fa)

### A. Signing In with Challenge

1. **Call Auth Request Challenge API.** The client needs to send a request with the device's public key and the Firebase ID token.&#x20;
   1. If HTTP 200 -> The server will respond with random challenge data. Go to A.2.
   2. If HTTP 400 with `PleaseSignUp` -> Go to [**C. Creating an Account.**](#c.-creating-an-account)

{% openapi src="/files/fga64SW2USHfQ96R2eO1" path="/auth/v1/signin/challenge" method="post" %}
[swagger.json](https://2622738714-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoXzDQclFMZX61nsrgiVE%2Fuploads%2FeAwTMXbA20yh1IgDdtbC%2Fswagger.json?alt=media\&token=a0c57374-3eaa-4701-a283-21b37d0bec21)
{% endopenapi %}

2. **Sign the Challenge Data with the Device Key**. The client should request the device keystore to sign the challenge data received from the server. The data is hex-encoded but don't decode the hex before signing it— just sign the UTF-8 binary data directly.\
   \
   The signature should be ECDSA P-256 signature with SHA2-256 digest, encoded in [IEEE P.1363](https://datatracker.ietf.org/doc/draft-ietf-httpbis-message-signatures/) format (a.k.a. r||s concat format).
3. **Call Auth Finish SignIn Challenge API**. Send the signature along with the original challenge data. The signature should be encoded in a hex string.
   1. If HTTP 200 -> Go to [**D. Finishing Authorization**](#d.-finishing-authorization)
   2. If HTTP 400 with PleaseDeploy: The account contract needs to be set up on the chain you're using.

{% openapi src="/files/fga64SW2USHfQ96R2eO1" path="/auth/v1/signin/challenge/respond" method="post" %}
[swagger.json](https://2622738714-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoXzDQclFMZX61nsrgiVE%2Fuploads%2FeAwTMXbA20yh1IgDdtbC%2Fswagger.json?alt=media\&token=a0c57374-3eaa-4701-a283-21b37d0bec21)
{% endopenapi %}

### B. Signing In with 2FA

On the source device (i.e. who currently tries to sign in), It should request 2FA Sign-in.

1. **Generate a Device Key**. The device key needs to be stored on the device's HSM keystore, such as Secure Enclave or Android Keystore. The keypair should be ECDSA with P-256 (secp256p1) curve.
2. **Call Auth Request 2FA API**: Send a request with the device registration data, including the public key generated in the previous step and the push token of the device.
   * If HTTP 200 -> The server will respond with the 2FA request data. A push will be sent on the random device registered on the user's account.

{% openapi src="/files/fga64SW2USHfQ96R2eO1" path="/auth/v1/signin/2fa" method="post" %}
[swagger.json](https://2622738714-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoXzDQclFMZX61nsrgiVE%2Fuploads%2FeAwTMXbA20yh1IgDdtbC%2Fswagger.json?alt=media\&token=a0c57374-3eaa-4701-a283-21b37d0bec21)
{% endopenapi %}

On the other device which is selected for 2FA target, it should receive a Firebase push with the 2FA request data.

1. **Request user's approval**: Make sure that the client is displaying enough information for the user to know about the request.
   1. If approves -> Go to step 2.
   2. If denies -> **Call Deny 2FA request API** to cancel the request.
2. **Send the transaction in the request using the device key.**
3. **Sign the payload in the request using the device key.** Note that the payload is hex-encoded, so you need to decode it before signing it.
4. **Call Approve 2FA request API**: with the signature.
5. Close the screen.

Now go back to the source device. It will receive a foreground data push as the status changes.

1. **Receive the silent push: `2fa-status-update`.**
   1. If approved -> a transaction ID, credentials, and account info will be given. Go to step 2.
   2. If denied -> Show the user an error message that the other device rejected the request.
2. **Wait for the transaction ID to confirm**. The transaction registers your new key to the account.&#x20;
3. **Go to** [**D. Finishing Authorization.**](#d.-finishing-authorization)

{% openapi src="/files/fga64SW2USHfQ96R2eO1" path="/auth/v1/signin/2fa/finish" method="post" %}
[swagger.json](https://2622738714-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoXzDQclFMZX61nsrgiVE%2Fuploads%2FeAwTMXbA20yh1IgDdtbC%2Fswagger.json?alt=media\&token=a0c57374-3eaa-4701-a283-21b37d0bec21)
{% endopenapi %}

### C. Creating an Account&#x20;

1. **Generate a Device Key**. The device key needs to be stored on the device's HSM keystore, such as Secure Enclave or Android Keystore. The keypair should be ECDSA with P-256 (secp256p1) curve.
2. **Call Sign Up API**. Send a request with the device registration data, including the public key generated in the previous step and the push token of the device.
   * *If HTTP 200* -> Go to [**D. Finishing Authorization**](broken://pages/kmnbaEaCk5zv3iVEdcqM)
   * *If HTTP 400* with PleaseDeploy: The account contract needs to be set up on the chain you're using.

{% openapi src="/files/fga64SW2USHfQ96R2eO1" path="/auth/v1/signup" method="post" %}
[swagger.json](https://2622738714-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoXzDQclFMZX61nsrgiVE%2Fuploads%2FeAwTMXbA20yh1IgDdtbC%2Fswagger.json?alt=media\&token=a0c57374-3eaa-4701-a283-21b37d0bec21)
{% endopenapi %}

### D. Finishing Authorization

1. The server will respond with the credentials and account info.
2. **Store the credential data in the local storage**. The credential object consists of a JWT access token and a refresh token.

All done! The client can redirect the user to the home screen of your application.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.hyphen.at/without-using-sdk/authenticating-users.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
