Skip to content

Commit 47567d3

Browse files
authored
RFC: projectId (#163)
* RFC: projectId * incorporate @petemoore's feedback * mention chracter set for projectId * update after further discussion: no scopes required to create if no projectId
1 parent cdca981 commit 47567d3

File tree

3 files changed

+122
-0
lines changed

3 files changed

+122
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,5 @@ See [mechanics](mechanics.md) for more detail.
5757
| RFC#153 | [remove the email validation for metadata.owner](rfcs/0153-remove-email-validation-for-metadata-owner.md) |
5858
| RFC#154 | [Migrate Taskcluster to postgres](rfcs/0154-Migrate-taskcluster-to-postgres.md) |
5959
| RFC#155 | [Create an object service](rfcs/Create-object-service.md) |
60+
| RFC#163 | [ProjectId](rfcs/0163-project-id.md) |
6061
| RFC#166 | [Sign Public S3 URLs](rfcs/0166-Sign-public-S3-urls.md) |

rfcs/0163-project-id.md

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
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+
-->

rfcs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,5 @@
4545
| RFC#153 | [remove the email validation for metadata.owner](0153-remove-email-validation-for-metadata-owner.md) |
4646
| RFC#154 | [Migrate Taskcluster to postgres](0154-Migrate-taskcluster-to-postgres.md) |
4747
| RFC#155 | [Create an object service](Create-object-service.md) |
48+
| RFC#163 | [ProjectId](0163-project-id.md) |
4849
| RFC#166 | [Sign Public S3 URLs](0166-Sign-public-S3-urls.md) |

0 commit comments

Comments
 (0)