{"id":78752,"date":"2026-09-26T07:16:33","date_gmt":"2026-09-26T07:16:33","guid":{"rendered":"https:\/\/www.devopsschool.com\/blog\/?p=78752"},"modified":"2026-09-26T07:16:37","modified_gmt":"2026-09-26T07:16:37","slug":"github-repository-settings-essentials-2-hour-tutorial","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/blog\/github-repository-settings-essentials-2-hour-tutorial\/","title":{"rendered":"GitHub Repository Settings Essentials \u2014 2-Hour Tutorial"},"content":{"rendered":"\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Last Verified:<\/strong>&nbsp;September 2026<br><strong>Based on:<\/strong>&nbsp;<em>GitHub Repository Settings \u2014 Complete Reference Guide &amp; Tutorial<\/em><br><strong>Duration:<\/strong>&nbsp;2 hours<br><strong>Platform:<\/strong>&nbsp;GitHub.com \/ GitHub Enterprise Cloud unless stated otherwise<br><strong>Audience:<\/strong>&nbsp;Developers, DevOps\/platform engineers, repository administrators, security engineers, team leads, and technical trainers.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">This is the&nbsp;<strong>Essentials<\/strong>&nbsp;version of the complete GitHub Repository Settings guide. It intentionally removes deep API automation, Terraform, Pages, Copilot\/MCP administration, Code Quality deep-dives, advanced governance, and rarely used settings so a learner can understand and practice the&nbsp;<strong>repository controls that matter most in normal engineering work in about two hours<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The goal is not to memorize every item in the&nbsp;<strong>Settings<\/strong>&nbsp;sidebar. The goal is to understand the repository control path:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">General behavior -&gt; Access -&gt; Change protection -&gt; CI\/CD authority\n                 -&gt; Deployment protection -&gt; Security -&gt; Lifecycle safety\n<\/code><\/span><\/pre>\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">flowchart<\/span> <span class=\"hljs-selector-tag\">LR<\/span>\n    <span class=\"hljs-selector-tag\">G<\/span><span class=\"hljs-selector-attr\">&#91;General]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">A<\/span><span class=\"hljs-selector-attr\">&#91;Access]<\/span>\n    <span class=\"hljs-selector-tag\">A<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">R<\/span><span class=\"hljs-selector-attr\">&#91;Rulesets]<\/span>\n    <span class=\"hljs-selector-tag\">R<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">C<\/span><span class=\"hljs-selector-attr\">&#91;Actions]<\/span>\n    <span class=\"hljs-selector-tag\">C<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">E<\/span><span class=\"hljs-selector-attr\">&#91;Environments]<\/span>\n    <span class=\"hljs-selector-tag\">E<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">S<\/span><span class=\"hljs-selector-attr\">&#91;Security]<\/span>\n    <span class=\"hljs-selector-tag\">S<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">L<\/span><span class=\"hljs-selector-attr\">&#91;Lifecycle]<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">By the end of this tutorial, a learner should be able to configure a normal repository safely, explain why a pull request is blocked, understand what authority a workflow has, protect production deployments, and recognize high-risk repository changes.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Important:<\/strong>&nbsp;Exact settings depend on repository visibility, GitHub plan, enabled products, organization settings, and enterprise policy. A repository administrator cannot override a more restrictive organization or enterprise policy.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">1. Two-Hour Learning Plan<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-right\" data-align=\"right\">Time<\/th><th class=\"has-text-align-left\" data-align=\"left\">Module<\/th><th class=\"has-text-align-left\" data-align=\"left\">Outcome<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-right\" data-align=\"right\">0\u201310 min<\/td><td>Repository foundations<\/td><td>Understand settings hierarchy and repository roles<\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">10\u201325 min<\/td><td>General settings<\/td><td>Configure default branch, features, and merge behavior<\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">25\u201340 min<\/td><td>Access and permissions<\/td><td>Understand teams, direct access, roles, and access review<\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">40\u201360 min<\/td><td>Rulesets and branches<\/td><td>Protect&nbsp;<code>main<\/code>&nbsp;with PR, review, and CI requirements<\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">60\u201380 min<\/td><td>GitHub Actions<\/td><td>Control workflow authority, trusted Actions, runners, and forks<\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">80\u201395 min<\/td><td>Environments and secrets<\/td><td>Protect deployments and scope credentials correctly<\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">95\u2013105 min<\/td><td>Security essentials<\/td><td>Understand dependencies, code scanning, secrets, and push protection<\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">105\u2013115 min<\/td><td>Hands-on baseline lab<\/td><td>Apply the essentials to a training repository<\/td><\/tr><tr><td class=\"has-text-align-right\" data-align=\"right\">115\u2013120 min<\/td><td>Review<\/td><td>Reinforce the operating model and troubleshooting sequence<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">What is intentionally outside this 2-hour scope?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Use the complete reference guide later for:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Detailed moderation and interaction limits<\/li>\n\n\n\n<li>Advanced tag and push rules<\/li>\n\n\n\n<li>Release immutability deep-dive<\/li>\n\n\n\n<li>Actions retention and cache tuning<\/li>\n\n\n\n<li>Advanced self-hosted runner architecture<\/li>\n\n\n\n<li>Webhook implementation and signature verification<\/li>\n\n\n\n<li>Copilot instructions, coding agent, and MCP<\/li>\n\n\n\n<li>GitHub Pages<\/li>\n\n\n\n<li>Code Quality and AI Scan administration<\/li>\n\n\n\n<li>Detailed deploy-key operations<\/li>\n\n\n\n<li>Codespaces and Dependabot secret administration<\/li>\n\n\n\n<li>REST, GraphQL, and Terraform automation<\/li>\n\n\n\n<li>Enterprise-scale repository governance<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">These are important, but they are&nbsp;<strong>not prerequisites for day-to-day repository administration<\/strong>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Module 1 \u2014 Repository Settings Foundations<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">2. What Do Repository Settings Control?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Repository settings are the&nbsp;<strong>control plane for one repository<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">They decide:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Who can access the repository<\/li>\n\n\n\n<li>Which branch is the default<\/li>\n\n\n\n<li>How pull requests may be merged<\/li>\n\n\n\n<li>Whether unsafe changes are blocked<\/li>\n\n\n\n<li>Which GitHub Actions workflows may run<\/li>\n\n\n\n<li>What permissions workflows receive<\/li>\n\n\n\n<li>How production deployment is protected<\/li>\n\n\n\n<li>Where secrets and variables are stored<\/li>\n\n\n\n<li>Which security features are enabled<\/li>\n\n\n\n<li>Whether the repository can be exposed, transferred, archived, or deleted<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Think of two planes:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Development plane\n- Code\n- Issues\n- Pull requests\n- Releases\n- Workflows\n\nControl plane\n- Settings\n- Access\n- Rulesets\n- Actions policy\n- Environments\n- Security\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Developers spend most of their time in the development plane. Repository administrators must understand the control plane.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">3. Repository Configuration Hierarchy<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A repository does not operate in isolation.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">flowchart<\/span> <span class=\"hljs-selector-tag\">TD<\/span>\n    <span class=\"hljs-selector-tag\">E<\/span><span class=\"hljs-selector-attr\">&#91;Enterprise policy]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">O<\/span><span class=\"hljs-selector-attr\">&#91;Organization policy]<\/span>\n    <span class=\"hljs-selector-tag\">O<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">R<\/span><span class=\"hljs-selector-attr\">&#91;Repository settings]<\/span>\n    <span class=\"hljs-selector-tag\">R<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">B<\/span><span class=\"hljs-selector-attr\">&#91;Branch \/ tag rules]<\/span>\n    <span class=\"hljs-selector-tag\">R<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">A<\/span><span class=\"hljs-selector-attr\">&#91;Actions settings]<\/span>\n    <span class=\"hljs-selector-tag\">R<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">V<\/span><span class=\"hljs-selector-attr\">&#91;Environment protection]<\/span>\n    <span class=\"hljs-selector-tag\">A<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">W<\/span><span class=\"hljs-selector-attr\">&#91;Workflow permissions]<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">A useful precedence model is:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Enterprise policy\n        \u2193\nOrganization policy\n        \u2193\nRepository settings\n        \u2193\nEnvironment protection\n        \u2193\nWorkflow \/ job permissions\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">For example, a repository cannot allow an Action that the organization has blocked.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Troubleshooting rule<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">When a setting is disabled or cannot be made more permissive, ask:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Is this control owned by the repository, organization, or enterprise?<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">4. Repository Roles<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For organization repositories, the standard roles are:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Role<\/th><th class=\"has-text-align-left\" data-align=\"left\">Typical use<\/th><th class=\"has-text-align-right\" data-align=\"right\">Code write?<\/th><th class=\"has-text-align-left\" data-align=\"left\">Administration<\/th><\/tr><\/thead><tbody><tr><td>Read<\/td><td>Viewers, auditors<\/td><td class=\"has-text-align-right\" data-align=\"right\">No<\/td><td>Minimal<\/td><\/tr><tr><td>Triage<\/td><td>Issue\/PR coordinators<\/td><td class=\"has-text-align-right\" data-align=\"right\">No<\/td><td>Issue\/PR management<\/td><\/tr><tr><td>Write<\/td><td>Developers<\/td><td class=\"has-text-align-right\" data-align=\"right\">Yes<\/td><td>Normal development<\/td><\/tr><tr><td>Maintain<\/td><td>Repository maintainers<\/td><td class=\"has-text-align-right\" data-align=\"right\">Yes<\/td><td>Many management operations<\/td><\/tr><tr><td>Admin<\/td><td>Repository administrators<\/td><td class=\"has-text-align-right\" data-align=\"right\">Yes<\/td><td>Full repository administration, subject to higher policy<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Use the&nbsp;<strong>lowest role that enables the job<\/strong>.<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Developer        -&gt; Write\nRepository lead  -&gt; Maintain when sufficient\nRepo admin       -&gt; Admin only when required\nAuditor          -&gt; Read\nIssue coordinator -&gt; Triage\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">5. Training Repository Setup<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Use a disposable test repository, for example:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">acme-engineering\/repository-settings-lab\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Recommended prerequisites:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Admin access to the test repository<\/li>\n\n\n\n<li>GitHub CLI installed<\/li>\n\n\n\n<li>Git installed<\/li>\n\n\n\n<li>GitHub Actions enabled<\/li>\n\n\n\n<li>A simple CI workflow<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Authenticate:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">gh auth login\ngh auth status\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Set reusable variables:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">export<\/span> OWNER=<span class=\"hljs-string\">\"acme-engineering\"<\/span>\n<span class=\"hljs-keyword\">export<\/span> REPO=<span class=\"hljs-string\">\"repository-settings-lab\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Verify access:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">gh repo view <span class=\"hljs-string\">\"$OWNER\/$REPO\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Module 2 \u2014 General Settings That Matter<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">6. Repository Identity and Default Branch<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Repository identity includes the name, owner, description, website, topics, and visibility.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A rename can affect:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Clone URLs<\/li>\n\n\n\n<li>CI\/CD references<\/li>\n\n\n\n<li>Documentation<\/li>\n\n\n\n<li>Badges<\/li>\n\n\n\n<li>Package configuration<\/li>\n\n\n\n<li>External integrations<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">GitHub commonly redirects old repository URLs, but integrations should be updated rather than relying on redirects indefinitely.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Update a local remote after a rename:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">git remote <span class=\"hljs-keyword\">set<\/span>-url origin git@github.com:acme\/payments-api.git\ngit remote -v\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Default branch<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The default branch\u2014commonly&nbsp;<code>main<\/code>\u2014influences:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>New pull requests<\/li>\n\n\n\n<li>Repository landing view<\/li>\n\n\n\n<li>Branch comparisons<\/li>\n\n\n\n<li>Workflow assumptions<\/li>\n\n\n\n<li>Protection rules<\/li>\n\n\n\n<li>Deployment rules<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">A workflow may explicitly depend on it:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">on<\/span>:\n  <span class=\"hljs-selector-tag\">push<\/span>:\n    <span class=\"hljs-selector-tag\">branches<\/span>: <span class=\"hljs-selector-attr\">&#91;main]<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Changing the default branch does&nbsp;<strong>not<\/strong>&nbsp;automatically rewrite every workflow or external integration.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">7. Repository Features<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Common optional features include:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Feature<\/th><th class=\"has-text-align-left\" data-align=\"left\">Use it for<\/th><\/tr><\/thead><tbody><tr><td>Issues<\/td><td>Bugs, tasks, feature requests<\/td><\/tr><tr><td>Discussions<\/td><td>Community or long-form discussion<\/td><\/tr><tr><td>Projects<\/td><td>Planning connected to repository work<\/td><\/tr><tr><td>Wiki<\/td><td>Repository documentation when a wiki model fits<\/td><\/tr><tr><td>Actions<\/td><td>CI\/CD and automation<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Enable what the team actually uses.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example internal microservice:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"HTTP\" data-shcb-language-slug=\"http\"><span><code class=\"hljs language-http\"><span class=\"hljs-attribute\">Issues<\/span>: Yes\n<span class=\"hljs-attribute\">Actions<\/span>: Yes\n<span class=\"hljs-attribute\">Projects<\/span>: Only if planning happens in GitHub\n<span class=\"hljs-attribute\">Discussions<\/span>: Usually no\n<span class=\"hljs-attribute\">Wiki<\/span>: Usually no if docs live elsewhere\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTTP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">http<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">8. Pull Request Merge Methods<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">GitHub supports three common strategies:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Method<\/th><th class=\"has-text-align-left\" data-align=\"left\">Result<\/th><th class=\"has-text-align-left\" data-align=\"left\">Good fit<\/th><\/tr><\/thead><tbody><tr><td>Merge commit<\/td><td>Keeps branch commits and adds merge commit<\/td><td>Full branch history<\/td><\/tr><tr><td>Squash merge<\/td><td>One commit per PR<\/td><td>Clean application history<\/td><\/tr><tr><td>Rebase merge<\/td><td>Replays commits onto base<\/td><td>Linear individual-commit history<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Simple decision model:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">One commit per PR?           -&gt; Squash\nKeep complete branch history? -&gt; Merge commit\nLinear individual commits?    -&gt; Rebase\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">The right method depends on how the team uses Git history.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">9. Auto-Merge and Branch Cleanup<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Auto-merge lets a pull request merge automatically after all required conditions pass.<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">flowchart LR\n    PR&#91;Pull request] --&gt; RV&#91;Review]\n    RV --&gt; CI&#91;Required CI]\n    CI --&gt; Q{All rules pass?}\n    Q -- No --&gt; W&#91;Wait]\n    Q -- Yes --&gt; M&#91;Merge]\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">It works well when CI is reliable and protection rules are meaningful.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">GitHub can also automatically delete the source branch after merge. This is useful for short-lived feature branches and keeps the repository clean.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Practical baseline<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">Default<\/span> branch: main\nIssues: Enabled\nActions: Enabled\nSquash merge: Enabled\nAuto-merge: Optional, when team uses it\nDelete merged head branches: Enabled\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Module 3 \u2014 Access and Permissions<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">10. Repository Access Model<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Access can come from multiple sources.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">flowchart<\/span> <span class=\"hljs-selector-tag\">TD<\/span>\n    <span class=\"hljs-selector-tag\">T<\/span><span class=\"hljs-selector-attr\">&#91;Team]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">E<\/span><span class=\"hljs-selector-attr\">&#91;Effective access]<\/span>\n    <span class=\"hljs-selector-tag\">D<\/span><span class=\"hljs-selector-attr\">&#91;Direct collaborator]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">E<\/span>\n    <span class=\"hljs-selector-tag\">O<\/span><span class=\"hljs-selector-attr\">&#91;Organization \/ base access]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">E<\/span>\n    <span class=\"hljs-selector-tag\">E<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">P<\/span><span class=\"hljs-selector-attr\">&#91;Repository protections still apply]<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Important distinction:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Permission determines what a user may attempt. Rules determine what changes GitHub will accept.<\/strong><\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">A developer may have&nbsp;<code>Write<\/code>&nbsp;access and still be blocked from pushing to&nbsp;<code>main<\/code>&nbsp;because a ruleset requires pull requests.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">11. Team Access vs Direct Access<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For organization repositories, prefer team-based access.<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Alice ----+\nBob ------+--&gt; payments-team --&gt; payments repositories\nCarol ----+\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Benefits:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Easier onboarding\/offboarding<\/li>\n\n\n\n<li>Easier access review<\/li>\n\n\n\n<li>Better ownership model<\/li>\n\n\n\n<li>Works well with CODEOWNERS<\/li>\n\n\n\n<li>Less permission drift<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Direct access is reasonable for exceptional or temporary cases, such as a contractor who needs one repository for a limited period.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">12. Mixed Roles and Access Review<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A user can receive access from multiple sources.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Alice\n  -&gt; engineering team: Write\n  -&gt; direct grant: Admin\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Her effective access is more powerful than the team role suggests.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Use&nbsp;<strong>Settings -&gt; Collaborators and teams<\/strong>&nbsp;to inspect people, teams, roles, and mixed access.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A simple review table:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Actor<\/th><th class=\"has-text-align-left\" data-align=\"left\">Source<\/th><th class=\"has-text-align-left\" data-align=\"left\">Role<\/th><th class=\"has-text-align-left\" data-align=\"left\">Needed?<\/th><th class=\"has-text-align-left\" data-align=\"left\">Action<\/th><\/tr><\/thead><tbody><tr><td><code>payments-team<\/code><\/td><td>Team<\/td><td>Write<\/td><td>Yes<\/td><td>Keep<\/td><\/tr><tr><td><code>platform-team<\/code><\/td><td>Team<\/td><td>Maintain<\/td><td>Yes<\/td><td>Keep<\/td><\/tr><tr><td><code>contractor-a<\/code><\/td><td>Direct<\/td><td>Write<\/td><td>No<\/td><td>Remove<\/td><\/tr><tr><td><code>alice<\/code><\/td><td>Direct<\/td><td>Admin<\/td><td>Maybe not<\/td><td>Replace with team role<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Essential rule<\/h3>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Repository access should be explainable in one minute.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Module 4 \u2014 Rulesets and Protected Branches<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">13. Why Rulesets Matter<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Rulesets control how users interact with branches, tags, and\u2014on eligible plans\u2014pushes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The most important use case is protecting the default branch.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">flowchart<\/span> <span class=\"hljs-selector-tag\">LR<\/span>\n    <span class=\"hljs-selector-tag\">F<\/span><span class=\"hljs-selector-attr\">&#91;Feature branch]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">PR<\/span><span class=\"hljs-selector-attr\">&#91;Pull request]<\/span>\n    <span class=\"hljs-selector-tag\">PR<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">R<\/span><span class=\"hljs-selector-attr\">&#91;Review]<\/span>\n    <span class=\"hljs-selector-tag\">R<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">CI<\/span><span class=\"hljs-selector-attr\">&#91;Required checks]<\/span>\n    <span class=\"hljs-selector-tag\">CI<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">M<\/span><span class=\"hljs-selector-attr\">&#91;Merge]<\/span>\n    <span class=\"hljs-selector-tag\">M<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">MAIN<\/span><span class=\"hljs-selector-attr\">&#91;main]<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Without protection:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Developer -&gt; direct push -&gt; main\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">With a ruleset:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Developer -&gt; PR -&gt; review -&gt; CI -&gt; merge -&gt; main\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">14. Rulesets vs Legacy Branch Protection<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Both can protect branches.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Capability<\/th><th class=\"has-text-align-left\" data-align=\"left\">Branch protection<\/th><th class=\"has-text-align-left\" data-align=\"left\">Rulesets<\/th><\/tr><\/thead><tbody><tr><td>Protect branch<\/td><td>Yes<\/td><td>Yes<\/td><\/tr><tr><td>Multiple policies layer<\/td><td>Limited<\/td><td>Yes<\/td><\/tr><tr><td>Easy visibility of active policy<\/td><td>Less<\/td><td>Better<\/td><\/tr><tr><td>Branch and tag targeting<\/td><td>Primarily branch<\/td><td>Branch and tag<\/td><\/tr><tr><td>Push restrictions<\/td><td>No<\/td><td>Supported on eligible plans<\/td><\/tr><tr><td>Disable policy without deleting<\/td><td>Less flexible<\/td><td>Yes<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Rulesets and legacy branch protection can apply&nbsp;<strong>at the same time<\/strong>. If a pull request is unexpectedly blocked, inspect both.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">15. Essential Default-Branch Rules<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For an important application repository, a practical starting baseline is:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Require pull request before merge<\/li>\n\n\n\n<li>Require at least one approval<\/li>\n\n\n\n<li>Require meaningful status checks<\/li>\n\n\n\n<li>Require conversation resolution where useful<\/li>\n\n\n\n<li>Require CODEOWNER review for sensitive paths when needed<\/li>\n\n\n\n<li>Block force pushes<\/li>\n\n\n\n<li>Restrict deletion of the protected branch<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Optional depending on policy:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Signed commits<\/li>\n\n\n\n<li>Linear history<\/li>\n\n\n\n<li>Multiple approvals<\/li>\n\n\n\n<li>Required deployment before merge<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">Target: main\n<span class=\"hljs-keyword\">Require<\/span> pull request: Yes\nApprovals: <span class=\"hljs-number\">1<\/span>\nRequired check: test\nBlock force push: Yes\nRestrict deletion: Yes\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Start simple. A ruleset nobody understands becomes operational friction.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">16. Required Status Checks<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Required checks connect CI to merge governance.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">name: CI\n\non:\n  pull_request:\n\npermissions:\n  contents: read\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\/checkout@v7\n      - run: <span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"run tests\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">If the required check is renamed or the workflow no longer triggers, the pull request may remain blocked.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Troubleshoot in this order:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Did the workflow trigger?<\/li>\n\n\n\n<li>Did the job run?<\/li>\n\n\n\n<li>What is the exact check name?<\/li>\n\n\n\n<li>Does the ruleset require that exact check?<\/li>\n\n\n\n<li>Does another ruleset or branch protection rule also apply?<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">17. CODEOWNERS and Bypass<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><code>CODEOWNERS<\/code>&nbsp;maps sensitive paths to responsible reviewers.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\">* <span class=\"hljs-keyword\">@acme<\/span>\/platform\n.github\/workflows\/ @acme\/platform @acme\/security\nsrc\/payments\/ @acme\/payments\ninfra\/ @acme\/platform\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">A ruleset can require code-owner review.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is valuable for workflow files because they may control:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>GITHUB_TOKEN<\/code><\/li>\n\n\n\n<li>Secrets<\/li>\n\n\n\n<li>OIDC cloud identity<\/li>\n\n\n\n<li>Production deployment<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Bypass<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Rulesets can allow approved users, teams, roles, or GitHub Apps to bypass rules.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Keep bypass narrow and documented.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Before adding bypass, ask:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">What exact operational scenario requires it?<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Module 5 \u2014 GitHub Actions Repository Settings<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">18. Why Actions Settings Are Security Settings<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">GitHub Actions can:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Execute arbitrary code<\/li>\n\n\n\n<li>Read source code<\/li>\n\n\n\n<li>Use\u00a0<code>GITHUB_TOKEN<\/code><\/li>\n\n\n\n<li>Read secrets<\/li>\n\n\n\n<li>Request OIDC tokens<\/li>\n\n\n\n<li>Publish packages\/releases<\/li>\n\n\n\n<li>Deploy applications<\/li>\n\n\n\n<li>Reach internal networks from self-hosted runners<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Therefore:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Workflow authority is repository authority.<\/strong><\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">19. Five Essential Actions Controls<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">flowchart<\/span> <span class=\"hljs-selector-tag\">TD<\/span>\n    <span class=\"hljs-selector-tag\">A<\/span><span class=\"hljs-selector-attr\">&#91;Actions enabled?]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">B<\/span><span class=\"hljs-selector-attr\">&#91;Which Actions are trusted?]<\/span>\n    <span class=\"hljs-selector-tag\">B<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">C<\/span><span class=\"hljs-selector-attr\">&#91;What may GITHUB_TOKEN do?]<\/span>\n    <span class=\"hljs-selector-tag\">C<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">D<\/span><span class=\"hljs-selector-attr\">&#91;Where does the job run?]<\/span>\n    <span class=\"hljs-selector-tag\">D<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">E<\/span><span class=\"hljs-selector-attr\">&#91;Which credentials can it access?]<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">The five controls are:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Actions enablement<\/li>\n\n\n\n<li>Allowed Actions and reusable workflows<\/li>\n\n\n\n<li>Default\u00a0<code>GITHUB_TOKEN<\/code>\u00a0permissions<\/li>\n\n\n\n<li>Runner trust boundary<\/li>\n\n\n\n<li>Secrets \/ OIDC access<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">20. Allowed Actions and Reusable Workflows<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Repository settings can disable Actions or restrict which actions and reusable workflows may run, subject to organization policy.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Treat third-party Actions as software dependencies.<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">- uses: vendor\/action@v1\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">This means third-party code executes inside your CI\/CD trust boundary.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Prefer:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">GitHub-maintained Actions\nOrganization-maintained reusable workflows\nReviewed third-party Actions\nImmutable SHA pinning for high-assurance workflows\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">21.&nbsp;<code>GITHUB_TOKEN<\/code>&nbsp;Permissions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">GitHub Actions can receive a repository-scoped&nbsp;<code>GITHUB_TOKEN<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Strong baseline:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">Repository <span class=\"hljs-keyword\">default<\/span>: Restricted\/read-oriented\n<span class=\"hljs-attr\">Workflow<\/span>: Request only the permission it needs\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">CI example:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">name: CI\n\non:\n  push:\n    branches: &#91;main]\n  pull_request:\n\npermissions:\n  contents: read\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\/checkout@v7\n      - run: <span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"test\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">A release workflow may need:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">permissions:\n  contents: write\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">OIDC-based cloud authentication commonly needs:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">permissions:\n  contents: read\n  id-token: write\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\"><code>id-token: write<\/code>&nbsp;permits requesting an OIDC token; the cloud trust policy still decides what cloud permissions are granted.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">22. Fork Workflows and Runners<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Fork pull requests are a trust boundary because an external contributor may control code executed by CI.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ask:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Does the workflow receive secrets?<\/li>\n\n\n\n<li>Is the token write-capable?<\/li>\n\n\n\n<li>Does it run on a self-hosted runner?<\/li>\n\n\n\n<li>Does it require approval first?<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Runner types<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>GitHub-hosted runners<\/li>\n\n\n\n<li>Repository self-hosted runners<\/li>\n\n\n\n<li>Organization runners<\/li>\n\n\n\n<li>Enterprise runners<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">A self-hosted runner executes repository-controlled code on infrastructure you operate.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Strong rule:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Do not run untrusted public pull-request code on a privileged, persistent self-hosted runner.<\/p>\n<\/blockquote>\n\n\n\n<h3 class=\"wp-block-heading\">Actions baseline<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">Actions: Enabled when needed\nAllowed Actions: Follow approved organization policy\n<span class=\"hljs-keyword\">Default<\/span> GITHUB_TOKEN: Restricted\nWorkflow permissions: Explicit in YAML\n<span class=\"hljs-keyword\">Self<\/span>-hosted runner: Only when justified\nCloud access: OIDC where practical\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Module 6 \u2014 Environments, Secrets, and Variables<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">23. What Is a GitHub Environment?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">An environment represents a deployment target such as:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">development\nstaging\nproduction\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">A job can reference it:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">jobs:\n  deploy:\n    runs-on: ubuntu-latest\n    environment: production\n    steps:\n      - run: <span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"deploying production\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Depending on plan and repository visibility, an environment can provide:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Required reviewers<\/li>\n\n\n\n<li>Wait timers<\/li>\n\n\n\n<li>Deployment branch\/tag restrictions<\/li>\n\n\n\n<li>Custom protection rules<\/li>\n\n\n\n<li>Environment secrets<\/li>\n\n\n\n<li>Environment variables<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">24. Production Environment Flow<\/h2>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">flowchart TD\n    M&#91;Code merged] --&gt; W&#91;Deployment workflow]\n    W --&gt; E&#91;production environment]\n    E --&gt; A{Protection satisfied?}\n    A -- No --&gt; X&#91;Wait \/ block]\n    A -- Yes --&gt; S&#91;Environment secrets available]\n    S --&gt; P&#91;Deploy]\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Environment protection separates normal CI from production authority.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Useful controls include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Required reviewer<\/li>\n\n\n\n<li>Prevent self-review where supported<\/li>\n\n\n\n<li>Branch\/tag restriction such as\u00a0<code>main<\/code>\u00a0or\u00a0<code>v*<\/code><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">An approval should represent a real control, not ceremony.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">25. Secrets vs Variables<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Type<\/th><th class=\"has-text-align-left\" data-align=\"left\">Use for<\/th><th class=\"has-text-align-left\" data-align=\"left\">Example<\/th><\/tr><\/thead><tbody><tr><td>Secret<\/td><td>Sensitive value<\/td><td>API token<\/td><\/tr><tr><td>Variable<\/td><td>Non-sensitive configuration<\/td><td><code>REGION=ap-northeast-1<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Repository secret:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">env:\n  API_TOKEN: ${{ secrets.API_TOKEN }}\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Environment secret:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Available only to jobs that reference the environment<\/li>\n\n\n\n<li>Released only after environment protections pass<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">For production credentials, environment scope is often better than broad repository scope.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Variable:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-19\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">- run: <span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"Region: ${{ vars.REGION }}\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-19\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Never use variables as a password\/token store.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">26. Prefer OIDC for Cloud Credentials<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Avoid long-lived cloud credentials when federation is practical.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Instead of:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">AWS_ACCESS_KEY_ID -&gt; GitHub secret\nAWS_SECRET_ACCESS_KEY -&gt; GitHub secret\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Prefer:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">GitHub workflow\n   -&gt; OIDC token\n   -&gt; cloud IAM trust policy\n   -&gt; short-lived cloud credential\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Benefits:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>No permanent cloud key copied into GitHub<\/li>\n\n\n\n<li>Short-lived credentials<\/li>\n\n\n\n<li>Trust can be restricted by repository, branch, environment, or workflow identity<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">OIDC still requires least-privilege cloud IAM permissions.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Module 7 \u2014 Repository Security Essentials<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">27. Security Controls Mental Model<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-20\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">Dependencies -&gt; Dependabot\nSource code  -&gt; Code scanning\nSecrets      -&gt; Secret scanning\n<span class=\"hljs-keyword\">New<\/span> pushes   -&gt; Push protection\nChanges      -&gt; Rulesets <span class=\"hljs-keyword\">and<\/span> reviews\nDeployment   -&gt; Environments\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-20\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Feature availability depends on plan, visibility, organization policy, and security-product licensing.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">28. Dependency Security<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The dependency graph helps GitHub understand packages used by the repository.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dependabot can provide:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Vulnerability alerts<\/li>\n\n\n\n<li>Security update pull requests<\/li>\n\n\n\n<li>Scheduled version update pull requests<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Minimal example:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-21\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">version: <span class=\"hljs-number\">2<\/span>\n<span class=\"hljs-attr\">updates<\/span>:\n  - package-ecosystem: <span class=\"hljs-string\">\"npm\"<\/span>\n    <span class=\"hljs-attr\">directory<\/span>: <span class=\"hljs-string\">\"\/\"<\/span>\n    <span class=\"hljs-attr\">schedule<\/span>:\n      interval: <span class=\"hljs-string\">\"weekly\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-21\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Remember:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Dependabot alerts          -&gt; tell you a dependency is vulnerable\nDependabot security update -&gt; can open a remediation PR\nDependabot version update  -&gt; keeps dependencies current on schedule\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">29. Code Scanning<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Code scanning analyzes source code for vulnerabilities and coding errors. GitHub supports CodeQL and compatible SARIF integrations.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Sensible rollout:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Enable scanning.<\/li>\n\n\n\n<li>Establish a baseline.<\/li>\n\n\n\n<li>Fix meaningful existing findings.<\/li>\n\n\n\n<li>Focus merge policy on important new findings.<\/li>\n\n\n\n<li>Avoid blocking developers on an unexplained flood of legacy alerts.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Security gates work best when teams trust the signal.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">30. Secret Scanning and Push Protection<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Secret scanning detects supported credentials committed to the repository.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If a real credential is committed, removing the line from the latest commit is not enough; the credential may still exist in history.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Response:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-22\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">Detect\n-&gt; revoke \/ rotate\n-&gt; remove <span class=\"hljs-keyword\">from<\/span> code\/history <span class=\"hljs-keyword\">as<\/span> appropriate\n-&gt; review exposure\n-&gt; prevent recurrence\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-22\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Push protection attempts to stop supported secrets&nbsp;<strong>before they enter the repository<\/strong>.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-23\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">Secret scanning -&gt; detect committed secrets\nPush protection -&gt; prevent supported secrets <span class=\"hljs-keyword\">from<\/span> being introduced\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-23\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Essential security baseline<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>[ ] Dependency visibility enabled\/available as appropriate<\/li>\n\n\n\n<li>[ ] Dependabot alerts enabled where applicable<\/li>\n\n\n\n<li>[ ] Code scanning enabled where available and useful<\/li>\n\n\n\n<li>[ ] Secret scanning enabled where available<\/li>\n\n\n\n<li>[ ] Push protection enabled where available<\/li>\n\n\n\n<li>[ ] Default branch protected<\/li>\n\n\n\n<li>[ ] Workflow files protected through review\/CODEOWNERS<\/li>\n\n\n\n<li>[ ] Production protected with environments<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Module 8 \u2014 High-Risk Lifecycle Settings<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">31. Danger Zone<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Repository&nbsp;<strong>Danger Zone<\/strong>&nbsp;actions include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Change repository visibility<\/li>\n\n\n\n<li>Transfer repository<\/li>\n\n\n\n<li>Archive repository<\/li>\n\n\n\n<li>Delete repository<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Treat them as change-management events, not routine clicks.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">32. Visibility Changes<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Visibility may be public, private, or internal for eligible enterprise repositories.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A visibility change can affect more than source files, including:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Fork relationships<\/li>\n\n\n\n<li>Actions history\/exposure<\/li>\n\n\n\n<li>Security behavior<\/li>\n\n\n\n<li>Pages or packages<\/li>\n\n\n\n<li>Stars\/watchers<\/li>\n\n\n\n<li>External access expectations<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Safe procedure:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Confirm why the change is needed.<\/li>\n\n\n\n<li>Review code, issues, PRs, Actions logs\/artifacts, and integrations.<\/li>\n\n\n\n<li>Review forks, packages, and publishing surfaces.<\/li>\n\n\n\n<li>Confirm organization policy permits it.<\/li>\n\n\n\n<li>Make the change.<\/li>\n\n\n\n<li>Validate access afterward.<\/li>\n<\/ol>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Never convert a private repository to public as a casual experiment.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">33. Transfer, Archive, and Delete<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Transfer<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Before transfer, review:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>New owner permissions<\/li>\n\n\n\n<li>Automation\/integrations<\/li>\n\n\n\n<li>Packages<\/li>\n\n\n\n<li>Fork relationships<\/li>\n\n\n\n<li>Secrets\/deploy keys<\/li>\n\n\n\n<li>Organization policies that will change<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Archive<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Archiving makes a repository read-only while preserving it as reference.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Good for retired or superseded systems.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Delete<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Deletion is destructive and can affect source code, issues, PRs, automation references, packages, and integrations.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Recommended lifecycle:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-24\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">flowchart<\/span> <span class=\"hljs-selector-tag\">LR<\/span>\n    <span class=\"hljs-selector-tag\">A<\/span><span class=\"hljs-selector-attr\">&#91;Active]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">D<\/span><span class=\"hljs-selector-attr\">&#91;Deprecated]<\/span>\n    <span class=\"hljs-selector-tag\">D<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">AR<\/span><span class=\"hljs-selector-attr\">&#91;Archived]<\/span>\n    <span class=\"hljs-selector-tag\">AR<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">X<\/span><span class=\"hljs-selector-attr\">&#91;Deleted only if justified]<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-24\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">When practical:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Deprecate -&gt; Archive -&gt; Delete only after review\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Module 9 \u2014 10-Minute Hands-On Essentials Lab<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">34. Scenario<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You administer:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">acme-engineering\/repository-settings-lab\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">The repository contains a small web service. Your goal is to create a safe baseline without over-engineering it.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">35. Lab Step 1 \u2014 General and Access<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Confirm:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-25\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">Default<\/span> branch: main\nIssues: Enabled\nActions: Enabled\nSquash merge: Enabled\nDelete merged head branches: Enabled\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-25\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Then open:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Settings -&gt; Collaborators and teams\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Review:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Who has Admin?<\/li>\n\n\n\n<li>Which teams have Write\/Maintain?<\/li>\n\n\n\n<li>Are direct grants necessary?<\/li>\n\n\n\n<li>Are there stale collaborators or mixed roles?<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Target model:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">payments-dev -&gt; Write\nplatform     -&gt; Maintain\nrepo-admins  -&gt; Admin only where necessary\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">36. Lab Step 2 \u2014 CI and Ruleset<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Create&nbsp;<code>.github\/workflows\/ci.yml<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-26\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">name: CI\n\non:\n  pull_request:\n  push:\n    branches: &#91;main]\n\npermissions:\n  contents: read\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\/checkout@v7\n      - name: Test\n        run: <span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"tests passed\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-26\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Create a branch ruleset targeting&nbsp;<code>main<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-27\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">Require<\/span> pull request: Yes\nRequired approvals: <span class=\"hljs-number\">1<\/span> when practical\nRequired status check: CI\/test when stable\nBlock force push: Yes\nRestrict deletion: Yes\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-27\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Test that GitHub explains which condition blocks a merge.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">37. Lab Step 3 \u2014 Actions and Environment<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Open:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Settings -&gt; Actions -&gt; General\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Review:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Allowed Actions\/reusable workflows<\/li>\n\n\n\n<li>Default\u00a0<code>GITHUB_TOKEN<\/code>\u00a0permissions<\/li>\n\n\n\n<li>Fork workflow policy<\/li>\n\n\n\n<li>Runner configuration<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Then create environment:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">production\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Where supported, configure:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Required reviewer<\/li>\n\n\n\n<li>Prevent self-review<\/li>\n\n\n\n<li>Deployment branch restriction to\u00a0<code>main<\/code><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Add non-sensitive variable:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">REGION=ap-northeast-1\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Example workflow:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-28\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">name: Deploy\n\non:\n  workflow_dispatch:\n\npermissions:\n  contents: read\n\njobs:\n  deploy:\n    runs-on: ubuntu-latest\n    environment: production\n    steps:\n      - run: <span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"Deploying to ${{ vars.REGION }}\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-28\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">38. Lab Step 4 \u2014 Security Review<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Identify which controls are available in your repository:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Dependency graph<\/li>\n\n\n\n<li>Dependabot alerts<\/li>\n\n\n\n<li>Dependabot security updates<\/li>\n\n\n\n<li>Code scanning<\/li>\n\n\n\n<li>Secret scanning<\/li>\n\n\n\n<li>Push protection<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Do not enable licensed features in a production organization without confirming policy and licensing.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Expected learning outcome<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">You can explain this chain:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">User access\n-&gt; repository role\n-&gt; pull request\n-&gt; ruleset\n-&gt; CI authority\n-&gt; environment gate\n-&gt; security controls\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">That chain is the core of GitHub Repository Settings administration.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">5-Minute Review<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">39. Ten Rules to Remember<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Learn the policy hierarchy.<\/strong>\u00a0Organization and enterprise controls can restrict repository settings.<\/li>\n\n\n\n<li><strong>Keep Admin rare.<\/strong>\u00a0Use Write or Maintain when sufficient.<\/li>\n\n\n\n<li><strong>Prefer teams.<\/strong>\u00a0Direct grants are harder to review and revoke.<\/li>\n\n\n\n<li><strong>Protect the default branch.<\/strong>\u00a0Important changes should flow through PR + review + CI.<\/li>\n\n\n\n<li><strong>Prefer rulesets for modern protection.<\/strong>\u00a0They are visible, targetable, and layerable.<\/li>\n\n\n\n<li><strong>Treat workflows as privileged code.<\/strong>\u00a0They can control tokens, secrets, OIDC, and deployment.<\/li>\n\n\n\n<li><strong>Keep\u00a0<code>GITHUB_TOKEN<\/code>\u00a0restrictive.<\/strong>\u00a0Grant write permissions only where needed.<\/li>\n\n\n\n<li><strong>Protect production with environments.<\/strong>\u00a0Separate CI authority from deployment authority.<\/li>\n\n\n\n<li><strong>Use secrets correctly and prefer OIDC for cloud access.<\/strong>\u00a0Variables are not a credential store.<\/li>\n\n\n\n<li><strong>Treat Danger Zone actions as governance events.<\/strong>\u00a0Visibility, transfer, archive, and delete can have broad side effects.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">40. Common Anti-Patterns<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Anti-pattern<\/th><th class=\"has-text-align-left\" data-align=\"left\">Why it is a problem<\/th><th class=\"has-text-align-left\" data-align=\"left\">Better approach<\/th><\/tr><\/thead><tbody><tr><td>Everyone is Admin<\/td><td>Large destructive blast radius<\/td><td>Write\/Maintain + limited Admin<\/td><\/tr><tr><td>Direct grants everywhere<\/td><td>Hard to review\/revoke<\/td><td>Team access<\/td><\/tr><tr><td>Unprotected&nbsp;<code>main<\/code><\/td><td>Review\/CI can be bypassed<\/td><td>Ruleset<\/td><\/tr><tr><td>Too many required checks<\/td><td>Slow, flaky merges<\/td><td>Require policy-critical checks only<\/td><\/tr><tr><td>Broad bypass<\/td><td>Policy becomes optional<\/td><td>Small documented bypass set<\/td><\/tr><tr><td>Broad&nbsp;<code>GITHUB_TOKEN<\/code><\/td><td>Workflow compromise gains power<\/td><td>Restricted default + explicit permissions<\/td><\/tr><tr><td>Any Marketplace Action allowed<\/td><td>Supply-chain risk<\/td><td>Approved Actions<\/td><\/tr><tr><td>Privileged self-hosted runner for untrusted PRs<\/td><td>Host\/network exposure<\/td><td>Trusted isolated\/ephemeral runners<\/td><\/tr><tr><td>Production secret is repository-wide<\/td><td>Broader exposure<\/td><td>Environment secret or OIDC<\/td><\/tr><tr><td>Secret placed in&nbsp;<code>vars<\/code><\/td><td>Not a secret store<\/td><td>Use&nbsp;<code>secrets<\/code><\/td><\/tr><tr><td>Workflow files have no special review<\/td><td>CI\/CD authority can change casually<\/td><td>CODEOWNERS + ruleset<\/td><\/tr><tr><td>Private repo made public without review<\/td><td>Data exposure<\/td><td>Visibility checklist<\/td><\/tr><tr><td>Old repo immediately deleted<\/td><td>History\/context lost<\/td><td>Deprecate -&gt; archive -&gt; delete if justified<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">41. Troubleshooting Essentials<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Problem<\/th><th class=\"has-text-align-left\" data-align=\"left\">First thing to check<\/th><\/tr><\/thead><tbody><tr><td>User cannot access repository<\/td><td>Team\/direct access and role<\/td><\/tr><tr><td>User has too much access<\/td><td>Mixed roles and direct grants<\/td><\/tr><tr><td>Direct push blocked<\/td><td>Rulesets + branch protection<\/td><\/tr><tr><td>PR cannot merge<\/td><td>Review, status check, conversation, deployment rule<\/td><\/tr><tr><td>Required check missing<\/td><td>Workflow trigger and exact check name<\/td><\/tr><tr><td>Ruleset seems ignored<\/td><td>Target and enforcement status<\/td><\/tr><tr><td>Admin cannot bypass<\/td><td>Bypass configuration<\/td><\/tr><tr><td>Workflow does not run<\/td><td>Actions policy + trigger<\/td><\/tr><tr><td>Action denied<\/td><td>Repository\/org allowlist<\/td><\/tr><tr><td>Workflow gets 403<\/td><td><code>GITHUB_TOKEN<\/code>&nbsp;permissions<\/td><\/tr><tr><td>Job stays queued<\/td><td>Runner labels\/access\/capacity<\/td><\/tr><tr><td>Secret unavailable<\/td><td>Secret scope, event, environment reference<\/td><\/tr><tr><td>Production waits<\/td><td>Environment protection\/reviewer<\/td><\/tr><tr><td>Branch cannot deploy<\/td><td>Environment branch\/tag rule<\/td><\/tr><tr><td>Security feature unavailable<\/td><td>Plan, visibility, license, org policy<\/td><\/tr><tr><td>Setting greyed out<\/td><td>Organization\/enterprise policy<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Universal troubleshooting order:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">1. What action is failing?\n2. Which repository role does the actor have?\n3. Which ruleset\/protection applies?\n4. Is there a higher-level policy?\n5. Is the problem access, rules, Actions, environment, or security?\n6. What exact unmet condition does GitHub show?\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">42. Quick Reference Cheat Sheet<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Main settings locations<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Need<\/th><th class=\"has-text-align-left\" data-align=\"left\">Common area<\/th><\/tr><\/thead><tbody><tr><td>Rename \/ merge settings<\/td><td>Settings -&gt; General<\/td><\/tr><tr><td>Manage people\/teams<\/td><td>Settings -&gt; Collaborators and teams<\/td><\/tr><tr><td>Rulesets<\/td><td>Settings -&gt; Rulesets<\/td><\/tr><tr><td>Legacy branch protection<\/td><td>Settings -&gt; Branches<\/td><\/tr><tr><td>Actions permissions<\/td><td>Settings -&gt; Actions -&gt; General<\/td><\/tr><tr><td>Runners<\/td><td>Settings -&gt; Actions -&gt; Runners<\/td><\/tr><tr><td>Environments<\/td><td>Settings -&gt; Environments<\/td><\/tr><tr><td>Actions secrets\/variables<\/td><td>Settings -&gt; Secrets and variables -&gt; Actions<\/td><\/tr><tr><td>Security features<\/td><td>Settings -&gt; Advanced Security \/ Security and analysis<\/td><\/tr><tr><td>Visibility \/ transfer \/ archive \/ delete<\/td><td>Settings -&gt; General -&gt; Danger Zone<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">GitHub navigation changes over time. Learn the&nbsp;<strong>capability name and purpose<\/strong>, not only the sidebar position.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Essential CLI<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-29\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">gh auth status\ngh repo view <span class=\"hljs-string\">\"$OWNER\/$REPO\"<\/span>\ngh api <span class=\"hljs-string\">\"\/repos\/$OWNER\/$REPO\"<\/span>\ngh api --paginate <span class=\"hljs-string\">\"\/repos\/$OWNER\/$REPO\/collaborators\"<\/span>\ngh api <span class=\"hljs-string\">\"\/repos\/$OWNER\/$REPO\/actions\/permissions\"<\/span>\ngh api <span class=\"hljs-string\">\"\/repos\/$OWNER\/$REPO\/rulesets\"<\/span>\ngh api <span class=\"hljs-string\">\"\/repos\/$OWNER\/$REPO\/environments\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-29\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">API access depends on token permissions and repository policy.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">43. Knowledge Check<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Why can an admin be unable to change a repository setting?<\/li>\n\n\n\n<li>What is the difference between Write, Maintain, and Admin?<\/li>\n\n\n\n<li>Why are teams preferable to repeated direct grants?<\/li>\n\n\n\n<li>What can break when the default branch changes?<\/li>\n\n\n\n<li>When is squash merge useful?<\/li>\n\n\n\n<li>Why protect\u00a0<code>main<\/code>?<\/li>\n\n\n\n<li>How do rulesets differ from legacy branch protection?<\/li>\n\n\n\n<li>Why can multiple protection layers make troubleshooting confusing?<\/li>\n\n\n\n<li>Why protect\u00a0<code>.github\/workflows\/<\/code>\u00a0with CODEOWNERS\/review?<\/li>\n\n\n\n<li>What does\u00a0<code>GITHUB_TOKEN<\/code>\u00a0represent?<\/li>\n\n\n\n<li>Why make workflow permissions explicit?<\/li>\n\n\n\n<li>Why are fork workflows a trust boundary?<\/li>\n\n\n\n<li>What is risky about privileged persistent self-hosted runners?<\/li>\n\n\n\n<li>What does an environment protect?<\/li>\n\n\n\n<li>How do environment secrets differ from repository secrets?<\/li>\n\n\n\n<li>Why prefer OIDC to long-lived cloud keys?<\/li>\n\n\n\n<li>How do secret scanning and push protection differ?<\/li>\n\n\n\n<li>Why is visibility change a governance event?<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Fast answers<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Organization or enterprise policy may be more restrictive.<\/li>\n\n\n\n<li>Write supports development, Maintain adds repository operations, Admin provides full repository administration.<\/li>\n\n\n\n<li>Teams simplify onboarding, offboarding, review, and ownership.<\/li>\n\n\n\n<li>Workflows, rules, deployment policies, docs, and external integrations may still reference the old branch.<\/li>\n\n\n\n<li>When the team wants one clean commit per PR.<\/li>\n\n\n\n<li>To require controlled review and CI instead of direct unsafe changes.<\/li>\n\n\n\n<li>Rulesets provide more flexible targeting, layering, and visibility.<\/li>\n\n\n\n<li>All applicable rules can be enforced simultaneously.<\/li>\n\n\n\n<li>Workflow changes can change tokens, secrets, OIDC, and deployments.<\/li>\n\n\n\n<li>It is the repository-scoped token issued to Actions jobs.<\/li>\n\n\n\n<li>So the workflow receives only the authority it needs.<\/li>\n\n\n\n<li>External contributors may control code executed by CI.<\/li>\n\n\n\n<li>Untrusted code may access host files, credentials, or internal networks.<\/li>\n\n\n\n<li>It gates deployment using approvals, ref restrictions, protection rules, secrets, and variables.<\/li>\n\n\n\n<li>Environment secrets are available only to jobs using that environment after protections pass.<\/li>\n\n\n\n<li>OIDC provides short-lived identity-based credentials instead of stored permanent keys.<\/li>\n\n\n\n<li>Secret scanning detects committed secrets; push protection tries to block supported secrets before introduction.<\/li>\n\n\n\n<li>It can alter exposure of code, history, automation, forks, and related repository data.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">44. What to Learn Next<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">After this Essentials guide, continue with:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Advanced rulesets, tag rules, and push rules<\/li>\n\n\n\n<li>Reusable workflows and Actions supply-chain hardening<\/li>\n\n\n\n<li>OIDC trust design for AWS\/Azure\/GCP<\/li>\n\n\n\n<li>Self-hosted runner security<\/li>\n\n\n\n<li>Webhooks and GitHub Apps<\/li>\n\n\n\n<li>Dependabot and dependency review<\/li>\n\n\n\n<li>Code scanning\/security configurations<\/li>\n\n\n\n<li>Release immutability and release-tag governance<\/li>\n\n\n\n<li>GitHub Pages<\/li>\n\n\n\n<li>Copilot\/MCP repository governance where used<\/li>\n\n\n\n<li>REST\/GraphQL\/CLI automation<\/li>\n\n\n\n<li>Terraform and Repository-as-Code<\/li>\n\n\n\n<li>Organization\/enterprise policy architecture<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">45. Essential Production Baseline<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-30\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">GitHub Repository\n|\n|-- General\n|   |-- Stable identity\n|   |-- Deliberate <span class=\"hljs-keyword\">default<\/span> branch\n|   |-- Deliberate merge strategy\n|   <span class=\"hljs-string\">`-- Only useful features enabled\n|\n|-- Access\n|   |-- Teams preferred\n|   |-- Least-privilege roles\n|   `<\/span>-- Admin rare\n|\n|-- Change protection\n|   |-- Ruleset on main\n|   |-- Pull request required\n|   |-- Review + meaningful CI\n|   |-- Force push blocked\n|   <span class=\"hljs-string\">`-- Sensitive paths owned\n|\n|-- Actions\n|   |-- Approved Actions\/workflows\n|   |-- Restricted GITHUB_TOKEN\n|   |-- Trusted runner boundary\n|   `<\/span>-- OIDC \/ scoped secrets\n|\n|-- Environments\n|   |-- Production protected\n|   |-- Approved refs only\n|   <span class=\"hljs-string\">`-- Production credentials scoped\n|\n|-- Security\n|   |-- Dependency protection\n|   |-- Code scanning where available\n|   |-- Secret scanning where available\n|   `<\/span>-- Push protection where available\n|\n<span class=\"hljs-string\">`-- Lifecycle\n    |-- Visibility changes reviewed\n    |-- Archive before delete when practical\n    `<\/span>-- Destructive actions deliberate\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-30\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">The core principle is:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Access gives authority, rules constrain change, Actions automate authority, environments constrain deployment, security detects risk, and lifecycle controls protect the repository itself.<\/strong><\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Selected Official References<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/docs.github.com\/en\/repositories\/managing-your-repositorys-settings-and-features\/managing-repository-settings\">Managing repository settings<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/docs.github.com\/en\/repositories\/managing-your-repositorys-settings-and-features\/managing-repository-settings\/managing-teams-and-people-with-access-to-your-repository\">Managing teams and people with access to your repository<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/docs.github.com\/en\/repositories\/configuring-branches-and-merges-in-your-repository\">Configuring branches and merges<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/docs.github.com\/en\/repositories\/configuring-branches-and-merges-in-your-repository\/managing-rulesets\/about-rulesets\">About rulesets<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/docs.github.com\/en\/repositories\/configuring-branches-and-merges-in-your-repository\/managing-rulesets\/available-rules-for-rulesets\">Available rules for rulesets<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/docs.github.com\/en\/repositories\/managing-your-repositorys-settings-and-features\/enabling-features-for-your-repository\/managing-github-actions-settings-for-a-repository\">Managing GitHub Actions settings for a repository<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/docs.github.com\/en\/actions\/how-tos\/deploy\/configure-and-manage-deployments\/manage-environments\">Managing environments for deployment<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/docs.github.com\/en\/repositories\/managing-your-repositorys-settings-and-features\/enabling-features-for-your-repository\/managing-security-and-analysis-settings-for-your-repository\">Managing security and analysis settings<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/docs.github.com\/en\/code-security\/getting-started\/quickstart-for-securing-your-repository\">Quickstart for securing your repository<\/a><\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">End of 2-Hour Essentials Tutorial<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Recommended training principle:<\/strong>&nbsp;teach the repository operating model first. Students should leave able to answer six questions:&nbsp;<strong>Who has access? What protects&nbsp;<code>main<\/code>? What can workflows do? What protects production? Which security controls are active? What happens if the repository itself is renamed, exposed, archived, or deleted?<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Last Verified:&nbsp;September 2026Based on:&nbsp;GitHub Repository Settings \u2014 Complete Reference Guide &amp; TutorialDuration:&nbsp;2 hoursPlatform:&nbsp;GitHub.com \/ GitHub Enterprise Cloud unless stated otherwiseAudience:&nbsp;Developers, DevOps\/platform engineers, repository administrators, security engineers, team&#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_joinchat":[],"footnotes":""},"categories":[11138],"tags":[],"class_list":["post-78752","post","type-post","status-publish","format-standard","hentry","category-best-tools"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/78752","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/comments?post=78752"}],"version-history":[{"count":1,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/78752\/revisions"}],"predecessor-version":[{"id":78753,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/78752\/revisions\/78753"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media?parent=78752"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/categories?post=78752"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/tags?post=78752"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}