-
Notifications
You must be signed in to change notification settings - Fork 422
Hawk authentication session
Hawk is an authentication mechanism, famous because of its replay attack protection.
It is a way to prevent users to tamper with request content or to replay the same request multiple times.
This is especially useful in games where you don't want users to publish fake scores or if you call costly API's (send SMS, trigger a costly lambda job, etc)
Hawk credentials looks like a record with the following keys:
{
'id': 'hawk-id',
'key': 'hawk-secret',
'algorithm': 'sha256',
}
Because we don't want people to be able to read the credentials in clear through the network we use a mechanism to share them between the server and the client.
For this to happen we use the Hawk-Session-Token
header.
The Hawk-Session-Token
is a random string of 32 bytes rendered as hexadecimal characters:
Hawk-Session-Token: 47d5616e561443e79d0db605771db46234a984629a6e681059b76657f790583b
You can retrieve this string for your user on a Kinto server, if the account
and the hawk
plugins are enabled by calling the POST /accounts/(user_id)/hawk-sessions
endpoint below. Note that you need to use your account userID and password for Basic Authentication. Once you are using your session for HAWK authentication, you will no longer need to use your account credentials:
$ http POST https://kinto.dev.mozaws.net/v1/accounts/userID/hawk-sessions -v --auth (userID):(password)
POST /v1/accounts/userID/hawk-sessions HTTP/1.1
Host: kinto.dev.mozaws.net
HTTP/1.1 201 Created
Hawk-Session-Token: 47d5616e561443e79d0db605771db46234a984629a6e681059b76657f790583b
In order to get the hawk credentials from the Hawk-Session-Token
for the client to use them you will need to use the HKDF derivation function with the following parameters:
-
secret: The
Hawk-Session-Token
value - salt: '' (Empty string)
- info: 'identity.mozilla.com/picl/v1/sessionToken'
- length: 64 (2*32) The first 32 bytes for the ID, The last 32 bytes for the Key
-
Do an HKDF derivation on the given Hawk-Session-ID. With the following parameters:
key_material = HKDF(hawk_session, "", 'identity.mozilla.com/picl/v1/sessionToken', 32*2)
-
The key material you’ll get out of the HKDF need to be separated into two parts, the first 32 bytes are the Hawk ID, and the next 32 ones are the Hawk key.
Credentials:
credentials = { 'id': codecs.encode(keyMaterial[0:32], 'hex_codec'), 'key': codecs.encode(keyMaterial[32:64], 'hex_codec'), 'algorithm': 'sha256', }
If you are writing a client, you might find these resources useful:
- With JavaScript: https://dxr.mozilla.org/mozilla-central/source/services/common/hawkrequest.js#127,128-144 & https://github.com/mozilla-services/express-hawkauth/blob/master/lib/token.js
- With Python: https://github.com/mozilla-services/requests-hawk/blob/master/requests_hawk/__init__.py#L51-L59
You can remove all current sessions to your account by calling DELETE /accounts/(user_id)/hawk-sessions
. This endpoint requires HAWK authentication.
$ http DELETE https://kinto.dev.mozaws.net/v1/accounts/userID/hawk-sessions -v
Authorization: Hawk id="...", ts="...", nonce="...", mac="..."
DELETE /v1/accounts/userID/hawk-sessions HTTP/1.1
Host: kinto.dev.mozaws.net
HTTP/1.1 204 No Content
It is possible to define the hawk_session.ttl_seconds
in the Kinto server configuration:
kinto.hawk_session.ttl_seconds = 86400 # 24 hours in seconds
Its value defaults to 24 hours in seconds (86400)
Each time the Hawk session is used, we delay the session expiration for ttl_seconds
more, so that the Hawk session keeps being valid as long as it is used. With the default settings, users will have to reconnect after they stop to use their session for 24h.
It is possible to disconnect all session by removing all of them using DELETE https://kinto.dev.mozaws.net/v1/accounts/userID/hawk-sessions
It is possible to disconnect the current session by using it and calling DELETE https://kinto.dev.mozaws.net/v1/accounts/userID/hawk-sessions/current
Requests to remove sessions require HAWK authentication.
Join us on irc.freenode.net #kinto or on our Slack Workspace for more info.