README.md 5.68 KB
Newer Older
1
# ungleichotp #
Nico Schottelius's avatar
Nico Schottelius committed
2

3 4
ungleich-otp is a full blown authentication and authorisation service
made for micro services.
5

6 7 8
The basic idea is that every micro service has a (long term) triple
constisting of (name, realm, seed) and creates time based tokens.

Nico Schottelius's avatar
Update  
Nico Schottelius committed
9
This basically revamps Kerberos in a simple way into the web area.
10 11 12 13 14 15 16 17 18

ungleichotp has been created and is maintained by [ungleich](https://ungleich.ch/).

Related documentation:

* [Python pyotp](https://pyotp.readthedocs.io/)
* [RFC6238, TOTP](https://tools.ietf.org/html/rfc6238)
* [RFC4120, Kerberos](https://tools.ietf.org/html/rfc4120)

Nico Schottelius's avatar
Cleanup  
Nico Schottelius committed
19
## Overview ##
20

21
This repository the reference implementation of the ungleichotp server.
22

Nico Schottelius's avatar
Nico Schottelius committed
23 24 25

## Using the ungleichotpclient ##

26 27
The client can be used to test the ungleich-otp-server.

28 29
All client commands need the parameters --auth-name and --auth-realm.
Also either --auth-seed or --auth-token needs to be specified.
Nico Schottelius's avatar
Nico Schottelius committed
30 31 32
```
python manage.py ungleichotpclient create \
    --server-url https://otp.ungleich.ch/ungleichotp/
33 34 35 36
    --auth-name admin
    --auth-realm ungleich-admin
    [--auth-seed THESEEDFORADMIN]
    [--auth-token THECURRENTTOKEN]
Nico Schottelius's avatar
Nico Schottelius committed
37
```
Nico Schottelius's avatar
Update  
Nico Schottelius committed
38

39
### Creating new users
Nico Schottelius's avatar
Nico Schottelius committed
40

41
```
42
--name USERNAME --realm REALMOFUSER create
43 44
```

45
The seed is randomly created.
46

47
### Listing users
48 49

```
50
list
51 52
```

53
### Deleting users
54 55

```
56
--name USERNAME --realm REALMOFUSER delete
57
```
Nico Schottelius's avatar
Nico Schottelius committed
58

59

60
### Verifying a token is correct
Nico Schottelius's avatar
Cleanup  
Nico Schottelius committed
61

62
Verify using:
Nico Schottelius's avatar
Nico Schottelius committed
63 64

```
65
--name USERNAME --realm REALMOFUSER --token TOKENTOBEVERIFIED verify
Nico Schottelius's avatar
Nico Schottelius committed
66 67
```

68
You can also verify using a seed:
Nico Schottelius's avatar
Nico Schottelius committed
69 70

```
71
--name USERNAME --realm REALMOFUSER --seed SEEDOFUSER verify
Nico Schottelius's avatar
Nico Schottelius committed
72 73 74
```


Nico Schottelius's avatar
Cleanup  
Nico Schottelius committed
75 76 77
## Server Setup instructions ##

This is a standard django project and thus can be easily setup using
78

79
```
Nico Schottelius's avatar
Cleanup  
Nico Schottelius committed
80 81
pip install -r requirements.txt
python manage.py createsuperuser
82 83
python manage.py runserver
```
84

Nico Schottelius's avatar
++ API  
Nico Schottelius committed
85

86
## Realms ##
Nico Schottelius's avatar
++ API  
Nico Schottelius committed
87

88 89
Access is granting/denied based on realms. There are two reserved
realms, all other realms can be used by the users:
Nico Schottelius's avatar
++ API  
Nico Schottelius committed
90

91 92 93 94 95 96 97 98 99 100 101 102
### Reserved realms

Conceptually the realms "ungleich-admin" and "ungleich-auth" are
reserved for higher priviliged applications.

Usually there is only 1 entry in ungleich-admin that is used to
bootstrap and manage ungleich-otp.

All micro services that are trusted to authenticate another micro
service should have an entry in the ungleich-auth realm, which allows
them to verify a token of somebody else.

103
```
104 105 106 107 108
| Name             | Capabilities                               |
|------------------+--------------------------------------------|
| ungleich-admin   | authenticate, create, delete, list, update |
| ungleich-auth    | authenticate                               |
| all other realms | NO ACCESS                                  |
109
```
110

111

Nico Schottelius's avatar
Cleanup  
Nico Schottelius committed
112
## Verify using http POST  ##
113

Nico Schottelius's avatar
Cleanup  
Nico Schottelius committed
114 115
Post a JSON object to the server at /ungleichotp/verify/ that
contains the following elements:
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

Request JSON object:

```
{
    name: "your-name",
    realm: "your-realm",
    token: "current time based token",
    verifyname: "name that wants to be authenticated",
    verifyrealm: "realm that wants to be authenticated",
    verifytoken: "token that wants to be authenticated",
}
```

Response JSON object:

Either HTTP 200 with
```
{
    status: "OK",
}
```

OR return code 403:

* If token for authenticating is wrong, you get

```
{"detail":"Incorrect authentication credentials."}
```

* If token that is being verified is wrong, you get

```
{"detail":"You do not have permission to perform this action."}
```

Nico Schottelius's avatar
Cleanup  
Nico Schottelius committed
153
## Authorize the request ##
154 155 156 157 158 159 160

From the ungleichotp-server, you get a validated information that a
name on a realm authenticated successfully. The associated permissions
("authorization") is application specific and needs to be decided by
your application.


Nico Schottelius's avatar
Nico Schottelius committed
161 162
## Limitations ##

163 164
* Name, Realm and seed are hard coded to 128 bytes length.
  This can be changed, if necessary.
Nico Schottelius's avatar
Nico Schottelius committed
165 166 167
* Only python3 support for ungleichotp


Nico Schottelius's avatar
Nico Schottelius committed
168 169
## TODOs

170 171 172 173 174 175 176
- [x] (server) Serialize / input request
- [x] (server) Make seed read only
- [x] (server) Implement registering of new entries
- [x] (server) OTPSerializer: allow to read seed for admin
- [x] (server) Implement deleting entry
- [x] (server) Include verify in ModelSerializer
- [x] (server) Map name+realm == User (?)
Nico Schottelius's avatar
Nico Schottelius committed
177
  - name == name@realm
178
  - password is used for admin login (?)
Nico Schottelius's avatar
Nico Schottelius committed
179 180
  - seed
  - custom auth method
181 182 183 184 185 186 187
- [n] (server) Try to fake username for django based on name+realm (?)
  - No need
- [n] (server) maybe overwrite get_username()
  - No need
- [x] (server) Use Custom authentication  - needs to have a user!
- [x] (server) Implement creating new "User" by POST / Model based
- [n] (server) Remove hard coded JSON in /verify (no - good enough for the moment)
Nico Schottelius's avatar
Nico Schottelius committed
188
- [x] (server) Fully rename server from ungleichotp to ungleichotpserver
189 190
- [x] (security) Ensure that only the right realms can verify
- [x] (security) Ensure that only the right realms can manage
Nico Schottelius's avatar
Nico Schottelius committed
191
- [ ] (doc) Add proper documentation
192 193 194 195
- [ ] (server) Add tests for verify
- [ ] (server) Add tests for authentication
- [ ] (server) move totp constants into settings
- [ ] (server) move field lengths into settings
Nico Schottelius's avatar
Nico Schottelius committed
196
- [ ] (server) Document how admin vs. rest works
197 198
- [ ] (server, client) Make settings adjustable by environment - k8s/docker compatible
- [ ] (server, client) Read DB from outside (?) (fallback to sqlite)
Nico Schottelius's avatar
Nico Schottelius committed
199 200 201 202
- [x] (client) Establish auth using urllib
- [ ] (client) Bootstrap Django + DRF (including an object for CRUD)
- [ ] (client) Add custom authentication / remote auth
- [ ] (client) Show case: any realm vs. specific realm
203 204
- [x] (library) Write a "client library" that can use ungleichotp
- [x] (library) extract generic parts from server
205
- [ ] (library) upload to pypi
206

207 208


209
## Changelog
210

211 212 213 214
### 0.8, 2019-02-08

* Verify needed to call super()

Nico Schottelius's avatar
Nico Schottelius committed
215 216 217 218
### 0.6, 2018-11-18

* Reuse TokenSerializer for VerifySerializer logic

219 220 221
### 0.5, 2018-11-18

* Require authentication on all rest endpoints by token