Include workflows in write-all when feature flag is enabled

The write-all permission level should include workflows:write when the
AllowWorkflowsPermission feature flag is enabled, matching the behavior
of other gated permissions like copilot-requests. Previously workflows
was unconditionally excluded from write-all. This aligns with the ADR
decision that write-all means permissive access.
This commit is contained in:
Salman Muin Kayser Chishti
2026-04-11 08:49:41 +01:00
parent 273538003e
commit 18f53d3c9e
3 changed files with 11 additions and 7 deletions
@@ -32,7 +32,7 @@ namespace GitHub.Actions.WorkflowParser.Conversion
return;
}
var effectiveMax = explicitMax ?? CreatePermissionsFromPolicy(context, permissionsPolicy, includeIdToken: isTrusted, includeModels: context.GetFeatures().AllowModelsPermission);
var effectiveMax = explicitMax ?? CreatePermissionsFromPolicy(context, permissionsPolicy, includeIdToken: isTrusted, includeModels: context.GetFeatures().AllowModelsPermission, includeWorkflows: context.GetFeatures().AllowWorkflowsPermission);
if (requested.ViolatesMaxPermissions(effectiveMax, out var permissionLevelViolations))
{
@@ -59,7 +59,8 @@ namespace GitHub.Actions.WorkflowParser.Conversion
TemplateContext context,
string permissionsPolicy,
bool includeIdToken,
bool includeModels)
bool includeModels,
bool includeWorkflows)
{
switch (permissionsPolicy)
{
@@ -70,7 +71,7 @@ namespace GitHub.Actions.WorkflowParser.Conversion
Packages = PermissionLevel.Read,
};
case WorkflowConstants.PermissionsPolicy.Write:
return new Permissions(PermissionLevel.Write, includeIdToken: includeIdToken, includeAttestations: true, includeModels: includeModels);
return new Permissions(PermissionLevel.Write, includeIdToken: includeIdToken, includeAttestations: true, includeModels: includeModels, includeWorkflows: includeWorkflows);
default:
throw new ArgumentException($"Unexpected permission policy: '{permissionsPolicy}'");
}
@@ -1877,7 +1877,7 @@ namespace GitHub.Actions.WorkflowParser.Conversion
permissionsStr.AssertUnexpectedValue(permissionsStr.Value);
break;
}
return new Permissions(permissionLevel, includeIdToken: true, includeAttestations: true, includeModels: context.GetFeatures().AllowModelsPermission);
return new Permissions(permissionLevel, includeIdToken: true, includeAttestations: true, includeModels: context.GetFeatures().AllowModelsPermission, includeWorkflows: context.GetFeatures().AllowWorkflowsPermission);
}
var mapping = token.AssertMapping("permissions");
+6 -3
View File
@@ -39,7 +39,8 @@ namespace GitHub.Actions.WorkflowParser
PermissionLevel permissionLevel,
bool includeIdToken,
bool includeAttestations,
bool includeModels)
bool includeModels,
bool includeWorkflows = false)
{
Actions = permissionLevel;
ArtifactMetadata = permissionLevel;
@@ -60,8 +61,10 @@ namespace GitHub.Actions.WorkflowParser
Models = includeModels
? (permissionLevel == PermissionLevel.Write ? PermissionLevel.Read : permissionLevel)
: PermissionLevel.NoAccess;
// Workflows is excluded from write-all / read-all; must be explicitly requested
Workflows = PermissionLevel.NoAccess;
// Workflows is write-only, so only grant it when permissionLevel is Write
Workflows = includeWorkflows && permissionLevel == PermissionLevel.Write
? PermissionLevel.Write
: PermissionLevel.NoAccess;
}
private static KeyValuePair<string, (PermissionLevel, PermissionLevel)>[] ComparisonKeyMapping(Permissions left, Permissions right)