CHAPTER 9:Actions and Security
正如前面几章所看到的,动作提供了令人印象深刻的自动信息水平。
它们还提供了直接在GitHub中完成任务的方法,否则这是不可能的。
然而,这些同样的功能也可能意味着必须事先考虑和计划的安全风险。
否则,您将打开存储库到多个攻击面和漏洞。
这可以是通过有人故意利用安全漏洞或通过辅助牙科滥用。
你就打开了任何一个接受同样类型的曝光的人的存储库。
请记住,您正在使用的是一个完全为协作而设计的框架。
虽然GitHub为其平台和数据提供了世界级的安全性,但仍应由各个存储库所有者采取适当的预防措施和措施来保护他们的存储库。
这包括管理谁和什么被允许在他们里面操作。
这对于混合中的工作流和操作尤为重要,因为它们的具体目的是执行代码。
在本章中,我将介绍在存储库的上下文中使用工作流和操作时所产生的安全影响。
我将回顾Git- Hub提供的机制,以允许您为您的操作可以做什么以及何时可以执行它们设置适当的界限。
在整个过程中,我还将强调GitHub关于工作流和操作的一些最佳实践。确保操作的使用需要一种多层的方法。
有很多方法可以用来看待这些层,但最简单的方法如下。
实施适当的控制和设置来管理什么可以运行和何时运行
利用令牌和秘密来保护数据;防止常见的威胁,如不受信任的输入;保护依赖关系
检查更改,特别是在通过拉请求时;扫描;监视执行
一个好的开始是利用GitHub的安全选项为您的修复。
Security by Configuration
由于涉及到操作框架,根据配置确定的安全性是关于以下几点的:
• 是否允许运行操作和工作流
• 如果允许,可以运行它们的标准是什么
操作和工作流选项的配置可以通过转到存储库的设置选项卡,然后转到左侧的操作菜单,然后选择常规选项(图9-1)来完成。
(这假设您具有修改存储库的设置的权限。)
❗Actions Runners Menu Item请注意,“Actions”菜单下的另一个选项是“Runners”选项。在这里,您可以配置自己的自托管运行程序。跑步者的内容详见第五章。
选择“General
”选项后,页面顶部是一组选项,用于指定允许此存储库使用的操作和工作流。
目前,此列表中的第一项是操作权限部分。
在这里,您可以允许所有操作、完全禁用它们、将操作和工作流限制在当前用户拥有的存储库中,
或者允许当前用户拥有的符合特定条件的操作和工作流。
(其中的一个共同元素是可重用的工作流。可重用的工作流将在第12章中进一步讨论。)
前三个选项可以通过阅读相关的文本来理解。最后一个选择值得作出一些进一步的解释。
当您选择该选项时(图9-2),您将获得一种指定不同标准的方法。
这个屏幕上的第一个复选框,对于GitHub创建的操作,指的是你在https://github.com/github/actions
下找到的操作。
这些行动都是由GitHub自己支持的(图9-3)。
第二个复选框是允许经过市场验证的创建者进行操作。
在撰写本文时,这里的验证创建者这个术语是指动作的创建者已经被GitHub的业务开发团队验证了。
点击该选项中的已验证的创建者链接将把您带到操作市场页面,列表由已验证的创建者的操作筛选。
这些操作将有一个小图标,看起来像一个齿轮,在作者旁边有一个复选标记(参见图9-4)。
由GitHub本身创建的所有操作都将被验证。
下面是一个自由形式的文本输入框,您可以在其中输入一个以逗号分隔的您想要允许的操作和工作流列表。
不同类型的条目示例,但对于操作,它遵循工作流中的use语句中的标准语法。
对于工作流本身,您可以指定包含.github/workflows
目录的完整路径(图9-5)。
在此部分之后,有一个区域可以将工件和日志保留期从默认的90天更改。(在第7章中讨论了人工制品。)
Managing Execution of Workflows from Pull Requests
页面上的下一节允许您管理哪些外部协作者可以对存储库的拉出请求运行工作流。
这里的想法是,您不一定希望允许分叉您的存储库的每个人执行您在其中定义的工作流(图9-6)。
❗Who Is an Outside Collaborator?谁是外部合作者?
如果您在GitHub上有一个组织,外部协作者是指不是您组织的成员,但存储库管理员允许访问您组织中的存储库的人。
可以这样想:您的工作流是为您的存储库设计的。
它们可能依赖于特定的内容或输入,并可能为您的特定用途创建输出。
如果那些分支您的存储库的人创建了拉请求,然后在没有您批准的情况下执行工作流,这可能会导致意想不到的后果。
如果你使用自我托管的跑步者,情况可能会更糟。
如果允许拉请求以一种计划外的方式执行工作流,则可以处理和访问不应该允许的资源。
请注意,任何刚协作存储库的人都理解执行工作流的含义。
这就是为什么前两个与首次贡献者相关的选项都会关注这个场景。
类似的警告也适用于任何自动化帐户,比如机器人。
这里的选项从限制最少发展到限制最多。
在第一个
选项中,你可以要求批准那些正在执行第一个拉出请求的人,同时他们也是GitHub的“新”用户,并且可能没有意识到其后果。
这里使用new意味着以前从未贡献过。
在第二个
选项中,您可以要求对您的工作流执行第一次拉请求的人的批准,无论他们在GitHub上的时间长度如何。
对于最后一个选项,任何做拉出请求的人都需要批准。
对于大多数存储库来说,默认选项是一个很好的中间地带的选择。
Workflow Permissions
最后,在这个页面上,有一些选项可以设置在存储库中运行工作流时对GITHUB_TOKEN所允许的默认权限集(图9-7)。
GitHub操作提供了一个默认的访问密钥或令牌,可以通过需要访问存储库的工作流中的步骤来使用它。
这些访问可以用于处理存储库中的任何标准项,如内容(文件)、问题、页面、部署等。
这个标记被引用为GITHUB_TOKEN,它有一组广泛的权限,您可以在这里的默认只读或读写的级别上控制。
但是在任何工作流中,您都可以通过权限子句来微调分配给令牌的权限。
我将在下一节的安全性设计问题中详细讨论这个令牌。(GITHUB_TOKEN也将在第6章中进行讨论。)
❗GITHUB_TOKEN默认值
所有新的repos都默认为提供对GITHUB_令牌的只读访问权限。
利用刚才提到的设置是管理谁和什么可以执行特定工作流的好方法。
但是工作流的作者和维护者不应该忘记GitHub允许您保护内容的更通用的方式。
您也可以在存储库中使用它们来保护工作流和操作内容。
其中一个例子是限制对存储库中的个人或团队的访问和所有权。
在一个广泛的层面上,这可以通过使存储库私有化和/或管理邀请谁成为合作者来实现。
在更细粒度的级别上,您可以使用另一个GitHub构造,即代码所有者文件。
The CODEOWNERS File
在GitHub存储库中,具有管理员权限或所有者权限的用户可以在存储库中设置一个代码所有者文件。
此文件的目的是定义负责存储库中(自己的)代码的个人或团队。
在下一个列表中显示了代码所有者文件的示例语法:
此文件与所有其他内容一起存在于存储库的一个分支中。
存储库结构中的建议位置位于根目录、文档子目录中,或在.github子目录中。
行的格式通常是区分大小写的文件或目录模式(类似于.gitignore文件的格式),然后是行上所需的所有者。
所有者通常由@预先提供的GitHub用户id或团队id列出。它们必须具有对存储库的显式写访问权限。
在大多数情况下,您还可以使用他们在GitHub中注册的电子邮件地址。
代码所有者文件提供的是提取请求的自动审核者和批准者。
当用户打开适合代码所有者文件中模式的代码的拉请求时,相应的GitHub用户将自动添加为请求的审阅者。
审核员不会自动请求。由于它特别与工作流文件特别相关,因此可以为代码所有者文件中的.github/工作流目录添加一个条目。
(这是假设您的工作流文件存储在该目录中。)
那么,对这些文件的任何更改都需要指定的审查员的批准。
您可以在GitHub文档中了解关于创建和使用代码所有者文件的更多信息。
除了批准分支中的更改之外,您还可以利用GitHub中可用的其他控制机制,包括受保护的标记、预先检测到的分支和存储库规则,进一步限制对某些破坏性操作的访问,并设置对标记的任何推送和更改的要求。
Protected Tags
在存储库中,您可以配置规则,以防止贡献者创建或删除标记。
这意味着,为了创建受保护的标记,用户必须拥有管理或维护权限,或者拥有在存储库中使用每个任务编辑存储库规则的自定义角色。
同样地,要删除受保护的标记,用户必须具有管理权限或具有编辑存储库规则权限的自定义角色。
❗Beta Feature在撰写本文时,标签保护规则是一个测试版特性,可能会发生变化。
创建标记保护规则是一个简单的过程,只涉及到设置选项卡,然后选择代码和自动化,然后是标签,最后是新规则。
然后您将看到一个对话框,在那里您可以使用基本模式匹配语法输入标签名称模式。
例子如图9-8所示。
分支机构也可以以类似的方式进行保护。但是,可能影响分支的各种操作需要更广泛的选项和规则规范。
Protected Branches
对于存储库中的某些分支以及其中定义的工作流,您可能希望保护它们免受潜在破坏性操作的影响。
这类操作可能包括被删除或被强制推送给它们。
GitHub中的分支保护规则允许您创建一个必须满足某些条件的门,才能继续操作。
鉴于您的GitHub操作工作流对像CI/CD这样的进程至关重要,您可能需要添加一个额外的保护层。
对于重要的分支尤其如此,比如具有生产工作流的分支,它们需要更严格的控制。
下面的列表显示了您可以创建的规则类型的一些示例:
• Require pull request reviews before merging
• Require status checks before merging
• Require conversation resolution before merging
• Require signed commits
• Require linear history
• Require merge queue
• Require deployments to succeed before merging
• Do not allow bypassing the above settings
• Restrict who can push to matching branches
• Allow force pushes
• Allow deletions
要创建新的分支保护规则,请导航到存储库的“settings
”,然后在“Code and automation
”部分中,单击“Branches
”。
在出现的页面上,选择“Add branch protection rule
”,然后填写各个字段(图9-9)。GitHub在线文档详细介绍了各个字段和设置的含义。
如果您发现自己定义了多个保护规则,希望能够作为一个单元管理并且更容易,您可能需要考虑利用存储库规则。
Repository Rules
在存储库规则框架中,规则集是由应用于存储库的名称标识的规则列表。
创建规则集允许您控制用户如何在存储库中与指定的标记和分支进行交互。
创建规则集的目的是通过一组规则来管理,他们可以执行某些操作,比如向特定分支推送提交或删除/重命名标记。
对于您所创建的任何规则集,您都可以指定以下内容:
• A name for the ruleset
• Which branches or tags the ruleset is using via fnmatch syntax
• Users allowed to bypass the ruleset (if any)
• Which protection rules you want the ruleset to enforce
创建一个新的规则集涉及到“设置”选项卡,然后选择代码和自动化,然后选择规则、规则集,最后选择新的分支规则集。见图9-10。
如果规则集与标记保护和分支保护规则也存在于存储库中,那么这些规则集如何融入之中。
当前允许用于规则集的规则集类似于标准的分支保护规则。
它们包括:
• Restrict creations
• Restrict updates
• Restrict deletes
• Require linear history
• Require deployments to succeed before merging
• Require signed commits
• Require a pull request before merging
• Require status checks to pass before merging
• Block force pushes
因此,您可以开始使用规则集,而不覆盖任何现有的保护规则。但是,规则集与其他类型的保护规则相比,规则集有一些优势:
• 多个规则集可以通过一个称为分层的流程同时应用(请参见侧边栏)。
p202