GitHub Org Default Permissions
More Info:
The default permission given to new organization users should be set to none. Read permissions risk exposing private repositories, while write or admin permissions risk sensitive access to repositories for new users.
Risk Level
Medium
Address
Security
Compliance Standards
- Cloudanix Best Practice
Triage and Remediation
- Remediation
Remediation
Using Console
Here’s how to lock down Organization Default Permissions in GitHub using the web console.
1. Open your Organization Settings
- Sign in to GitHub.
- In the top-right, click your profile picture.
- Under “Organizations”, click the organization you want to configure.
- In the org view, click Settings (top tabs).
2. Reduce Default Repository Permissions (Base Permissions)
GitHub has a “base” (default) permission that applies to all org members on all repositories unless explicitly overridden.
- In the left sidebar, look for one of:
- Member privileges, or
- Organization security → Base permissions (newer UI)
- Find Base permissions or Default repository permissions.
- Change from overly permissive settings (e.g.,
WriteorAdmin) to a least-privilege option:- Prefer Read or None depending on your policy:
- Read: members can view all repos by default.
- None: members only see repos they are explicitly granted access to.
- Prefer Read or None depending on your policy:
- Click Save / Update.
3. Restrict Who Can Create Repositories (if needed)
- In the same Member privileges (or similar) section:
- Under Repository creation / Repository permissions, adjust:
- Allow creation of Private, Internal, Public repos only for:
- Organization owners (strict), or
- Selected members if you need delegated admins.
- Allow creation of Private, Internal, Public repos only for:
- Save changes.
4. Review & Clean Up Existing Access
Changing defaults does not fix past grants. Quickly review:
- People tab → check member roles (Owner vs Member).
- Repositories tab:
- For sensitive repos, open the repo → Settings → Collaborators and teams:
- Remove broad
Write/Adminfor@org/*or large teams. - Scope permissions narrowly (Read/Write/Admin per team/user).
- Remove broad
- For sensitive repos, open the repo → Settings → Collaborators and teams:
This sequence remediates overly permissive Org Default Permissions for GitHub IAM through the GitHub console.
Using CLI
Below are step‑by‑step instructions to remediate overly‑permissive Org Default Permissions in GitHub using the GitHub CLI (gh), by tightening the default member privileges and default repository permissions.
Assumptions:
- You’re an org owner (or have equivalent admin rights).
- You have
ghinstalled and authenticated (gh auth login).
1. Identify Current Organization Default Settings
Replace ORG with your organization login (e.g., my-company).
gh api \
-H "Accept: application/vnd.github+json" \
/orgs/ORG \
| jq '.default_repository_permission, .members_can_create_repositories, .members_allowed_repository_creation_type, .members_can_create_public_repositories, .members_can_create_private_repositories, .members_can_create_internal_repositories'
If you don’t have jq, remove the pipe and inspect JSON manually.
2. Restrict Default Repository Permission for Members
To remediate “org default permissions” you typically want read or none (instead of write or admin) as the default permission for organization members on new repos.
Available values: read, write, admin, none.
Example: set default to read:
gh api \
-X PATCH \
-H "Accept: application/vnd.github+json" \
/orgs/ORG \
-f default_repository_permission=read
For the strictest posture (no automatic access):
gh api \
-X PATCH \
-H "Accept: application/vnd.github+json" \
/orgs/ORG \
-f default_repository_permission=none
3. Restrict Members from Creating Repositories
If your misconfiguration is that “any member can create repos”:
3.1 Disable Member Repo Creation Entirely
gh api \
-X PATCH \
-H "Accept: application/vnd.github+json" \
/orgs/ORG \
-f members_can_create_repositories=false
This forces repo creation to be done only by org owners or via approved automation.
3.2 (Optional) If You Allow Some Creation, Limit Types
If you must allow creation, restrict types (GitHub Enterprise / orgs that support these flags):
gh api \
-X PATCH \
-H "Accept: application/vnd.github+json" \
/orgs/ORG \
-f members_can_create_repositories=true \
-f members_allowed_repository_creation_type=private \
-f members_can_create_public_repositories=false \
-f members_can_create_private_repositories=true \
-f members_can_create_internal_repositories=false
Adjust according to what is allowed in your org.
4. Confirm the New Configuration
Re-run:
gh api \
-H "Accept: application/vnd.github+json" \
/orgs/ORG \
| jq '.default_repository_permission, .members_can_create_repositories, .members_allowed_repository_creation_type, .members_can_create_public_repositories, .members_can_create_private_repositories, .members_can_create_internal_repositories'
Verify:
default_repository_permissionisreadornone(per your policy).members_can_create_repositoriesisfalse(or restricted as desired).- Allowed repo types match your security policy.
5. (Optional) Script It for Repeatable Use
Example remediation script:
ORG="my-org"
gh api -X PATCH -H "Accept: application/vnd.github+json" /orgs/$ORG \
-f default_repository_permission=none \
-f members_can_create_repositories=false
Run this for each organization you manage, adjusting $ORG and the values as needed.
If you share your current JSON for /orgs/ORG, I can give you the exact gh api patch command tailored to your current misconfiguration.
Using Python
Below are concrete, step‑by‑step remediation instructions to lock down an organization’s default (base) permissions in GitHub using Python.
Assumption:
You want to enforce least-privilege by ensuring that new org members and newly created repos don’t get broad access by default.
1. Decide the Desired Default Permissions
Typical least-privilege setup:
default_repository_permission:"read"or"none"members_can_create_repositories:false- Optionally, also restrict:
members_can_create_private_repositoriesmembers_can_create_internal_repositoriesmembers_can_create_public_repositoriesmembers_can_create_pagesmembers_can_create_public_pagesmembers_can_create_private_pages
You can tune these, but for a strict setup:
{
"default_repository_permission": "read",
"members_can_create_repositories": false,
"members_can_create_private_repositories": false,
"members_can_create_internal_repositories": false,
"members_can_create_public_repositories": false
}
2. Prepare a Token with Correct Scopes
-
Create a Fine-grained personal access token or classic PAT with:
admin:orgscope (for managing org settings)- If classic: also
read:orgif you want to read config first
-
Store it securely (e.g., environment variable
GITHUB_TOKEN).
3. Identify Your Organization Name
You need the login name of the org, e.g.:
ORG_NAME = "my-org-name"
4. Install Dependencies
You can use requests (no extra install beyond pip install requests) or PyGithub. Below is with requests (simplest for IAM-like config changes):
pip install requests
5. Python: Read Current Org Default Permissions
import os
import requests
GITHUB_TOKEN = os.environ["GITHUB_TOKEN"]
ORG_NAME = "my-org-name"
session = requests.Session()
session.headers.update({
"Authorization": f"Bearer {GITHUB_TOKEN}",
"Accept": "application/vnd.github+json",
"X-GitHub-Api-Version": "2022-11-28"
})
org_url = f"https://api.github.com/orgs/{ORG_NAME}"
resp = session.get(org_url)
resp.raise_for_status()
data = resp.json()
print("Current defaults:")
print("default_repository_permission:", data.get("default_repository_permission"))
print("members_can_create_repositories:", data.get("members_can_create_repositories"))
print("members_can_create_private_repositories:", data.get("members_can_create_private_repositories"))
print("members_can_create_internal_repositories:", data.get("members_can_create_internal_repositories"))
print("members_can_create_public_repositories:", data.get("members_can_create_public_repositories"))
print("members_can_create_pages:", data.get("members_can_create_pages"))
print("members_can_create_public_pages:", data.get("members_can_create_public_pages"))
print("members_can_create_private_pages:", data.get("members_can_create_private_pages"))
Use this to verify what “org default permissions” currently are.
6. Python: Remediate (Set Least-Privilege Defaults)
import os
import requests
GITHUB_TOKEN = os.environ["GITHUB_TOKEN"]
ORG_NAME = "my-org-name"
session = requests.Session()
session.headers.update({
"Authorization": f"Bearer {GITHUB_TOKEN}",
"Accept": "application/vnd.github+json",
"X-GitHub-Api-Version": "2022-11-28"
})
org_url = f"https://api.github.com/orgs/{ORG_NAME}"
payload = {
# Base/default permission for org members on organization repositories
# Allowed: "read", "write", "admin", "none"
"default_repository_permission": "read",
# Strongly recommended: disable repo creation by members
"members_can_create_repositories": False,
# If your org supports these granular flags (GitHub Enterprise Cloud):
"members_can_create_private_repositories": False,
"members_can_create_internal_repositories": False,
"members_can_create_public_repositories": False,
# Optional, if you want to restrict GitHub Pages creation:
# "members_can_create_pages": False,
# "members_can_create_public_pages": False,
# "members_can_create_private_pages": False,
}
resp = session.patch(org_url, json=payload)
resp.raise_for_status()
print("Updated org settings:")
print(resp.json())
7. Verify Remediation
Run the “read current settings” script again and confirm:
default_repository_permissionmatches your target (e.g."read"or"none").- Repository creation and other default capabilities are aligned with policy.
8. (Optional) Make This Enforceable / Repeatable
- Put the script into CI/CD and:
- Run it periodically or
- Trigger on changes to a “org-policy” repo.
- Fail the pipeline if the current settings do not match your policy JSON.
If you tell me your exact desired policy (e.g., default permission level and which actions to allow for members), I can give you a ready-to-run Python script tailored to it.
Using Terraform
resource "github_organization_settings" "org" {
# Replace with your GitHub organization name
name = "GITHUB_ORG_NAME"
# Set default permission for new organization members to none
default_repository_permission = "none"
# Other required / commonly used settings as applicable to your org
billing_email = "BILLING_EMAIL@example.com"
# Add/retain any other arguments you already manage here
}
Changing default_repository_permission does not force resource replacement; it updates the organization setting in place.
After you update your configuration, terraform plan should show a single ~ (update in-place) on github_organization_settings.org with default_repository_permission changing from its current value (e.g., "read") to "none".