Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PARTNER-275] Add Authorization header for SEP-10 GET /Auth #1470

Merged
merged 12 commits into from
Mar 28, 2024
112 changes: 109 additions & 3 deletions ecosystem/sep-0010.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ Title: Stellar Web Authentication
Author: Sergey Nebolsin <@nebolsin>, Tom Quisel <tom.quisel@gmail.com>, Leigh McCulloch <@leighmcculloch>, Jake Urban <jake@stellar.org>
Status: Active
Created: 2018-07-31
Updated: 2022-04-22
Version: 3.3.2
Updated: 2024-03-20
Version: 3.4.0
```

## Simple Summary
Expand Down Expand Up @@ -139,7 +139,79 @@ operation of the challenge is the **Home Domain**, and that the web auth domain
GET <WEB_AUTH_ENDPOINT>
```

Request Parameters:
##### Request Header:

Optionally, the server may forbid unauthorized calls to `GET <WEB_AUTH_ENDPOINT>`. This could be done to protect an
endpoint against bad actors or limit access only to allowed applications.

In that case, the client must add an `Authorization` header, and the server should respond to all requests with missing
header with an error (see below). Server may choose to only accept calls from trusted applications, responding with an
error to all other requests (see below).

Authorized `WEB_AUTH_ENDPOINT` accepts `Authorization Bearer: <token>`, where token is [JSON Web Token](https://jwt.io/)
authorizing the request.

Client must specify the following claims:

- `iat` (the time at which the JWT was issued
[RFC7519, Section 4.1.6](https://tools.ietf.org/html/rfc7519#section-4.1.6)) — current timestamp (for example
`1530644093`)
- `exp` (the expiration time on or after which the JWT must not be accepted for processing,
[RFC7519, Section 4.1.4](https://tools.ietf.org/html/rfc7519#section-4.1.4))
- `web_auth_endpoint` - should match the auth endpoint (`<WEB_AUTH_ENDPOINT>`)
- All request's parameters (if specified in the request)
JakeUrban marked this conversation as resolved.
Show resolved Hide resolved

Client must then correctly sign the payload with appropriate Stellar private key. To choose the private key client
application should follow this steps:

- If `client_domain` is specified, the token must be signed with the **Client Domain Account** (i.e. [SEP-1] defined
`SIGNING_KEY`). (See [Verifying the Client Domain](#verifying-the-client-domain) section for more information)
- Otherwise, the token must be signed with a private key of the **Client Account** passed in the `account` field.

Token then should be signed with the selected private key, using **ed25519** algorithm. An appropriate header must be
included

```json
{
"alg": "EdDSA"
}
```

Example of the valid signed token in base64 format:

```
eyJhbGciOiJFZERTQSJ9.eyJpYXQiOjE3MTE2NDg0ODYsImV4cCI6MTcxMTY0OTM4NiwiYWNjb3VudCI6IkdDNlVDWFZUQU1ORzVKTE9NWkJTQ05ZWFZTTk5GSEwyM1NKUFlPT0ZKRTJBVllERFMyRkZUNDVDIiwiY2xpZW50X2RvbWFpbiI6ImV4YW1wbGUtd2FsbGV0LnN0ZWxsYXIub3JnIiwid2ViX2F1dGhfZW5kcG9pbnQiOiJodHRwczovL2V4YW1wbGUuY29tL3NlcDEwL2F1dGgifQ.UQt8FpUK-BlnFw35o8Ke4GDOoCrMe9ztEx4_TGQ06XhMgUbn_b7EMPMVLWJ8RRNgSk2dNhyGUgIbhKzKtWtBBw
```

This token was issued for the request URL
`https://example.com/sep10/auth?account=GC6UCXVTAMNG5JLOMZBSCNYXVSNNFHL23SJPYOOFJE2AVYDDS2FFT45C&client_domain=example-wallet.stellar.org`
and signed with the `GCADAIACE6CRWGOB3HJRXIOHMQEUKPNLAUIYFIE26F3OK72RSHGAMARK` key, belonging to a hypothetical domain
`example-wallet.stellar.org`

Another example of the valid signed token:

```
eyJhbGciOiJFZERTQSJ9.eyJpYXQiOjE3MTE2NDg0MjIsImV4cCI6MTcxMTY0OTMyMiwiYWNjb3VudCI6IkdDWFhINkFZSlVWVERHSUhUNDJPWk5NRjNMSENWNERPS0NYNkhIREtXRUNVWllYRFpTV1pONkhTIiwibWVtbyI6IjEyMzQ1NjciLCJ3ZWJfYXV0aF9lbmRwb2ludCI6Imh0dHBzOi8vZXhhbXBsZS5jb20vc2VwMTAvYXV0aCJ9.23TJFUWtadeNWW0N1mjk4gWUZJRTOnrxfs3gahNRuhrKHRbHonrksri6lzJdIvO71a_Ad851necSO6TTXB_IBw
```

The token was issued for the request URL
`https://example.com/sep10/auth?account=GCXXH6AYJUVTDGIHT42OZNMF3LHCV4DOKCX6HHDKWECUZYXDZSWZN6HS&memo=1234567`. This
time the token is signed with a **Client Account** () private key

##### Verifying request header

When server receives a request with an `Authorization` header, server should validate the token before processing with
issuing a challenge transaction.
First, server must use the same steps of choosing the public key (see above), and verify **ed25519** signature of the
token. Next, server must verify JWT claims:

1. `web_auth_endpoint` must match `<WEB_AUTH_ENDPOINT>`
2. Query parameters from claims must match request's parameters.

If `client_domain` is provided in the request, but the Server doesn't support `client_domain` verification, Server
should respond with an error.

##### Request Parameters:

| Name | Type | Description |
| --------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
Expand All @@ -156,6 +228,8 @@ GET https://auth.example.com/?account=GCIBUCGPOHWMMMFPFTDWBSVHQRT4DIBJ7AD6BZJYDI

#### Response

##### Success

On success the endpoint must return `200 OK` HTTP status code and a JSON object with these fields:

- `transaction`: an XDR-encoded Stellar transaction with the following:
Expand Down Expand Up @@ -196,6 +270,8 @@ Example:
You can examine the example challenge transaction in the
[XDR Viewer](https://laboratory.stellar.org/#xdr-viewer?input=AAAAAgAAAADIiRu2BrqqeOcP28PWCkD4D5Rjjsqh71HwvqFX%2BF4VXAAAAGQAAAAAAAAAAAAAAAEAAAAAXzrUcQAAAABfOtf1AAAAAAAAAAEAAAABAAAAAEEB8rhqNa70RYjaNnF1ARE2CbL50iR9HPXST%2FfImJN1AAAACgAAADB0aGlzaXNhdGVzdC5zYW5kYm94LmFuY2hvci5hbmNob3Jkb21haW4uY29tIGF1dGgAAAABAAAAQGdGOFlIQm1zaGpEWEY0L0VJUFZucGVlRkxVTDY2V0tKMVBPYXZuUVVBNjBoL09XaC91M2Vvdk54WFJtSTAvQ2UAAAAAAAAAAfheFVwAAABAheKE1HjGnUCNwPbX8mz7CqotShKbA%2BxM2Hbjl6X0TBpEprVOUVjA6lqMJ1j62vrxn1mF3eJzsLa9s9hRofG3Ag%3D%3D&type=TransactionEnvelope)

##### Error

Every other HTTP status code will be considered an error. For example:

```json
Expand All @@ -204,6 +280,33 @@ Every other HTTP status code will be considered an error. For example:
}
```

When authorization header is required by the server, but is not provided in the request, the anchor should return status
code 401 (Unauthorized) and return comprehensive error message in the response body. For example:

```json
{
"error": "Missing authorization header"
}
```

When authorization header is invalid, status code 400 (Bad Request) should be returned, explaining why header is
invalid.

```json
{
"error": "Provided authorization JWT has been expired"
}
```

Finally, when authorization header is valid, but the server does not allow the application to use the endpoint, status
code 403 (Forbidden) should be returned,

```json
{
"error": "Application example-wallet.stellar.org is not allowed to authenticate."
}
```

### Token

This endpoint accepts a signed challenge transaction, validates it and responds with a session
Expand Down Expand Up @@ -445,6 +548,7 @@ When generating and validating JWTs it's important to follow best practices. The
of best current practices when using JWTs: [IETF JWT BCP].

[IETF JWT BCP]: https://tools.ietf.org/wg/oauth/draft-ietf-oauth-jwt-bcp/
[SEP-1]: sep-0001.md

## Implementations

Expand All @@ -454,5 +558,7 @@ of best current practices when using JWTs: [IETF JWT BCP].

## Changelog

- `v3.4.0`: Add Authorization header for `GET <WEB_AUTH_ENDPOINT>`
([#1470](https://github.com/stellar/stellar-protocol/pull/1470))
- `v3.3.2`: Fixed formatting of markdown section headers.
([1175](https://github.com/stellar/stellar-protocol/pull/1175))
Loading