Proposed spec: tenant-scoped admin web API
Change-Id: I9bebb61e9ce22b068d261fff208812ec489c2224
This commit is contained in:
parent
e0c975a980
commit
48a6c92064
|
@ -16,3 +16,4 @@ for those changes and help us work on them collaboratively.
|
|||
container-build-resources
|
||||
multiple-ansible-versions
|
||||
logs
|
||||
tenant-scoped-admin-web-API
|
||||
|
|
|
@ -0,0 +1,636 @@
|
|||
===========================
|
||||
Tenant-scoped admin web API
|
||||
===========================
|
||||
|
||||
https://storyboard.openstack.org/#!/story/2001771
|
||||
|
||||
The aim of this spec is to extend the existing web API of Zuul to
|
||||
privileged actions, and to scope these actions to tenants, projects and privileged users.
|
||||
|
||||
Problem Description
|
||||
===================
|
||||
|
||||
Zuul 3 introduced tenant isolation, and most privileged actions, being scoped
|
||||
to a specific tenant, reflect that change. However the only way to trigger
|
||||
these actions is through the Zuul CLI, which assumes either access to the
|
||||
environment of a Zuul component or to Zuul's configuration itself. This is a
|
||||
problem as being allowed to perform privileged actions on a tenant or for a
|
||||
specific project should not entail full access to Zuul's admin capabilities.
|
||||
|
||||
.. Likewise, Nodepool provides actions that could be scoped to a tenant:
|
||||
|
||||
* Ability to trigger an image build when the definition of an image used by
|
||||
that tenant has changed
|
||||
* Ability to delete nodesets that have been put on autohold (this is mitigated
|
||||
by the max-hold-age setting in Nodepool, if set)
|
||||
|
||||
These actions can only be triggered through Nodepool's CLI, with the same
|
||||
problems as Zuul. Another important blocker is that Nodepool has no notion of
|
||||
tenancy as defined by Zuul.
|
||||
|
||||
Proposed Change
|
||||
===============
|
||||
|
||||
Zuul will expose privileged actions through its web API. In order to do so, Zuul
|
||||
needs to support user authentication. A JWT (JSON Web Token) will be used to carry
|
||||
user information; from now on it will be called the **Authentication Token** for the
|
||||
rest of this specification.
|
||||
|
||||
Zuul needs also to support authorization and access control. Zuul's configuration
|
||||
will be modified to include access control rules.
|
||||
|
||||
A Zuul operator will also be able to generate an Authentication Token manually
|
||||
for a user, and communicate the Authentication Token to said user. This Authentication
|
||||
Token can optionally include authorization claims that override Zuul's authorization
|
||||
configuration, so that an operator can provide privileges temporarily to a user.
|
||||
|
||||
By querying Zuul's web API with the Authentication Token set in an
|
||||
"Authorization" header, the user can perform administration tasks.
|
||||
|
||||
Zuul will need to provide the following minimal new features:
|
||||
|
||||
* JWT validation
|
||||
* Access control configuration
|
||||
* administration web API
|
||||
|
||||
The manual generation of Authentication Tokens can also be used for testing
|
||||
purposes or non-production environments.
|
||||
|
||||
|
||||
JWT Validation
|
||||
--------------
|
||||
|
||||
Expected Format
|
||||
...............
|
||||
|
||||
Note that JWTs can be arbitrarily extended with custom claims, giving flexibility
|
||||
in its contents. It also allows to extend the format as needed for future
|
||||
features.
|
||||
|
||||
In its minimal form, the Authentication Token's contents will have the following
|
||||
format:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
{
|
||||
'iss': 'jwt_provider',
|
||||
'aud': 'my_zuul_deployment',
|
||||
'exp': 1234567890,
|
||||
'iat': 1234556780,
|
||||
'sub': 'venkman'
|
||||
}
|
||||
|
||||
* **iss** is the issuer of the Authorization Token. This can be logged for
|
||||
auditing purposes, and it can be used to filter Identity Providers.
|
||||
* **aud**, as the intended audience, is the client id for the Zuul deployment in the
|
||||
issuer.
|
||||
* **exp** is the Authorization Token's expiry timestamp.
|
||||
* **iat** is the Authorization Token's date of issuance timestamp.
|
||||
* **sub** is the default, unique identifier of the user.
|
||||
|
||||
These are standard JWT claims and ensure that Zuul can consume JWTs issued
|
||||
by external authentication systems as Authentication Tokens, assuming the claims
|
||||
are set correctly.
|
||||
|
||||
Authentication Tokens lacking any of these claims will be rejected.
|
||||
|
||||
Authentication Tokens with an ``iss`` claim not matching the white list of
|
||||
accepted issuers in Zuul's configuration will be rejected.
|
||||
|
||||
Authentication Tokens addressing a different audience than the expected one
|
||||
for the specific issuer will be rejected.
|
||||
|
||||
Unsigned or incorrectly signed Authentication Tokens will be rejected.
|
||||
|
||||
Authentication Tokens with an expired timestamp will be rejected.
|
||||
|
||||
|
||||
Extra Authentication Claims
|
||||
...........................
|
||||
|
||||
Some JWT Providers can issue extra claims about a user, like *preferred_username*
|
||||
or *email*. Zuul will allow an operator to set such an extra claim as the default,
|
||||
unique user identifier in place of *sub* if it is more convenient.
|
||||
|
||||
If the chosen claim is missing from the Authentication Token, it will be rejected.
|
||||
|
||||
Authorization Claims
|
||||
....................
|
||||
|
||||
If the Authentication Token is issued manually by a Zuul Operator, it can include
|
||||
extra claims extending Zuul's authorization rules for the Authentication Token's
|
||||
bearer:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
{
|
||||
'iss': 'zuul_operator',
|
||||
'aud': 'zuul.openstack.org',
|
||||
'exp': 1234567890,
|
||||
'iat': 1234556780,
|
||||
'sub': 'venkman',
|
||||
'zuul': {
|
||||
'admin': ['tenantA', 'tenantB']
|
||||
}
|
||||
}
|
||||
|
||||
* **zuul** is a claim reserved for zuul-specific information about the user.
|
||||
It is a dictionary, the only currently supported key is **admin**.
|
||||
* **zuul.admin** is a list of tenants on which the user is allowed privileged
|
||||
actions.
|
||||
|
||||
In the previous example, user **venkman** can perform privileged actions
|
||||
on every project of **tenantA** and **tenantB**. This is on top of venkman's
|
||||
default authorizations.
|
||||
|
||||
These are intended to be **whitelists**: if a tenant is unlisted the user is
|
||||
assumed not to be allowed to perform a privileged action (unless the
|
||||
authorization rules in effect for this deployment of Zuul allow it.)
|
||||
|
||||
Note that **iss** is set to ``zuul_operator``. This can be used to reject Authentication
|
||||
Tokens with a ``zuul`` claim if they come from other issuers.
|
||||
|
||||
|
||||
Access Control Configuration
|
||||
----------------------------
|
||||
|
||||
The Zuul main.yaml configuration file will accept new **admin-rule** objects
|
||||
describing access rules for privileged actions.
|
||||
|
||||
Authorization rules define conditions on the claims
|
||||
in an Authentication Token; if these conditions are met the action is authorized.
|
||||
|
||||
In order to allow the parsing of claims with complex structures like dictionaries,
|
||||
an XPath-like format will be supported.
|
||||
|
||||
Here is an example of how rules can be defined:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- admin-rule:
|
||||
name: ghostbuster_or_gozerian
|
||||
conditions:
|
||||
- resources_access.account.roles: "ghostbuster"
|
||||
iss: columbia_university
|
||||
- resources_access.account.roles: "gozerian"
|
||||
- admin-rule:
|
||||
name: venkman_or_stantz
|
||||
conditions:
|
||||
- zuul_uid: venkman
|
||||
- zuul_uid: stantz
|
||||
|
||||
* **name** is how the authorization rule will be refered as in Zuul's tenants
|
||||
configuration.
|
||||
* **conditions** is the list of conditions that define a rule. An Authentication
|
||||
Token must match **at least one** of the conditions for the rule to apply. A
|
||||
condition is a dictionary where keys are claims. **All** the associated values must
|
||||
match the claims in the user's Authentication Token.
|
||||
|
||||
Zuul's authorization engine will adapt matching tests depending on the nature of
|
||||
the claim in the Authentication Token, eg:
|
||||
|
||||
* if the claim is a JSON list, check that the condition value is in the claim
|
||||
* if the claim is a string, check that the condition value is equal to the claim's value
|
||||
|
||||
The special ``zuul_uid`` claim refers to the ``uid_claim`` setting in an
|
||||
authenticator's configuration, as will be explained below. By default it refers
|
||||
to the ``sub`` claim of an Authentication Token.
|
||||
|
||||
This configuration file is completely optional, if the ``zuul.admin`` claim
|
||||
is set in the Authentication Token to define tenants on which privileged actions
|
||||
are allowed.
|
||||
|
||||
Under the above example, the following Authentication Token would match rules
|
||||
``ghostbuster_or_gozerian`` and ``venkman_or_stantz``:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
{
|
||||
'iss': 'columbia_university',
|
||||
'aud': 'my_zuul_deployment',
|
||||
'exp': 1234567890,
|
||||
'iat': 1234556780,
|
||||
'sub': 'venkman',
|
||||
'resources_access': {
|
||||
'account': {
|
||||
'roles': ['ghostbuster', 'played_by_bill_murray']
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
And this Authentication Token would only match rule ``ghostbuster_or_gozerian``:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
{
|
||||
'iss': 'some_hellish_dimension',
|
||||
'aud': 'my_zuul_deployment',
|
||||
'exp': 1234567890,
|
||||
'sub': 'vinz_clortho',
|
||||
'iat': 1234556780,
|
||||
'resources_access': {
|
||||
'account': {
|
||||
'roles': ['gozerian', 'keymaster']
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
Privileged actions are tenant-scoped. Therefore the access control will be set
|
||||
in tenants definitions, e.g:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- tenant:
|
||||
name: tenantA
|
||||
admin_rules:
|
||||
- an_authz_rule
|
||||
- another_authz_rule
|
||||
source:
|
||||
gerrit:
|
||||
untrusted-projects:
|
||||
- org/project1:
|
||||
- org/project2
|
||||
- ...
|
||||
- tenant:
|
||||
name: tenantB
|
||||
admin_rules:
|
||||
- yet_another_authz_rule
|
||||
source:
|
||||
gerrit:
|
||||
untrusted-projects:
|
||||
- org/project1
|
||||
- org/project3
|
||||
- ...
|
||||
|
||||
|
||||
An action on the ``tenantA`` tenant will be allowed if ``an_authz_rule`` OR
|
||||
``another_authz_rule`` is matched.
|
||||
|
||||
An action on the ``tenantB`` tenant will be authorized if ``yet_another_authz_rule``
|
||||
is matched.
|
||||
|
||||
Administration Web API
|
||||
----------------------
|
||||
|
||||
Unless specified, all the following endpoints require the presence of the ``Authorization``
|
||||
header in the HTTP query.
|
||||
|
||||
Unless specified, all calls to the endpoints return with HTTP status code 201 if
|
||||
successful, 401 if unauthenticated, 403 if the user is not allowed to perform the
|
||||
action, and 400 with a JSON error description otherwise.
|
||||
In case of a 401 code, an additional ``WWW-Authenticate`` header is emitted, for example::
|
||||
|
||||
WWW-Authenticate: Bearer realm="zuul.openstack.org"
|
||||
error="invalid_token"
|
||||
error_description="Token expired"
|
||||
|
||||
Zuul's web API will be extended to provide the following endpoints:
|
||||
|
||||
POST /api/tenant/{tenant}/project/{project}/enqueue
|
||||
...................................................
|
||||
|
||||
This call allows a user to re-enqueue a buildset, like the *enqueue* or
|
||||
*enqueue-ref* subcommands of Zuul's CLI.
|
||||
|
||||
To trigger the re-enqueue of a change, the following JSON body must be sent in
|
||||
the query:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
{"trigger": <Zuul trigger>,
|
||||
"change": <changeID>,
|
||||
"pipeline": <pipeline>}
|
||||
|
||||
To trigger the re-enqueue of a ref, the following JSON body must be sent in
|
||||
the query:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
{"trigger": <Zuul trigger>,
|
||||
"ref": <ref>,
|
||||
"oldrev": <oldrev>,
|
||||
"newrev": <newrev>,
|
||||
"pipeline": <pipeline>}
|
||||
|
||||
|
||||
POST /api/tenant/{tenant}/project/{project}/dequeue
|
||||
...................................................
|
||||
|
||||
This call allows a user to dequeue a buildset, like the *dequeue* subcommand of
|
||||
Zuul's CLI.
|
||||
|
||||
To dequeue a change, the following JSON body must be sent in the query:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
{"change": <changeID>,
|
||||
"pipeline": <pipeline>}
|
||||
|
||||
To dequeue a ref, the following JSON body must be sent in
|
||||
the query:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
{"ref": <ref>,
|
||||
"pipeline": <pipeline>}
|
||||
|
||||
|
||||
POST /api/tenant/{tenant}/project/{project}/autohold
|
||||
..............................................................
|
||||
|
||||
This call allows a user to automatically put a node set on hold in case of
|
||||
a build failure on the chosen job, like the *autohold* subcommand of Zuul's
|
||||
CLI.
|
||||
|
||||
Any of the following JSON bodies must be sent in the query:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
{"change": <changeID>,
|
||||
"reason": <reason>,
|
||||
"count": <count>,
|
||||
"node_hold_expiration": <expiry>,
|
||||
"job": <job>}
|
||||
|
||||
or
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
{"ref": <ref>,
|
||||
"reason": <reason>,
|
||||
"count": <count>,
|
||||
"node_hold_expiration": <expiry>,
|
||||
"job": <job>}
|
||||
|
||||
|
||||
GET /api/user/authorizations
|
||||
.........................................
|
||||
|
||||
This call returns the list of tenant the authenticated user can perform privileged
|
||||
actions on.
|
||||
|
||||
This endpoint can be consumed by web clients in order to know which actions to display
|
||||
according to the user's authorizations, either from Zuul's configuration or
|
||||
from the valid Authentication Token's ``zuul.admin`` claim if present.
|
||||
|
||||
The return value is similar in form to the `zuul.admin` claim:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
{
|
||||
'zuul': {
|
||||
'admin': ['tenantA', 'tenantB']
|
||||
}
|
||||
}
|
||||
|
||||
The call needs authentication and returns with HTTP code 200, or 401 if no valid
|
||||
Authentication Token is passed in the request's headers. If no rule applies to
|
||||
the user, the return value is
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
{
|
||||
'zuul': {
|
||||
'admin': []
|
||||
}
|
||||
}
|
||||
|
||||
Logging
|
||||
.......
|
||||
|
||||
Zuul will log an event when a user presents an Authentication Token with a
|
||||
``zuul.admin`` claim, and if the authorization override is granted or denied:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
Issuer %{iss}s attempt to override user %{sub}s admin rules granted|denied
|
||||
|
||||
At DEBUG level the log entry will also contain the ``zuul.admin`` claim.
|
||||
|
||||
Zuul will log an event when a user presents a valid Authentication Token to
|
||||
perform a privileged action:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
User %{sub}s authenticated from %{iss}s requesting %{action}s on %{tenant}s/%{project}s
|
||||
|
||||
At DEBUG level the log entry will also contain the JSON body passed to the query.
|
||||
|
||||
The events will be logged at zuul.web's level but a new handler focused on auditing
|
||||
could also be created.
|
||||
|
||||
Zuul Client CLI and Admin Web API
|
||||
.................................
|
||||
|
||||
The CLI will be modified to call the REST API instead of using a Gearman server
|
||||
if the CLI's configuration file is lacking a ``[gearman]`` section but has a
|
||||
``[web]`` section.
|
||||
|
||||
In that case the CLI will take the --auth-token argument on
|
||||
the ``autohold``, ``enqueue``, ``enqueue-ref`` and ``dequeue`` commands. The
|
||||
Authentication Token will be used to query the web API to execute these
|
||||
commands; allowing non-privileged users to use the CLI remotely.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ zuul --auth-token AaAa.... autohold --tenant openstack --project example_project --job example_job --reason "reason text" --count 1
|
||||
Connecting to https://zuul.openstack.org...
|
||||
<usual autohold output>
|
||||
|
||||
|
||||
JWT Generation by Zuul
|
||||
-----------------------
|
||||
|
||||
Client CLI
|
||||
..........
|
||||
|
||||
A new command will be added to the Zuul Client CLI to allow an operator to generate
|
||||
an Authorization Token for a third party. It will return the contents of the
|
||||
``Authorization`` header as it should be set when querying the admin web API.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ zuul create-auth-token --auth-config zuul-operator --user venkman --tenant tenantA --expires-in 1800
|
||||
bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwOi8vbWFuYWdlc2Yuc2ZyZG90ZXN0aW5zdGFuY2Uub3JnIiwienV1bC50ZW5hbnRzIjp7ImxvY2FsIjoiKiJ9LCJleHAiOjE1Mzc0MTcxOTguMzc3NTQ0fQ.DLbKx1J84wV4Vm7sv3zw9Bw9-WuIka7WkPQxGDAHz7s
|
||||
|
||||
The ``auth-config`` argument refers to the authenticator configuration to use
|
||||
(see configuration changes below). The configuration must mention the secret
|
||||
to use to sign the Token.
|
||||
|
||||
This way of generating Authorization Tokens is meant for testing
|
||||
purposes only and should not be used in production, where the use of an
|
||||
external Identity Provider is preferred.
|
||||
|
||||
Configuration Changes
|
||||
.....................
|
||||
|
||||
JWT creation and validation require a secret and an algorithm. While several algorithms are
|
||||
supported by the pyJWT library, using ``RS256`` offers asymmetrical encryption,
|
||||
which allows the public key to be used in untrusted contexts like javascript
|
||||
code living browser side. Therefore this should be the preferred algorithm for
|
||||
issuers. Zuul will also support ``HS256`` as the most widely used algorithm.
|
||||
|
||||
Some identity providers use key sets (also known as **JWKS**), therefore the key to
|
||||
use when verifying the Authentication Token's signatures cannot be known in advance.
|
||||
Zuul must support the ``RS256`` algorithm with JWKS as well.
|
||||
|
||||
Here is an example defining the three supported types of authenticators:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[web]
|
||||
listen_address=127.0.0.1
|
||||
port=9000
|
||||
static_cache_expiry=0
|
||||
status_url=https://zuul.example.com/status
|
||||
|
||||
# symmetrical encryption
|
||||
[auth "zuul_operator"]
|
||||
driver=HS256
|
||||
# symmetrical encryption only needs a shared secret
|
||||
secret=NoDanaOnlyZuul
|
||||
# accept "zuul.actions" claim in Authentication Token
|
||||
allow_authz_override=true
|
||||
# what the "aud" claim must be in Authentication Token
|
||||
client_id=zuul.openstack.org
|
||||
# what the "iss" claim must be in Authentication Token
|
||||
issuer_id=zuul_operator
|
||||
# the claim to use as the unique user identifier, defaults to "sub"
|
||||
uid_claim=sub
|
||||
# Auth realm, used in 401 error messages
|
||||
realm=openstack
|
||||
# (optional) Ensure a Token cannot be valid for longer than this amount of time, in seconds
|
||||
max_validity_time = 1800000
|
||||
|
||||
# asymmetrical encryption
|
||||
[auth "my_oidc_idp"]
|
||||
driver=RS256
|
||||
public_key=/path/to/key.pub
|
||||
# optional, needed only if Authentication Token must be generated manually as well
|
||||
private_key=/path/to/key
|
||||
# if not explicitly set, allow_authz_override defaults to False
|
||||
# what the "aud" claim must be in Authentication Token
|
||||
client_id=my_zuul_deployment_id
|
||||
# what the "iss" claim must be in Authentication Token
|
||||
issuer_id=my_oidc_idp_id
|
||||
# Auth realm, used in 401 error messages
|
||||
realm=openstack
|
||||
# (optional) Ensure a Token cannot be valid for longer than this amount of time, in seconds
|
||||
max_validity_time = 1800000
|
||||
|
||||
# asymmetrical encryption using JWKS for validation
|
||||
# The signing secret being known to the Identity Provider only, this
|
||||
# authenticator cannot be used to manually issue Tokens with the CLI
|
||||
[auth google_oauth_playground]
|
||||
driver=RS256withJWKS
|
||||
# URL of the JWKS; usually found in the .well-known config of the Identity Provider
|
||||
keys_url=https://www.googleapis.com/oauth2/v3/certs
|
||||
# what the "aud" claim must be in Authentication Token
|
||||
client_id=XXX.apps.googleusercontent.com
|
||||
# what the "iss" claim must be in Authentication Token
|
||||
issuer_id=https://accounts.google.com
|
||||
uid_claim=name
|
||||
# Auth realm, used in 401 error messages
|
||||
realm=openstack
|
||||
|
||||
|
||||
Implementation
|
||||
==============
|
||||
|
||||
Assignee(s)
|
||||
-----------
|
||||
|
||||
Primary assignee:
|
||||
mhu
|
||||
|
||||
.. feel free to add yourself as an assignee, the more eyes/help the better
|
||||
|
||||
Gerrit Topic
|
||||
------------
|
||||
|
||||
Use Gerrit topic "zuul_admin_web" for all patches related to this spec.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
git-review -t zuul_admin_web
|
||||
|
||||
Work Items
|
||||
----------
|
||||
|
||||
Due to its complexity the spec should be implemented in smaller "chunks":
|
||||
|
||||
* https://review.openstack.org/576907 - Add admin endpoints, support for JWT
|
||||
providers declaration in the configuration, JWT validation mechanism
|
||||
* https://review.openstack.org/636197 - Allow Auth Token generation from
|
||||
Zuul's CLI
|
||||
* https://review.openstack.org/636315 - Allow users to use the REST API from
|
||||
the CLI (instead of Gearman), with a bearer token
|
||||
* https://review.openstack.org/#/c/639855 - Authorization configuration objects declaration and validation
|
||||
* https://review.openstack.org/640884 - Authorization engine
|
||||
* https://review.openstack.org/641099 - REST API: add /api/user/authorizations route
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
* The changes in the configuration will need to be documented:
|
||||
|
||||
* configuring authenticators in zuul.conf, supported algorithms and their
|
||||
specific configuration options
|
||||
* creating authorization rules
|
||||
|
||||
* The additions to the web API need to be documented.
|
||||
* The additions to the Zuul Client CLI need to be documented.
|
||||
* The potential impacts of exposing administration tasks in terms of build results
|
||||
or resources management need to be clearly documented for operators (see below).
|
||||
|
||||
Security
|
||||
--------
|
||||
|
||||
Anybody with a valid Authentication Token can perform administration tasks exposed
|
||||
through the Web API. Revoking JWT is not trivial, and not in the scope of this spec.
|
||||
|
||||
As a mitigation, Authentication Tokens should be generated with a short time to
|
||||
live, like 30 minutes or less. This is especially important if the Authentication
|
||||
Token overrides predefined authorizations with a ``zuul.admin`` claim. This
|
||||
could be the default value for generating Tokens with the CLI; this will depend on the configuration of
|
||||
other external issuers otherwise. If using the ``zuul.admin`` claims, the
|
||||
Authentication Token should also be generated with as little a scope as possible
|
||||
(one tenant only) to reduce the surface of attack should the
|
||||
Authentication Token be compromised.
|
||||
|
||||
Exposing administration tasks can impact build results (dequeue-ing buildsets),
|
||||
and pose potential resources problems with Nodepool if the ``autohold`` feature
|
||||
is abused, leading to a significant number of nodes remaining in "hold" state for
|
||||
extended periods of time. Such power should be handed over responsibly.
|
||||
|
||||
These security considerations concern operators and the way they handle this
|
||||
feature, and do not impact development. They however need to be clearly documented,
|
||||
as operators need to be aware of the potential side effects of delegating privileges
|
||||
to other users.
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
* Unit testing of the new web endpoints will be needed.
|
||||
* Validation of the new configuration parameters will be needed.
|
||||
|
||||
Follow-up work
|
||||
--------------
|
||||
|
||||
The following items fall outside of the scope of this spec but are logical features
|
||||
to implement once the tenant-scoped admin REST API gets finalized:
|
||||
|
||||
* Web UI: log-in, log-out and token refresh support with an external Identity Provider
|
||||
* Web UI: dequeue button near a job's status on the status page, if the authenticated
|
||||
user has sufficient authorization
|
||||
* autohold button near a job's build result on the builds page, if the authenticated
|
||||
user has sufficient authorization
|
||||
* reenqueue button near a buildset on a buildsets page, if the authenticated user
|
||||
has sufficient authorization
|
||||
|
||||
Dependencies
|
||||
============
|
||||
|
||||
* This implementation will use an existing dependency to **pyJWT** in Zuul.
|
||||
* A new dependency to **jsonpath-rw** will be added to support XPath-like parsing
|
||||
of complex claims.
|
Loading…
Reference in New Issue