|
| 1 | +# RFC 0163 - ProjectId |
| 2 | +* Comments: [#0163](https://github.com/taskcluster/taskcluster-rfcs/pull/163) |
| 3 | +* Proposed by: @djmitche |
| 4 | + |
| 5 | +# Summary |
| 6 | + |
| 7 | +Taskcluster users typically want to be able to manipulate their tasks after they are created (cancel, rerun, etc.). |
| 8 | +Experience shows that `schedulerId` is not suitable for this purpose (see below for details). |
| 9 | +This RFC proposes a new task property, `projectId`, identifying the project to which a task corresponds. |
| 10 | +This aligns nicely with the conventional definition of a "project" as a portion of identifiers such as `roleId` and `hookGroupId`. |
| 11 | +It also introduces new scopes based on this property that control API methods such as `cancelTask` and `rerunTask`. |
| 12 | + |
| 13 | +## Motivation |
| 14 | + |
| 15 | +Taskcluster users would like to be able to manipulate tasks after they are created, but would prefer that other users *not* be allowed to perform such manipulations. |
| 16 | +At present, Taskcluster lacks an effective mechanism for doing so. |
| 17 | + |
| 18 | +### Use Cases |
| 19 | + |
| 20 | +1. Administration of the `exciting-app` project is delegated to `github-team:excitement/core`. |
| 21 | + Members of this team would like to be able to rerun tasks that fail due to infrastructure or intermittent issues, using the Taskcluster UI, but would like to prevent members of other projects from doing so. |
| 22 | + |
| 23 | +2. Similar to above, but exciting-app administrators would like to allow `github-team:excitement/contributors` to rerun test tasks, but not rerun deployment-related tasks nor cancel anything. |
| 24 | + |
| 25 | +3. The `exciting-app` project has several repos, each with a different set of developers. |
| 26 | + They would like to allow each set of developers to manipulate tasks for their repo, without allowing everyone access to all tasks. |
| 27 | + |
| 28 | +4. Several mutually-trusting projects share a worker pool to reduce overhead. |
| 29 | + The accounting department would like to determine the cost for compute resources for each of those projects, by assigning the compute time for each task to the tasks's project. |
| 30 | + |
| 31 | +### What about SchedulerId? |
| 32 | + |
| 33 | +The `schedulerId` property currently appears in scopes related to task manipulation, making it an seem like a good choice for controlling access to such actions. |
| 34 | +However, the property is overridden with several other meanings that tend to interfere: |
| 35 | + |
| 36 | +* it can represent the entity that created the task; |
| 37 | +* it can limit addition of new tasks to a task group: all tasks in task group must have the same `schedulerId`; and |
| 38 | +* it appears in pulse message routes and can be used to filter messages. |
| 39 | + |
| 40 | +The first and last points are currently in use by the GitHub srevice, which sets `schedulerId` on tasks it creates and uses its presence in Pulse routes to identify activity on those tasks. |
| 41 | + |
| 42 | +The second point could conflict with task manipulation in some use-cases. |
| 43 | +For example, a task-group created in response to a pull request might contain a mix of test tasks and tasks to do a staging deployment. |
| 44 | +Since all tasks in a task group must share the same `schedulerId`, the property would not support use-case 2, above, where tasks are differentiated within the same task-group. |
| 45 | + |
| 46 | +Finally, as a component in a pulse route, `schedulerId` is limited to 38 characters. |
| 47 | +While this is generally adequate for a single identifier, use cases 2 and 3 can both be addressed with slash-separated identifiers like `exciting-app/repo-a/test`, and such identifiers will quickly outgrow a 38-character limit. |
| 48 | + |
| 49 | +### Why Only Tasks? |
| 50 | + |
| 51 | +The fourth use-case, regarding accounting, might wish to determine costs for other Taskcluster resources. |
| 52 | +The costly resources in a Taskcluster deployment are artifact storage and compute time. |
| 53 | +This RFC would permit accounting for storage, since it assigns a `projectId` to each task, and artifacts are associated with tasks. |
| 54 | +It also permits allocation of active compute time to projects as described in the use-case itself. |
| 55 | +However, it does not address worker overhead -- setup time and idle time. |
| 56 | +Why not include `projectId` as a top-level property of worker pools? |
| 57 | + |
| 58 | +The reasoning is that worker pools have user-supplied names which can include a projectId as a substring, e.g., `project-exciting-app/linux-ci`, and use of worker pools is constrained by scopes. |
| 59 | +Tasks have only random identifiers (`taskIds`), and thus require a separate field to identify the associated project. |
| 60 | + |
| 61 | +# Details |
| 62 | + |
| 63 | +## Tasks |
| 64 | + |
| 65 | +Tasks will have a new top-level property, `projectId`, of unlimited length, composed of printable ASCII characters. |
| 66 | +The property will appear in task definitions returned from various API methods, like any other property of a task (but see "Compatibility" below). |
| 67 | +The property does not automatically appear in Pulse routes. |
| 68 | + |
| 69 | +## Scopes and API Methods |
| 70 | + |
| 71 | +### Creation |
| 72 | + |
| 73 | +The Queue service's `createTask` API method will require the scope `queue:create-task:project:<projectId>` in addition to the current set of scopes. |
| 74 | + |
| 75 | +This scope is required to satisfy the fourth use-case, regarding process accounting. |
| 76 | +It allows use of scopes to limit who or what may create a task in a particular project, in effect limiting who may "spend" that project's budget. |
| 77 | + |
| 78 | +### Manipulation |
| 79 | + |
| 80 | +The Queue service's `cancelTask`, `scheduleTask`, and `rerunTask` API methods currently require `queue:<method-name>:<schedulerId>/<taskGroupId>/<taskId>` or a legacy scope set. |
| 81 | +In this RFC, a third alternative would be added, `queue:<method-name>-in-project:<projectId>`, such that the action will be permitted if either scope is present. |
| 82 | + |
| 83 | +The naming of this scope is unfortunate, but required to disambiguate it from the existing scopes. |
| 84 | +The simpler scope pattern `queue:<method-name>:<projectId>` would give new permissions to credentials with existing `schedulerId`-based scopes. |
| 85 | +For example, would `queue:cancel-task:taskcluster-ui/*` refer to tasks with `schedulerId` `taskcluster-ui` or to tasks with a `projectId` matching `taskcluster-ui/*`? |
| 86 | + |
| 87 | +## Compatibility |
| 88 | + |
| 89 | +To support the transition from the current situation to one where every task has a `projectId`, this RFC specifies a default `projectId` for tasks, `none`. |
| 90 | +On upgrade to the version of Taskcluster supporting `projectId`, every existing task will be given `projectId` `none`. |
| 91 | +Calls to `createTask` that omit a `projectId` will create a task with `projectId` `none`, in which case the scope `queue:create-task:project:none` is *not* required. |
| 92 | +Calls to `createTask` with `projectId` explicitly set to `none` *will* require the scope. |
| 93 | + |
| 94 | +This allows existing code to continue operating after the upgrade. |
| 95 | +Calls to `createTask` without a `projectId` will be considered deprecated and support may be removed entirely one year after this change is released. |
| 96 | + |
| 97 | +No changes to the manipulation methods are required for compatibility. |
| 98 | + |
| 99 | +# Open Questions |
| 100 | + |
| 101 | +## Should `queue.task()` return a payload containing `projectId: "none"`? |
| 102 | + |
| 103 | +The risk is that returning an unexpected value in a task payload will cause task validations, such as chain-of-trust, to fail. |
| 104 | +The alternative would be to omit `projectId` from the task payload when it is `"none"`. |
| 105 | +However, this alternative differs from the handling of all other fields in a task payload (for example, `task.extra` is always present, defaulting to `{}`). |
| 106 | + |
| 107 | +# Implementation |
| 108 | + |
| 109 | +TBD |
| 110 | +<!-- |
| 111 | +<Once the RFC is decided, these links will provide readers a way to track the |
| 112 | +implementation through to completion, and to know if they are running a new |
| 113 | +enough version to take advantage of this change. It's fine to update this |
| 114 | +section using short PRs or pushing directly to master after the RFC is |
| 115 | +decided> |
| 116 | +
|
| 117 | +* <link to tracker bug, issue, etc.> |
| 118 | +* <...> |
| 119 | +* Implemented in Taskcluster version ... |
| 120 | +--> |
0 commit comments