Set Up an Agent to Push Directly to a GitHub Repo
Set Up an Agent to Push Directly to a GitHub Repo
Goal
This guide walks through a gentle, practical way to let an agent such as Hermes commit and push directly to a GitHub repository without placing your main personal GitHub SSH key on the server.
The target architecture is:
Local developer machine -> GitHub repository
Hermes agent on server -> commit and push directly to master
The server uses a dedicated GitHub machine user and a dedicated SSH key:
Hermes agent -> dedicated machine user -> server-only SSH key -> minimal repo access
When to use this setup
This approach tends to fit well when:
- The agent needs to create commits.
- The agent needs to push changes back to GitHub.
- The server needs write access to the repository.
- You want commit history to clearly show which commits were made by the agent.
- You do not want your main personal GitHub key stored on the server.
If the server only needs to pull code, a read-only deploy key is usually enough. If the agent needs to push, a machine user is often cleaner than sharing a personal account key.
Required GitHub permissions
The machine user only needs:
Repository permission: Write
Write access allows the machine user to:
- Clone the repository.
- Pull updates.
- Create commits.
- Push branches.
- Push directly to
masterif branch rules allow it.
Try to avoid Admin unless the agent genuinely needs repository administration rights.
Step 1: Create a dedicated GitHub machine user
Create a separate GitHub account for the agent.
Example:
skywirex-hermes
Recommended account setup:
- Enable 2FA.
- Use a separate email address.
- Give the profile a clear automation identity.
- Prefer not to reuse your main GitHub account.
Example display name:
Hermes Agent
GitHub allows manually created machine users for automation. In most cases, it is best to avoid auto-created accounts or multiple accounts for the same workflow.
Step 2: Add the machine user to the repository
Open the target repository on GitHub.
For a personal repository:
Repository -> Settings -> Collaborators
For an organization repository:
Repository -> Settings -> Collaborators and teams
Add the machine user:
skywirex-hermes
Give it:
Write
Then log in as the machine user and accept the invitation.
Step 3: Generate a dedicated SSH key on the server
SSH into the server using the same Linux user that runs the agent:
ssh your-user@your-server
Generate a dedicated SSH key:
ssh-keygen -t ed25519 -C "hermes@your-server"
When prompted for the key path, use a clear filename:
~/.ssh/id_ed25519_hermes_github
For unattended automation, leaving the passphrase empty is usually simpler, though it does make server security more important. If you prefer a passphrase, just make sure the agent runtime has a proper SSH agent setup.
Print the public key:
cat ~/.ssh/id_ed25519_hermes_github.pub
Copy the full public key line.
Step 4: Add the SSH key to the machine user
Log in to GitHub as the machine user.
Go to:
Settings -> SSH and GPG keys -> New SSH key
Use:
Title: production-server-hermes
Key type: Authentication Key
Key: paste the public key from the server
Save the key.
Add this key to the machine user account rather than your main personal GitHub account.
Step 5: Configure an SSH alias on the server
Edit SSH config on the server:
nano ~/.ssh/config
Add:
Host github-hermes
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_hermes_github
IdentitiesOnly yes
Set permissions:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519_hermes_github
chmod 600 ~/.ssh/config
Test authentication:
ssh -T github-hermes
Expected result:
Hi skywirex-hermes! You've successfully authenticated...
Step 6: Configure the repository remote
Enter the repository directory on the server:
cd /path/to/your/repo
Check the current remote:
git remote -v
Set the remote to use the SSH alias:
git remote set-url origin git@github-hermes:OWNER/REPO.git
Example:
git remote set-url origin git@github-hermes:skywirex/brain.git
Verify:
git remote -v
Expected shape:
origin git@github-hermes:skywirex/brain.git (fetch)
origin git@github-hermes:skywirex/brain.git (push)
Step 7: Configure Git commit identity
Inside the repository on the server:
git config user.name "Hermes Agent"
git config user.email "[email protected]"
If the machine user’s GitHub noreply email has a different format, get it from:
GitHub -> Settings -> Emails
Verify:
git config user.name
git config user.email
Expected result:
Hermes Agent
[email protected]
Step 8: Allow direct pushes to master
If the repository has no branch protection or ruleset blocking master, Write access is enough for direct pushes.
If branch protection is in place, open:
Repository -> Settings -> Branches
Check the rule for:
master
To let the agent push directly to master, make sure these settings are not blocking it:
Require a pull request before merging: off
Require status checks before merging: off
Restrict who can push to matching branches: off
If you want to keep protection rules, add the machine user as an allowed bypass or allowed pusher if your GitHub plan and repository settings support it.
The simplest direct-push configuration usually looks like this:
Machine user: Write access
master: no required pull request
master: no required status checks
master: no push restriction
It is usually best to avoid force-push permission unless you have a very specific recovery workflow in mind.
Step 9: Test pull and push
On the server:
cd /path/to/your/repo
git checkout master
git pull --rebase origin master
Create an empty test commit:
git commit --allow-empty -m "Test Hermes push"
Push directly to master:
git push origin master
If this succeeds, the setup is in good shape.
Check GitHub. The commit should appear under the machine user or the configured commit identity:
Hermes Agent
Step 10: Let Hermes use the repository
It helps if Hermes runs as the same Linux user that owns the SSH key and repository checkout.
The runtime user should be able to access:
~/.ssh/id_ed25519_hermes_github
~/.ssh/config
/path/to/your/repo
A typical sync sequence for Hermes is:
git pull --rebase origin master
git add .
git commit -m "Update from Hermes"
git push origin master
Using git pull --rebase before committing or pushing can reduce conflicts when your local machine and the server both push to the same branch.
Daily workflow
From your local machine:
git pull origin master
# edit files
git add .
git commit -m "Update from local"
git push origin master
From the server or Hermes:
git pull --rebase origin master
# agent edits files
git add .
git commit -m "Update from Hermes"
git push origin master
Both sides can push to the same master branch while still using separate identities and separate SSH keys.
Security risks
Direct agent pushes to master are convenient, though they do carry real risk:
- The agent can push broken commits.
- The server and local machine can create Git conflicts.
- If the server is compromised, an attacker can push to the repository.
- If the agent writes incorrect files,
masterhistory can become noisy.
Risk reduction checklist:
Keep Admin permission off the machine user.
Keep your main personal SSH key off the server.
Avoid force push unless it is truly necessary.
Enable 2FA for the machine user.
Use clear commit messages.
Back up the repository and server.
Review commit history regularly.
Revoking access
If the server is compromised or the agent should no longer have access, revoke access right away.
Option 1: remove the SSH key from the machine user:
GitHub machine user -> Settings -> SSH and GPG keys
Delete:
production-server-hermes
Option 2: remove the machine user from the repository:
Repository -> Settings -> Collaborators
Remove:
skywirex-hermes
Option 3: remove the local key from the server:
rm ~/.ssh/id_ed25519_hermes_github
rm ~/.ssh/id_ed25519_hermes_github.pub
Final setup
Recommended final state:
Machine user: skywirex-hermes
Repository permission: Write
Server SSH key: dedicated Hermes key
Remote URL: git@github-hermes:OWNER/REPO.git
Branch: master
Branch protection: does not block direct push
This setup is a practical balance between:
Simple deployment
No personal key on the server
Minimal required repository permission
Clear commit attribution
Easy access revocation