Detection rules › Panther

GitHub Workflow Permissions Modified

Severity
medium
Entities
actor_ids, usernames
Log types
GitHub.Audit
Tags
GitHub, Initial Access:Supply Chain Compromise
Reference
https://docs.github.com/en/actions/security-for-github-actions/security-guides/automatic-token-authentication#permissions-for-the-github_token
Source
github.com/panther-labs/panther-analysis

Detects when the default workflow permissions for the GITHUB_TOKEN are modified at the organization level. GitHub Actions workflows use GITHUB_TOKEN for authentication, and changing these permissions can either expand or restrict what workflows can do by default. Unauthorized modifications could allow attackers to escalate privileges in CI/CD pipelines, potentially leading to supply chain compromise through malicious workflow modifications, unauthorized code deployments, or exfiltration of secrets. This is particularly concerning as it affects all repositories in the organization unless overridden at the repository level.

MITRE ATT&CK coverage

TacticTechniques
Initial AccessT1195 Supply Chain Compromise

Rule body yaml

AnalysisType: rule
Filename: github_workflow_permission_modified.py
RuleID: "GitHub.Workflow.PermissionsModified"
DisplayName: "GitHub Workflow Permissions Modified"
Enabled: true
LogTypes:
  - GitHub.Audit
Tags:
  - GitHub
  - Initial Access:Supply Chain Compromise
Reports:
  MITRE ATT&CK:
    - TA0001:T1195
Severity: Medium
Description: >
  Detects when the default workflow permissions for the GITHUB_TOKEN are modified at the organization level.
  GitHub Actions workflows use GITHUB_TOKEN for authentication, and changing these permissions can either
  expand or restrict what workflows can do by default. Unauthorized modifications could allow attackers to
  escalate privileges in CI/CD pipelines, potentially leading to supply chain compromise through malicious
  workflow modifications, unauthorized code deployments, or exfiltration of secrets. This is particularly
  concerning as it affects all repositories in the organization unless overridden at the repository level.
Runbook: |
  1. Identify the actor who modified the workflow permissions by reviewing the alert details for the 'actor' and 'actor_id' fields.
  2. Verify the legitimacy of the change:
     - Contact the user to confirm they made this change intentionally
     - Check if there was a recent change request or ticket associated with this modification
     - Verify the user's current role and whether they should have organization admin privileges
  3. Review the permission change details:
     - Navigate to GitHub Organization Settings > Actions > General > Workflow permissions
     - Document the current permission level (Read and write permissions vs. Read repository contents and packages permissions)
     - Check if "Allow GitHub Actions to create and approve pull requests" is enabled
  4. Assess the security impact:
     - Determine if permissions were expanded (potentially dangerous) or restricted (potentially disruptive)
     - Review recent workflow runs across the organization for any suspicious activity
     - Check for any new or modified workflows that may have been added around the time of this change
  5. If unauthorized or suspicious:
     - Immediately revert the permissions to the previous secure state
     - Review GitHub audit logs for other suspicious activities by the same actor
     - Check for any workflows that executed between the permission change and reversion
     - Rotate any secrets that may have been exposed
     - Consider revoking the actor's admin privileges pending investigation
     - Review all recent commits and pull requests for signs of compromise
  6. Implement preventive measures:
     - Enable branch protection rules requiring reviews for workflow file changes
     - Implement the principle of least privilege for workflow permissions at the repository level
     - Consider using environment protection rules for sensitive deployments
     - Enable secret scanning and push protection
     - Document approved workflow permission settings in your security policies
Reference: https://docs.github.com/en/actions/security-for-github-actions/security-guides/automatic-token-authentication#permissions-for-the-github_token
Tests:
  - Name: Workflow Permissions Modified
    ExpectedResult: true
    Log:
      {
        "p_any_actor_ids": [
          "12345678"
        ],
        "p_any_usernames": [
          "homersimpson"
        ],
        "p_event_time": "2025-10-15 18:41:19.605000000",
        "p_log_type": "GitHub.Audit",
        "p_parse_time": "2025-10-15 18:54:06.098589038",
        "p_source_label": "AuditLog",
        "p_udm": {
          "user": {
            "name": "homersimpson",
            "provider_id": "12345678"
          }
        },
        "_document_id": "2bY2MKh36kTq5SWjmj5__Q",
        "action": "org.set_default_workflow_permissions",
        "actor": "homersimpson",
        "actor_id": "12345678",
        "actor_is_bot": false,
        "actor_location": {
          "country_code": "US"
        },
        "at_sign_timestamp": "2025-10-15 18:41:19.605000000",
        "business": "yourcompany",
        "business_id": "1234",
        "created_at": "2025-10-15 18:41:19.605000000",
        "operation_type": "modify",
        "org": "YourCompany",
        "org_id": 123456780,
      }
  - Name: Workflow Permissions Created
    ExpectedResult: false
    Log:
      {
        "p_any_actor_ids": [
          "12345678"
        ],
        "p_any_usernames": [
          "homersimpson"
        ],
        "p_event_time": "2025-10-15 18:41:19.605000000",
        "p_log_type": "GitHub.Audit",
        "p_parse_time": "2025-10-15 18:54:06.098589038",
        "p_source_label": "AuditLog",
        "p_udm": {
          "user": {
            "name": "homersimpson",
            "provider_id": "12345678"
          }
        },
        "_document_id": "2bY2MKh36kTq5SWjmj5__Q",
        "action": "org.set_default_workflow_permissions",
        "actor": "homersimpson",
        "actor_id": "12345678",
        "actor_is_bot": false,
        "actor_location": {
          "country_code": "US"
        },
        "at_sign_timestamp": "2025-10-15 18:41:19.605000000",
        "business": "yourcompany",
        "business_id": "1234",
        "created_at": "2025-10-15 18:41:19.605000000",
        "operation_type": "create",
        "org": "YourCompany",
        "org_id": 123456780,
      }

Detection logic

Condition

action eq "org.set_default_workflow_permissions"
operation_type eq "modify"

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
actioneq
  • org.set_default_workflow_permissions
operation_typeeq
  • modify

Output fields

Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.

Field
org
actor