Skip to main content

GitHub User Email should be Private

More Info:

Checks that the primary email addresses associated with a GitHub account is set to private visibility. Email addresses added to GitHub should be set to private visibility to increase privacy and prevent account reconnaissance.

Risk Level

Medium

Address

Security

Compliance Standards

  • Cloudanix Best Practice

Triage and Remediation

Remediation

Using Console

To make a GitHub user’s email private using the GitHub web console:

  1. Sign in to GitHub
    Log into the GitHub account whose email you want to make private.

  2. Open User Settings

    • Click your profile picture (top-right corner).
    • Click “Settings” in the dropdown.
  3. Go to Email Settings

    • In the left-hand menu, click “Emails”.
  4. Hide your email address from public profile
    Under “Primary email address” / “Email privacy”:

    • Check “Keep my email addresses private”.
    • If available, also check “Block command line pushes that expose my email” to prevent your real email from appearing in commits.
  5. Use GitHub-provided noreply email (recommended)

    • Still under “Emails”, note the @users.noreply.github.com address.
    • Optionally set it as your primary email if you want all GitHub operations to use this masked address where possible.
  6. Confirm profile visibility

    • Go to Settings → Profile.
    • Ensure the Email field is either empty or shows the noreply address, not your real email.

If this is for an organization policy, you cannot centrally force all members’ email addresses to be private via IAM alone; each user must perform the above steps on their own account. You can, however, document this as a security requirement and verify via profile checks or audits.

Using CLI

For GitHub, “making user email private” has two parts:

  1. Avoid exposing your real email in commits (git config)
  2. Use GitHub’s noreply email (per-user setting + git config)

GitHub does not currently expose the “Keep my email address private” toggle as a GitHub CLI command, but you can fully remediate exposure in Git and use gh to automate the rest.


1. Get your GitHub noreply email (with gh)

gh api user/emails --method GET --jq '.[] | select(.primary == true and .visibility == "public") | .email'

If you use email privacy, your primary public email will be something like:

12345678+username@users.noreply.github.com

If that doesn’t return the noreply, list all emails and pick the noreply one:

gh api user/emails --method GET --jq '.[].email'

2. Set noreply email as your global Git identity

Replace <NOREPLY_EMAIL> with the value from above:

git config --global user.email "<NOREPLY_EMAIL>"
git config --global user.name "<YOUR_NAME>"

For a single repo only:

cd /path/to/repo
git config user.email "<NOREPLY_EMAIL>"
git config user.name "<YOUR_NAME>"

This prevents future commits from exposing your real email.


3. Block pushes that expose real email (per‑repo policy)

You can script a guard using gh + git hooks.

Create .git/hooks/pre-push:

#!/usr/bin/env bash
REAL_EMAIL_PATTERN='@gmail\.com\|@outlook\.com\|@yourcompany\.com' # adjust
if git log --format='%ae' origin/main..HEAD 2>/dev/null | grep -E "$REAL_EMAIL_PATTERN" ; then
echo "Push blocked: commits contain real email addresses. Use your GitHub noreply email."
exit 1
fi

Make it executable:

chmod +x .git/hooks/pre-push

You can distribute this with:

gh repo clone <owner>/<repo>
# then commit the hook logic in a script and tell users to install it, or manage via internal tooling

4. (Required via Web UI once per user) Turn on email privacy and blocking

This part cannot be fully done via gh today; it’s a one‑time user action:

  1. GitHub → SettingsEmails
  2. Check “Keep my email address private”
  3. Check “Block command line pushes that expose my email”

After you do that once, the CLI + git config setup above will ensure ongoing compliance.


Summary (CLI-focused “remediation”)

  • Use gh api to discover your noreply email.
  • Use git config (scriptable and enforceable in your org) to set that as user.email.
  • Optionally add pre-push hooks (distributed via gh repo flows) to block pushes that contain real emails.
Using Python

Below are concrete steps and a Python example to remediate “User Email should be Private” for GitHub by removing (or replacing) the public email via the GitHub API.

