🔄 Automate GitHub Access Checks with Shell Scripting (Real-Life Use Case)
Hey DevOps enthusiasts! 👋 Ever find yourself constantly hopping into GitHub just to double-check who can access your repositories?
Whether you're managing a few projects or overseeing dozens across multiple teams, access control is non-negotiable. But doing it manually? That’s time better spent elsewhere.
Let’s solve this the smart way: a shell script + GitHub API = one-click visibility.
🚨 The Problem
Manually verifying repo access:
Let’s ditch the browser and embrace automation.
🧰 The Tools We’ll Use
There are two main options for interacting with GitHub from the command line:
API Tip: Think of the API as GitHub’s "back door" that lets us automate almost anything you can do in the UI.
🎯 Our Mission
We want a script that will:
🔑 Set Up GitHub Authentication
To access GitHub programmatically, you need:
🔧 How to Get a PAT:
Then, in your terminal:
🧾 The Script: list-users.sh
The heart of the automation is this bash script. It does all the heavy lifting:
#!/bin/bash
##########################################################
# Script Name : list-users.sh
# Author : Swasti
# Version : v1.2
# Date : 13-May-2025
#
# Purpose : Lists GitHub collaborators with read access
# using GitHub REST API and jq parser.
#
# Requirements:
# - jq installed (sudo apt install jq)
# - Export GitHub credentials:
# export username="your_username"
# export token="your_token"
#
# Usage:
# ./list-users.sh <org_name> <repo_name>
##########################################################
API_URL="https://api.github.com"
USERNAME=$username
TOKEN=$token
REPO_OWNER=$1
REPO_NAME=$2
function helper {
if [ $# -ne 2 ]; then
echo "Usage: ./list-users.sh <org_name> <repo_name>"
exit 1
fi
if [[ -z "$USERNAME" || -z "$TOKEN" ]]; then
echo "Please export 'username' and 'token' first."
exit 1
fi
if ! command -v jq &>/dev/null; then
echo "'jq' is required. Install using: sudo apt install jq"
exit 1
fi
}
helper "$@"
function github_api_get {
local endpoint="$1"
curl -s -u "${USERNAME}:${TOKEN}" "${API_URL}/${endpoint}"
}
function list_users_with_read_access {
local endpoint="repos/${REPO_OWNER}/${REPO_NAME}/collaborators"
collaborators=$(github_api_get "$endpoint" | jq -r '.[] | select(.permissions.pull == true) | .login')
if [[ -z "$collaborators" ]]; then
echo "No users with read access found."
else
echo "Users with read access to ${REPO_OWNER}/${REPO_NAME}:"
echo "$collaborators"
fi
}
echo "🔍 Checking collaborators for ${REPO_OWNER}/${REPO_NAME}..."
list_users_with_read_access
🛠️ Before You Run It
Make sure you have:
Then run it:
Detailed Script Explanation – list-users.sh
This script is a practical tool to fetch a list of GitHub users who have read (pull) access to a repository. Let’s dissect it step by step:
##########################################################
# Script Name : list-users.sh
# Author : Swasti
# Version : v1.2
# Date : 13-May-2025
#
# Purpose : Lists GitHub collaborators with read access
# using GitHub REST API and jq parser.
#
# Requirements:
# - jq installed (sudo apt install jq)
# - Export GitHub credentials:
# export username="your_username"
# export token="your_token"
#
# Usage:
# ./list-users.sh <org_name> <repo_name>
##########################################################
✅ Purpose:
This block acts as a header comment. It's considered good scripting practice, especially in production or shared environments.
This ensures maintainability and clarity for future readers or collaborators.
🔐 2. Environment Variables and Inputs
Recommended by LinkedIn
API_URL="https://api.github.com"
USERNAME=$username
TOKEN=$token
REPO_OWNER=$1
REPO_NAME=$2
✅ Purpose:
🔐 Security note: Never hardcode credentials. Exporting them from your shell session is safer.
🧩 3. Input Validation with Helper Function
function helper {
if [ $# -ne 2 ]; then
echo "Usage: ./list-users.sh <org_name> <repo_name>"
exit 1
fi
if [[ -z "$USERNAME" || -z "$TOKEN" ]]; then
echo "Please export 'username' and 'token' first."
exit 1
fi
if ! command -v jq &>/dev/null; then
echo "'jq' is required. Install using: sudo apt install jq"
exit 1
fi
}
helper "$@"
✅ Purpose:
Before doing anything else, the script:
Failing any of these, it exits early and tells the user what to fix.
🧠 This is called "fail fast" logic — a defensive programming technique that saves debugging time later.
🌐 4. GitHub API Wrapper Function
function github_api_get {
local endpoint="$1"
curl -s -u "${USERNAME}:${TOKEN}" "${API_URL}/${endpoint}"
}
✅ Purpose:
This helper function:
💡 Reusability: You could expand this to support POST, PUT, DELETE for a complete GitHub automation toolkit.
📋 5. Main Logic – List Users With Read Access
function list_users_with_read_access {
local endpoint="repos/${REPO_OWNER}/${REPO_NAME}/collaborators"
collaborators=$(github_api_get "$endpoint" | jq -r '.[] | select(.permissions.pull == true) | .login')
if [[ -z "$collaborators" ]]; then
echo "No users with read access found."
else
echo "Users with read access to ${REPO_OWNER}/${REPO_NAME}:"
echo "$collaborators"
fi
}
✅ Purpose:
This function does the core work:
🧠 jq is a powerful tool for filtering, transforming, and formatting JSON — perfect for shell scripts working with APIs.
▶️ 6. Script Execution
echo "🔍 Checking collaborators for ${REPO_OWNER}/${REPO_NAME}..."
list_users_with_read_access
✅ Purpose:
The script ends with a friendly message and a call to the list_users_with_read_access function.
This is the "main" part of the script, akin to a main() function in other programming languages.
🧠 How It Works (In Plain English)
✔️ Input Validation
Checks for missing arguments, credentials, or missing jq. You get a helpful error if something's wrong.
✔️ GitHub API Call
Uses curl and your credentials to talk to GitHub securely.
✔️ Data Parsing with jq
Filters the API response to show only users with "pull" (read) access.
✔️ Clean Output
Prints usernames in a clean, readable list — perfect for auditing or reporting.
🔁 Real-World Scenario
Let’s say you support 20+ teams, each with their own GitHub repo. You want to:
Instead of opening every repo manually, just run this script across your org's repos. Automate it with a cron job, GitHub Actions, or your internal CI/CD system.
Time saved = hours.