Secure script management and execution framework for Remote Monitoring and Management (RMM) platforms.
GitExec is a security-focused framework that enables RMM platforms to securely download and execute scripts from private GitHub repositories on managed endpoints. The framework provides encrypted credential storage, RSA signature verification, and cross-platform support for Windows and macOS systems.
- Secure Credential Storage - GitHub Personal Access Tokens (PAT) and RSA public keys encrypted using platform-native security (DPAPI on Windows, Keychain on macOS)
- Signature Verification - RSA public key infrastructure ready for script integrity verification
- Simple Deployment - Deploy the framework once, execute any script on-demand
- Version Control Integration - All scripts tracked in Git with full history
- Cross-Platform Support - Unified framework for both Windows and macOS endpoints
- Flexible Execution - Run scripts as SYSTEM/root or as logged-in users
- Dual-Secret Security - Both GitHub PAT and RSA public key required and managed together
- Modular Architecture - Bootstrap scripts download core libraries at runtime
GitExec/
├── _framework/ # GitExec execution framework
│ ├── _bootstrap/ # Bootstrap scripts (download core modules)
│ │ ├── WIN-GitExec.ps1
│ │ └── macOS-GitExec.sh
│ ├── _library/ # Core libraries (downloaded by bootstrap)
│ │ ├── WIN-GitExec-core.psm1
│ │ └── macOS-GitExec-core.sh
│ ├── _setup/ # Initial secrets configuration
│ │ ├── WIN-GitExec_Secrets.ps1
│ │ └── macOS-GitExec_Secrets.sh
│ └── README.md # Detailed framework documentation
│
├── _bin/ # Repository maintenance tools
│ ├── macOS-GitExec-gen_sigs.sh
│ ├── WIN-GitExec-gen_sigs.ps1
│ └── _setup/
│ ├── macOS-GitExec-gen_rsa_keys.sh
│ └── WIN-GitExec-gen_rsa_keys.ps1
│
├── _key/ # RSA public key for verification
│ └── AC-RMM_RSA_public.key
│
├── _sig/ # Script signatures (mirrors repo structure)
│ └── _framework/
│
└── RMM-Scripts/ # Your payload scripts go here
├── macOS/
└── Windows/
Create a fine-grained personal access token with read-only access to this repository:
- Navigate to GitHub Settings → Fine-grained tokens
- Click Generate new token
- Configure the token:
- Name:
GitExec-ReadOnly - Expiration: 90 days (recommended, rotate regularly)
- Repository access: Only select repositories → Choose this repository
- Permissions: Repository permissions → Contents → Read-only
- Name:
- Click Generate token
- Copy the token (format:
github_pat_...)
Locate the RSA public key in this repository at _key/AC-RMM_RSA_public.key. Copy the entire contents including the header and footer markers:
-----BEGIN PUBLIC KEY-----
MIICIjANBg...
-----END PUBLIC KEY-----
Choose the appropriate script for your platform and deploy via your RMM system.
Windows (PowerShell):
# One-time setup per endpoint (both secrets required)
$GitExec_GitHubPAT = "github_pat_YOUR_TOKEN_HERE"
$GitExec_RSA_Pub = "-----BEGIN PUBLIC KEY-----
MIICIjANBg...
-----END PUBLIC KEY-----"
.\_framework\_setup\WIN-GitExec_Secrets.ps1macOS (Bash):
# One-time setup per endpoint (both secrets required)
GitExec_GitHubPAT="github_pat_YOUR_TOKEN_HERE" \
GitExec_RSA_Pub="-----BEGIN PUBLIC KEY-----
MIICIjANBg...
-----END PUBLIC KEY-----" \
./_framework/_setup/macOS-GitExec_Secrets.shOnce configured, execute any script from this repository. All variables are RMM-provided (no editing of bootstrap scripts required).
Windows:
# Set in your RMM platform
$github_Org = "YOUR_GITHUB_ORG"
$github_Repo = "YOUR_SCRIPTS_REPO"
$scriptUrl = "https://github.com/YOUR_GITHUB_ORG/YOUR_SCRIPTS_REPO/blob/main/scripts/Windows/example-script.ps1"
.\_framework\_bootstrap\WIN-GitExec.ps1macOS:
# Set in your RMM platform
github_Org="YOUR_GITHUB_ORG" \
github_Repo="YOUR_SCRIPTS_REPO" \
scriptUrl="https://github.com/YOUR_GITHUB_ORG/YOUR_SCRIPTS_REPO/blob/main/scripts/macOS/example-script.sh" \
./_framework/_bootstrap/macOS-GitExec.sh- Create your script in
RMM-Scripts/Windows/orRMM-Scripts/macOS/ - Commit and push to GitHub
- Execute via the framework using the GitHub URL
┌──────────────────────────────────────────────────────────────┐
│ Execution Flow │
└──────────────────────────────────────────────────────────────┘
1. RMM deploys framework script to endpoint
2. Framework retrieves encrypted credentials from local storage
3. Framework downloads target script from GitHub using PAT
4. Framework verifies script signature (optional, infrastructure ready)
5. Script executes on endpoint (as SYSTEM/root or logged-in user)
6. Results return to RMM console
7. Downloaded script automatically deleted from endpoint
Windows:
- Storage: DPAPI encryption with LocalMachine scope
- Location:
C:\ProgramData\GitExec\ - Files:
GitExecPAT.bin- Encrypted GitHub PATGitExecRSA.bin- Encrypted RSA public key
- Access Control: Administrators and SYSTEM only
macOS:
- Storage: System Keychain (
/Library/Keychains/System.keychain) - PAT Entry:
- Service:
com.gitexec.github-pat - Account:
gitexec_pat
- Service:
- RSA Entry:
- Service:
com.gitexec.rsa-public-key - Account:
gitexec_rsa_pub
- Service:
- Access Control: Root and admin users only
Both secrets are required and managed as a unit:
- GitHub PAT - Authenticates to download scripts from private repository
- RSA Public Key - Verifies script signatures before execution (infrastructure ready)
Both secrets must be configured during initial setup and are cleared together when removing credentials.
The GitHub PAT requires minimal permissions:
- ✅ Repository Contents: Read-only
- ❌ No write access
- ❌ No admin access
- ❌ No access to other repositories
RSA signature verification infrastructure is ready for deployment:
- All scripts can be signed with a private key (stored securely by maintainer)
- Public key distributed to endpoints via secrets configuration
- Framework can verify signatures before execution using stored public key
Bootstrap scripts download the core library from GitHub at runtime.
Features:
- Small footprint on endpoints (~10KB bootstrap)
- Always uses latest framework code
- Automatic updates without redeployment
- Signature verification of downloaded library
Files:
- Windows:
_framework/_bootstrap/WIN-GitExec.ps1 - macOS:
_framework/_bootstrap/macOS-GitExec.sh
Windows:
$github_Org = "YOUR_GITHUB_ORG"
$github_Repo = "YOUR_SCRIPTS_REPO"
$scriptUrl = "https://github.com/YOUR_GITHUB_ORG/YOUR_SCRIPTS_REPO/blob/main/scripts/Windows/user-config.ps1"
$runAsUser = $true
.\_framework\_bootstrap\WIN-GitExec.ps1macOS:
github_Org="YOUR_GITHUB_ORG" \
github_Repo="YOUR_SCRIPTS_REPO" \
scriptUrl="https://github.com/YOUR_GITHUB_ORG/YOUR_SCRIPTS_REPO/blob/main/scripts/macOS/user-setup.sh" \
runAsUser="true" \
./_framework/_bootstrap/macOS-GitExec.shFor immediate updates without waiting for CDN cache expiration:
Windows:
$github_Org = "YOUR_GITHUB_ORG"
$github_Repo = "YOUR_SCRIPTS_REPO"
$scriptUrl = "https://github.com/YOUR_GITHUB_ORG/YOUR_SCRIPTS_REPO/blob/main/scripts/Windows/hotfix.ps1"
$useAPI = $true
.\_framework\_bootstrap\WIN-GitExec.ps1macOS:
github_Org="YOUR_GITHUB_ORG" \
github_Repo="YOUR_SCRIPTS_REPO" \
scriptUrl="https://github.com/YOUR_GITHUB_ORG/YOUR_SCRIPTS_REPO/blob/main/scripts/macOS/hotfix.sh" \
useAPI="true" \
./_framework/_bootstrap/macOS-GitExec.shWhen rotating your GitHub PAT or updating your RSA key:
Windows:
$GitExec_GitHubPAT = "github_pat_NEW_TOKEN_HERE"
$GitExec_RSA_Pub = "-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----"
$force_update = $true
.\_framework\_setup\WIN-GitExec_Secrets.ps1macOS:
GitExec_GitHubPAT="github_pat_NEW_TOKEN_HERE" \
GitExec_RSA_Pub="-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----" \
force_update="true" \
./_framework/_setup/macOS-GitExec_Secrets.shTo remove stored credentials from an endpoint:
Windows:
$clear_variable = $true
.\_framework\_setup\WIN-GitExec_Secrets.ps1macOS:
clear_variable="true" ./_framework/_setup/macOS-GitExec_Secrets.shThe framework returns standardized exit codes for automation:
0- Success1- Critical error or authentication failure>1- Script-specific error code
When running as multiple users (Windows $runAsUser = $true or macOS runAsUser="true"):
- Returns
1if any user script fails critically - Returns highest exit code if no critical failures
- Returns
0if all user scripts succeed
Run once to create RSA key pair for signing (maintainer only):
macOS/Linux:
cd _bin/_setup
./macOS-GitExec-gen_rsa_keys.shWindows:
cd _bin\_setup
.\WIN-GitExec-gen_rsa_keys.ps1This creates:
- Private key stored in Keychain/secure location
- Public key saved to
_key/AC-RMM_RSA_public.key
After adding or modifying scripts, generate new signatures:
macOS/Linux:
cd _bin
./macOS-GitExec-gen_sigs.shWindows:
cd _bin
.\WIN-GitExec-gen_sigs.ps1This creates/updates .sig files in the _sig/ folder mirroring repository structure.
"No stored PAT found" or "No stored secrets found"
- Ensure the secrets setter script was run first
- Verify both GitHub PAT and RSA public key were provided
- Confirm script ran with correct privileges (SYSTEM/root)
"Failed to download script"
- Check that GitHub PAT has not expired
- Verify network connectivity to github.com
- Confirm script URL is correct and accessible
"Must run as SYSTEM/root"
- Framework scripts require elevated privileges
- Configure RMM to run with SYSTEM (Windows) or root (macOS) privileges
Script URL format errors
- Use standard GitHub URLs, not raw URLs
- Example:
https://github.com/org/repo/blob/main/path/script.ps1 - Framework automatically converts to appropriate format
- Review script headers for detailed parameter documentation
- Check
_framework/README.mdfor comprehensive framework documentation - Verify GitHub PAT permissions and expiration
- Examine RMM logs for execution output and error messages
- Create your script in the appropriate folder:
- Windows scripts:
RMM-Scripts/Windows/ - macOS scripts:
RMM-Scripts/macOS/
- Windows scripts:
- Test locally to ensure proper functionality
- Commit with descriptive message following conventions
- Generate signatures:
cd _bin && ./macOS-GitExec-gen_sigs.sh(or Windows equivalent) - Push to GitHub
Windows Scripts:
- Format:
WIN-[Action]-[Target].ps1 - Example:
WIN-Get-SystemInfo.ps1 - Capitalize each word in PowerShell naming style
macOS Scripts:
- Format:
macOS-[action]-[target].sh - Example:
macOS-get-systeminfo.sh - Use lowercase with hyphens for bash naming style
- ✅ Include comprehensive script headers with synopsis, description, and examples
- ✅ Use consistent parameter naming across similar scripts
- ✅ Return appropriate exit codes (0 = success, 1 = critical error, >1 = specific errors)
- ✅ Clean up temporary files before exiting
- ✅ Log important operations for troubleshooting
- ✅ Test on clean endpoints before production deployment
- ✅ Document any external dependencies or requirements
See CHANGELOG.md for version history and release notes.
Copyright (C) 2026 Peet, Inc.
This project is licensed under the GNU General Public License v2.0 (GPLv2).
See the LICENSE file or https://www.gnu.org/licenses/old-licenses/gpl-2.0.html for details.
Important Security Practices:
- Rotate GitHub PATs every 90 days minimum
- Never commit PATs or private keys to version control
- Use fine-grained PATs with read-only permissions only
- Regularly audit PAT access in GitHub settings
- Monitor RMM logs for unusual activity
- Keep framework scripts updated to latest version
- Store private RSA keys securely (never in repository)
- Test secret rotation procedures before PAT expiration
- Framework Documentation: See
_framework/README.mdfor detailed technical documentation - Inspired By: TheFramework
- License: GNU General Public License v2.0
- Repository: https://github.com/YOUR_GITHUB_ORG/GitExec
Ready to get started? Follow the Quick Start guide above or refer to _framework/README.md for comprehensive technical documentation.