-
Notifications
You must be signed in to change notification settings - Fork 5
Bug 1415868 - create hooks and roles for actions as hooks #20
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good. I've suggested a few changes, but this is involved enough that I think another pass after they are made is probably worthwhile.
var roleId = `mozilla-group:active_scm_level_${level}`; | ||
var scopes = projectsWithGroup.map(project => { | ||
|
||
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1415868 for "old" and "new" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, we need to not take scopes away from people until the new stuff works!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm more unhappy with the variables names. But if this exists for a short enough period, it won't be a problem.
src/update-action-hook-perms.js
Outdated
.description('update action-related `hooks:trigger-hook:` scopes in mozilla-group:* roles'); | ||
}; | ||
|
||
EXPECTED_PERMS = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if this wants to be in ci-configuration
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, almost all of this does -- but I'm holding that for a follow-up.
src/update-action-hook-perms.js
Outdated
{trustDomain: 'gecko', level: '3', actionPerm: 'relpromo'}, | ||
]}, | ||
{group: 'releng', actions: [ | ||
{trustDomain: 'gecko', level: '3', actionPerm: 'relpromo'}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably want to give comm
/relpromo
here too.
Also, at least releng
(but potentially wider) will want level 1/2 scopes for this too. We eventually want to be able to do staging release on try, and I've already been doing it a bit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I meant to change this from relpromo to something more innocuous like purge-cache to start with. I don't want to mess with "scary things" yet! But yes, this will be the place to add such scopes.
src/util/tcyml.js
Outdated
|
||
const CENTRAL_RAW = 'https://hg.mozilla.org/mozilla-central/raw-file/default/'; | ||
|
||
exports.getCentralTaskclusterYml = async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would make more sense for this to grabbed per-project (even if you only use it for m-c here).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't have a hook per project, though -- only per level. We could potentially have one per repo, but then we have a hook per repo, per actionPerm, and we are granting those individual trigger-hook scopes to users, so it's quite an explosion. I don't see a great benefit, either -- it would just leave us running tcadmin
on every uplift, if there was something important changing in .taskcluster.yml
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm happy if you call it only with mozilla-central
(although I think we also need to call it with comm-central
), but I think it is worth making the utility general, even if the callers aren't).
@@ -0,0 +1,17 @@ | |||
exports.ACTION_HOOKS = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ci-configuration?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup
src/make-gecko-action-hooks.js
Outdated
tasks_for: 'action', | ||
action: { | ||
$merge: [ | ||
{$eval: 'payload.decision.action'}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would there be any value in changing this so that the stuff that can be overridden is in a sub-key here, instead of merging? This will require some .taskcluster.yml
refactoring, but I think it will be less error prone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are only two, and one of them (cb_name) is only sometimes overridden. So I'm not sure that'd be less confusing. Also, a sub-key would still require merging..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could have (in python python psuedo-code):
repo_scope = {...}
if action.actionPerm == 'generic':
cb_name = action.pop('cb_name')
else:
cb_name = action.actionPerm
task = {
...
'action': {
'repo_scope': repo_scope,
'cb_name': {'$eval': 'payload.action.cb_name',
'params': {'$eval': 'payload.action.params'},
},
...
}
with bikesheading over param
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I laid out the three contexts concerned here in this gist.
My initial reaction to your comment is that stuffWeWillNotOverride
would be a better name than params
. It seems to be designing the data structure to suit the software constructing it (and I'm not even convinced the proposed design suits any better). We could potentially flatten out all of the stuff in the action
subkey.
I'd like to introduce minimal churn here, and keep risk of breaking existing (kind=task) actions as low as possible. Is that risk worthwhile?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My concern is less about what the code looks like than about security; making it harder to future changes to accidentally let the security sensitive values be overridden (which suggests the name should be something like untrusted
, maybe).
To be clear, I don't think the code as-is is insecure. I just think that it would be easy for somebody to not realize the security impact of the code (for example, that the order of merging is critical). By moving the security critical values outside of the user-provided dictionary, I think that makes mistakes here less likely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, I see. So, a few things to change:
- add detail to hooks'
triggerSchema
to indiciate specific keys in action, push, and repository - don't include
repo_scope
in the hookPayload (and don't generate it in the in-tree code) - Rework these overrides to be a little clearer that we either take the given value, or force it, and why (with some comments).
OK, this is substantially updated to reflect reviews and conversation on the topic. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good! Thanks for the changes. I've just got a minor nit about an unclear comment.
taskGroupId: '${payload.decision.action.taskGroupId}', | ||
// repo_scope is calculated in the hook's JSON-e rendering; note that this is limited | ||
// by the hook's `hook-id:..` role, too | ||
repo_scope: 'assume:repo:${payload.decision.repository.url[8:]}:action:' + action.actionPerm, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It took me a few minute to convince myself that this was safe. I think it would make sense to specifically call out that this can only allow scopes that are also given to the hook-id:*
role, so that the validation of the repository url happens there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks - updated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Also, simplify some logic by requiring that repository.url not have a trailing slash
trustDomain: 'gecko', | ||
level: '1', | ||
actionPerm: 'purge-caches', | ||
groups: ['taskcluster', 'vpn_sheriff'], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see no reason this should be so limited :)
But it's a good example nonetheless...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, we can work out the permissions later -- this is almost just placeholder stuff right now.
No description provided.