Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .github/workflows/dependency-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Dependency Review

on: [pull_request]

permissions:
contents: read
pull-requests: write

jobs:
dependency-review:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6.0.1

- name: Dependency Review
uses: actions/dependency-review-action@v4.8.2
with:
# Block pull requests with any vulnerabilities
fail-on-severity: low
# Post detailed summary in PR comments when vulnerabilities are found
comment-summary-in-pr: on-failure
78 changes: 20 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# GitHub Security Configuration CLI Extension

A GitHub CLI extension to create and apply security configurations across many organizations in a GitHub Enterprise.
A GitHub CLI extension to create, apply, modify, or delete security configurations across many organizations in a GitHub Enterprise.

> [!NOTE]
> This extension is intended for GitHub Enterprise Server (GHES) 3.15 and supports configuring GitHub Advanced Security, Secret Scanning, and Dependabot features as part of a security configuration. For GHES 3.16+ and GitHub Enterprise Cloud (GHEC) it's recommended to use [Enterprise Security Configurations](https://docs.github.com/en/enterprise-cloud@latest/admin/managing-code-security/securing-your-enterprise/about-security-configurations) instead of this solution.
> For GHES 3.16+ and GitHub Enterprise Cloud (GHEC) it's recommended to use a single [Enterprise Security Configuration](https://docs.github.com/en/enterprise-cloud@latest/admin/managing-code-security/securing-your-enterprise/about-security-configurations) instead of creating security configurations per organization.

## Pre-requisites

Expand Down Expand Up @@ -37,7 +37,7 @@ The extension provides four main commands for managing security configurations a

### Commands

- **`generate`** - Create and apply new security configurations across organizations
- **`generate`** - Create and optionally apply new security configurations across organizations
- **`apply`** - Apply existing security configurations to repositories across organizations
- **`modify`** - Update existing security configurations across organizations
- **`delete`** - Remove existing security configurations from organizations
Expand All @@ -52,18 +52,14 @@ These flags are available on all commands:
- **`--org-list string`** (`-l`) - Path to CSV file containing organization names to target (one per line, no header)
- **`--all-orgs`** - Target all organizations in the enterprise

> [!IMPORTANT]
> For the `generate` command, exactly one of `--org`, `--org-list`, or `--all-orgs` must be specified.
> For the `apply`, `delete`, and `modify` commands, if no org targeting flag is provided, you will be prompted to select a targeting method interactively.

#### Other Flags

- **`--concurrency int`** (`-c`) - Number of concurrent requests (1-20, default: 1)
- **`--concurrency int`** (`-c`) - Number of concurrent requests (1-20, default: 1, mutually exclusive with `--delay`)
- **`--delay int`** (`-d`) - Delay in seconds between organizations (1-600, mutually exclusive with `--concurrency`)
- **`--enterprise-slug string`** (`-e`) - GitHub Enterprise slug (e.g., github). Skips interactive prompt when provided
- **`--github-enterprise-server-url string`** (`-u`) - GitHub Enterprise Server URL (e.g., github.company.com). Skips interactive prompt when provided
- **`--dependabot-alerts-available string`** (`-a`) - Whether Dependabot Alerts are available in your GHES instance (true/false). Skips interactive prompt when provided
- **`--dependabot-security-updates-available string`** (`-s`) - Whether Dependabot Security Updates are available in your GHES instance (true/false). Skips interactive prompt when provided
- **`--enterprise-slug string`** (`-e`) - GitHub Enterprise slug (e.g., github)
- **`--github-enterprise-server-url string`** (`-u`) - GitHub Enterprise Server URL (e.g., github.company.com)
- **`--dependabot-alerts-available string`** (`-a`) - Whether Dependabot Alerts are available in your GHES instance (true/false)
- **`--dependabot-security-updates-available string`** (`-s`) - Whether Dependabot Security Updates are available in your GHES instance (true/false)

### Generate Command Flags

Expand All @@ -81,45 +77,28 @@ The `apply`, `delete`, and `modify` commands have an additional required flag:
### Basic Usage Examples

```bash
# Create a new security configuration interactively for all orgs
gh security-config generate --all-orgs
# Create a new security configuration
gh security-config generate

# Apply an existing security configuration from a template org to all orgs
gh security-config apply --template-org my-template-org --all-orgs
# Apply an existing security configuration to all orgs
gh security-config apply --all-orgs

# Modify a security configuration (fetched from template org) for a single org
gh security-config modify --template-org my-template-org --org my-org
# Modify a security configuration
gh security-config modify

# Delete a security configuration from organizations in a CSV
gh security-config delete --template-org my-template-org --org-list orgs.csv
# Delete a security configuration from a CSV list of organizations
gh security-config delete --org-list orgs.csv

# Use flags to skip interactive prompts
gh security-config generate --all-orgs -e my-enterprise -u github.mycompany.com -a true -s false

# Apply with interactive org selection (no org flag provided)
gh security-config apply --template-org my-template-org

# Use concurrent processing for faster execution (up to 20 organizations at once)
gh security-config generate --all-orgs --concurrency 5

# Use delayed processing to avoid rate limits and reduce system overhead (30 second delay between organizations)
gh security-config generate --org-list orgs.csv --delay 30
```

