Merge lp:~cjwatson/canonical-identity-provider/doc-macaroons into lp:canonical-identity-provider/release

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: no longer in the source branch.
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: lp:~cjwatson/canonical-identity-provider/doc-macaroons
Merge into: lp:canonical-identity-provider/release
Diff against target: 311 lines (+289/-1)
1 file modified
docs/resources/token.txt (+289/-1)
To merge this branch: bzr merge lp:~cjwatson/canonical-identity-provider/doc-macaroons
Reviewer Review Type Date Requested Status
Matias Bordese (community) Approve
Review via email: mp+344886@code.launchpad.net

Commit message

Document macaroon API endpoints.

To post a comment you must log in.
Revision history for this message
Matias Bordese (matiasb) wrote :

LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'docs/resources/token.txt'
2--- docs/resources/token.txt 2013-12-04 13:49:39 +0000
3+++ docs/resources/token.txt 2018-05-01 12:22:58 +0000
4@@ -11,6 +11,7 @@
5
6 * :ref:`OAuth token <token_oauth>`
7 * :ref:`Password reset token <token_password>`
8+* :ref:`Macaroon <macaroon>`
9
10
11 .. _token_oauth:
12@@ -71,7 +72,7 @@
13 existing token will be returned (status code 200) instead of a new one being
14 created (status code 201).
15
16-If an otp (one-time-password) is provided then it will checked against any
17+If an otp (one-time-password) is provided then it will be checked against any
18 two factor devices registered for the account. If the otp does not match any
19 devices then a 403 will be returned.
20
21@@ -338,3 +339,290 @@
22 "message": "Too many non-consumed tokens exist. Further token creation is not allowed until existing tokens are consumed.",
23 "extra": {}
24 }
25+
26+
27+.. _macaroon:
28+
29+========
30+Macaroon
31+========
32+
33+A `macaroon` is a bearer token with fine-grained constraints. See the
34+`original paper <https://research.google.com/pubs/pub41892.html>`_ for
35+details.
36+
37+Ubuntu SSO issues discharge macaroons, which can be bound to macaroons
38+issued by other cooperating services to prove the user's identity.
39+
40+Use cases
41+=========
42+
43+.. _macaroon_discharge:
44+
45+Issue a discharge macaroon
46+--------------------------
47+
48+.. http:post:: /api/v2/tokens/discharge
49+
50+ Issues a new discharge macaroon
51+
52+ :form email: user's email address
53+ :form password: user's password
54+ :form caveat_id: the caveat ID addressed to Ubuntu SSO from the macaroon that is to be discharged
55+ :form otp: one-time password (optional)
56+
57+ :status 200: macaroon issued
58+ :status 400: invalid request data
59+ :status 401: invalid credentials or otp password required
60+ :status 403: invalid otp provided
61+ :status 403: account is suspended or inactive
62+ :status 403: email invalidated
63+ :status 403: password does not meet security constraints
64+
65+The service that issued the macaroon that this discharge is to be bound to
66+should have included a caveat in that macaroon addressed to Ubuntu SSO. To
67+issue an appropriate discharge macaroon, the caller must extract the ID of
68+this caveat. This can be done in Python as follows:
69+
70+.. code-block:: python
71+
72+ from pymacaroons import Macaroon
73+
74+ def extract_caveat_id(macaroon_raw):
75+ macaroon = Macaroon.deserialize(macaroon_raw)
76+ for caveat in macaroon.caveats:
77+ if caveat.location == 'login.ubuntu.com':
78+ return caveat.caveat_id
79+ else:
80+ raise ValueError('No login.ubuntu.com caveat found')
81+
82+If an otp (one-time-password) is provided then it will be checked against any
83+two factor devices registered for the account. If the otp does not match any
84+devices then a 403 will be returned.
85+
86+If an otp is required for the account, but not sent, then a 401 will be
87+returned.
88+
89+
90+Errors
91+......
92+
93+* **INVALID_CREDENTIALS**: Provided email/password is not correct.
94+
95+ Error status code 401.
96+
97+ This error has no additional fields in ``extra``.
98+
99+* **ACCOUNT_SUSPENDED**: Account has been suspended.
100+
101+ Error status code 403.
102+
103+ This error has no additional fields in ``extra``.
104+
105+* **ACCOUNT_DEACTIVATED**: Account has been deactivated.
106+
107+ Error status code 403.
108+
109+ This error has no additional fields in ``extra``.
110+
111+* **EMAIL_INVALIDATED**: This email address has been invalidated.
112+
113+ Error status code 403.
114+
115+ This error has no additional fields in ``extra``.
116+
117+* **TWOFACTOR_REQUIRED**: 2-factor authentication required.
118+
119+ Error status code 401.
120+
121+ This error has no additional fields in ``extra``.
122+
123+* **TWOFACTOR_FAILURE**: The provided 2-factor key is not recognised.
124+
125+ Error status code 403.
126+
127+ This error has no additional fields in ``extra``.
128+
129+* **PASSWORD_POLICY_ERROR**: The user's password doesn't comply with the
130+ security constraints in force for the account. It must be reset via the
131+ web.
132+
133+ Error status code 403.
134+
135+ The ``extra`` field includes:
136+
137+ - ``location``: the domain to visit via the web to reset the password
138+
139+ - ``reason``: the reason why the password doesn't comply with the policy
140+
141+* **TOO_MANY_REQUESTS**: Too many requests from the same IP address.
142+
143+ Error status code 429.
144+
145+ This error has no additional fields in ``extra``.
146+
147+
148+Examples
149+........
150+
151+**Request**:
152+
153+.. sourcecode:: http
154+
155+ POST /api/v2/tokens/discharge HTTP/1.1
156+ Host: login.ubuntu.com
157+ Accept: application/json
158+ Content-Type: application/json
159+
160+ {
161+ "email": "foo@example.com",
162+ "password": "thepassword",
163+ "caveat_id": "{\"secret\": \"thesecret\", \"version\": 1}"
164+ }
165+
166+If 2-factor authentication is required:
167+
168+.. sourcecode:: http
169+
170+ POST /api/v2/tokens/discharge HTTP/1.1
171+ Host: login.ubuntu.com
172+ Accept: application/json
173+ Content-Type: application/json
174+
175+ {
176+ "email": "foo@example.com",
177+ "password": "the-password",
178+ "caveat_id": "{\"secret\": \"the-secret\", \"version\": 1}",
179+ "otp": "123456"
180+ }
181+
182+**Response**:
183+
184+.. sourcecode:: http
185+
186+ HTTP/1.1 200 OK
187+ Content-Type: application/json
188+
189+ {
190+ "discharge_macaroon": "the-macaroon"
191+ }
192+
193+If credentials don't match:
194+
195+.. sourcecode:: http
196+
197+ HTTP/1.1 401 UNAUTHORIZED
198+ Content-Type: application/json
199+
200+ {
201+ "error_list": [
202+ {
203+ "code": "invalid-credentials",
204+ "message": "Provided email/password is not correct."
205+ }
206+ ]
207+ }
208+
209+If 2-factor authentication is required:
210+
211+.. sourcecode:: http
212+
213+ HTTP/1.1 401 UNAUTHORIZED
214+ Content-Type: application/json
215+
216+ {
217+ "error_list": [
218+ {
219+ "code": "twofactor-required",
220+ "message": "2-factor authentication required."
221+ }
222+ ]
223+ }
224+
225+
226+.. _macaroon_refresh:
227+
228+Refresh a discharge macaroon
229+----------------------------
230+
231+.. http:post:: /api/v2/tokens/refresh
232+
233+ Refreshes a discharge macaroon
234+
235+ :form discharge_macaroon: the serialized macaroon to be refreshed
236+
237+ :status 200: macaroon refreshed
238+ :status 400: invalid request data
239+ :status 401: discharge macaroon does not verify
240+ :status 403: account is inactive
241+
242+Discharge macaroons are time-limited and must eventually be refreshed. The
243+need for this will be indicated by an error response from the cooperating
244+service. When this happens, the caller should send the old discharge
245+macaroon to this endpoint, which will issue a refreshed version if the
246+original credentials are still valid.
247+
248+Among other reasons, the discharge macaroon may fail to verify if the user's
249+password has changed since it was issued. In this case, the caller must
250+:ref:`request a new discharge macaroon <macaroon_discharge>`.
251+
252+
253+Errors
254+......
255+
256+* **INVALID_CREDENTIALS**: The provided discharge macaroon is invalid, or
257+ the user's password has changed since the discharge macaroon was issued.
258+
259+ Error status code 401.
260+
261+ This error has no additional fields in ``extra``.
262+
263+* **ACCOUNT_DEACTIVATED**: Account has been deactivated.
264+
265+ Error status code 403.
266+
267+ This error has no additional fields in ``extra``.
268+
269+
270+Examples
271+........
272+
273+**Request**:
274+
275+.. sourcecode:: http
276+
277+ POST /api/v2/tokens/refresh HTTP/1.1
278+ Host: login.ubuntu.com
279+ Accept: application/json
280+ Content-Type: application/json
281+
282+ {
283+ "discharge_macaroon": "the-old-macaroon"
284+ }
285+
286+**Response**:
287+
288+.. sourcecode:: http
289+
290+ HTTP/1.1 200 OK
291+ Content-Type: application/json
292+
293+ {
294+ "discharge_macaroon": "the-new-macaroon"
295+ }
296+
297+If the user's password has changed:
298+
299+.. sourcecode:: http
300+
301+ HTTP/1.1 401 UNAUTHORIZED
302+ Content-Type: application/json
303+
304+ {
305+ "error_list": [
306+ {
307+ "code": "invalid-credentials",
308+ "message": "Provided email/password is not correct."
309+ }
310+ ]
311+ }