Git Workflows for Security Teams
Build a security detection repo with professional Git workflows and PR reviews.
Introduction
30 Second Summary
When a security incident hits, the first thing responders do is trace back through recent changes. If your commit history says "fix issues" and "add stuff," nobody can tell what changed or why. Clear, structured commits become critical documentation during an active investigation.
In this project, you will build a security detection rules repository with professional Git infrastructure. You'll experience the contrast between messy commits and proper conventional commits, then set up code owner reviews and a pull request template with a security checklist.
What You'll Build
You'll open a pull request on GitHub with a completed security checklist, a filled-in context section explaining your change, and a review request routed to the right code owner.
By the end of this project, you'll have:
- A commit history you can read like a changelog, where every entry tells you exactly what changed and why without opening a single diff.
- A CODEOWNERS file and PR template that automatically route detection rule changes to the right reviewer and force contributors to think about false positives, blast radius, and testing before requesting review.
- A live pull request you opened yourself, with a context section explaining your change, all security checklist items checked, and a code owner review request visible in the sidebar.
- Secret Mission: Add a second detection rule using a multi-commit feature branch with atomic commits that each tell a different part of the story.
Are there any prerequisites?
None. This project includes setup for all required tools. You just need a GitHub account and a Mac.
Before We Start
Before we dive in, let's get clear on what you're about to build and why a structured workflow matters for security work specifically.
Set Up Git and Create Your Repo
Every workflow in this project starts with a working Git installation connected to a remote repository on GitHub.
Verifying Git works now prevents mysterious debugging later. In this step, you will install Git, configure your identity, and push your first commit to a brand new GitHub repo.
In this step, get ready to:
- Install and verify Git on your Mac, then configure your identity.
- Create a local repository with a README and detection rule folder structure.
- Push your repo to GitHub so it exists both locally and in the cloud.
Install and verify Git
Git is the version control tool you will use throughout this project to track every change to your detection rules. Let's confirm it is installed on your Mac.
- In your Terminal, check whether Git is installed by running this command:
git --version
✔️ I see a version number
You should see output like git version 2.39.0 (your exact number may differ). Git is ready. Move on to configuring your identity below.
ⓧ I see a popup asking to install developer tools
macOS detected that Git is not yet installed and opened a dialog asking to install Xcode Command Line Tools. This is normal.
- Click Install in the dialog.
- Wait for the download and installation to complete. This can take several minutes depending on your internet speed.
- Once installation finishes, run git --version again in Terminal. You should now see a version number.
Still not working after the install dialog?
If you see a message about the software not being available from the Software Update server, try running this command instead:
xcode-select --install
This triggers a fresh install of the Command Line Tools. After it finishes, run git --version to confirm.
Help me install Git on my Mac
Configure your Git identity
Every Git commit records who made the change. You need to tell Git your name and the email address associated with your GitHub account.
- Set your Git identity and default branch name by running these commands:
git config --global user.name "[[YOUR_NAME="Your Name"]]"
git config --global user.email "[[YOUR_EMAIL="your-github-email@example.com"]]"
git config --global init.defaultBranch main
What do these commands do?
- user.name and user.email attach your identity to every commit you make. Use the same email you signed up to GitHub with so your commits link to your profile.
- init.defaultBranch main ensures any new repo you create uses main as the primary branch name (the modern default).
- Verify your name was saved by running:
git config --global user.name
You should see the name you just entered printed back to you.
Seeing a blank line or wrong name?
Make sure you included the quotes around your name in the original command. Without quotes, Git only captures the first word.
Re-run the git config --global user.name command with your full name in quotes to fix it.
Help me configure my Git identity
Create a local repo with a README and detection rule structure
Now you will create the project folder, initialize it as a Git repository, and set up the initial file structure that a security detection rules repo needs.
- Move to your Desktop by running this command:
cd ~/Desktop
- Create your project folder and initialize a Git repository by running these commands:
mkdir security-detections && cd security-detections
git init
You should see a message like Initialized empty Git repository in /Users/.../Desktop/security-detections/.git/. This confirms Git is now tracking this folder.
- Create a README file and a rules directory by running these commands:
mkdir rules
echo "# Security Detections" > README.md
echo "Detection rules for our security monitoring pipeline." >> README.md
- Confirm the files exist by running:
ls
You should see README.md and rules in the output.
- Stage all files and make your first commit by running these commands:
git add .
git commit -m "chore: initialize detection rules repository"
What does this commit message mean?
The message chore: initialize detection rules repository follows the Conventional Commits format. The chore prefix signals this is a maintenance task (project setup), not a new feature or bug fix. You will learn more about this format in a later step.
You should see output confirming the commit was created, including the branch name main and the number of files changed.
Seeing 'Author identity unknown'?
This means Git does not have your name and email configured. Scroll back up to the identity configuration commands and run them again. Then retry the commit command.
Help me fix my Git commit error
✔️ Awesome, I've got everything!
Great. Double check you have saved everything and move on to connecting GitHub.
ⓧ I'd like to double check the full code
Your README.md should contain exactly this:
# Security Detections
Detection rules for our security monitoring pipeline.
And the rules/ directory should exist (currently empty). Confirm with ls in your terminal.
Create a GitHub repo and push
Your local repo needs a remote home on GitHub. This is where teammates (and future you) access the code, open pull requests, and review changes.
- Open your browser and go to github.com. Sign in to your account.
- Click the + icon in the top-right corner of the page.
- Select New repository.
- Enter security-detections as the repository name.
- Leave the visibility set to Public.
- Do NOT check "Add a README file" (you already have one locally).
- Click Create repository.
Why skip the remote README?
If GitHub creates its own README, your local repo and the remote repo will have conflicting histories. Keeping the remote empty lets you push your existing local commits cleanly.
- Back in your Terminal, connect your local repo to GitHub and push by running these commands:
git remote add origin https://github.com/[[YOUR_USERNAME="YOUR_USERNAME"]]/security-detections.git
git push -u origin main
What do these commands do?
- git remote add origin tells Git where to send your code when you push. The URL points to the GitHub repo you just created.
- git push -u origin main uploads your main branch to GitHub. The -u flag sets origin main as the default push target, so future pushes only need git push.
GitHub may ask you to authenticate. If a browser window opens asking you to authorize Git, follow the prompts to sign in and grant access.
Push failed or permission denied?
Double check that you replaced YOUR_USERNAME in the remote URL with your actual GitHub username. You can verify the remote is correct by running git remote -v.
If you see a credentials error, GitHub may need you to authenticate via a personal access token or the browser OAuth flow. Follow the prompts in Terminal.
Help me push to GitHub
Before you check GitHub, what do you expect to see on the repo page? Think about which files you committed.
- Refresh your GitHub repository page in the browser.
You should see your README.md rendered with the heading "Security Detections" and the description below it. The rules folder appears in the file list.
- Back in Terminal, verify your commit history by running:
git log --oneline
You should see exactly one commit:
abc1234 chore: initialize detection rules repository
Your hash will differ, but the message should match. This confirms your local repo, remote connection, and first commit are all working.
Your repository is live on GitHub with a clean first commit. Next up, you will add a detection rule and experience firsthand why vague commit messages cause problems for security teams.
Commit the Wrong Way (and See Why It Fails)
Your repository is live on GitHub with a clean first commit. Now it's time to add your first detection rule.
When you're in a rush, it's tempting to commit with whatever message comes to mind. In this step, you'll do exactly that and then check what your commit history actually tells a reader.
In this step, get ready to:
- Add a brute-force login detection rule to your repo.
- Modify the rule's sensitivity settings and commit the change.
- Examine your commit history for readability.
Add a detection rule with a vague commit
Your repo needs its first detection rule. Detection rules are YAML files that define what suspicious behavior looks like in your logs.
- Create the brute-force detection rule by running this command:
cat > rules/brute-force-login.yml << 'EOF'
name: Brute Force Login Attempts
description: Detects multiple failed login attempts from a single source
severity: medium
source: authentication_logs
condition:
event: login_failed
threshold: 10
window: 5m
group_by: source_ip
actions:
- alert
- create_case
EOF
What does this rule do?
This rule watches authentication logs for repeated failed logins from the same IP address. If one IP fails 10 times within 5 minutes, it triggers an alert and creates a case for investigation.
The severity: medium and threshold: 10 values are intentionally lenient. You'll tighten them in a moment.
- Confirm the file was created by running:
ls rules/
You should see brute-force-login.yml in the output.
- Commit the new file by running these commands:
git add .
git commit -m "add stuff"
Git confirms the commit with a summary showing one file changed.
Seeing 'nothing to commit'?
Make sure the cat command ran without errors. Run ls rules/ to check that brute-force-login.yml exists. If it's missing, re-run the cat command from above.
help me debug a 'nothing to commit' error after creating a file
Modify the rule and commit again
The threshold of 10 failed attempts is too lenient for a real environment. You'll tighten the rule by raising the severity and lowering the threshold.
- Lower the threshold and raise the severity by running these commands:
sed -i '' 's/severity: medium/severity: high/' rules/brute-force-login.yml
sed -i '' 's/threshold: 10/threshold: 5/' rules/brute-force-login.yml
What do these commands do?
The sed -i '' command edits a file in place on macOS. The s/old/new/ part swaps the first match of "old" with "new" in the file.
The first command changes the severity from medium to high. The second lowers the threshold from 10 failed attempts to 5.
- Verify the changes took effect by running:
cat rules/brute-force-login.yml
You should see severity: high and threshold: 5 in the output.
✔️ Awesome, I've got everything!
Great. Your rule is updated and ready to commit.
ⓧ I'd like to double check the full code
Your rules/brute-force-login.yml should look exactly like this:
name: Brute Force Login Attempts
description: Detects multiple failed login attempts from a single source
severity: high
source: authentication_logs
condition:
event: login_failed
threshold: 5
window: 5m
group_by: source_ip
actions:
- alert
- create_case
- Commit the change by running:
git add .
git commit -m "fix issues"
Git confirms your second commit.
Seeing 'extra characters at the end of d command'?
This error means the sed syntax is wrong for your shell. Make sure you include the empty quotes '' right after -i with a space between them. The correct pattern is sed -i '' 's/...' on macOS.
help me fix a sed in-place editing error on macOS
Examine your unreadable commit history
You've made three commits now. Time to look at your history the way a teammate would during an incident.
Before you run the next command, think: will you be able to tell what each commit changed just from reading the messages?
- Check your commit history by running:
git log --oneline
Your output looks something like this:
abc1234 fix issues
def5678 add stuff
ghi9012 chore: initialize detection rules repository
Three commits. Can you tell which one introduced the brute-force rule? Can you tell which one changed the threshold, and why?
You can't. The messages "add stuff" and "fix issues" give you nothing. This is what reviewers and incident responders see when they run git blame during an active incident.
Why does this matter in security?
During a security incident, responders trace changes with git blame and git log to understand when a rule changed and why. Vague messages force them to open every diff manually. That costs minutes when seconds count.
You've felt the problem firsthand. Next, you'll rewrite these commits using conventional commit messages that tell the full story.
Commit the Right Way with Conventional Commits
You just experienced the pain of vague commit messages. Six months from now, nobody can tell what "add stuff" or "fix issues" actually changed.
Conventional Commits solve this by forcing every message to declare its type and intent. In this step, you will rewrite your bad commits into proper conventional messages using interactive rebase, and push the clean history to GitHub.
In this step, get ready to:
- Rewrite your vague commits with proper conventional commit messages.
- Learn the anatomy of a good security commit message.
- Push your clean history to GitHub.
Rewrite your commits with interactive rebase
Interactive rebase lets you go back in time and edit commits that already exist in your history. You will use it to change the messages on your two bad commits without changing the code itself.
Set nano as your Git editor
By default, Git opens vim for editing, which can be confusing if you have not used it before. To use the friendlier nano editor instead, run this before continuing:
git config --global core.editor "nano -w"
If you are comfortable with vim, you can skip this. To save and quit in vim, press Esc, type :wq, and press Enter. In nano, press Ctrl+O then Enter to save, and Ctrl+X to exit.
- Check your current commit history by running:
git log --oneline
You should see three commits. Note the hash of your earliest commit (the one that says chore: initialize detection rules repository).
- Start an interactive rebase on the two most recent commits by running:
git rebase -i HEAD~2
What happens when you run this?
Git opens a text editor showing your two most recent commits, oldest first. Each line starts with the word pick followed by the commit hash and message. You are about to tell Git you want to reword (change the message of) each commit.
- In the editor that opens, you will see two lines that look like:
pick abc1234 add stuff
pick def5678 fix issues
- Change the word pick to reword on both lines, so it looks like:
reword abc1234 add stuff
reword def5678 fix issues
- Save and close the editor.
- Git will now open the editor again for the first commit. Replace the entire message add stuff with:
feat(rules): add brute-force login detection rule
- Save and close the editor.
- Git will open the editor once more for the second commit. Replace fix issues with:
fix(rules): lower brute-force threshold to reduce missed attacks
- Save and close the editor. The rebase completes automatically.
Seeing a merge conflict or error?
If Git reports a conflict or you accidentally edited the wrong thing, you can abort the rebase and start fresh by running git rebase --abort. This returns your repo to the state before you started the rebase.
If the editor closed without saving or you see a message about an empty commit message, run git rebase --abort and try again from the git rebase -i HEAD~2 step.
Help me fix my interactive rebase
Verify the anatomy of a good security commit message
Before you run the next command, think about what your git log should look like now. Do you expect three commits, or two? What should the messages say?
- Check your rewritten history by running:
git log --oneline
Your history now reads something like:
aaa1111 fix(rules): lower brute-force threshold to reduce missed attacks
bbb2222 feat(rules): add brute-force login detection rule
ccc3333 chore: initialize detection rules repository
Each commit now tells you exactly what changed and in what context, without opening the diff.
What is the conventional commit format?
The format is type(scope): description.
- type: what kind of change. Common types are feat, fix, chore, docs, test, and refactor.
- scope: what area of the codebase changed, in parentheses. For this project, rules, infra, or ci are good scopes.
- description: what you did, with enough context to understand why.
Compare good messages to bad ones. Bad: "fix issues", "test", "update file". Good: "fix(rules): exclude benign events from brute-force rule", "feat(rules): add credential-stuffing detection for SSO endpoints".
Push the rewritten history to GitHub
Your local history is clean, but GitHub still has the old vague commits. Because you rewrote history that already exists on the remote, a normal git push will be rejected. You need to force push.
- Update GitHub with your clean history by running:
git push --force-with-lease origin main
Why --force-with-lease instead of --force?
Both flags overwrite the remote history, but --force-with-lease adds a safety check. It refuses to push if someone else has pushed changes you have not seen yet. This protects you from accidentally overwriting a teammate's work.
Since you are the only contributor right now, either flag would work. Building the habit of --force-with-lease now means you are ready for team environments later.
- Visit your repository on GitHub and click the commit count (e.g. "3 commits") near the top of the page.
- Confirm that your commits now show the clean conventional messages instead of the old vague ones.
Push was rejected?
If you see a rejection message, make sure you included --force-with-lease in your push command. A regular git push fails because the rewritten commits have different hashes than the ones on GitHub.
Help me fix my force push
Your commit history now tells a clear story. Next up, you will set up team infrastructure so other contributors get routed to the right reviewer automatically.
Set Up Team Infrastructure (CODEOWNERS and PR Template)
Your commit history now tells a clear story. Each message declares exactly what changed and why. But readable commits solve only the individual contributor problem.
On a real security team, you also need to control who reviews what. A detection rule change should automatically route to the security team. An infrastructure change should route to the platform team. In this step, you'll add two files that automate review routing and enforce security-specific questions on every pull request.
In this step, get ready to:
- Create a CODEOWNERS file that routes reviews to the right people.
- Add a PR template with a security-specific checklist.
- Push the infrastructure to GitHub and confirm it appears in your repository.
Create a CODEOWNERS file
GitHub uses a special file called CODEOWNERS to automatically assign reviewers when someone opens a pull request. Each line maps a file path pattern to one or more owners. When a PR touches files matching that pattern, GitHub adds those owners as requested reviewers.
- Create the .github directory and CODEOWNERS file by running this command:
mkdir -p .github
cat > .github/CODEOWNERS << 'EOF'
# Default owner for everything
* @[[YOUR_USERNAME="your-github-username"]]
# Detection rules require security team review
/rules/ @[[YOUR_USERNAME="your-github-username"]]
# Infrastructure changes require platform team review
/.github/ @[[YOUR_USERNAME="your-github-username"]]
EOF
What does this file do?
Each line pairs a file path pattern with an owner using @username syntax.
- * @YOUR_USERNAME sets a default owner for every file in the repo.
- /rules/ matches anything inside the rules directory. On a real team, you'd point this at your security engineering team handle.
- The last matching pattern takes precedence. So a change to /rules/ triggers the security team rule, not the default.
- Confirm the file was created by running:
ls .github/
You should see CODEOWNERS in the output.
Don't see the file?
- Make sure you ran the full heredoc command including the closing EOF line. If your terminal shows a > prompt, it's still waiting for the closing marker. Type EOF and press Enter.
- Check that you're still in the security-detections directory by running pwd.
Help me troubleshoot my CODEOWNERS file creation
Create a PR template with a security checklist
A pull request template auto-fills the description field every time someone opens a PR. This forces contributors to answer key questions before requesting a review. For security repos, those questions should cover false positives, alert volume, and testing.
- Create the pull request template by running this command:
cat > .github/pull_request_template.md << 'EOF'
## Context
<!-- Why is this change being made? What problem does it solve? -->
## Changes
<!-- What specifically was added, modified, or removed? -->
## Security Checklist
- [ ] Detection logic has been tested against sample events
- [ ] False positive rate has been considered and documented
- [ ] Rule does not create excessive alert volume (blast radius)
- [ ] Severity level is appropriate for the threat
- [ ] No secrets or internal infrastructure details are exposed
- [ ] Related rules have been checked for conflicts or overlap
## Reviewer Notes
<!-- Anything specific the reviewer should look at or test? -->
EOF
What does this template do?
When the template lives at .github/pull_request_template.md on the default branch, GitHub automatically loads it into the PR description. Contributors see the sections and checklist before they type anything.
- Context asks why the change exists. This is critical for incident responders who find the PR months later.
- Security Checklist forces the contributor to think about false positives, blast radius, and overlap before a reviewer ever sees the PR.
- Reviewer Notes lets the author point the reviewer at specific decisions or tradeoffs.
- Verify both files exist by running:
ls .github/
You should see both CODEOWNERS and pull_request_template.md listed.
Only see CODEOWNERS?
- Check if your terminal is still showing a > prompt. The heredoc for the PR template is long. If you missed the closing EOF, type it now and press Enter.
- Make sure the filename is exactly pull_request_template.md. GitHub only recognizes this specific name.
Help me troubleshoot my PR template file
Commit and push the team infrastructure
- Stage and commit the new files by running these commands:
git add .github/
git commit -m "chore(infra): add CODEOWNERS and PR template for security reviews"
What does this commit message mean?
- chore is the type. This is a maintenance task, not a feature or bug fix.
- infra is the scope. It tells readers this change lives in the infrastructure layer, not the detection rules.
- The description names both files so a reviewer scanning git log knows exactly what was added.
- Push to GitHub by running:
git push origin main
Before you check GitHub, predict: what do you expect to see in your repository now that wasn't there before?
- Switch to your browser and refresh your security-detections repository page on GitHub.
You should see a .github directory in the file list. Click into it and confirm both CODEOWNERS and pull_request_template.md appear.
Don't see .github on GitHub?
- Make sure the push succeeded. Check your terminal for error messages. If you see a rejection, verify your remote URL is correct with git remote -v.
- Confirm you committed the files (not just staged them) by running git status. It should say nothing to commit, working tree clean.
Help me troubleshoot pushing to GitHub
Why do these files live in .github/?
GitHub looks for CODEOWNERS in the repository root, .github/, or docs/. Placing both files in .github/ keeps your repo root clean and groups all GitHub-specific configuration in one place.
Your repository now has professional team infrastructure. Next up, you'll run the full workflow end-to-end: branch, commit, push, and open a pull request that uses everything you just built.
Run the Full Professional Workflow
Your repository now has professional team infrastructure in place. CODEOWNERS routes changes to the right reviewer, and the PR template forces security-specific thinking before every merge.
Now it's time to put it all together. In this step, you'll run the exact workflow you'd use every day on a security team: create a feature branch, write a detection rule, commit with a conventional message, push, and open a pull request that uses your template.
In this step, get ready to:
- Create a feature branch with a kebab-case name.
- Write a detection rule and commit with a conventional message.
- Push the branch and open a pull request with a completed security checklist.
Create a feature branch with a kebab-case name
Feature branches keep your work isolated from main until it's reviewed and approved. The branch name itself communicates what the work is about.
- Create and switch to a new feature branch by running this command:
git checkout -b feat/add-impossible-travel-detection
What does this branch name mean?
The name follows a type/description pattern in kebab-case. feat/ tells your team this branch adds new functionality. add-impossible-travel-detection describes exactly what the work delivers.
Other examples you'd see on a security team: fix/reduce-vpn-false-positives, chore/update-rule-schema.
- Confirm you're on the new branch by running:
git branch
You should see an asterisk next to feat/add-impossible-travel-detection, confirming that's your active branch.
Still on main?
If git branch shows the asterisk next to main, the checkout may have failed silently. Run git checkout feat/add-impossible-travel-detection to switch to the branch you created.
help me switch to my feature branch
Write a new detection rule and commit with a conventional message
This rule detects impossible travel, a pattern where a user logs in from two geographically distant locations within a time window that makes physical travel between them impossible. It's a strong signal of compromised credentials.
- Create the impossible-travel detection rule by running this command:
cat > rules/impossible-travel.yml << 'EOF'
name: Impossible Travel Detection
description: Detects logins from geographically distant locations within a short time window
severity: high
source: authentication_logs
condition:
event: login_success
logic: geo_distance_between_consecutive_logins > 500km
window: 60m
group_by: user_id
exceptions:
- known_vpn_ranges
- corporate_travel_approved
actions:
- alert
- require_mfa_reverification
EOF
What does this rule do?
The rule watches for consecutive successful logins from the same user_id where the geographic distance exceeds 500km within 60 minutes. No one can physically travel that far that fast, so this flags likely credential theft.
The exceptions block prevents false positives from VPN usage and pre-approved corporate travel. The require_mfa_reverification action forces a re-challenge rather than just alerting.
- Confirm the file was created by running:
ls rules/
You should see both brute-force-login.yml and impossible-travel.yml listed.
Only see brute-force-login.yml?
The cat command may have failed if you missed the closing EOF line or if your terminal interpreted special characters. Make sure EOF sits alone on its own line with no spaces before it. Re-run the full cat > rules/impossible-travel.yml << 'EOF' command from the beginning.
help me create my impossible-travel detection rule file
- Commit your new rule with a conventional commit message by running:
git add rules/impossible-travel.yml
git commit -m "feat(rules): add impossible-travel detection for compromised credentials"
Why this commit message works
The type is feat because you're adding new functionality. The scope (rules) tells readers which area of the codebase changed. The description names both the what (impossible-travel detection) and the why (compromised credentials).
- Verify your commit was recorded by running:
git log --oneline
Your newest commit should appear at the top with the message feat(rules): add impossible-travel detection for compromised credentials.
✔️ Awesome, I've got everything!
Great. Make sure you've saved your work and your commit appears in the log.
ⓧ I'd like to double check the full code
Here's the complete rules/impossible-travel.yml file:
name: Impossible Travel Detection
description: Detects logins from geographically distant locations within a short time window
severity: high
source: authentication_logs
condition:
event: login_success
logic: geo_distance_between_consecutive_logins > 500km
window: 60m
group_by: user_id
exceptions:
- known_vpn_ranges
- corporate_travel_approved
actions:
- alert
- require_mfa_reverification
Push the branch and open a pull request on GitHub
Your feature branch and commit exist only on your local machine right now. Pushing makes it available on GitHub so you can open a pull request for review.
- Push your feature branch to GitHub by running:
git push -u origin feat/add-impossible-travel-detection
- Switch to your browser and navigate to your security-detections repository on GitHub.
- You should see a yellow banner at the top of the repository page saying your branch was recently pushed.
- Click Compare & pull request in that banner.
What is this banner?
GitHub detects when you push a new branch and offers a shortcut to create a pull request from it. Your PR template auto-fills in the description field because the template file exists on your main branch.
Now fill in the pull request form. The template sections are already in the description box waiting for your input.
- Set the PR title to: feat(rules): add impossible-travel detection for compromised credentials.
- In the Context section, replace the HTML comment with: Adds detection for account compromise via impossible travel. Credential theft often shows up as logins from two distant locations within a short window. This rule catches that pattern while excluding known VPN ranges and approved corporate travel..
- In the Changes section, replace the HTML comment with: Adds rules/impossible-travel.yml with geo-distance logic, 60-minute window, user_id grouping, and VPN/travel exceptions..
- Check all six boxes in the Security Checklist by clicking each one.
- In the Reviewer Notes section, replace the HTML comment with: Threshold of 500km may need tuning based on our user base geography..
Why fill in every section?
On a real security team, a PR without context gets sent back. Reviewers need to understand why a detection rule exists, what it changes, and whether false positives were considered. The checklist ensures nothing is missed before code lands in production.
- In the right sidebar, look under Reviewers. Click the gear icon and type your GitHub username to add yourself as a reviewer.
What about CODEOWNERS auto-requesting?
On a real team, GitHub automatically requests code owners as reviewers when a PR touches files they own. Since you are both the PR author and the code owner in this solo repo, GitHub cannot auto-request you to review your own PR.
In a team setting, a different team member would be listed in CODEOWNERS, and GitHub would automatically assign them the moment you open the PR. Adding yourself manually here simulates what that experience looks like from the reviewer's side.
- Click Create pull request.
Before you look at the result, think about what you expect to see. What should a professional pull request look like after everything you've set up?
Your PR page now shows the filled-in Context section explaining why the change was made, a completed Security Checklist with all six items checked, and your reviewer assignment in the sidebar.
Don't see the template sections?
The PR template auto-fills only when .github/pull_request_template.md exists on the base branch (main). Make sure you pushed the template file in the previous step. Run git log main --oneline and confirm you see the commit that added the .github/ directory.
help me figure out why my PR template isn't showing up
You just ran the complete professional workflow from start to finish. Branch, commit with context, push, open a PR that explains itself, complete the security checklist, and assign a reviewer. This is exactly how contributions flow on security engineering teams.
Secret mission
Multi-Commit Feature Branch with Atomic Commits
Real security contributions rarely fit in a single commit. Can you plan three atomic commits that build on each other, each with a different conventional commit type, and open a PR that tells the full story?
Clean Up Your Resources
Clean Up Your Resources
Decide whether to keep your resources running, pause them to come back later, or delete them entirely. This project runs entirely locally with a free GitHub repository, so there are no ongoing costs.
Resources you used:
- Local security-detections folder on your Desktop.
- GitHub repository security-detections (with open pull requests).
Keep everything running
No action needed. Choose this if you're still actively building or want to reference your detection rules and commit history later.
- Your local repo stays on your Desktop for future use.
- Your GitHub repo remains public with your pull requests and commit history intact.
- Git remains installed on your machine via Xcode Command Line Tools.
Pause - I'll come back to this later
Close any open terminals and browser tabs. Your files and GitHub repo will be waiting when you return.
- Close your Terminal window.
- Close any GitHub browser tabs.
- Everything stays in place. When you come back, open Terminal and run cd ~/Desktop/security-detections to pick up where you left off.
Delete - I don't want to use this again
Remove all project resources from your machine and GitHub.
- Delete the local project folder by running this command in Terminal:
rm -rf ~/Desktop/security-detections
- Delete the GitHub repository:
- Go to your security-detections repository on GitHub.
- Click Settings in the top navigation bar.
- Scroll down to the Danger Zone section at the bottom of the page.
- Click Delete this repository and follow the confirmation prompts.
Nice Work!
Nice Work!
You just built a professional security detection rules repository with the same Git workflow that real security engineering teams use every day.
You've learned how to:
- Rewrite vague commit history into conventional commits that make every change self-documenting using the type(scope): description format.
- Set up CODEOWNERS and a PR template with a security checklist that routes reviews to the right people and forces contributors to consider false positives, blast radius, and testing.
- Run the full professional workflow: kebab-case feature branch, conventional commits, a pull request with a filled-in Context section, completed security checklist, and a code owner review request.
- Secret Mission: Created a multi-commit feature branch with atomic commits (feat, fix, docs) that tell a cohesive story across a single pull request.
Ready to quiz yourself?