Important limitation:
GitHub does not let an org admin change a member’s profile email. Each user must do this themself using their own personal access token (PAT). The script below is meant to be run per user (or with that user’s token).


1. Decide the desired state

You typically want no real email shown on the public profile. Two common options:

  1. Clear the public email (best for privacy):

    • Set email to null (or omit it) so the profile doesn’t show a public email.
  2. Replace with GitHub’s noreply email:

    • Format: <id>+<username>@users.noreply.github.com
    • This is still an email but not a real one.

If your scanner says “User Email should be Private,” either clearing it or switching to noreply will usually satisfy the requirement.


2. Get a GitHub Personal Access Token (PAT)

For each user:

  1. Go to Settings → Developer settings → Personal access tokens → Tokens (classic).
  2. Create a token with:
    • Scope: user (this is needed to update the profile).
  3. Copy the token (you’ll use it in the script as GITHUB_TOKEN).

3. Python code to clear or replace public email

Option A: Clear public email

import os
import requests

GITHUB_TOKEN = os.getenv("GITHUB_TOKEN") # or hardcode for testing
if not GITHUB_TOKEN:
raise SystemExit("Set GITHUB_TOKEN in the environment.")

API_URL = "https://api.github.com/user"
headers = {
"Authorization": f"token {GITHUB_TOKEN}",
"Accept": "application/vnd.github+json",
}

# Get current user profile to show what will be changed (optional)
resp = requests.get(API_URL, headers=headers)
resp.raise_for_status()
user = resp.json()
print(f"Current login: {user['login']}, public email: {user.get('email')}")

# PATCH to clear the public email by setting it to null
payload = {
"email": None
}

resp = requests.patch(API_URL, headers=headers, json=payload)
resp.raise_for_status()

# Confirm
resp = requests.get(API_URL, headers=headers)
resp.raise_for_status()
updated = resp.json()
print(f"Updated public email: {updated.get('email')}")

Option B: Set to GitHub noreply email

import os
import requests

GITHUB_TOKEN = os.getenv("GITHUB_TOKEN")
if not GITHUB_TOKEN:
raise SystemExit("Set GITHUB_TOKEN in the environment.")

API_URL = "https://api.github.com/user"
headers = {
"Authorization": f"token {GITHUB_TOKEN}",
"Accept": "application/vnd.github+json",
}

# Get current user to build noreply address
resp = requests.get(API_URL, headers=headers)
resp.raise_for_status()
user = resp.json()

user_id = user["id"]
username = user["login"]
noreply_email = f"{user_id}+{username}@users.noreply.github.com"
print(f"Setting public email to noreply: {noreply_email}")

payload = {
"email": noreply_email
}

resp = requests.patch(API_URL, headers=headers, json=payload)
resp.raise_for_status()

# Confirm
resp = requests.get(API_URL, headers=headers)
resp.raise_for_status()
updated = resp.json()
print(f"Updated public email: {updated.get('email')}")

4. (Optional) Enforce noreply in Git commits

Even if the profile email is private, commits can still leak real emails. Each user should:

  1. Set global Git config to noreply:
    git config --global user.email "<id>+<username>@users.noreply.github.com"
  2. In GitHub UI: Settings → Emails →
    • Check “Keep my email addresses private”
    • Check “Block command line pushes that expose my email” (if available)

This must be done per user; there is no GitHub API for those checkboxes right now.


If you tell me how your scanner checks this (e.g., via GitHub API or UI), I can adjust the payload/logic to match that exact rule.

Using Terraform

Terraform cannot remediate this finding: the GitHub provider does not expose any resource or argument to manage a user’s primary email or its visibility setting.

You must change this at the account level, either:

  • Via GitHub UI:
    Profile → Settings → Emails → set your primary email to “Keep my email addresses private”.

or

  • Via GitHub API (as per the docs you linked), authenticated as the user, e.g.:
    • GET /user/emails to list emails and find the primary one.
    • PATCH /user/email/visibility with {"visibility": "private"} to toggle the primary email’s visibility.

Additional Reading: