1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
|
# meta.sr.ht OAuth API
Authentication with all sr.ht services is done with OAuth and is governed by
meta.sr.ht.
# Supported authentication profiles
There are various ways, in order of complexity and flexibility, of
authenticating with the APIs around sr.ht. Your goal is to obtain an **access
token**, which can be used to authenticate with sr.ht APIs.
## Personal Access Tokens
The easiest and fastest way to authenticate with sr.ht is to [create a personal
access token](https://meta.sr.ht/oauth/personal-token). This token will have
unrestricted access to all sr.ht APIs and can be used like a normal access token
to authenticate API requests (see [Authenticating API
requests](#authenticating-api-requests)).
**Warning**: do not give your personal access tokens to third parties. Any third
party which encourages you to give them a personal access token should instead
develop an OAuth client as described in the next section.
## OAuth Clients
Personal access tokens are suitable for authenticating yourself, but if you
intend to provide software that other sr.ht users can log into, you should
[create an OAuth client](https://meta.sr.ht/oauth/register) instead. The OAuth
flow allows end-users to grant your client only the privileges it requires to
execute its duties and to revoke this access at any time. This is accomplished
through an **OAuth exchange**:
1. Direct the user (in a web browser) to a special page on meta.sr.ht where we
present them with the permissions you're asking for and they provide consent.
2. The user is redirected back to your application's **base redirect URI**. We
will add an **exchange token** to the query string.
3. Your application sends an HTTP request directly to meta.sr.ht using this
exchange token and your client credentials to obtain an access token.
To this end, you need to have an HTTP server running somewhere (`localhost` is
suitable for testing) that the user can be redirected to upon consenting to the
permissions you requested. Decide on a URL we can redirect the user to in your
application, and fill out the base redirect URI accordingly.
Upon submitting the form, your **client ID** and **client secret** will be shown
to you. **Record your client secret now**. It will not be shown to you again.
### The OAuth consent page
To start the exchange, direct the user to the following URL:
https://meta.sr.ht/oauth/authorize
Provide the following parameters in the query string:
<dl>
<dt>client_id</dt>
<dd>The client ID assigned to you in the previous step.</dd>
<dt>scopes</dt>
<dd>A list of scopes you're requesting - see next section.</dd>
<dt>state</dt>
<dd>Optional: an arbitrary string - see notes.</dd>
<dt>redirect_uri</dt>
<dd>Optional: your application URI for redirect the user to - see notes.</dd>
</dl>
The optional `state` field is returned to you after the redirect. One example
use-case of this field is generating a token before directing the user to the
authorization page and validating it after the redirect, to prevent users from
initiating the OAuth flow without you. Most users don't need to worry about
this.
The optional `redirect_uri` field can allow you to specify a route more precise
than the base URI affords, for example to include a user ID. The `redirect_uri`
must begin with the `base_uri`.
### OAuth scopes
API endpoints on sr.ht generally require an access token valid for a specific
*scope* to be used. This allows you to only request access to the subset of the
API that you require. Scopes are written with the following notation(s):
name
name:access
service/name:access
`name` is the name of the OAuth scope, which is documented alongside the API
endpoints which require it (e.g. `/api/user/profile` requires the `profile`
scope). `access` is either `read` or `write`, and may be omitted (default:
`read`). `service` is the name of the service for which the scope is applicable.
If omitted, the default is `meta.sr.ht`. The following services are also
recognized:
- `git.sr.ht`
- `builds.sr.ht`
- `todo.sr.ht`
- `lists.sr.ht`
- `man.sr.ht`
- `dispatch.sr.ht`
### The application redirect
Once the user consents, they will be redirected to your `redirect_uri`, or the
`base_uri` for your client if unspecified. We will update your redirect URI with
some additional query string parameters you can use for the next steps:
<dl>
<dt>exchange</dt>
<dd>An exchange token you can use to obtain an access token in the next step.</dd>
<dt>scopes</dt>
<dd>The list of OAuth scopes the user consented to.</dd>
<dt>error</dt>
<dd>If present, indicates that an error occurred in the process - see notes.</dd>
<dt>details</dt>
<dd>If present, a human friendly error string, if that human is an engineer.</dd>
</dl>
Possible values for `error`:
- `invalid_redirect`
- `invalid_scope`
- `user_declined`
**Important**: the user is able to **edit** the scopes you've requested before
consenting. You must handle the case where the scopes returned in the redirect
do not match the scopes you requested.
### Obtaining an access token
Once your application retrieves the exchange token from the redirect, you can
submit an HTTP POST request to `https://meta.sr.ht/oauth/exchange`. The request
body should be `application/json` and include the following parameters:
<dl>
<dt>client_id</dt>
<dd>The client ID assigned to you when you registered the application.</dd>
<dt>client_secret</dt>
<dd>The client secret assigned to you when you registered the application.</dd>
<dt>exchange</dt>
<dd>The exchange token issued in the previous step.</dd>
</dl>
You will receive a response like this:
```json
{
"token": "your access token",
"expires": "%Y-%m-%dT%H:%M:%S"
}
```
You can now use this token for [Authenticating API
requests](#authenticating-api-requests).
# Authenticating API requests
Authenticating your API request is simple once you have an access token. You
just need to set the `Authorization` header to `token your-access-token`. For
example:
curl \
-H Authorization:'token your-access-token' \
https://meta.sr.ht/api/user/profile
# OAuth Maintenance
meta.sr.ht offers several resources for ongoing maintenance of an OAuth client
and its access tokens.
## Refreshing access tokens
TODO
## Rotating your client secret
On the security tab of your OAuth client's dashboard (which can be accessed from
the [OAuth summary on your account](https://meta.sr.ht/oauth)), you can rotate
your client secret, in the event that it is compromised.
## Revoking access tokens
On the security tab of your OAuth client's dashboard (which can be accessed from
the [OAuth summary on your account](https://meta.sr.ht/oauth)), you can revoke
all issued access tokens at once, in the event some or all of them are
compromised. Users will have to repeat the authorization flow.
|