Skip to content
This repository has been archived by the owner on Jan 19, 2022. It is now read-only.

Commit

Permalink
Merge 0f4e33b into 65443fc
Browse files Browse the repository at this point in the history
  • Loading branch information
djmitche committed Feb 23, 2015
2 parents 65443fc + 0f4e33b commit 3a93a7c
Show file tree
Hide file tree
Showing 20 changed files with 1,452 additions and 321 deletions.
7 changes: 7 additions & 0 deletions docs/development/@relengapi/api_methods.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ Compound types are defined by subclassing ``wsme.types.Base``::

See the WSME_ documentation for more detail.

As a utility, an arbitrary JSON Object can be described with this class:

.. class:: relengapi.lib.api.JsonObject

A WSME custom type describing an arbitrary JSON object.
This validates that the value is an object (equivalent to a ``dict`` in Python) and that it can be JSON-encoded.

Decorator
---------

Expand Down
13 changes: 12 additions & 1 deletion docs/development/@relengapi/auth.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,18 @@ A simple example::
if address == '127.0.0.1':
return LocalhostUser()

In most cases, this form of authentication is handled in a blueprint which also provides the necessary UI for managing credentials.
This is a very low-level interface.
In most cases, you will take advantage of token authentication to handle non-browser authentication.

Token Authentication
--------------------

The ``tokenauth`` blueprint implements a request loader which looks for bearer tokens containing JSON Web Tokens.
When this authentication succeeds, the curent user is a ``TokenUser`` object, with type ``"token"``.
It has a ``claims`` attribute which contains the JWT claims in the original token.
This can be used, for example, for access to the metadata in temporary tokens.

See :doc:`tokenauth` for more detail on the implementation of token authentication.

Authorization
-------------
Expand Down
1 change: 1 addition & 0 deletions docs/development/@relengapi/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
proxies
tasks
auth
tokenauth
utils
app
testing
Expand Down
42 changes: 42 additions & 0 deletions docs/development/@relengapi/tokenauth.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
Token Authentication
====================

Aside from the usual browser-based cookie sessions, RelengAPI has a very flexible token-based authentication mechanism, implemented by the ``tokenauth`` blueprint.

Tokens come in the form of `JSON Web Tokens <http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html>`_ in JWS format, signed by the application's secret.
Each token has a type.
The token types are summarized here:

=============== ======== =========================== ========= ========= ======================
Name Type Permissions Duration Revokable Notes
=============== ======== =========================== ========= ========= ======================
permanent token ``prm`` perms granted to token unlimited yes
--------------- -------- --------------------------- --------- --------- ----------------------
temporary token ``tmp`` perms granted to token limited no
--------------- -------- --------------------------- --------- --------- ----------------------
user token ``usr`` intersection of user's unlimited yes user must be valid
authz perms and token perms
=============== ======== =========================== ========= ========= ======================

When a token is used to authenticate a request, the Flask ``current_user`` is a ``TokenUser`` instance with a ``claims`` attribute containing the token's JWT claims.
After verifying that ``current_user.type`` is ``token``, it is safe to rely on any of the values in ``current_user.claim``.
If the token type is linked to a user, then ``current_user.authenticated_email`` will be set to that user's email address.
If the token type is not linked to a user, then this attribute does not exist (it is not just set to ``None``).

Every token has these claims:

* ``typ`` -- the token type as given in the table above
* ``iss`` -- always ``ra2`` for this token scheme

The remaining claims vary by type, and are defined as follows.
For limited-duration, non-revokable tokens:

* ``nbf`` -- "not-before" time in seconds since the epoch
* ``exp`` -- expiration time in seconds since the epoch
* ``mta`` -- arbitrary token metadata to limit the scope of the permissions

For unlimited-duration, revokable tokens:

* ``jti`` -- token identifier; typically ``"t"`` plus the token ID, but subject to change
* ``sub``
* for app-linked tokens (``ucli``, and ``pcli``), the client identifier; typically ``c`` plus the client id, but subject to change
69 changes: 60 additions & 9 deletions docs/usage/@relengapi/tokenauth.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ Token Authentication
Authenticating with Tokens
--------------------------

When systems outside of the Releng API need to perform restriction operations, they can do so using a *token*.
Tokens are opaque strings (currently implemented as JSON Web Tokens) which are provided in the Authentication header:
When systems outside of the Releng API need to make API calls, they can do so using a *token*.
Tokens are opaque strings (actually JSON Web Tokens) which are provided in the Authentication header:

.. code-block:: none
Expand All @@ -17,16 +17,67 @@ Each token permits a limited set of permissions, specified when the token is iss
Managing Tokens
---------------

Each token has a numeric ID, a description, and a set of associated permissions.
The string form of the token is only shown when the token is initially issued; thereafter it is referred to only by ID.
In order to issue a new token, the caller must have the appropriate issuing permission (see below) as well as all permissions in the requested token.
The string form of the token is only produced when the token is initially issued; thereafter it is referred to only by ID, if at all.

Those who are permitted the ``base.tokens.view`` permission can view all tokens, but not derive their string form.
Some tokens do not have IDs.
These tokens cannot be managed after they are issued.
Fortunately, all such tokens have limited lifetimes.

Tokens can be issued via the form available from ``/tokenauth`` by those who have permission to the ``base.tokens.issue`` permission.
The selected permissions for the token must be a subset of those permissions the issuer can perform.
Token Types
-----------

Tokens can be issued, revoked, looked up by string, and so on using API calls.
See the API documentation below for details.
There are several types of tokens available.
Depending on your permissions, some or all of these may be unavailable to you.

To issue a token, supply all of the required attributes except ``id``.

Permanent Token (``prm``)
.........................

A permanent token is issued by an administrator and never expires -- even if that administrator's account is terminated.
Permannent tokens are used for authentication of other, internal systems to RelengAPI.

A permanent token has attributes ``id``, ``permissions``, and ``description``.

User Token (``usr``)
....................

A user token is issued by a non-administrative user, and lasts as long as that user's account is still active.
User tokens are very similar to GitHub's "personal access tokens" -- they entitle the bearer to act as the user, with some subset of the user's permissions.

A user token has attributes ``id``, ``permissions``, ``user``, and ``description``.
The ``user`` attribute is filled in automatically when the token is issued.
A request to issue a user token must use an authentication mechanism associated with a user (a browser session or another user token).

Temporary Token (``tmp``)
.........................

A temporary token has a limited lifetime, and can have a small amount of metadata attached.
Temporary tokens are used to give short-term, narrowly-focused permissions to other systems.
For example, a build job might use a temporary token to record its results, with the permissions of the token limited to writing results for its build ID.

A temporary token has attributes ``not_before``, ``expires``, ``permissions``, and ``metadata``.

Token Permissions
-----------------

Permission to manipulate tokens are controlled by a number of permissions:

For permanent tokens:
* ``base.tokens.prm.view`` -- view all permanent tokens
* ``base.tokens.prm.issue`` -- issue a permanent token
* ``base.tokens.prm.revoke`` -- revoke a permanent token

For user tokens:
* ``base.tokens.usr.view.all`` -- view all user tokens
* ``base.tokens.usr.view.my`` -- view my user tokens
* ``base.tokens.usr.issue`` -- issue a user token
* ``base.tokens.usr.revoke.all`` -- revoke any user token
* ``base.tokens.usr.revoke.my`` -- revoke a user token issued by me

For temporary tokens:
* ``base.tokens.tmp.issue`` -- issue a temporary token.

API
---
Expand Down
Loading

0 comments on commit 3a93a7c

Please sign in to comment.