├── .github
├── steps
│ ├── 1-enable-secret-scanning.md
│ ├── 2-review-alerts.md
│ ├── 3-enable-push-protection.md
│ └── x-review.md
└── workflows
│ ├── 0-start-exercise.yml
│ ├── 1-enable-secret-scanning.yml
│ ├── 2-review-alerts.yml
│ └── 3-enable-push-protection.yml
├── .gitignore
├── LICENSE
└── README.md
/.github/steps/1-enable-secret-scanning.md:
--------------------------------------------------------------------------------
1 | ## Step 1: Enable Secret Protection
2 |
3 | If you check your email, you probably just got an alert from GitHub with the subject "Possible valid secrets found". Oh no! 😮
4 |
5 | Don't worry! We put some expired credentials in the exercise on purpose since public repositories get secret protection for free. Nice! 🕵️
6 |
7 | In this step, you will enable secret protection on your repository. After it is enabled, you will add a new credential to see how secret protection identifies the credential and alerts you.
8 |
9 | > [!WARNING]
10 | > If your repository is private, you will need [GitHub Advanced Security](https://docs.github.com/en/enterprise-cloud@latest/get-started/learning-about-github/about-github-advanced-security) to continue. We recommend [changing this exercise repository to public](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/managing-repository-settings/setting-repository-visibility) to enable it.
11 |
12 | ### What is a secret?
13 |
14 | In the our context, a secret (or credential) is a plain-text string, or a pair of strings, that authorizes access a service. Examples could be AWS secret access keys/ID's, Google API keys, or GitHub Personal Access Tokens (PATs).
15 |
16 | The GitHub Docs provides a list of [all supported patterns](https://docs.github.com/en/code-security/secret-scanning/secret-scanning-patterns#supported-secrets).
17 |
18 | ### What is secret protection?
19 |
20 | Secret protection is a powerful tool which allows teams to identify these plain-text credentials, remove them, and create rules to prevent them from being written to GitHub in the first place.
21 |
22 | Secret protection is available **for free for public repositories** on all plans. Enterprises that need secret protection capabilities for private repositories should review [GitHub Advanced Security](https://github.com/security/advanced-security). Not only does it include secret protection, it also provides advanced static analysis, software composition analysis (SCA), and enterprise tools to manage your entire AppSec pipeline and reduce your risk profile.
23 |
24 | ### :keyboard: Activity: Configure secret protection
25 |
26 | 1. In the header of your repository, open **Settings** in a new browser tab.
27 |
28 | 1. In the left navigation, under the **Security** section, select **Advanced Security**.
29 |
30 | 1. Scroll down past the **Code Scanning** and **Dependabot** sections until you find the **Secret Protection** section.
31 |
32 | > 💡 **Tip:** We also have exercises about [code scanning](https://github.com/skills/introduction-to-codeql) and [supply chain protection](https://github.com/skills/secure-repository-supply-chain)!
33 |
34 | 1. Adjust the default configuration to match the below.
35 |
36 | - **Secret Protection:** `enabled`
37 | - **Push Protection:** `disabled`
38 |
39 |
40 |
41 | ### :keyboard: Activity: Commit a sensitive file
42 |
43 | Now let's (accidentally) commit a sensitive file to see how it works. Don't worry, these are inactive credentials.
44 |
45 | 1. In the header of your repository, click the **Code** tab.
46 |
47 | 1. Above the list of files, click the **Add file** dropdown and select **Create new file**.
48 |
49 |
50 |
51 | 1. Enter the file name `credentials.yml` and copy following **inactive** example credentials into it.
52 |
53 |
54 |
55 | ```yaml
56 | default:
57 | aws_access_key_id: AKIAQYLPMN5HNM4OZ56B
58 | aws_secret_access_key: Rm29CHLQCeaT6V/Rsw3UFWW1/UWQ0lhsWBa3bdca
59 | mongodb: mongodb+srv://svc-admin:kLeioeBne5lsopPf@mergington-high.avocado.mongodb.net
60 | output: json
61 | region: us-east-2
62 | ```
63 |
64 | 1. In the top right, use the **Commit changes...** button to commit directly to the `main` branch.
65 |
66 | > ❗️ **Important:** Committing to your default branch is not usually a recommended practice. We only do this to simplify the exercise.
67 |
68 | 1. With our credentials file (accidentally) shared, Mona should quickly notice it and prepare the next step.
69 |
--------------------------------------------------------------------------------
/.github/steps/2-review-alerts.md:
--------------------------------------------------------------------------------
1 | ## Step 2: Review and close secret scanning alerts
2 |
3 | In the last step, you enabled secret protection and committed a sensitive file to the repository. Now, let's review our open secret scanning alerts and close one.
4 |
5 | ### :keyboard: Activity: Triage secret scanning alerts
6 |
7 | 1. In the header of your repository, click the **Security** tab.
8 |
9 | 1. In the left navigation, select the **Secret scanning** option.
10 |
11 | 1. Notice various options in the header bar that can help triage our alerts.
12 |
13 |
14 |
15 | 1. Click the **Provider** dropdown and select `Amazon AWS` to filter the view. Notice only 2 of the 3 entries are listed now.
16 |
17 |
18 |
19 | ### :keyboard: Activity: Review a secret scanning alert
20 |
21 | 1. In the list of open alerts, select the `Amazon AWS Access Key ID` alert. This will open a details page with more information.
22 |
23 | 1. At the top of the page, we can quickly view the alert status, when it was opened, the exposed secret, and some remediation steps.
24 |
25 |
26 |
27 | 1. Scroll down slightly to the **Detected in X locations** area and you will see all the places where this secret was detected, including the `credentials.yml` file that you created. Notice that secret protection doesn't create duplicate alerts for the same secret found across multiple locations, for example in our learning issue.
28 |
29 |
30 |
31 | ### :keyboard: Activity: Close an alert
32 |
33 | When secret protection finds a secret in your repository, the first thing you should do is **disable that secret with the provider**. You should assume it has been exposed.
34 |
35 | > [!TIP]
36 | > Some [supported secrets](https://docs.github.com/en/code-security/secret-scanning/introduction/supported-secret-scanning-patterns#default-patterns) are automatically sent to the provider when leaked.
37 |
38 | 1. Assuming you have taken remediation steps, we can update the status of our alert. In the top right, select the **Close as** dropdown.
39 |
40 | > 🚨 **Caution:** Do **NOT** close an open alert without performing remediation steps. This simply hides the problem and provides a false sense of security. It might even trigger additional alerts with your cybersecurity department. 🤦
41 |
42 | 1. Choose the `Revoked` option and enter a useful description of your remediation steps in the comment box (example below). Then choose **Close alert**.
43 |
44 | ```txt
45 | The secret owner was contacted. They provided proof that the exposed secret was replaced.
46 | ```
47 |
48 | > 💡 **Tip:** This is important so the audit log can later provide critical information if an investigation is required.
49 |
50 |
51 |
52 |
53 | 1. The alert status now displays `Closed` and the audit trail includes our explanation.
54 |
55 |
56 |
57 |
58 |
59 | 1. With at least one of our alerts resolved, let's add a comment to inform Mona we are done with this step, so she can share the next one.
60 |
61 | ```txt
62 | Hello @professortocat, I've resolved the security alert. What's next?
63 | ```
64 |
--------------------------------------------------------------------------------
/.github/steps/3-enable-push-protection.md:
--------------------------------------------------------------------------------
1 | ## Step 3: Enable push protection
2 |
3 | In this section, you will configure your repository to prevent new secrets from being exposed.
4 |
5 | ### What is push protection?
6 |
7 | When someone tries to send code changes to GitHub (a push), secret scanning checks for high-confidence secrets. Secret scanning lists any secrets it detects so the author can review the secrets and remove them or, if needed, allow those secrets to be pushed.
8 |
9 | ### :keyboard: Activity: Configure push protection
10 |
11 | > [!IMPORTANT]
12 | > We disabled push protection in our first step for learning practice. It is normally enabled by default for all public repositories.
13 |
14 | 1. In the header of your repository, click the **Settings** tab.
15 | 1. In the left navigation, under the **Security** section, select **Advanced Security**.
16 | 1. Scroll down past the **Code Scanning** and **Dependabot** sections until you find the **Secret Protection** section.
17 | 1. Adjust the default configuration to match the below.
18 |
19 | - **Secret Protection:** `enabled`
20 | - **Push Protection:** `enabled`
21 |
22 |
23 |
24 | ### :keyboard: Activity: Attempt to push a secret
25 |
26 | Now that secret push protection is enabled, let's give it a test!
27 |
28 | 1. In the header of your repository, click the **Code** tab.
29 |
30 | 1. In the list of files, click on the `credentials.yml` file to preview it.
31 |
32 | 1. Above the content preview, click the **Edit** button.
33 |
34 |
35 |
36 | 1. Copy the following inactive secret to the file, removing the `` text. It should look like the below screenshot.
37 |
38 | ```txt
39 | github-token: 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
40 | ```
41 |
42 | 
43 |
44 | 1. In the top right, use the **Commit changes...** button to **try to** commit directly to the `main` branch. Instead of committing the updated file, a push protection alert appeared. Nice! 🥰
45 |
46 |
47 |
48 | > [!IMPORTANT]
49 | > Secret Push Protection only scans while _**pushing**_ to GitHub. It cannot check your local commits. If you have a secret in a local commit and it is several commits deep, you will need to remove the secret from your branch's commit history. See [resolving a blocked push on the command line](https://docs.github.com/en/code-security/secret-scanning/pushing-a-branch-blocked-by-push-protection#resolving-a-blocked-push-on-the-command-line).
50 |
51 | ### :keyboard: Activity: Bypass push protection
52 |
53 | In some cases, you may write code that looks similar to a secret and a commit is incorrectly blocked. For example writing tests for an authorization process. In those situations, you can choose to bypass push protection. Let's practice that.
54 |
55 | 1. Select the radio button next to `It's used in tests`. Notice the description, matches our current learning use case.
56 |
57 |
58 |
59 | 1. Click **Allow secret**. A notification banner reports that you can now try committing again.
60 |
61 | 1. In the top right, use the **Commit changes...** button to commit directly to the `main` branch.
62 |
63 | 1. With the file updated, Mona should be busy checking your work. After checking, she'll provide feedback and the final review. Nice work! You are all done! 🎉
64 |
--------------------------------------------------------------------------------
/.github/steps/x-review.md:
--------------------------------------------------------------------------------
1 | ## Review 📖
2 |
3 | _Congratulations friend, you've completed this course!_
4 |
5 | Here's a recap of all the tasks you've accomplished in your repository:
6 |
7 | - Enabled secret scanning if your repository has private or internal visibility
8 | - Committed a secret to the repository
9 | - Reviewed secrets that have been identified by secret scanning
10 | - Closed a secret scanning alert
11 | - Enabled secret scanning push protection to prevent secrets from being written to the repository (required only for private or internal repositories)
12 | - Attempted to commit a secret, but had that commit stopped by push protection
13 | - Bypassed push protection
14 |
15 | It's important to note that secret scanning capabilities are available for free for all public repositories. Customers who want to enable secret scanning on private repos should find out more about [GitHub Advanced Security](https://docs.github.com/en/enterprise-cloud@latest/get-started/learning-about-github/about-github-advanced-security) or [Set up a trial of GitHub Advanced Security](https://docs.github.com/en/enterprise-cloud@latest/billing/managing-billing-for-github-advanced-security/setting-up-a-trial-of-github-advanced-security).
16 |
17 | In addition to the features you worked with here, GitHub Advanced Security also provides the following features:
18 |
19 | - Custom secret scanning patterns
20 | - Non-partner and generic patterns including passwords, RSA and SSH keys, and database connection strings
21 | - Code scanning with CodeQL
22 | - Security Overview
23 | - Supply chain security capabilities
24 |
25 | ### What's next?
26 |
27 | - [Take another Skills Exercise](https://skills.github.com).
28 | - [Read the GitHub Getting Started docs](https://docs.github.com/en/get-started).
29 | - To find projects to contribute to, check out [GitHub Explore](https://github.com/explore).
30 |
--------------------------------------------------------------------------------
/.github/workflows/0-start-exercise.yml:
--------------------------------------------------------------------------------
1 | name: Step 0 # Start Exercise
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 |
8 | permissions:
9 | contents: write
10 | actions: write
11 | issues: write
12 |
13 | env:
14 | STEP_1_FILE: ".github/steps/1-enable-secret-scanning.md"
15 |
16 | jobs:
17 | start_exercise:
18 | if: |
19 | !github.event.repository.is_template
20 | name: Start Exercise
21 | uses: skills/exercise-toolkit/.github/workflows/start-exercise.yml@v0.3.0
22 | with:
23 | exercise-title: "Introduction to Secret Scanning"
24 | intro-message: "In this exercise, you'll learn how to identify and protect sensitive information in your repositories. 🔍 Let's work together to keep your code secure! 🛡️"
25 |
26 | post_next_step_content:
27 | name: Post next step content
28 | runs-on: ubuntu-latest
29 | needs: [start_exercise]
30 | env:
31 | ISSUE_URL: ${{ needs.start_exercise.outputs.issue-url }}
32 |
33 | steps:
34 | - name: Checkout
35 | uses: actions/checkout@v4
36 |
37 | - name: Get response templates
38 | uses: actions/checkout@v4
39 | with:
40 | repository: skills/response-templates
41 | path: skills-response-templates
42 |
43 | - name: Configure Git user
44 | run: |
45 | git config user.name github-actions[bot]
46 | git config user.email github-actions[bot]@users.noreply.github.com
47 |
48 | - name: Build comment - add step content
49 | id: build-comment
50 | uses: skills/action-text-variables@v2
51 | with:
52 | template-file: ${{ env.STEP_1_FILE }}
53 | template-vars: |
54 | login: ${{ github.actor }}
55 | full_repo_name: ${{ github.repository }}
56 |
57 | - name: Create comment - add step content
58 | run: |
59 | gh issue comment "$ISSUE_URL" \
60 | --body "$ISSUE_BODY"
61 | env:
62 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
63 | ISSUE_BODY: ${{ steps.build-comment.outputs.updated-text }}
64 |
65 | - name: Create comment - watching for progress
66 | run: |
67 | gh issue comment "$ISSUE_URL" \
68 | --body-file "skills-response-templates/step-feedback/watching-for-progress.md"
69 | env:
70 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
71 |
72 | - name: Enable next workflow
73 | run: |
74 | gh workflow enable "Step 1" || true
75 | env:
76 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
--------------------------------------------------------------------------------
/.github/workflows/1-enable-secret-scanning.yml:
--------------------------------------------------------------------------------
1 | name: Step 1 # Enable scanning
2 |
3 | on:
4 | push:
5 | paths:
6 | - credentials.yml
7 |
8 | permissions:
9 | contents: read
10 | actions: write
11 | issues: write
12 |
13 | env:
14 | STEP_2_FILE: ".github/steps/2-review-alerts.md"
15 |
16 | jobs:
17 |
18 | find_exercise:
19 | name: Find Exercise Issue
20 | uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.3.0
21 |
22 | check_step_work:
23 | name: Check Step Work
24 | needs: [find_exercise]
25 | runs-on: ubuntu-latest
26 | env:
27 | ISSUE_URL: ${{ needs.find_exercise.outputs.issue-url }}
28 |
29 | steps:
30 | - name: Checkout
31 | uses: actions/checkout@v4
32 |
33 | - name: Get response templates
34 | uses: actions/checkout@v4
35 | with:
36 | repository: skills/response-templates
37 | path: skills-response-templates
38 |
39 | - name: Update comment - checking work
40 | run: |
41 | gh issue comment "$ISSUE_URL" \
42 | --body-file skills-response-templates/step-feedback/checking-work.md \
43 | --edit-last
44 | env:
45 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
46 |
47 | # START: Check practical exercise
48 |
49 | # The fact that the file was updated is enough for now.
50 | # A more detailed check will be added later.
51 |
52 | # END: Check practical exercise
53 |
54 | - name: Create comment - step results
55 | run: |
56 | gh issue comment "$ISSUE_URL" \
57 | --body "Great job configuring secret protection! 🎉 Now let's take a look at some of the alerts that got created."
58 | env:
59 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
60 |
61 | - name: Build message - step finished
62 | id: build-message-step-finish
63 | uses: skills/action-text-variables@v2
64 | with:
65 | template-file: skills-response-templates/step-feedback/step-finished-prepare-next-step.md
66 | template-vars: |
67 | next_step_number: 2
68 |
69 | - name: Create comment - step finished
70 | run: |
71 | gh issue comment "$ISSUE_URL" \
72 | --body "$ISSUE_BODY"
73 | env:
74 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
75 | ISSUE_BODY: ${{ steps.build-message-step-finish.outputs.updated-text }}
76 |
77 | post_next_step_content:
78 | name: Post next step content
79 | needs: [find_exercise, check_step_work]
80 | runs-on: ubuntu-latest
81 | env:
82 | ISSUE_URL: ${{ needs.find_exercise.outputs.issue-url }}
83 |
84 | steps:
85 | - name: Checkout
86 | uses: actions/checkout@v4
87 |
88 | - name: Get response templates
89 | uses: actions/checkout@v4
90 | with:
91 | repository: skills/response-templates
92 | path: skills-response-templates
93 |
94 | - name: Create comment - add step content
95 | run: |
96 | gh issue comment "$ISSUE_URL" \
97 | --body-file "$STEP_2_FILE"
98 | env:
99 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
100 |
101 | - name: Create comment - watching for progress
102 | run: |
103 | gh issue comment "$ISSUE_URL" \
104 | --body-file skills-response-templates/step-feedback/watching-for-progress.md
105 | env:
106 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
107 |
108 | - name: Enable next workflow
109 | run: |
110 | gh workflow disable "Step 1" || true
111 | gh workflow enable "Step 2" || true
112 | env:
113 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
114 |
--------------------------------------------------------------------------------
/.github/workflows/2-review-alerts.yml:
--------------------------------------------------------------------------------
1 | name: Step 2 # Review Alerts
2 |
3 | on:
4 | issue_comment:
5 | types: [created]
6 |
7 | permissions:
8 | contents: write
9 | actions: write
10 | issues: write
11 |
12 | env:
13 | # Keywords required in the issue comment to let this workflow run
14 | REQUIRED_ISSUE_COMMENT_KEYWORDS: "@professortocat"
15 | STEP_3_FILE: ".github/steps/3-enable-push-protection.md"
16 |
17 | jobs:
18 | required_issue_comment_keywords:
19 | name: Check issue comment text for required keywords
20 | runs-on: ubuntu-latest
21 |
22 | steps:
23 | - name: Stop early if missing the expected keywords
24 | run: |
25 | required_keywords=(${REQUIRED_ISSUE_COMMENT_KEYWORDS//,/ })
26 | for keyword in "${required_keywords[@]}"; do
27 | if [[ ! "$COMMENT_BODY" =~ $keyword ]]; then
28 | echo "Unrecognized request. Ending workflow."
29 | exit 0
30 | fi
31 | done
32 | env:
33 | COMMENT_BODY: ${{ github.event.comment.body }}
34 |
35 | find_exercise:
36 | name: Find Exercise Issue
37 | uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.3.0
38 |
39 | check_step_work:
40 | name: Check step work
41 | needs: [find_exercise, required_issue_comment_keywords]
42 | runs-on: ubuntu-latest
43 | env:
44 | ISSUE_URL: ${{ needs.find_exercise.outputs.issue-url }}
45 |
46 | steps:
47 | - name: Checkout
48 | uses: actions/checkout@v4
49 |
50 | - name: Get response templates
51 | uses: actions/checkout@v4
52 | with:
53 | repository: skills/response-templates
54 | path: skills-response-templates
55 |
56 | - name: Update comment - checking work
57 | run: |
58 | gh issue comment "$ISSUE_URL" \
59 | --body-file skills-response-templates/step-feedback/checking-work.md
60 | env:
61 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
62 |
63 | # START: Check practical exercise
64 |
65 | # The workflow GITHUB_TOKEN doesn't allow us to verify if any alerts were closed.
66 | # We will trust the learner to ask to proceed.
67 |
68 | # END: Check practical exercise
69 |
70 | - name: Create comment - step results
71 | run: |
72 | gh issue comment "$ISSUE_URL" \
73 | --body "Great work reviewing security alerts! 🎉 This is exactly what we wanted! GitHub detected the token pattern and alerted us so we could handle it properly."
74 | env:
75 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
76 |
77 | - name: Build message - step finished
78 | id: build-message-step-finish
79 | uses: skills/action-text-variables@v2
80 | with:
81 | template-file: skills-response-templates/step-feedback/step-finished-prepare-next-step.md
82 | template-vars: |
83 | next_step_number: 3
84 |
85 | - name: Create comment - step finished
86 | run: |
87 | gh issue comment "$ISSUE_URL" \
88 | --body "$ISSUE_BODY"
89 | env:
90 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
91 | ISSUE_BODY: ${{ steps.build-message-step-finish.outputs.updated-text }}
92 |
93 | post_next_step_content:
94 | name: Post next step content
95 | needs: [find_exercise, check_step_work]
96 | runs-on: ubuntu-latest
97 | env:
98 | ISSUE_URL: ${{ needs.find_exercise.outputs.issue-url }}
99 |
100 | steps:
101 | - name: Checkout
102 | uses: actions/checkout@v4
103 |
104 | - name: Get response templates
105 | uses: actions/checkout@v4
106 | with:
107 | repository: skills/response-templates
108 | path: skills-response-templates
109 |
110 | - name: Create comment - add step content
111 | run: |
112 | gh issue comment "$ISSUE_URL" \
113 | --body-file "$STEP_3_FILE"
114 | env:
115 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
116 |
117 | - name: Create comment - watching for progress
118 | run: |
119 | gh issue comment "$ISSUE_URL" \
120 | --body-file skills-response-templates/step-feedback/watching-for-progress.md
121 | env:
122 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
123 |
124 | - name: Enable next workflow
125 | run: |
126 | gh workflow disable "Step 2" || true
127 | gh workflow enable "Step 3" || true
128 | env:
129 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
130 |
--------------------------------------------------------------------------------
/.github/workflows/3-enable-push-protection.yml:
--------------------------------------------------------------------------------
1 | name: Step 3 # Enable push protection
2 |
3 | on:
4 | push:
5 | paths:
6 | - credentials.yml
7 |
8 | permissions:
9 | contents: write
10 | actions: write
11 | issues: write
12 |
13 | env:
14 | REVIEW_FILE: ".github/steps/x-review.md"
15 |
16 | jobs:
17 | find_exercise:
18 | name: Find Exercise Issue
19 | uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.3.0
20 |
21 | check_step_work:
22 | name: Check if push protection is enabled
23 | needs: [find_exercise]
24 | runs-on: ubuntu-latest
25 | env:
26 | ISSUE_URL: ${{ needs.find_exercise.outputs.issue-url }}
27 |
28 | steps:
29 | - name: Checkout
30 | uses: actions/checkout@v4
31 |
32 | - name: Get response templates
33 | uses: actions/checkout@v4
34 | with:
35 | repository: skills/response-templates
36 | path: skills-response-templates
37 |
38 | - name: Update comment - checking work
39 | run: |
40 | gh issue comment "$ISSUE_URL" \
41 | --body-file skills-response-templates/step-feedback/checking-work.md \
42 | --edit-last
43 | env:
44 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
45 |
46 | # START: Check practical exercise
47 |
48 | # The fact that the file was updated is enough for now.
49 | # A more detailed check will be added later.
50 |
51 | # END: Check practical exercise
52 |
53 | - name: Create comment - step results
54 | run: |
55 | gh issue comment "$ISSUE_URL" \
56 | --body "Excellent! 🛡️ Push protection is now enabled. Your repository is ready to block any accidental commits containing secrets."
57 | env:
58 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
59 |
60 | - name: Create comment - step finished - final review next
61 | run: |
62 | gh issue comment "$ISSUE_URL" \
63 | --body-file skills-response-templates/step-feedback/lesson-review.md
64 | env:
65 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
66 |
67 | post_review_content:
68 | name: Post review content
69 | needs: [find_exercise, check_step_work]
70 | runs-on: ubuntu-latest
71 | env:
72 | ISSUE_URL: ${{ needs.find_exercise.outputs.issue-url }}
73 |
74 | steps:
75 | - name: Checkout
76 | uses: actions/checkout@v4
77 |
78 | - name: Create comment - add step content
79 | run: |
80 | gh issue comment "$ISSUE_URL" \
81 | --body-file "$REVIEW_FILE"
82 | env:
83 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
84 |
85 | - name: Enable next workflow
86 | run: |
87 | gh workflow disable "Step 3" || true
88 | env:
89 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
90 |
91 | finish_exercise:
92 | name: Finish Exercise
93 | needs: [find_exercise, post_review_content]
94 | uses: skills/exercise-toolkit/.github/workflows/finish-exercise.yml@v0.3.0
95 | with:
96 | issue-url: ${{ needs.find_exercise.outputs.issue-url }}
97 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled source #
2 | ###################
3 | *.com
4 | *.class
5 | *.dll
6 | *.exe
7 | *.o
8 | *.so
9 |
10 | # Packages #
11 | ############
12 | # it's better to unpack these files and commit the raw source
13 | # git has its own built in compression methods
14 | *.7z
15 | *.dmg
16 | *.gz
17 | *.iso
18 | *.jar
19 | *.rar
20 | *.tar
21 | *.zip
22 |
23 | # Logs and databases #
24 | ######################
25 | *.log
26 | *.sql
27 | *.sqlite
28 |
29 | # OS generated files #
30 | ######################
31 | .DS_Store
32 | .DS_Store?
33 | ._*
34 | .Spotlight-V100
35 | .Trashes
36 | ehthumbs.db
37 | Thumbs.db
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) GitHub, Inc.
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Introduction to secret protection
2 |
3 | _Learn how to configure secret protection to identify secrets and prevent new ones from being committed to your repository._
4 |
5 | ## Welcome
6 |
7 | Plain-text credentials accidentally stored in repositories on GitHub are a common target for attackers. In fact, we find well over a million tokens stored on the GitHub platform each year. Let's learn how to prevent that!
8 |
9 | - **Who is this for**: Developers, DevOps Engineers, security teams.
10 | - **What you'll learn**: How to identify plain-text credentials in your repository and how to prevent them from being exposed on GitHub in future pushes.
11 | - **Prerequisites**: Basics of git and GitHub functionality. We recommend you complete [Introduction to GitHub](https://github.com/skills/introduction-to-github).
12 | - **How long**: This course takes less than 15 minutes to complete.
13 |
14 | In this course, you will:
15 |
16 | 1. Enable secret protection
17 | 2. Identify secrets stored in your repository
18 | 3. Enable push protection
19 | 4. Stop secrets from being written to your repository
20 |
21 | ### How to start this exercise
22 |
23 | Simply copy the exercise to your account, then give your favorite Octocat (Mona) **about 20 seconds** to prepare the first lesson, then **refresh the page**.
24 |
25 | [](https://github.com/new?template_owner=skills&template_name=introduction-to-secret-scanning&owner=%40me&name=skills-introduction-to-secret-scanning&description=GitHub+Skills:+Introduction+to+Secret+Scanning&visibility=public)
26 |
27 |
28 | Having trouble? 🤷
29 |
30 | When copying the exercise, we recommend the following settings:
31 |
32 | - For owner, choose your personal account or an organization to host the repository.
33 |
34 | - We recommend creating a public repository, since private repositories will use Actions minutes.
35 |
36 | If the exercise isn't ready in 20 seconds, please check the [Actions](../../actions) tab.
37 |
38 | - Check to see if a job is running. Sometimes it simply takes a bit longer.
39 |
40 | - If the page shows a failed job, please submit an issue. Nice, you found a bug! 🐛
41 |
42 |
43 |
44 | ---
45 |
46 | © 2025 GitHub • [Code of Conduct](https://www.contributor-covenant.org/version/2/1/code_of_conduct/code_of_conduct.md) • [MIT License](https://gh.io/mit)
--------------------------------------------------------------------------------