--- id: auth title: Auth API sidebar_label: Auth description: Authentication portion of the Standard Notes API. keywords: - standard notes - docs - notes app - end-to-end encryption - sync image: /img/logo.png hide_title: false hide_table_of_contents: false --- ### POST /auth **Registers a new user** | | | | |-------------|---------|---------------------------------------------------------------------------------------------------------------------| | api | `string` | The API version to use. Must not be null, otherwise oldest API version used. Latest value is "20200115" | | created | `string` | Integer timestamp representing the date the client generated the account's encryption keys. Example "1622494310383" | | email | `string` | The account email. | | ephemeral | `boolean` | Whether the initial session created for this account is ephemeral ("Stay signed in" unchecked). | | identifier | `string` | Should equal the account email. | | origination | `string` | Should equal "registration" | | password | `string` | The server password generated by the client from the user's master password. | | pw_nonce | `string` | The nonce generated by the client for the user's encryption key. | | version | `string` | The protocol version the client used to generate the user's encryption key. Latest is "004". | #### Response ```JSON { "session": { "access_token": "1:457b1f4b-88c2-4328-bf32-fe7dd9431d62:WwKgTEDUoEhxECu6", "refresh_token": "1:457b1f4b-88c2-4328-bf32-fe7dd9431d62:G-qEoZsFtoj~RLL-", "access_expiration": 1627678312000, "refresh_expiration": 1654051238000 }, "key_params": { "created": "1622494310383", "identifier": "foo@example.com", "origination": "registration", "pw_nonce": "d97ed41c581fe8c3e0dce7d2ee72afcb63f9f461ae875bae66e30ecf3d952900", "version": "004" }, "user": { "uuid": "682f9deb-b75f-4d97-91fa-6fd82a482db1", "email": "foo@example.com" } } ``` ### POST /auth/sign_in **Authenticates a user and returns a session.** | | | | |-------------|---------|---------------------------------------------------------------------------------------------------------------------| | api | `string` | The API version to use. Must not be null, otherwise oldest API version used. Latest value is "20200115" | | email | `string` | The account email. | | ephemeral | `boolean` | Whether the session created for this account is ephemeral ("Stay signed in" unchecked). | | password | `string` | The server password generated by the client from the user's master password. | #### Response ```JSON { "session": { "access_token": "1:ee03808d-dd05-417c-9c87-d471e49bcc49:Q~-UoIpDhdtkii_t", "refresh_token": "1:ee03808d-dd05-417c-9c87-d471e49bcc49:Jn8UWzeHx2H5nZI5", "access_expiration": 1627678779000, "refresh_expiration": 1654051705000 }, "key_params": { "created": "1622494310383", "identifier": "foo@example.com", "origination": "registration", "pw_nonce": "d97ed41c581fe8c3e0dce7d2ee72afcb63f9f461ae875bae66e30ecf3d952900", "version": "004" }, "user": { "uuid": "682f9deb-b75f-4d97-91fa-6fd82a482db1", "email": "foo@example.com" } } ``` ### GET /auth/params **Queries the parameters used for key generation for an email address. Queried before signing into an account.** | | | | |-------------|---------|---------------------------------------------------------------------------------------------------------------------| | api | `string` | The API version to use. Must not be null, otherwise oldest API version used. Latest value is "20200115" | | email | `string` | The account email. | #### Response ```JSON { "identifier": "foo@example.com", "pw_nonce": "d97ed41c581fe8c3e0dce7d2ee72afcb63f9f461ae875bae66e30ecf3d952900", "version": "004" } ``` ### POST /auth/change_pw **Changes a user's password.** | | | | |-------------|---------|---------------------------------------------------------------------------------------------------------------------| | api | `string` | The API version to use. Must not be null, otherwise oldest API version used. Latest value is "20200115" | | created | `string` | Integer timestamp representing the date the client generated the account's new encryption keys. Example "1622494310383" | | identifier | `string` | The account email. | | origination | `string` | Should equal "password-change" | | current_password | `string` | The old server password generated by the client from the user's master password. | | new_password | `string` | The new server password generated by the client from the user's master password. | | pw_nonce | `string` | The nonce generated by the client for the user's encryption key. | | version | `string` | The protocol version the client used to generate the user's encryption key. Latest is "004". | #### Response ```JSON { "session": { "access_token": "1:27d4fd8f-b730-4e0a-afd3-1600fb466aaa:HMgmZwV5k5ePt0vj", "refresh_token": "1:27d4fd8f-b730-4e0a-afd3-1600fb466aaa:wHuTeOB-qWGP3AE3", "access_expiration": 1627679129000, "refresh_expiration": 1654052055000 }, "key_params": { "created": "1622494310383", "identifier": "foo@example.com", "origination": "password-change", "pw_nonce": "be1974ff6fb1c541aa8c71fd3c66851b6492cf224b661c72daf44e0bef3096bb", "version": "004" }, "user": { "uuid": "682f9deb-b75f-4d97-91fa-6fd82a482db1", "email": "foo@example.com" } } ``` ## Sessions ### Session Model | Field | Type | Description | |----------------|-----------|---------------------------------------------------| | uuid | `string` | Unique identifier of the session | | user_uuid | `string` | Unique identifier of the user | | user_agent | `string` | The user agent used to create the session | | api_version | `string` | The server API version used to create the session | | access_token | `string` | The access token used to authenticate requests | | refresh_token | `string` | The refresh token used to extend tokens | | access_expiration | `datetime` | The expiration time of the access token | | refresh_expiration | `datetime` | The expiration time of the refresh token | | created_at | `datetime` | Date and time of creation of the session | | updated_at | `datetime` | Last updated date and time of the session | - Each `session` includes the API version they were created with. This way we can deny sessions for a given API version if we detect a vulnerability with that version in the future - Sessions are created in the following cases: - When a user signs in - When a user registers a new account --- ### Authenticated requests The `Authorization` request header field is used by clients to make authenticated request. `Bearer` is the only authentication scheme allowed. The client must send the `access` token generated by the session, in the `Authorization` header. For example: ``` GET /sessions HTTP/1.1 Host: sync.standardnotes.org Authorization: Bearer ``` --- Below is a list of endpoints related to session management: | Method | URL | Params | Description | Successful response code | |-----------|--------------------------|---------------------|--------------------------------------------------------|--------------------------| |`POST` | /auth/sign_out | *None* | Terminates the current session | `204` | |`DELETE` | /session | **uuid** | Terminates the specified session by UUID | `204` | |`DELETE` | /sessions | *None* | Terminates all sessions, except the current one | `204` | |`GET` | /sessions | *None* | Lists all sessions active sessions | `200` | |`POST` | /session/token/refresh | **refresh_token** | Obtains new pair of `access_token` and `refresh_token` | `200` | A successful request to `GET /sessions` returns the following JSON response: ```json { "sessions": [ { "uuid": "xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx", "user_agent": " / ", "api_version": "xxxxyyzz", "current": "", "created_at": "2020-01-01T00:00:00.000Z" } ... ] } ``` #### Obtaining tokens Tokens can be obtained every time the user performs any of the following actions: 1. When a user signs in 1. When a user registers an account 1. When the tokens are refreshed #### Refreshing tokens When an expired `access_token` is provided in the `Authorization` HTTP header, the following JSON response is returned: HTTP Status Code: `498 Expired Access Token` ```json { "error": { "tag": "expired-access-token", "message": "The provided access token has expired." } } ``` To continue accessing resources, the `access_token` must be refreshed. That is, the current `access_token` is replaced with a new one with an extended expiration date. To refresh an `access_token`, a valid `refresh_token` is needed. This `refresh_token` must meet the following requirements: - It should belong to the session of the `access_token` - It should not be expired Since the `refresh_token` is of single-use, a new `refresh_token` is obtained when the `access_token` is refreshed. Refreshing tokens is a process that is transparent to the user, meaning that the client will perform the requests to keep valid tokens without user intervention. Here's how to refresh tokens: 1. Send a `POST` request to `/session/token/refresh`. The body should contain a JSON paylaod with the `refresh_token`: ``` POST /session/token/refresh HTTP/1.1 Host: sync.standardnotes.org Authorization: Bearer { "refresh_token": "R_xxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx" } ``` 1. The `refresh_token` is validated on the server. Depending of the circumstances, there should be two outcomes: 1. The provided `refresh_token` is valid. If so, a new pair of tokens is generated and the following JSON response is returned: ```json { "token": "xxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx", "session": { "refresh_expiration": 1583020800, "refresh_token": "xxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx", } } ``` 1. The provided `refresh_token` is expired. If so, the following JSON response is returned: HTTP Status Code: `400 Bad Request` ```json { "error": { "tag": "expired-refresh-token", "message": "The refresh token has expired." } } ``` User must start a new session by re-entering their credentials. ### Expiration #### Sessions Sessions should be terminated after a period of inactivity. This is for best security practices. `Long-lived sessions` are a good choice for our use case, because it can build a better user experience than expiring sessions for a short idle-timeout. - A `session` that remains inactive for `1 year` will be terminated, along with all `tokens` #### Tokens | Name | Type | Expiration | |-----------|-------------|---------------| | `access` | Short-lived | `60 days` | | `refresh` | Long-lived | `1 year` | - A `refresh` token is of single-use, while an `access` token can be used as long as it is not expired