Fortify Development
coollabsio/coolify
ACTIVATE when the user works on authentication in Laravel. An agent skill from coollabsio/coolify.
Agent skill
Performs OAuth 2.0 scope minimization review to identify over-permissioned third-party application integrations, excessive API scopes, unused token grants, and risky OAuth consent patterns across…
$ npx skills add mukul975/Anthropic-Cybersecurity-Skills --skill performing-oauth-scope-minimization-review -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install mukul975/Anthropic-Cybersecurity-Skills performing-oauth-scope-minimization-review --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/performing-oauth-scope-minimization-review .claude/skills/performing-oauth-scope-minimization-review && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "performing-oauth-scope-minimization-review" agent skill from https://github.com/mukul975/Anthropic-Cybersecurity-Skills/tree/main/skills/performing-oauth-scope-minimization-review into .claude/skills/performing-oauth-scope-minimization-review/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "performing-oauth-scope-minimization-review", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/mukul975/Anthropic-Cybersecurity-Skills/tree/main/skills/performing-oauth-scope-minimization-reviewType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add mukul975/Anthropic-Cybersecurity-Skills --skill performing-oauth-scope-minimization-review -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install mukul975/Anthropic-Cybersecurity-Skills performing-oauth-scope-minimization-review --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/performing-oauth-scope-minimization-review .agents/skills/performing-oauth-scope-minimization-review && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "performing-oauth-scope-minimization-review" agent skill from https://github.com/mukul975/Anthropic-Cybersecurity-Skills/tree/main/skills/performing-oauth-scope-minimization-review into .agents/skills/performing-oauth-scope-minimization-review/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "performing-oauth-scope-minimization-review", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add mukul975/Anthropic-Cybersecurity-Skills --skill performing-oauth-scope-minimization-review -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install mukul975/Anthropic-Cybersecurity-Skills performing-oauth-scope-minimization-review --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/performing-oauth-scope-minimization-review .cursor/skills/performing-oauth-scope-minimization-review && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "performing-oauth-scope-minimization-review" agent skill from https://github.com/mukul975/Anthropic-Cybersecurity-Skills/tree/main/skills/performing-oauth-scope-minimization-review into .cursor/skills/performing-oauth-scope-minimization-review/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "performing-oauth-scope-minimization-review", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git --path skills/performing-oauth-scope-minimization-review--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add mukul975/Anthropic-Cybersecurity-Skills --skill performing-oauth-scope-minimization-review -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install mukul975/Anthropic-Cybersecurity-Skills performing-oauth-scope-minimization-review --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/performing-oauth-scope-minimization-review .gemini/skills/performing-oauth-scope-minimization-review && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "performing-oauth-scope-minimization-review" agent skill from https://github.com/mukul975/Anthropic-Cybersecurity-Skills/tree/main/skills/performing-oauth-scope-minimization-review into .gemini/skills/performing-oauth-scope-minimization-review/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "performing-oauth-scope-minimization-review", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install mukul975/Anthropic-Cybersecurity-Skills performing-oauth-scope-minimization-reviewInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add mukul975/Anthropic-Cybersecurity-Skills --skill performing-oauth-scope-minimization-review -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/performing-oauth-scope-minimization-review .github/skills/performing-oauth-scope-minimization-review && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "performing-oauth-scope-minimization-review" agent skill from https://github.com/mukul975/Anthropic-Cybersecurity-Skills/tree/main/skills/performing-oauth-scope-minimization-review into .github/skills/performing-oauth-scope-minimization-review/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "performing-oauth-scope-minimization-review", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add mukul975/Anthropic-Cybersecurity-Skills --skill performing-oauth-scope-minimization-review -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install mukul975/Anthropic-Cybersecurity-Skills performing-oauth-scope-minimization-review --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/performing-oauth-scope-minimization-review .opencode/skills/performing-oauth-scope-minimization-review && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "performing-oauth-scope-minimization-review" agent skill from https://github.com/mukul975/Anthropic-Cybersecurity-Skills/tree/main/skills/performing-oauth-scope-minimization-review into .opencode/skills/performing-oauth-scope-minimization-review/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "performing-oauth-scope-minimization-review", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
performing-oauth-scope-minimization-reviewPerforms OAuth 2.0 scope minimization review to identify over-permissioned third-party application integrations, excessive API scopes, unused token grants, and risky OAuth consent patterns across…
Performing OAuth Scope Minimization Review is an agent skill from mukul975/Anthropic-Cybersecurity-Skills. Performs OAuth 2.0 scope minimization review to identify over-permissioned third-party application integrations, excessive API scopes, unused token grants, and risky OAuth consent patterns across identity providers and SaaS platforms. Activates for requests involving OAuth scope audit, API permission review, third-party app risk assessment, or consent grant minimization.
Its SKILL.md is about 6.2k tokens, which your agent loads only when the skill is triggered. The skill folder holds 5 other files, including scripts and reference files (for example `references/api-reference.md` and `scripts/agent.py`).
It sits in Backend & APIs, covering OAuth and OpenID Connect. The repository describes itself as: 817 structured cybersecurity skills for AI agents · Mapped to 6 frameworks: MITRE ATT&CK, NIST CSF 2.0, MITRE ATLAS, D3FEND, NIST AI RMF & MITRE F3 (Fight Fraud) · agentskills.io…. The licence is Apache-2.0.
5 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 54a7988. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Ships 1 file in scripts/ (Python), which the agent can run.
From the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
graph.microsoft.comlogin.microsoftonline.comFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Performing OAuth Scope Minimization Review loads about 6.2k tokens when it runs, and up to ~6.7k if it reads all its reference files. Until then it costs about 104 tokens; SKILL.md has 590 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.
The full file from mukul975/Anthropic-Cybersecurity-Skills at commit 54a7988, republished under its Apache-2.0 licence (© mukul975). 590 words, ~6,229 tokens.
.claude/skills/performing-oauth-scope-minimization-review/SKILL.md (or your agent's skills folder). This skill also uses 3 other files; get the full folder from GitHub.Do not use for reviewing first-party application permissions within the same trust boundary; OAuth scope minimization focuses on third-party and cross-boundary consent grants.
Enumerate all OAuth application registrations and delegated permissions:
"""
OAuth Grant Inventory - Microsoft Entra ID
Enumerates all application registrations, service principals,
and delegated/application permission grants.
"""
import requests
import json
from collections import defaultdict
class EntraOAuthAuditor:
def __init__(self, tenant_id, client_id, client_secret):
self.tenant_id = tenant_id
self.base_url = "https://graph.microsoft.com/v1.0"
self.token = self._get_token(client_id, client_secret)
self.headers = {"Authorization": f"Bearer {self.token}"}
def _get_token(self, client_id, client_secret):
url = f"https://login.microsoftonline.com/{self.tenant_id}/oauth2/v2.0/token"
response = requests.post(url, data={
"grant_type": "client_credentials",
"client_id": client_id,
"client_secret": client_secret,
"scope": "https://graph.microsoft.com/.default"
})
return response.json()["access_token"]
def get_all_service_principals(self):
"""Get all service principals (enterprise applications)."""
apps = []
url = f"{self.base_url}/servicePrincipals?$top=999&$select=id,appId,displayName,appOwnerOrganizationId,servicePrincipalType,accountEnabled,createdDateTime"
while url:
response = requests.get(url, headers=self.headers)
data = response.json()
apps.extend(data.get("value", []))
url = data.get("@odata.nextLink")
return apps
def get_oauth2_permission_grants(self):
"""Get all delegated permission grants (user consent)."""
grants = []
url = f"{self.base_url}/oauth2PermissionGrants?$top=999"
while url:
response = requests.get(url, headers=self.headers)
data = response.json()
grants.extend(data.get("value", []))
url = data.get("@odata.nextLink")
return grants
def get_app_role_assignments(self, sp_id):
"""Get application permission assignments for a service principal."""
url = f"{self.base_url}/servicePrincipals/{sp_id}/appRoleAssignments"
response = requests.get(url, headers=self.headers)
return response.json().get("value", [])
def build_permission_inventory(self):
"""Build comprehensive OAuth permission inventory."""
service_principals = self.get_all_service_principals()
delegated_grants = self.get_oauth2_permission_grants()
# Map service principal IDs to names
sp_map = {sp["id"]: sp for sp in service_principals}
inventory = []
# Process delegated permissions
for grant in delegated_grants:
sp = sp_map.get(grant["clientId"], {})
scopes = grant.get("scope", "").split()
for scope in scopes:
if not scope:
continue
inventory.append({
"app_name": sp.get("displayName", "Unknown"),
"app_id": grant.get("clientId"),
"publisher_tenant": sp.get("appOwnerOrganizationId"),
"is_third_party": sp.get("appOwnerOrganizationId") != self.tenant_id,
"permission_type": "Delegated",
"scope": scope,
"consent_type": grant.get("consentType"), # AllPrincipals or Principal
"principal_id": grant.get("principalId"),
"granted_date": sp.get("createdDateTime"),
"is_enabled": sp.get("accountEnabled", True)
})
# Process application permissions
for sp in service_principals:
app_roles = self.get_app_role_assignments(sp["id"])
for role in app_roles:
inventory.append({
"app_name": sp.get("displayName"),
"app_id": sp.get("id"),
"publisher_tenant": sp.get("appOwnerOrganizationId"),
"is_third_party": sp.get("appOwnerOrganizationId") != self.tenant_id,
"permission_type": "Application",
"scope": role.get("appRoleId"),
"consent_type": "AdminConsent",
"granted_date": role.get("createdDateTime"),
"is_enabled": sp.get("accountEnabled", True)
})
return inventoryCategorize permissions based on data access sensitivity:
"""
OAuth Scope Risk Classification
Maps API scopes to risk levels based on data sensitivity and access breadth.
"""
MICROSOFT_GRAPH_SCOPE_RISK = {
# CRITICAL - Full administrative or unrestricted access
"critical": {
"scopes": [
"Directory.ReadWrite.All",
"RoleManagement.ReadWrite.Directory",
"Application.ReadWrite.All",
"AppRoleAssignment.ReadWrite.All",
"Mail.ReadWrite",
"Mail.Send",
"Files.ReadWrite.All",
"Sites.FullControl.All",
"User.ReadWrite.All",
"Group.ReadWrite.All",
"MailboxSettings.ReadWrite",
"full_access_as_app",
],
"risk_description": "Can read/write all data, modify directory, or impersonate users",
"review_frequency": "Monthly",
"requires_admin_consent": True
},
# HIGH - Broad read access or sensitive data write
"high": {
"scopes": [
"Mail.Read",
"Mail.Read.Shared",
"Calendars.ReadWrite",
"Contacts.ReadWrite",
"Files.Read.All",
"Sites.Read.All",
"User.Read.All",
"Group.Read.All",
"Directory.Read.All",
"AuditLog.Read.All",
"SecurityEvents.ReadWrite.All",
"TeamSettings.ReadWrite.All",
],
"risk_description": "Broad read access to sensitive organizational data",
"review_frequency": "Quarterly",
"requires_admin_consent": True
},
# MEDIUM - Scoped data access
"medium": {
"scopes": [
"Calendars.Read",
"Contacts.Read",
"Files.ReadWrite",
"Sites.ReadWrite.All",
"Tasks.ReadWrite",
"Notes.ReadWrite.All",
"Chat.ReadWrite",
"ChannelMessage.Send",
"Team.ReadBasic.All",
],
"risk_description": "Scoped access to specific data types with write capability",
"review_frequency": "Semi-annually"
},
# LOW - Minimal or user-profile only access
"low": {
"scopes": [
"User.Read",
"openid",
"profile",
"email",
"offline_access",
"Calendars.Read.Shared",
"People.Read",
"User.ReadBasic.All",
],
"risk_description": "Basic user profile or minimal scoped access",
"review_frequency": "Annually"
}
}
def classify_scope_risk(scope):
"""Classify a single OAuth scope by risk level."""
for risk_level, config in MICROSOFT_GRAPH_SCOPE_RISK.items():
if scope in config["scopes"]:
return {
"scope": scope,
"risk_level": risk_level,
"description": config["risk_description"],
"review_frequency": config["review_frequency"]
}
# Unknown scopes default to HIGH risk
return {
"scope": scope,
"risk_level": "high",
"description": "Unknown scope - requires manual classification",
"review_frequency": "Quarterly"
}
def analyze_app_risk(app_permissions):
"""Calculate aggregate risk score for an application's permissions."""
risk_weights = {"critical": 40, "high": 20, "medium": 10, "low": 2}
total_score = 0
classified_scopes = []
for perm in app_permissions:
classification = classify_scope_risk(perm["scope"])
classified_scopes.append(classification)
total_score += risk_weights.get(classification["risk_level"], 10)
# Bonus risk for application (vs delegated) permissions
app_type_permissions = [p for p in app_permissions if p["permission_type"] == "Application"]
total_score += len(app_type_permissions) * 15
# Bonus risk for admin-consented broad access
admin_consent = [p for p in app_permissions if p["consent_type"] == "AllPrincipals"]
total_score += len(admin_consent) * 10
if total_score >= 100:
aggregate_risk = "CRITICAL"
elif total_score >= 60:
aggregate_risk = "HIGH"
elif total_score >= 30:
aggregate_risk = "MEDIUM"
else:
aggregate_risk = "LOW"
return {
"total_score": total_score,
"aggregate_risk": aggregate_risk,
"scope_count": len(app_permissions),
"critical_scopes": len([s for s in classified_scopes if s["risk_level"] == "critical"]),
"high_scopes": len([s for s in classified_scopes if s["risk_level"] == "high"]),
"classified_scopes": classified_scopes
}Detect apps requesting more permissions than functionally needed:
"""
Over-Permission Detection
Identifies applications with excessive OAuth scopes relative to their function.
"""
def detect_over_permissions(inventory, approved_apps_catalog):
"""
Compare actual permissions against approved scope catalog
to find over-permissioned applications.
"""
findings = []
# Group permissions by application
app_permissions = defaultdict(list)
for perm in inventory:
app_permissions[perm["app_name"]].append(perm)
for app_name, permissions in app_permissions.items():
# Check against approved catalog
approved = approved_apps_catalog.get(app_name)
if not approved:
# Unknown/unapproved application
findings.append({
"app_name": app_name,
"finding_type": "UNAPPROVED_APPLICATION",
"severity": "HIGH",
"detail": f"Application not in approved catalog with {len(permissions)} permission grants",
"scopes": [p["scope"] for p in permissions],
"recommendation": "Review and approve or revoke all permissions"
})
continue
approved_scopes = set(approved.get("approved_scopes", []))
actual_scopes = set(p["scope"] for p in permissions)
# Find excessive scopes (granted but not approved)
excessive = actual_scopes - approved_scopes
if excessive:
risk = analyze_app_risk([p for p in permissions if p["scope"] in excessive])
findings.append({
"app_name": app_name,
"finding_type": "EXCESSIVE_SCOPES",
"severity": risk["aggregate_risk"],
"detail": f"{len(excessive)} scopes beyond approved list",
"excessive_scopes": list(excessive),
"approved_scopes": list(approved_scopes),
"recommendation": "Remove excessive scopes or update approved catalog"
})
# Find unused scopes (approved but activity logs show no API calls)
# This requires API activity log correlation
unused = approved_scopes - actual_scopes
if unused:
findings.append({
"app_name": app_name,
"finding_type": "UNUSED_APPROVED_SCOPES",
"severity": "LOW",
"detail": f"{len(unused)} approved scopes not currently granted",
"unused_scopes": list(unused)
})
# Check for overly broad permissions
broad_patterns = [
("Mail.ReadWrite", "Mail.Read", "Write access to mail when only read needed"),
("Files.ReadWrite.All", "Files.Read.All", "Write access to all files when only read needed"),
("Directory.ReadWrite.All", "Directory.Read.All", "Write access to directory when only read needed"),
("User.ReadWrite.All", "User.Read.All", "Write access to users when only read needed"),
]
for broad, narrow, description in broad_patterns:
if broad in actual_scopes:
findings.append({
"app_name": app_name,
"finding_type": "OVERLY_BROAD_SCOPE",
"severity": "MEDIUM",
"detail": description,
"current_scope": broad,
"recommended_scope": narrow,
"recommendation": f"Downgrade from {broad} to {narrow}"
})
return findingsIdentify OAuth tokens that are no longer actively used:
"""
Token Usage Audit
Analyzes sign-in logs and API activity to identify stale OAuth grants.
"""
def audit_token_usage(auditor, days_inactive=90):
"""Identify OAuth grants with no recent API activity."""
# Get sign-in activity for service principals
url = f"{auditor.base_url}/auditLogs/signIns"
params = {
"$filter": f"createdDateTime ge {(datetime.utcnow() - timedelta(days=days_inactive)).isoformat()}Z and signInEventTypes/any(t: t eq 'servicePrincipal')",
"$top": 999
}
active_apps = set()
while url:
response = requests.get(url, headers=auditor.headers, params=params)
data = response.json()
for signin in data.get("value", []):
active_apps.add(signin.get("appId"))
url = data.get("@odata.nextLink")
params = {}
# Compare against all granted apps
all_grants = auditor.get_oauth2_permission_grants()
sp_map = {sp["id"]: sp for sp in auditor.get_all_service_principals()}
stale_grants = []
for grant in all_grants:
sp = sp_map.get(grant["clientId"], {})
app_id = sp.get("appId")
if app_id and app_id not in active_apps:
stale_grants.append({
"app_name": sp.get("displayName", "Unknown"),
"app_id": app_id,
"scopes": grant.get("scope", "").split(),
"consent_type": grant.get("consentType"),
"is_third_party": sp.get("appOwnerOrganizationId") != auditor.tenant_id,
"days_inactive": days_inactive,
"recommendation": "Revoke - no API activity in {days_inactive} days"
})
return sorted(stale_grants, key=lambda x: len(x["scopes"]), reverse=True)Create and execute the scope minimization remediation plan:
"""
OAuth Scope Remediation
Generates and executes scope reduction actions.
"""
def generate_remediation_plan(findings, stale_grants):
"""Create prioritized remediation plan."""
plan = []
# Priority 1: Revoke unapproved applications
for f in findings:
if f["finding_type"] == "UNAPPROVED_APPLICATION":
plan.append({
"priority": 1,
"action": "REVOKE_ALL_PERMISSIONS",
"app_name": f["app_name"],
"reason": "Unapproved third-party application",
"impact": f"Removes {len(f['scopes'])} permission grants",
"risk_if_not_addressed": "CRITICAL"
})
# Priority 2: Remove excessive scopes from approved apps
for f in findings:
if f["finding_type"] == "EXCESSIVE_SCOPES":
plan.append({
"priority": 2,
"action": "REMOVE_EXCESSIVE_SCOPES",
"app_name": f["app_name"],
"scopes_to_remove": f["excessive_scopes"],
"reason": "Scopes beyond approved catalog",
"risk_if_not_addressed": f["severity"]
})
# Priority 3: Downgrade overly broad scopes
for f in findings:
if f["finding_type"] == "OVERLY_BROAD_SCOPE":
plan.append({
"priority": 3,
"action": "DOWNGRADE_SCOPE",
"app_name": f["app_name"],
"current_scope": f["current_scope"],
"target_scope": f["recommended_scope"],
"reason": f["detail"],
"risk_if_not_addressed": "MEDIUM"
})
# Priority 4: Revoke stale grants
for grant in stale_grants:
plan.append({
"priority": 4,
"action": "REVOKE_STALE_GRANT",
"app_name": grant["app_name"],
"scopes_to_revoke": grant["scopes"],
"reason": f"No API activity in {grant['days_inactive']} days",
"risk_if_not_addressed": "MEDIUM"
})
return sorted(plan, key=lambda x: x["priority"])
def execute_scope_reduction(auditor, grant_id, scopes_to_remove):
"""Remove specific scopes from an OAuth permission grant."""
# Get current grant
url = f"{auditor.base_url}/oauth2PermissionGrants/{grant_id}"
response = requests.get(url, headers=auditor.headers)
current_grant = response.json()
current_scopes = set(current_grant.get("scope", "").split())
updated_scopes = current_scopes - set(scopes_to_remove)
if not updated_scopes:
# Remove entire grant
requests.delete(url, headers=auditor.headers)
return {"action": "grant_deleted", "grant_id": grant_id}
else:
# Update with reduced scopes
update_body = {"scope": " ".join(updated_scopes)}
requests.patch(url, headers=auditor.headers, json=update_body)
return {
"action": "scopes_reduced",
"grant_id": grant_id,
"removed": list(scopes_to_remove),
"remaining": list(updated_scopes)
}| Term | Definition |
|---|---|
| OAuth Scope | Permission string defining the specific API access level granted to a client application (e.g., Mail.Read, Files.ReadWrite.All) |
| Delegated Permission | OAuth scope exercised on behalf of a signed-in user, limited by both the app's permissions and the user's own access rights |
| Application Permission | OAuth scope granted directly to the application without user context, providing access to all users' data (high risk) |
| Admin Consent | Tenant-wide permission grant made by an administrator that applies to all users without individual consent |
| Scope Minimization | Security principle of reducing OAuth permissions to the minimum set required for application functionality |
| Stale Grant | OAuth permission that remains active but has no recent API usage, indicating the integration is abandoned or deprecated |
Context: After a phishing attack compromised an admin account, investigation reveals the attacker registered a malicious OAuth application with Mail.ReadWrite and Files.ReadWrite.All scopes, exfiltrating 6 months of email. The organization needs a comprehensive OAuth scope review.
Approach:
Pitfalls:
OAUTH SCOPE MINIMIZATION REVIEW REPORT
=========================================
Tenant: corp.onmicrosoft.com
Review Period: 2026-02-01 to 2026-02-24
Total Applications: 147
Third-Party Apps: 98
First-Party Apps: 49
PERMISSION INVENTORY
Total OAuth Grants: 487
Delegated Permissions: 312
Application Permissions: 175
Admin-Consented: 89
User-Consented: 223
RISK CLASSIFICATION
Critical Risk Apps: 7
- UnknownCRMApp (Mail.ReadWrite, Files.ReadWrite.All - UNAPPROVED)
- LegacySync (Directory.ReadWrite.All - EXCESSIVE)
- DevToolX (Application.ReadWrite.All - OVERLY BROAD)
High Risk Apps: 18
Medium Risk Apps: 34
Low Risk Apps: 88
FINDINGS
Unapproved Applications: 12 (REVOKE IMMEDIATELY)
Excessive Scopes: 23 apps with scopes beyond approved list
Overly Broad Permissions: 15 apps that can be downgraded
Stale Grants (90+ days): 31 apps with no recent API activity
REMEDIATION PLAN
Priority 1 (Immediate): 12 unapproved app revocations
Priority 2 (This Week): 23 excessive scope removals
Priority 3 (This Month): 15 scope downgrades
Priority 4 (Next Quarter): 31 stale grant revocations
Estimated Scope Reduction: 34% of total permissions© mukul975, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 3 other files (scripts, references) in skills/performing-oauth-scope-minimization-review of mukul975/Anthropic-Cybersecurity-Skills.
Open the folder on GitHubat commit 54a7988
Performing OAuth Scope Minimization Review next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Performing OAuth Scope Minimization Review this skillmukul975/Anthropic-Cybersecurity-Skills | 34k | — | ~6.2k | Automated safety check: Pass | Apache-2.0 | |
| Fortify Developmentcoollabsio/coolify | 63k | 4 repos | ~1.9k | Automated safety check: Pass | MIT | |
| OmniRoute Provider Managementdiegosouzapw/OmniRoute | 75k | — | ~2.4k | Automated safety check: Pass | MIT | |
| Antipattern Preventiondoorkeeper-gem/doorkeeper | 5.5k | — | ~1.1k | Automated safety check: Pass | MIT | |
| Cognitoitsmostafa/aws-agent-skills | 1.2k | 1 repos | ~2.3k | Automated safety check: Pass | MIT | |
| Notion Worker Third-Party Auth Guidemakenotion/workers-template | 439 | 1 repos | ~3.5k | Automated safety check: Notes | MIT |
coollabsio/coolify
ACTIVATE when the user works on authentication in Laravel. An agent skill from coollabsio/coolify.
diegosouzapw/OmniRoute
Manages AI provider connections, API keys, OAuth flows and connection tests through OmniRoute's REST API across its 327-provider catalog.
doorkeeper-gem/doorkeeper
Avoid common Ruby and Rails antipatterns that degrade maintainability and performance.
itsmostafa/aws-agent-skills
AWS Cognito user authentication and authorization service. An agent skill from itsmostafa/aws-agent-skills.
makenotion/workers-template
Decides whether a Notion Worker should use a brokered credential, a plaintext environment secret, or OAuth to authenticate against a non-Notion service.
kanchengw/cnllm
Guides Stripe integration decisions — API selection (Checkout Sessions vs PaymentIntents), Connect platform setup (Accounts v2, controller properties), billing/subscriptions, Treasury financial…
mukul975/Anthropic-Cybersecurity-Skills
Weighs infrastructure, TTP, malware code and timing evidence with the Diamond Model and competing hypotheses to reach a confidence-rated attribution.
mukul975/Anthropic-Cybersecurity-Skills
Walks through reverse engineering Go-compiled malware in Ghidra: parsing buildinfo and pclntab, recovering stripped function names and extracting dependencies.
mukul975/Anthropic-Cybersecurity-Skills
Guides forensic analysis of Windows LNK shortcut files and Jump Lists with LECmd, JLECmd and manual parsing to show file access and program execution.
mukul975/Anthropic-Cybersecurity-Skills
Hunts Windows malware persistence with Sysinternals Autoruns, covering run keys, services, scheduled tasks and drivers, with baseline comparison.
mukul975/Anthropic-Cybersecurity-Skills
Guides a Windows forensic examination of the NTFS Master File Table to recover deleted-file evidence, build timelines and spot timestomping.
mukul975/Anthropic-Cybersecurity-Skills
Detects DNS tunneling, ICMP exfiltration and HTTP-based covert channels in packet captures and DNS logs when hunting for hidden command-and-control traffic.
Categories
Performs OAuth 2.0 scope minimization review to identify over-permissioned third-party application integrations, excessive API scopes, unused token grants, and risky OAuth consent patterns across…. Performing OAuth Scope Minimization Review is an agent skill from mukul975/Anthropic-Cybersecurity-Skills.0 scope minimization review to identify over-permissioned third-party application integrations, excessive API scopes, unused token grants, and risky OAuth consent patterns across identity providers and SaaS platforms.
Performing OAuth Scope Minimization Review fits situations like: tasks that involve OAuth and OpenID Connect.
Run `npx skills add mukul975/Anthropic-Cybersecurity-Skills --skill performing-oauth-scope-minimization-review -a claude-code`. Or copy the skill folder (skills/performing-oauth-scope-minimization-review in mukul975/Anthropic-Cybersecurity-Skills) into .claude/skills/performing-oauth-scope-minimization-review in your project. Claude Code loads it when a task matches its description.
Run `npx skills add mukul975/Anthropic-Cybersecurity-Skills --skill performing-oauth-scope-minimization-review -a codex`. Or copy the skill folder (skills/performing-oauth-scope-minimization-review in mukul975/Anthropic-Cybersecurity-Skills) into .agents/skills/performing-oauth-scope-minimization-review in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add mukul975/Anthropic-Cybersecurity-Skills --skill performing-oauth-scope-minimization-review -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/performing-oauth-scope-minimization-review, .gemini/skills/performing-oauth-scope-minimization-review, .github/skills/performing-oauth-scope-minimization-review and .opencode/skills/performing-oauth-scope-minimization-review in your project.
Going by SKILL.md and its folder, Performing OAuth Scope Minimization Review needs Python for the scripts in its folder. Our summary lists: Python 3.
SKILL.md names 2 domains. In commands or code: graph.microsoft.com and login.microsoftonline.com; the agent is likely to contact these when it follows the instructions. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.
Performing OAuth Scope Minimization Review is published under the Apache-2.0 licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.
About 6.2k tokens (SKILL.md is roughly 25k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 492 tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Performing OAuth Scope Minimization Review: Fortify Development (coollabsio/coolify, 63k stars), OmniRoute Provider Management (diegosouzapw/OmniRoute, 75k stars), Antipattern Prevention (doorkeeper-gem/doorkeeper, 5.5k stars) and Cognito (itsmostafa/aws-agent-skills, 1.2k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
mukul975 (a GitHub user) maintains it in mukul975/Anthropic-Cybersecurity-Skills, which has 34,116 GitHub stars. The repository holds 644 skills in this directory. The repository was last updated on August 31, 2026.
Source: mukul975/Anthropic-Cybersecurity-Skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.