diff --git a/src/Sdk/WorkflowParser/Conversion/PermissionsHelper.cs b/src/Sdk/WorkflowParser/Conversion/PermissionsHelper.cs index b53408950..5b0272a2b 100644 --- a/src/Sdk/WorkflowParser/Conversion/PermissionsHelper.cs +++ b/src/Sdk/WorkflowParser/Conversion/PermissionsHelper.cs @@ -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}'"); } diff --git a/src/Sdk/WorkflowParser/Conversion/WorkflowTemplateConverter.cs b/src/Sdk/WorkflowParser/Conversion/WorkflowTemplateConverter.cs index d281a8ba9..2cb05ebcc 100644 --- a/src/Sdk/WorkflowParser/Conversion/WorkflowTemplateConverter.cs +++ b/src/Sdk/WorkflowParser/Conversion/WorkflowTemplateConverter.cs @@ -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"); diff --git a/src/Sdk/WorkflowParser/Permissions.cs b/src/Sdk/WorkflowParser/Permissions.cs index eacac7a5b..85a9f2aa0 100644 --- a/src/Sdk/WorkflowParser/Permissions.cs +++ b/src/Sdk/WorkflowParser/Permissions.cs @@ -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[] ComparisonKeyMapping(Permissions left, Permissions right)