Skip to content

Commit d222243

Browse files
committed
Design doc: secure access to APIs from builders
- Ref readthedocs/meta#21 - Ref #7928 (not directly, but it opens the door for the future)
1 parent 51d03d6 commit d222243

File tree

1 file changed

+130
-0
lines changed

1 file changed

+130
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
Secure API access from builders
2+
===============================
3+
4+
Goals
5+
-----
6+
7+
- Provide a secure way for builders to access the API.
8+
- Limit the access of the tokens to the minimum required.
9+
10+
Non-goals
11+
---------
12+
13+
- Migrate builds to use API V3
14+
- Implement this mechanism in API V3
15+
- Expose it to users
16+
17+
All these changes can be made in the future, if needed.
18+
19+
Current state
20+
-------------
21+
22+
Currently, we access the API V2 from the builders using the credentials of the "builder" user.
23+
This user is a superuser, it has access to all projects,
24+
write access to the API, access to restricted endpoints, and restricted fields.
25+
26+
The credentials are hardcoded in our settings file,
27+
so if there is a vulnerability that allows users to have access to the settings file,
28+
the attacker will have access to the credentials of the "builder" user,
29+
giving them full access to the API and all projects.
30+
31+
Proposed solution
32+
-----------------
33+
34+
Instead of using the credential of a super user to access the API,
35+
we will create a temporal token attached to a project, and one of the owners of the project.
36+
This way this token will have access to the given project only for a limited period of time.
37+
38+
This token will be generated from the webs,
39+
and passed to the builders via the celery task,
40+
where it can be used to access the API.
41+
Once the build has finished, this token will be revoked.
42+
43+
Technical implementation
44+
------------------------
45+
46+
We will use the rest-knox_ package,
47+
this package is recommended by the DRF documentation,
48+
since the default token implementation of DRF is very basic,
49+
some relevant features of knox are:
50+
51+
- Support for several tokens per user.
52+
- Tokens are stored in a hashed format in the database.
53+
We don't have access the tokens after they are created.
54+
- Tokens can hava an expiration date.
55+
- Tokens can be created with a prefix (rtd_xxx) (unreleased)
56+
- Support for custom token model (unreleased)
57+
58+
We won't expose the token creation view directly,
59+
since we can create the tokens from the webs,
60+
and this isn't exposed to users.
61+
62+
The view to revoke the token will be exposed,
63+
since we need it to revoke the token once the build has finished.
64+
65+
From the API, we just need to add the proper permission and authentication classes
66+
to the views we want to support.
67+
68+
To differentiate from a normal user and a token authed user,
69+
we will have access to the token via the ``request.auth`` attribute in the API views,
70+
this will also be used to get the attached projects to filter the querysets.
71+
72+
The knox package allows us to provide our own token model,
73+
this will be useful to add our own fields to the token model.
74+
Fields like the projects attached to the token,
75+
or access to all projects the user has access to, etc.
76+
77+
.. _rest-knox: https://james1345.github.io/django-rest-knox/
78+
79+
Flow
80+
----
81+
82+
The flow of creation and usage of the token will be:
83+
84+
- Create a token from the webs when a build is triggered.
85+
The triggered project will be attached to the token,
86+
if the build was triggered by a user, that user will be attached to the token,
87+
otherwise the token will be attached to one of the owners of the project.
88+
- The token will be created with an expiration date
89+
of 3 hours, this should be enough for the build to finish.
90+
We could also make this dynamic depending of the project.
91+
- Pass the token to the builder via the celery task.
92+
- Pass the token to all places where the API is used.
93+
- Revoke the token when the build has finished.
94+
This is done by hitting the revoke endpoint.
95+
- In case the revoke endpoint fails, the token will expire in 3 hours.
96+
97+
Why attach tokens to users?
98+
---------------------------
99+
100+
Attaching tokens to users will ease the implementation,
101+
since we can re-use the code from knox package.
102+
103+
Attaching tokens to projects only is possible,
104+
but it will require to manage the authentication manually.
105+
106+
Kepping backwards compatibility
107+
-------------------------------
108+
109+
Access to write API V2 is restricted to superusers,
110+
and was used only from the builders.
111+
So we don't need to keep backwards compatibility for authed requests,
112+
but we need to keep the old implementation working while we deploy the new one.
113+
114+
Possible issues
115+
---------------
116+
117+
Some of the features that we may need are not released yet,
118+
we need the custom token model feature, specially.
119+
120+
There is a race condition when using the token,
121+
and the user that is attached to that token is removed from the project.
122+
This is, if the user is removed while the build is running,
123+
the builders won't be able to access the API.
124+
125+
Future work
126+
-----------
127+
128+
This work can be extended to API V3, and be exposed to users in the future.
129+
We only need to take into consideration that the token model will be shared by both,
130+
API V2 and API V3.

0 commit comments

Comments
 (0)