### Organization Targeting

All commands require exactly one of three mutually exclusive organization targeting options:

| Flag | Description |
|------|-------------|
| `--org <name>` | Target a single organization by name |
| `--org-list <path>` (`-l`) | Target organizations listed in a CSV file (one per line, no header) |
| `--all-orgs` | Target all organizations in the enterprise |

- **CSV Format**: Create a CSV file with one organization name per line (no header row required)
- **Example CSV**: See [example-organizations.csv](example-organizations.csv) for the correct format
- **Error Handling**: If an organization is not found or accessible, the tool will show a warning and continue with other organizations

### Copying Security Configurations

The `--copy-from-org` flag allows you to copy an existing security configuration from one organization and apply it to other organizations in your enterprise. This is useful for:
Expand Down Expand Up @@ -151,6 +130,10 @@ Process multiple organizations simultaneously to improve performance:
- **Usage**: Available on all commands (`generate`, `apply`, `modify`, `delete`)
- **Benefits**: Significantly reduces total processing time for large numbers of organizations

> [!WARNING]
> **Rate Limiting Considerations**: Setting concurrency higher than 1 increases the likelihood of encountering GitHub's secondary rate limits. To avoid rate limiting issues, consider [exempting the user from rate limits](https://docs.github.com/en/enterprise-server@3.15/admin/administering-your-instance/administering-your-instance-from-the-command-line/command-line-utilities#ghe-config).


#### Sequential Processing with Delay (`--delay`)

Process organizations one at a time with a configurable delay between each:
Expand All @@ -159,23 +142,6 @@ Process organizations one at a time with a configurable delay between each:
- **Usage**: Available on all commands (`generate`, `apply`, `modify`, `delete`)
- **Benefits**: Helps avoid rate limiting issues and provides controlled processing pace

#### Mutual Exclusivity

The `--concurrency` and `--delay` flags are mutually exclusive:

- **Cannot use both**: You must choose either concurrent processing OR sequential processing with delay
- **Default behavior**: When neither flag is specified, processing runs sequentially without delay (concurrency=1, delay=0)

#### Performance Benefits

- **Concurrent Mode**: Faster execution for time-sensitive operations
- **Delayed Mode**: Better for rate limit management and controlled processing
- **Configurable**: Choose the mode based on your needs and environment constraints
- **Progress Tracking**: Real-time progress updates work seamlessly with both processing modes

> [!WARNING]
> **Rate Limiting Considerations**: Setting concurrency higher than 1 increases the likelihood of encountering GitHub's secondary rate limits. To avoid rate limiting issues, consider [exempting the user from rate limits](https://docs.github.com/en/enterprise-server@3.15/admin/administering-your-instance/administering-your-instance-from-the-command-line/command-line-utilities#ghe-config).

### Error Handling and Requirements

#### Dependabot Feature Availability
Expand Down Expand Up @@ -254,10 +220,6 @@ When attaching configurations to repositories, you can choose:
- **private_or_internal**: Apply only to private and internal repositories
- **none**: Create the configuration without applying it to any repositories

## Demo

![Demo of gh-security-config generate](docs/gh-security-config-demo.gif)

## Development

To build the extension locally:
Expand Down
33 changes: 31 additions & 2 deletions cmd/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ func runGenerate(cmd *cobra.Command, args []string) error {
return err
}

// Validate org targeting flags
if err := utils.ValidateOrgFlags(commonFlags); err != nil {
// Validate org targeting flags (optional for generate command)
if err := utils.ValidateOrgFlagsOptional(commonFlags); err != nil {
return err
}

Expand Down Expand Up @@ -88,6 +88,35 @@ func runGenerate(cmd *cobra.Command, args []string) error {
// Set hostname if using GitHub Enterprise Server
ui.SetupGitHubHost(serverURL)

// If no org targeting method is provided, prompt user to select one
if !utils.HasOrgTargeting(commonFlags) {
targetingMethod, err := ui.SelectOrgTargetingMethod()
if err != nil {
return err
}

switch targetingMethod {
case "all-orgs":
commonFlags.AllOrgs = true
case "single-org":
orgName, err := ui.GetSingleOrgName()
if err != nil {
return err
}
commonFlags.Org = orgName
case "org-list":
csvPath, err := ui.GetOrgListPath()
if err != nil {
return err
}
commonFlags.OrgListPath = csvPath
// Validate the CSV file
if err := utils.ValidateOrgFlagsOptional(commonFlags); err != nil {
return err
}
}
}

// Check Dependabot availability
dependabotAlertsAvailable, err := ui.GetDependabotAlertsAvailability(commonFlags.DependabotAlertsAvailable)
if err != nil {
Expand Down
3 changes: 0 additions & 3 deletions docs/gh-security-config-demo.gif

This file was deleted.